2019-08-18 20:04:03 +00:00
|
|
|
#include "cache.h"
|
Fix sparse warnings
Fix warnings from 'make check'.
- These files don't include 'builtin.h' causing sparse to complain that
cmd_* isn't declared:
builtin/clone.c:364, builtin/fetch-pack.c:797,
builtin/fmt-merge-msg.c:34, builtin/hash-object.c:78,
builtin/merge-index.c:69, builtin/merge-recursive.c:22
builtin/merge-tree.c:341, builtin/mktag.c:156, builtin/notes.c:426
builtin/notes.c:822, builtin/pack-redundant.c:596,
builtin/pack-refs.c:10, builtin/patch-id.c:60, builtin/patch-id.c:149,
builtin/remote.c:1512, builtin/remote-ext.c:240,
builtin/remote-fd.c:53, builtin/reset.c:236, builtin/send-pack.c:384,
builtin/unpack-file.c:25, builtin/var.c:75
- These files have symbols which should be marked static since they're
only file scope:
submodule.c:12, diff.c:631, replace_object.c:92, submodule.c:13,
submodule.c:14, trace.c:78, transport.c:195, transport-helper.c:79,
unpack-trees.c:19, url.c:3, url.c:18, url.c:104, url.c:117, url.c:123,
url.c:129, url.c:136, thread-utils.c:21, thread-utils.c:48
- These files redeclare symbols to be different types:
builtin/index-pack.c:210, parse-options.c:564, parse-options.c:571,
usage.c:49, usage.c:58, usage.c:63, usage.c:72
- These files use a literal integer 0 when they really should use a NULL
pointer:
daemon.c:663, fast-import.c:2942, imap-send.c:1072, notes-merge.c:362
While we're in the area, clean up some unused #includes in builtin files
(mostly exec_cmd.h).
Signed-off-by: Stephen Boyd <bebarino@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-03-22 07:51:05 +00:00
|
|
|
#include "builtin.h"
|
2017-06-14 18:07:36 +00:00
|
|
|
#include "config.h"
|
2019-04-26 23:51:57 +00:00
|
|
|
#include "diff.h"
|
2005-06-23 22:06:04 +00:00
|
|
|
|
2015-03-13 23:39:35 +00:00
|
|
|
static void flush_current_id(int patchlen, struct object_id *id, struct object_id *result)
|
2005-06-23 22:06:04 +00:00
|
|
|
{
|
2019-08-18 20:04:03 +00:00
|
|
|
char name[GIT_MAX_HEXSZ + 1];
|
2005-06-23 22:06:04 +00:00
|
|
|
|
|
|
|
if (!patchlen)
|
|
|
|
return;
|
|
|
|
|
2019-08-18 20:04:03 +00:00
|
|
|
memcpy(name, oid_to_hex(id), the_hash_algo->hexsz + 1);
|
2015-03-13 23:39:35 +00:00
|
|
|
printf("%s %s\n", oid_to_hex(result), name);
|
2005-06-23 22:06:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int remove_space(char *line)
|
|
|
|
{
|
|
|
|
char *src = line;
|
|
|
|
char *dst = line;
|
|
|
|
unsigned char c;
|
|
|
|
|
|
|
|
while ((c = *src++) != '\0') {
|
|
|
|
if (!isspace(c))
|
|
|
|
*dst++ = c;
|
|
|
|
}
|
|
|
|
return dst - line;
|
|
|
|
}
|
|
|
|
|
2010-04-19 08:46:14 +00:00
|
|
|
static int scan_hunk_header(const char *p, int *p_before, int *p_after)
|
|
|
|
{
|
|
|
|
static const char digits[] = "0123456789";
|
|
|
|
const char *q, *r;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
q = p + 4;
|
|
|
|
n = strspn(q, digits);
|
|
|
|
if (q[n] == ',') {
|
|
|
|
q += n + 1;
|
|
|
|
n = strspn(q, digits);
|
|
|
|
}
|
|
|
|
if (n == 0 || q[n] != ' ' || q[n+1] != '+')
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
r = q + n + 2;
|
|
|
|
n = strspn(r, digits);
|
|
|
|
if (r[n] == ',') {
|
|
|
|
r += n + 1;
|
|
|
|
n = strspn(r, digits);
|
|
|
|
}
|
|
|
|
if (n == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
*p_before = atoi(q);
|
|
|
|
*p_after = atoi(r);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-03-13 23:39:35 +00:00
|
|
|
static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
|
2014-04-27 18:15:44 +00:00
|
|
|
struct strbuf *line_buf, int stable)
|
2005-06-23 22:06:04 +00:00
|
|
|
{
|
2010-04-19 08:46:13 +00:00
|
|
|
int patchlen = 0, found_next = 0;
|
2010-04-19 08:46:14 +00:00
|
|
|
int before = -1, after = -1;
|
2019-08-18 20:04:03 +00:00
|
|
|
git_hash_ctx ctx;
|
2014-04-27 18:15:44 +00:00
|
|
|
|
2019-08-18 20:04:03 +00:00
|
|
|
the_hash_algo->init_fn(&ctx);
|
2015-03-13 23:39:35 +00:00
|
|
|
oidclr(result);
|
2005-06-23 22:06:04 +00:00
|
|
|
|
2011-09-21 12:42:22 +00:00
|
|
|
while (strbuf_getwholeline(line_buf, stdin, '\n') != EOF) {
|
|
|
|
char *line = line_buf->buf;
|
2016-05-28 16:20:23 +00:00
|
|
|
const char *p = line;
|
2005-06-23 22:06:04 +00:00
|
|
|
int len;
|
|
|
|
|
2016-05-28 16:20:23 +00:00
|
|
|
if (!skip_prefix(line, "diff-tree ", &p) &&
|
|
|
|
!skip_prefix(line, "commit ", &p) &&
|
|
|
|
!skip_prefix(line, "From ", &p) &&
|
|
|
|
starts_with(line, "\\ ") && 12 < strlen(line))
|
2011-02-17 07:44:42 +00:00
|
|
|
continue;
|
2005-06-23 22:06:04 +00:00
|
|
|
|
2015-03-13 23:39:35 +00:00
|
|
|
if (!get_oid_hex(p, next_oid)) {
|
2010-04-19 08:46:13 +00:00
|
|
|
found_next = 1;
|
|
|
|
break;
|
2005-06-23 22:06:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Ignore commit comments */
|
2016-05-28 16:20:23 +00:00
|
|
|
if (!patchlen && !starts_with(line, "diff "))
|
2005-06-23 22:06:04 +00:00
|
|
|
continue;
|
|
|
|
|
2010-04-19 08:46:14 +00:00
|
|
|
/* Parsing diff header? */
|
|
|
|
if (before == -1) {
|
2016-05-28 16:20:23 +00:00
|
|
|
if (starts_with(line, "index "))
|
2010-04-19 08:46:14 +00:00
|
|
|
continue;
|
2016-05-28 16:20:23 +00:00
|
|
|
else if (starts_with(line, "--- "))
|
2010-04-19 08:46:14 +00:00
|
|
|
before = after = 1;
|
|
|
|
else if (!isalpha(line[0]))
|
|
|
|
break;
|
|
|
|
}
|
2005-10-09 23:52:50 +00:00
|
|
|
|
2010-04-19 08:46:14 +00:00
|
|
|
/* Looking for a valid hunk header? */
|
|
|
|
if (before == 0 && after == 0) {
|
2016-05-28 16:20:23 +00:00
|
|
|
if (starts_with(line, "@@ -")) {
|
2010-04-19 08:46:14 +00:00
|
|
|
/* Parse next hunk, but ignore line numbers. */
|
|
|
|
scan_hunk_header(line, &before, &after);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Split at the end of the patch. */
|
2016-05-28 16:20:23 +00:00
|
|
|
if (!starts_with(line, "diff "))
|
2010-04-19 08:46:14 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
/* Else we're parsing another header. */
|
2014-04-27 18:15:44 +00:00
|
|
|
if (stable)
|
|
|
|
flush_one_hunk(result, &ctx);
|
2010-04-19 08:46:14 +00:00
|
|
|
before = after = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we get here, we're inside a hunk. */
|
|
|
|
if (line[0] == '-' || line[0] == ' ')
|
|
|
|
before--;
|
|
|
|
if (line[0] == '+' || line[0] == ' ')
|
|
|
|
after--;
|
2005-06-23 22:06:04 +00:00
|
|
|
|
|
|
|
/* Compute the sha without whitespace */
|
|
|
|
len = remove_space(line);
|
|
|
|
patchlen += len;
|
2019-08-18 20:04:03 +00:00
|
|
|
the_hash_algo->update_fn(&ctx, line, len);
|
2010-04-19 08:46:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!found_next)
|
2015-03-13 23:39:35 +00:00
|
|
|
oidclr(next_oid);
|
2010-04-19 08:46:13 +00:00
|
|
|
|
2014-04-27 18:15:44 +00:00
|
|
|
flush_one_hunk(result, &ctx);
|
|
|
|
|
2010-04-19 08:46:13 +00:00
|
|
|
return patchlen;
|
|
|
|
}
|
|
|
|
|
2014-04-27 18:15:44 +00:00
|
|
|
static void generate_id_list(int stable)
|
2010-04-19 08:46:13 +00:00
|
|
|
{
|
2015-03-13 23:39:35 +00:00
|
|
|
struct object_id oid, n, result;
|
2010-04-19 08:46:13 +00:00
|
|
|
int patchlen;
|
2011-09-21 12:42:22 +00:00
|
|
|
struct strbuf line_buf = STRBUF_INIT;
|
2010-04-19 08:46:13 +00:00
|
|
|
|
2015-03-13 23:39:35 +00:00
|
|
|
oidclr(&oid);
|
2010-04-19 08:46:13 +00:00
|
|
|
while (!feof(stdin)) {
|
2015-03-13 23:39:35 +00:00
|
|
|
patchlen = get_one_patchid(&n, &result, &line_buf, stable);
|
|
|
|
flush_current_id(patchlen, &oid, &result);
|
|
|
|
oidcpy(&oid, &n);
|
2005-06-23 22:06:04 +00:00
|
|
|
}
|
2011-09-21 12:42:22 +00:00
|
|
|
strbuf_release(&line_buf);
|
2005-06-23 22:06:04 +00:00
|
|
|
}
|
|
|
|
|
usage: do not insist that standard input must come from a file
The synopsys text and the usage string of subcommands that read list
of things from the standard input are often shown like this:
git gostak [--distim] < <list-of-doshes>
This is problematic in a number of ways:
* The way to use these commands is more often to feed them the
output from another command, not feed them from a file.
* Manual pages outside Git, commands that operate on the data read
from the standard input, e.g "sort", "grep", "sed", etc., are not
described with such a "< redirection-from-file" in their synopsys
text. Our doing so introduces inconsistency.
* We do not insist on where the output should go, by saying
git gostak [--distim] < <list-of-doshes> > <output>
* As it is our convention to enclose placeholders inside <braket>,
the redirection operator followed by a placeholder filename
becomes very hard to read, both in the documentation and in the
help text.
Let's clean them all up, after making sure that the documentation
clearly describes the modes that take information from the standard
input and what kind of things are expected on the input.
[jc: stole example for fmt-merge-msg from Jonathan]
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-10-16 18:27:42 +00:00
|
|
|
static const char patch_id_usage[] = "git patch-id [--stable | --unstable]";
|
2014-04-27 18:15:44 +00:00
|
|
|
|
|
|
|
static int git_patch_id_config(const char *var, const char *value, void *cb)
|
|
|
|
{
|
|
|
|
int *stable = cb;
|
|
|
|
|
|
|
|
if (!strcmp(var, "patchid.stable")) {
|
|
|
|
*stable = git_config_bool(var, value);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return git_default_config(var, value, cb);
|
|
|
|
}
|
2005-06-23 22:06:04 +00:00
|
|
|
|
2010-01-22 04:31:25 +00:00
|
|
|
int cmd_patch_id(int argc, const char **argv, const char *prefix)
|
2005-06-23 22:06:04 +00:00
|
|
|
{
|
2014-04-27 18:15:44 +00:00
|
|
|
int stable = -1;
|
|
|
|
|
|
|
|
git_config(git_patch_id_config, &stable);
|
|
|
|
|
|
|
|
/* If nothing is set, default to unstable. */
|
|
|
|
if (stable < 0)
|
|
|
|
stable = 0;
|
|
|
|
|
|
|
|
if (argc == 2 && !strcmp(argv[1], "--stable"))
|
|
|
|
stable = 1;
|
|
|
|
else if (argc == 2 && !strcmp(argv[1], "--unstable"))
|
|
|
|
stable = 0;
|
|
|
|
else if (argc != 1)
|
2005-06-23 22:06:04 +00:00
|
|
|
usage(patch_id_usage);
|
|
|
|
|
2014-04-27 18:15:44 +00:00
|
|
|
generate_id_list(stable);
|
2005-06-23 22:06:04 +00:00
|
|
|
return 0;
|
2007-06-07 07:04:01 +00:00
|
|
|
}
|