git tag --force is used to replace an existing tag with
a new reference.  Git helpfully tells the user the old
ref when this happens.  But if the tag name is new and does
not exist, git tells the user the old ref anyway (000000).

Teach git to ignore --force if the tag is new.  Add a test
for this and also to ensure --force can replace tags at all.

Signed-off-by: Phil Hord <>
 builtin/tag.c  |  2 +-
 t/ | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/builtin/tag.c b/builtin/tag.c
index f826688..af3af3f 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -582,7 +582,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                die(_("%s: cannot lock the ref"), ref.buf);
        if (write_ref_sha1(lock, object, NULL) < 0)
                die(_("%s: cannot update the ref"), ref.buf);
-       if (force && hashcmp(prev, object))
+       if (force && !is_null_sha1(prev) && hashcmp(prev, object))
                printf(_("Updated tag '%s' (was %s)\n"), tag, 
find_unique_abbrev(prev, DEFAULT_ABBREV));
diff --git a/t/ b/t/
index f5a79b1..c8d6e9f 100755
--- a/t/
+++ b/t/
@@ -104,6 +104,18 @@ test_expect_success 'creating a tag using HEAD directly 
should succeed' '
        tag_exists myhead
+test_expect_success '--force can create a tag with the name of one existing' '
+       tag_exists mytag &&
+       git tag --force mytag &&
+       tag_exists mytag'
+test_expect_success '--force is moot with a non-existing tag name' '
+       git tag newtag >expect &&
+       git tag --force forcetag >actual &&
+       test_cmp expect actual
+git tag -d newtag forcetag
 # deleting tags:
 test_expect_success 'trying to delete an unknown tag should fail' '

To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to
More majordomo info at

Reply via email to