7
7
#include "parse-options.h"
8
8
#include "setup.h"
9
9
10
- static void flush_current_id (int patchlen , struct object_id * id , struct object_id * result )
10
+ static void flush_current_id (struct object_id * id , struct object_id * result )
11
11
{
12
- if (patchlen )
13
- printf ("%s %s\n" , oid_to_hex (result ), oid_to_hex (id ));
12
+ printf ("%s %s\n" , oid_to_hex (result ), oid_to_hex (id ));
14
13
}
15
14
16
15
static int remove_space (char * line )
@@ -60,9 +59,27 @@ static int scan_hunk_header(const char *p, int *p_before, int *p_after)
60
59
return 1 ;
61
60
}
62
61
62
+ /*
63
+ * flag bits to control get_one_patchid()'s behaviour.
64
+ *
65
+ * STABLE/VERBATIM are given from the command line option as
66
+ * --stable/--verbatim. FIND_HEADER conveys the internal state
67
+ * maintained by the caller to allow the function to avoid mistaking
68
+ * lines of log message before seeing the "diff" part as the beginning
69
+ * of the next patch.
70
+ */
71
+ enum {
72
+ GOPID_STABLE = (1 <<0 ), /* --stable */
73
+ GOPID_VERBATIM = (1 <<1 ), /* --verbatim */
74
+ GOPID_FIND_HEADER = (1 <<2 ), /* stop at the beginning of patch message */
75
+ };
76
+
63
77
static int get_one_patchid (struct object_id * next_oid , struct object_id * result ,
64
- struct strbuf * line_buf , int stable , int verbatim )
78
+ struct strbuf * line_buf , unsigned flags )
65
79
{
80
+ int stable = flags & GOPID_STABLE ;
81
+ int verbatim = flags & GOPID_VERBATIM ;
82
+ int find_header = flags & GOPID_FIND_HEADER ;
66
83
int patchlen = 0 , found_next = 0 ;
67
84
int before = -1 , after = -1 ;
68
85
int diff_is_binary = 0 ;
@@ -77,24 +94,40 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
77
94
const char * p = line ;
78
95
int len ;
79
96
80
- /* Possibly skip over the prefix added by "log" or "format-patch" */
81
- if (!skip_prefix (line , "commit " , & p ) &&
82
- !skip_prefix (line , "From " , & p ) &&
83
- starts_with (line , "\\ " ) && 12 < strlen (line )) {
84
- if (verbatim )
85
- the_hash_algo -> update_fn (& ctx , line , strlen (line ));
86
- continue ;
87
- }
88
-
89
- if (!get_oid_hex (p , next_oid )) {
90
- found_next = 1 ;
91
- break ;
97
+ /*
98
+ * The caller hasn't seen us find a patch header and
99
+ * return to it, or we have started processing patch
100
+ * and may encounter the beginning of the next patch.
101
+ */
102
+ if (find_header ) {
103
+ /*
104
+ * If we see a line that begins with "<object name>",
105
+ * "commit <object name>" or "From <object name>", it is
106
+ * the beginning of a patch. Return to the caller, as
107
+ * we are done with the one we have been processing.
108
+ */
109
+ if (skip_prefix (line , "commit " , & p ))
110
+ ;
111
+ else if (skip_prefix (line , "From " , & p ))
112
+ ;
113
+ if (!get_oid_hex (p , next_oid )) {
114
+ if (verbatim )
115
+ the_hash_algo -> update_fn (& ctx , line , strlen (line ));
116
+ found_next = 1 ;
117
+ break ;
118
+ }
92
119
}
93
120
94
121
/* Ignore commit comments */
95
122
if (!patchlen && !starts_with (line , "diff " ))
96
123
continue ;
97
124
125
+ /*
126
+ * We are past the commit log message. Prepare to
127
+ * stop at the beginning of the next patch header.
128
+ */
129
+ find_header = 1 ;
130
+
98
131
/* Parsing diff header? */
99
132
if (before == -1 ) {
100
133
if (starts_with (line , "GIT binary patch" ) ||
@@ -127,6 +160,16 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
127
160
break ;
128
161
}
129
162
163
+ /*
164
+ * A hunk about an incomplete line may have this
165
+ * marker at the end, which should just be ignored.
166
+ */
167
+ if (starts_with (line , "\\ " ) && 12 < strlen (line )) {
168
+ if (verbatim )
169
+ the_hash_algo -> update_fn (& ctx , line , strlen (line ));
170
+ continue ;
171
+ }
172
+
130
173
if (diff_is_binary ) {
131
174
if (starts_with (line , "diff " )) {
132
175
diff_is_binary = 0 ;
@@ -173,17 +216,20 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
173
216
return patchlen ;
174
217
}
175
218
176
- static void generate_id_list (int stable , int verbatim )
219
+ static void generate_id_list (unsigned flags )
177
220
{
178
221
struct object_id oid , n , result ;
179
222
int patchlen ;
180
223
struct strbuf line_buf = STRBUF_INIT ;
181
224
182
225
oidclr (& oid , the_repository -> hash_algo );
226
+ flags |= GOPID_FIND_HEADER ;
183
227
while (!feof (stdin )) {
184
- patchlen = get_one_patchid (& n , & result , & line_buf , stable , verbatim );
185
- flush_current_id (patchlen , & oid , & result );
228
+ patchlen = get_one_patchid (& n , & result , & line_buf , flags );
229
+ if (patchlen )
230
+ flush_current_id (& oid , & result );
186
231
oidcpy (& oid , & n );
232
+ flags &= ~GOPID_FIND_HEADER ;
187
233
}
188
234
strbuf_release (& line_buf );
189
235
}
@@ -219,6 +265,7 @@ int cmd_patch_id(int argc, const char **argv, const char *prefix)
219
265
/* if nothing is set, default to unstable */
220
266
struct patch_id_opts config = {0 , 0 };
221
267
int opts = 0 ;
268
+ unsigned flags = 0 ;
222
269
struct option builtin_patch_id_options [] = {
223
270
OPT_CMDMODE (0 , "unstable" , & opts ,
224
271
N_ ("use the unstable patch-id algorithm" ), 1 ),
@@ -250,7 +297,11 @@ int cmd_patch_id(int argc, const char **argv, const char *prefix)
250
297
if (!the_hash_algo )
251
298
repo_set_hash_algo (the_repository , GIT_HASH_SHA1 );
252
299
253
- generate_id_list (opts ? opts > 1 : config .stable ,
254
- opts ? opts == 3 : config .verbatim );
300
+ if (opts ? opts > 1 : config .stable )
301
+ flags |= GOPID_STABLE ;
302
+ if (opts ? opts == 3 : config .verbatim )
303
+ flags |= GOPID_VERBATIM ;
304
+ generate_id_list (flags );
305
+
255
306
return 0 ;
256
307
}
0 commit comments