commit: Let the callback of for_each_mergetag return on error
This is yet another patch to be filed under the keyword "libification". There is one subtle change in behavior here, where a `git log` that has been asked to show the mergetags would now stop reporting the mergetags upon the first failure, whereas previously, it would have continued to the next mergetag, if any. In practice, that change should not matter, as it is 1) uncommon to perform octopus merges using multiple tags as merge heads, and 2) when the user asks to be shown those tags, they really should be there. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Apr 25, 2018 at 11:54 UTC
fef461ea5d53dd84c6d946f57a018ffc9f391a05
4 files changed
+18
-15
builtin/replace.c
+4
-4
@@ -345,7 +345,7 @@ struct check_mergetag_data {
345
const char **argv;
346
};
347
348
-static void check_one_mergetag(struct commit *commit,
348
+static int check_one_mergetag(struct commit *commit,
349
struct commit_extra_header *extra,
350
void *data)
351
{
@@ -368,20 +368,20 @@ static void check_one_mergetag(struct commit *commit,
368
if (get_oid(mergetag_data->argv[i], &oid) < 0)
369
die(_("Not a valid object name: '%s'"), mergetag_data->argv[i]);
370
if (!oidcmp(&tag->tagged->oid, &oid))
371
- return; /* found */
371
+ return 0; /* found */
372
}
373
374
die(_("original commit '%s' contains mergetag '%s' that is discarded; "
375
"use --edit instead of --graft"), ref, oid_to_hex(&tag_oid));
376
}
377
378
-static void check_mergetags(struct commit *commit, int argc, const char **argv)
378
+static int check_mergetags(struct commit *commit, int argc, const char **argv)
379
{
380
struct check_mergetag_data mergetag_data;
381
382
mergetag_data.argc = argc;
383
mergetag_data.argv = argv;
384
- for_each_mergetag(check_one_mergetag, commit, &mergetag_data);
384
+ return for_each_mergetag(check_one_mergetag, commit, &mergetag_data);
385
}
386
387
static int create_graft(int argc, const char **argv, int force)
commit.c
+5
-3
@@ -1288,17 +1288,19 @@ struct commit_extra_header *read_commit_extra_headers(struct commit *commit,
1288
return extra;
1289
}
1290
1291
-void for_each_mergetag(each_mergetag_fn fn, struct commit *commit, void *data)
1291
+int for_each_mergetag(each_mergetag_fn fn, struct commit *commit, void *data)
1292
{
1293
struct commit_extra_header *extra, *to_free;
1294
+ int res = 0;
1295
1296
to_free = read_commit_extra_headers(commit, NULL);
1296
- for (extra = to_free; extra; extra = extra->next) {
1297
+ for (extra = to_free; !res && extra; extra = extra->next) {
1298
if (strcmp(extra->key, "mergetag"))
1299
continue; /* not a merge tag */
1299
- fn(commit, extra, data);
1300
+ res = fn(commit, extra, data);
1301
}
1302
free_commit_extra_headers(to_free);
1303
+ return res;
1304
}
1305
1306
static inline int standard_header_field(const char *field, size_t len)
commit.h
+2
-2
@@ -291,10 +291,10 @@ extern const char *find_commit_header(const char *msg, const char *key,
291
/* Find the end of the log message, the right place for a new trailer. */
292
extern int ignore_non_trailer(const char *buf, size_t len);
293
294
-typedef void (*each_mergetag_fn)(struct commit *commit, struct commit_extra_header *extra,
294
+typedef int (*each_mergetag_fn)(struct commit *commit, struct commit_extra_header *extra,
295
void *cb_data);
296
297
-extern void for_each_mergetag(each_mergetag_fn fn, struct commit *commit, void *data);
297
+extern int for_each_mergetag(each_mergetag_fn fn, struct commit *commit, void *data);
298
299
struct merge_remote_desc {
300
struct object *obj; /* the named object, could be a tag */
log-tree.c
+7
-6
@@ -488,9 +488,9 @@ static int is_common_merge(const struct commit *commit)
488
&& !commit->parents->next->next);
489
}
490
491
-static void show_one_mergetag(struct commit *commit,
492
- struct commit_extra_header *extra,
493
- void *data)
491
+static int show_one_mergetag(struct commit *commit,
492
+ struct commit_extra_header *extra,
493
+ void *data)
494
{
495
struct rev_info *opt = (struct rev_info *)data;
496
struct object_id oid;
@@ -502,7 +502,7 @@ static void show_one_mergetag(struct commit *commit,
502
hash_object_file(extra->value, extra->len, type_name(OBJ_TAG), &oid);
503
tag = lookup_tag(&oid);
504
if (!tag)
505
- return; /* error message already given */
505
+ return -1; /* error message already given */
506
507
strbuf_init(&verify_message, 256);
508
if (parse_tag_buffer(tag, extra->value, extra->len))
@@ -536,11 +536,12 @@ static void show_one_mergetag(struct commit *commit,
536
537
show_sig_lines(opt, status, verify_message.buf);
538
strbuf_release(&verify_message);
539
+ return 0;
540
}
541
541
-static void show_mergetag(struct rev_info *opt, struct commit *commit)
542
+static int show_mergetag(struct rev_info *opt, struct commit *commit)
543
{
543
- for_each_mergetag(show_one_mergetag, commit, opt);
544
+ return for_each_mergetag(show_one_mergetag, commit, opt);
545
}
546
547
void show_log(struct rev_info *opt)