Skip to content

Commit 40eff17

Browse files
crorvickgitster
authored andcommitted
push: require force for annotated tags
Do not allow fast-forwarding of references that point to a tag object. Updating from a tag is potentially destructive since it would likely leave the tag dangling. Disallowing updates to a tag also makes sense semantically and is consistent with the behavior of lightweight tags. Signed-off-by: Chris Rorvick <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent dbfeddb commit 40eff17

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

Documentation/git-push.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ updated.
5252
+
5353
The object referenced by <src> is used to update the <dst> reference
5454
on the remote side. By default this is only allowed if <dst> is not
55-
under refs/tags/, and then only if it can fast-forward <dst>. By having
56-
the optional leading `+`, you can tell git to update the <dst> ref even
57-
if it is not allowed by default (e.g., it is not a fast-forward.) This
58-
does *not* attempt to merge <src> into <dst>. See EXAMPLES below for
59-
details.
55+
a tag (annotated or lightweight), and then only if it can fast-forward
56+
<dst>. By having the optional leading `+`, you can tell git to update
57+
the <dst> ref even if it is not allowed by default (e.g., it is not a
58+
fast-forward.) This does *not* attempt to merge <src> into <dst>. See
59+
EXAMPLES below for details.
6060
+
6161
`tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.
6262
+

remote.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,9 +1281,16 @@ int match_push_refs(struct ref *src, struct ref **dst,
12811281

12821282
static inline int is_forwardable(struct ref* ref)
12831283
{
1284+
struct object *o;
1285+
12841286
if (!prefixcmp(ref->name, "refs/tags/"))
12851287
return 0;
12861288

1289+
/* old object must be a commit */
1290+
o = parse_object(ref->old_sha1);
1291+
if (!o || o->type != OBJ_COMMIT)
1292+
return 0;
1293+
12871294
return 1;
12881295
}
12891296

@@ -1323,8 +1330,8 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
13231330
* to overwrite it; you would not know what you are losing
13241331
* otherwise.
13251332
*
1326-
* (4) if both new and old are commit-ish, and new is a
1327-
* descendant of old, it is OK.
1333+
* (4) if old is a commit and new is a descendant of old
1334+
* (implying new is commit-ish), it is OK.
13281335
*
13291336
* (5) regardless of all of the above, removing :B is
13301337
* always allowed.

t/t5516-fetch-push.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,27 @@ test_expect_success 'push requires --force to update lightweight tag' '
950950
)
951951
'
952952

953+
test_expect_success 'push requires --force to update annotated tag' '
954+
mk_test heads/master &&
955+
mk_child child1 &&
956+
mk_child child2 &&
957+
(
958+
cd child1 &&
959+
git tag -a -m "message 1" Tag &&
960+
git push ../child2 Tag:refs/tmp/Tag &&
961+
git push ../child2 Tag:refs/tmp/Tag &&
962+
>file1 &&
963+
git add file1 &&
964+
git commit -m "file1" &&
965+
git tag -f -a -m "message 2" Tag &&
966+
test_must_fail git push ../child2 Tag:refs/tmp/Tag &&
967+
git push --force ../child2 Tag:refs/tmp/Tag &&
968+
git tag -f -a -m "message 3" Tag HEAD~ &&
969+
test_must_fail git push ../child2 Tag:refs/tmp/Tag &&
970+
git push --force ../child2 Tag:refs/tmp/Tag
971+
)
972+
'
973+
953974
test_expect_success 'push --porcelain' '
954975
mk_empty &&
955976
echo >.git/foo "To testrepo" &&

0 commit comments

Comments
 (0)