diff options
author | Junio C Hamano <gitster@pobox.com> | 2013-01-23 21:16:49 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-01-23 21:16:49 -0800 |
commit | d82dd26964b9d7b39fb74367e5fcc3e3f4593324 (patch) | |
tree | 98a0e47689e6494af3befdef3bbdad9dcdddabec | |
parent | a29e7118141e9dc60bf81c42fa3485d3d39ef7cc (diff) | |
parent | 256b9d70a497534338f0c22101cb6566ab3f1665 (diff) | |
download | git-d82dd26964b9d7b39fb74367e5fcc3e3f4593324.tar.gz |
Merge branch 'cr/push-force-tag-update'
Regression fix to stop "git push" complaining "target ref already
exists", when it is not the real reason the command rejected the
request (e.g. non-fast-forward).
* cr/push-force-tag-update:
push: fix "refs/tags/ hierarchy cannot be updated without --force"
-rw-r--r-- | cache.h | 1 | ||||
-rw-r--r-- | remote.c | 43 | ||||
-rwxr-xr-x | t/t5516-fetch-push.sh | 21 |
3 files changed, 7 insertions, 58 deletions
@@ -1011,7 +1011,6 @@ struct ref { requires_force:1, merge:1, nonfastforward:1, - not_forwardable:1, update:1, deletion:1; enum { @@ -1279,26 +1279,6 @@ int match_push_refs(struct ref *src, struct ref **dst, return 0; } -static inline int is_forwardable(struct ref* ref) -{ - struct object *o; - - if (!prefixcmp(ref->name, "refs/tags/")) - return 0; - - /* old object must be a commit */ - o = parse_object(ref->old_sha1); - if (!o || o->type != OBJ_COMMIT) - return 0; - - /* new object must be commit-ish */ - o = deref_tag(parse_object(ref->new_sha1), NULL, 0); - if (!o || o->type != OBJ_COMMIT) - return 0; - - return 1; -} - void set_ref_status_for_push(struct ref *remote_refs, int send_mirror, int force_update) { @@ -1320,32 +1300,23 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror, } /* - * The below logic determines whether an individual - * refspec A:B can be pushed. The push will succeed - * if any of the following are true: + * Decide whether an individual refspec A:B can be + * pushed. The push will succeed if any of the + * following are true: * * (1) the remote reference B does not exist * * (2) the remote reference B is being removed (i.e., * pushing :B where no source is specified) * - * (3) the update meets all fast-forwarding criteria: - * - * (a) the destination is not under refs/tags/ - * (b) the old is a commit - * (c) the new is a descendant of the old - * - * NOTE: We must actually have the old object in - * order to overwrite it in the remote reference, - * and the new object must be commit-ish. These are - * implied by (b) and (c) respectively. + * (3) the destination is not under refs/tags/, and + * if the old and new value is a commit, the new + * is a descendant of the old. * * (4) it is forced using the +A:B notation, or by * passing the --force argument */ - ref->not_forwardable = !is_forwardable(ref); - ref->update = !ref->deletion && !is_null_sha1(ref->old_sha1); @@ -1355,7 +1326,7 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror, !has_sha1_file(ref->old_sha1) || !ref_newer(ref->new_sha1, ref->old_sha1); - if (ref->not_forwardable) { + if (!prefixcmp(ref->name, "refs/tags/")) { ref->requires_force = 1; if (!force_ref_update) { ref->status = REF_STATUS_REJECT_ALREADY_EXISTS; diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 60093728fe..8f024a08f0 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -950,27 +950,6 @@ test_expect_success 'push requires --force to update lightweight tag' ' ) ' -test_expect_success 'push requires --force to update annotated tag' ' - mk_test heads/master && - mk_child child1 && - mk_child child2 && - ( - cd child1 && - git tag -a -m "message 1" Tag && - git push ../child2 Tag:refs/tmp/Tag && - git push ../child2 Tag:refs/tmp/Tag && - >file1 && - git add file1 && - git commit -m "file1" && - git tag -f -a -m "message 2" Tag && - test_must_fail git push ../child2 Tag:refs/tmp/Tag && - git push --force ../child2 Tag:refs/tmp/Tag && - git tag -f -a -m "message 3" Tag HEAD~ && - test_must_fail git push ../child2 Tag:refs/tmp/Tag && - git push --force ../child2 Tag:refs/tmp/Tag - ) -' - test_expect_success 'push --porcelain' ' mk_empty && echo >.git/foo "To testrepo" && |