replace: peel tag when passing a tag first to --graft
authorChristian Couder <christian.couder@gmail.com>
Sun, 31 Mar 2019 13:46:59 +0000 (15:46 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 15 Apr 2019 02:33:23 +0000 (11:33 +0900)
When passing a tag as the first argument to `git replace --graft`,
it can be useful to accept it and use the underlying commit as a
the commit that will be replaced.

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.

Especially we would pass the hash of the tag object to
replace_object_oid() where we would likely fail with an error
like:

"error: Objects must be of the same type.
'annotated_replaced_object' points to a replaced object of type 'tag'
while 'replacement' points to a replacement object of type 'commit'."

This patch fixes that by using the hash of the underlying commit
when an annotated tag is passed.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/replace.c
t/t6050-replace.sh
index 730a6448ae9bfdb8836d8ea704fb6cb48b4962d7..a06dc2b5015cd064c3044969508f9bffb193872c 100644 (file)
@@ -477,15 +477,18 @@ static int create_graft(int argc, const char **argv, int force, int gentle)
 
        strbuf_release(&buf);
 
-       if (oideq(&old_oid, &new_oid)) {
+       if (oideq(&commit->object.oid, &new_oid)) {
                if (gentle) {
-                       warning(_("graft for '%s' unnecessary"), oid_to_hex(&old_oid));
+                       warning(_("graft for '%s' unnecessary"),
+                               oid_to_hex(&commit->object.oid));
                        return 0;
                }
-               return error(_("new commit is the same as the old one: '%s'"), oid_to_hex(&old_oid));
+               return error(_("new commit is the same as the old one: '%s'"),
+                            oid_to_hex(&commit->object.oid));
        }
 
-       return replace_object_oid(old_ref, &old_oid, "replacement", &new_oid, force);
+       return replace_object_oid(old_ref, &commit->object.oid,
+                                 "replacement", &new_oid, force);
 }
 
 static int convert_graft_file(int force)
index 2385a60f680e4539930837d404ddfa598d2c6d4c..e7e64e085ddcfe7d7cf4df844472a6bf456ab079 100755 (executable)
@@ -417,6 +417,17 @@ test_expect_success '--graft using a tag as the new parent' '
        git replace -d $HASH7
 '
 
+test_expect_success '--graft using a tag as the replaced object' '
+       git tag replaced_object $HASH7 &&
+       git replace --graft replaced_object $HASH5 &&
+       commit_has_parents $HASH7 $HASH5 &&
+       git replace -d $HASH7 &&
+       git tag -a -m "annotated replaced object tag" annotated_replaced_object $HASH7 &&
+       git replace --graft annotated_replaced_object $HASH5 &&
+       commit_has_parents $HASH7 $HASH5 &&
+       git replace -d $HASH7
+'
+
 test_expect_success GPG 'set up a signed commit' '
        echo "line 17" >>hello &&
        echo "line 18" >>hello &&