3 static void flush_current_id(int patchlen
, unsigned char *id
, git_SHA_CTX
*c
)
5 unsigned char result
[20];
11 git_SHA1_Final(result
, c
);
12 memcpy(name
, sha1_to_hex(id
), 41);
13 printf("%s %s\n", sha1_to_hex(result
), name
);
17 static int remove_space(char *line
)
23 while ((c
= *src
++) != '\0') {
30 static int scan_hunk_header(const char *p
, int *p_before
, int *p_after
)
32 static const char digits
[] = "0123456789";
37 n
= strspn(q
, digits
);
40 n
= strspn(q
, digits
);
42 if (n
== 0 || q
[n
] != ' ' || q
[n
+1] != '+')
46 n
= strspn(r
, digits
);
49 n
= strspn(r
, digits
);
59 static int get_one_patchid(unsigned char *next_sha1
, git_SHA_CTX
*ctx
, struct strbuf
*line_buf
)
61 int patchlen
= 0, found_next
= 0;
62 int before
= -1, after
= -1;
64 while (strbuf_getwholeline(line_buf
, stdin
, '\n') != EOF
) {
65 char *line
= line_buf
->buf
;
69 if (!memcmp(line
, "diff-tree ", 10))
71 else if (!memcmp(line
, "commit ", 7))
73 else if (!memcmp(line
, "From ", 5))
75 else if (!memcmp(line
, "\\ ", 2) && 12 < strlen(line
))
78 if (!get_sha1_hex(p
, next_sha1
)) {
83 /* Ignore commit comments */
84 if (!patchlen
&& memcmp(line
, "diff ", 5))
87 /* Parsing diff header? */
89 if (!memcmp(line
, "index ", 6))
91 else if (!memcmp(line
, "--- ", 4))
93 else if (!isalpha(line
[0]))
97 /* Looking for a valid hunk header? */
98 if (before
== 0 && after
== 0) {
99 if (!memcmp(line
, "@@ -", 4)) {
100 /* Parse next hunk, but ignore line numbers. */
101 scan_hunk_header(line
, &before
, &after
);
105 /* Split at the end of the patch. */
106 if (memcmp(line
, "diff ", 5))
109 /* Else we're parsing another header. */
113 /* If we get here, we're inside a hunk. */
114 if (line
[0] == '-' || line
[0] == ' ')
116 if (line
[0] == '+' || line
[0] == ' ')
119 /* Compute the sha without whitespace */
120 len
= remove_space(line
);
122 git_SHA1_Update(ctx
, line
, len
);
131 static void generate_id_list(void)
133 unsigned char sha1
[20], n
[20];
136 struct strbuf line_buf
= STRBUF_INIT
;
140 while (!feof(stdin
)) {
141 patchlen
= get_one_patchid(n
, &ctx
, &line_buf
);
142 flush_current_id(patchlen
, sha1
, &ctx
);
145 strbuf_release(&line_buf
);
148 static const char patch_id_usage
[] = "git patch-id < patch";
150 int cmd_patch_id(int argc
, const char **argv
, const char *prefix
)
153 usage(patch_id_usage
);