replace: peel tag when passing a tag as parent to --graft

When passing a tag as a parent argument to `git replace --graft`, it can be useful to accept it and use the underlying commit as a parent. This already works for lightweight tags, but unfortunately for annotated tags we have been using the hash of the tag object instead of the hash of the underlying commit as a parent in the replacement object we create. This created invalid objects, but the replace succeeded even if it showed an error like: error: object A is a tag, not a commit This patch fixes that by using the hash of the underlying commit when an annotated tag is passed. While at it, let's also update an error message to make it clearer. Reviewed-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Christian Couder committed Mar 31, 2019 at 15:46 UTC f8e44a81bf82ae35e37500f9597e93b0bdfc05e4
2 files changed +17 -3
builtin/replace.c
+6 -3
@@ -366,16 +366,19 @@ static int replace_parents(struct strbuf *buf, int argc, const char **argv)
366 /* prepare new parents */
367 for (i = 0; i < argc; i++) {
368 struct object_id oid;
369 + struct commit *commit;
370 +
371 if (get_oid(argv[i], &oid) < 0) {
372 strbuf_release(&new_parents);
373 return error(_("not a valid object name: '%s'"),
374 argv[i]);
375 }
374 - if (!lookup_commit_reference(the_repository, &oid)) {
376 + commit = lookup_commit_reference(the_repository, &oid);
377 + if (!commit) {
378 strbuf_release(&new_parents);
376 - return error(_("could not parse %s"), argv[i]);
379 + return error(_("could not parse %s as a commit"), argv[i]);
380 }
378 - strbuf_addf(&new_parents, "parent %s\n", oid_to_hex(&oid));
381 + strbuf_addf(&new_parents, "parent %s\n", oid_to_hex(&commit->object.oid));
382 }
383
384 /* replace existing parents with new ones */
t/t6050-replace.sh
+11
@@ -406,6 +406,17 @@ test_expect_success '--graft with and without already replaced object' '
406 git replace -d $HASH5
407 '
408
409 +test_expect_success '--graft using a tag as the new parent' '
410 + git tag new_parent $HASH5 &&
411 + git replace --graft $HASH7 new_parent &&
412 + commit_has_parents $HASH7 $HASH5 &&
413 + git replace -d $HASH7 &&
414 + git tag -a -m "annotated new parent tag" annotated_new_parent $HASH5 &&
415 + git replace --graft $HASH7 annotated_new_parent &&
416 + commit_has_parents $HASH7 $HASH5 &&
417 + git replace -d $HASH7
418 +'
419 +
420 test_expect_success GPG 'set up a signed commit' '
421 echo "line 17" >>hello &&
422 echo "line 18" >>hello &&