fetch: clobber existing tags with --prune-tags
cover fetch: clobber existing tags with --prune-tags
This was documented but not implemented.
In the flag description: prune local tags no longer on remote and clobber changed tags
In the documentation: ... to prune local tags that don't exist on the remote, and force-update those tags that differ.
Orgad Shaneh (2):
fetch: add a test for --force flag
fetch: clobber existing tags with --prune-tags
builtin/fetch.c | 2 +- t/t5516-fetch-push.sh | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-)
base-commit: 852829b3dd2fe4e7c7fc4d8badde644cf1b66c74
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2200%2Forgads%2Ffetch-prune-clobber-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2200/orgads/fetch-prune-clobber-v1
Pull-Request: https://github.com/git/git/pull/2200
Signature · 1 line
gitgitgadget
PATCH 1/2 fetch: add a test for --force flag
From: Orgad Shaneh <[email protected]>
There are two ways to force-fetch tags that have changed: either by specifying an explicit forced ref (+refs/tags/*:refs/tags/*), or by using --force.
The first approach was already tested, but the second was not. This has now been addressed.
--- t/t5516-fetch-push.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
t/t5516-fetch-push.sh +4 -1
@@ -1105,7 +1105,10 @@ test_force_fetch_tag () { git commit -m 'file1' && git tag $tag_args testTag && test_must_fail git -C ../child1 fetch origin tag testTag && - git -C ../child1 fetch origin '+refs/tags/*:refs/tags/*' + git -C ../child1 fetch origin '+refs/tags/*:refs/tags/*' && + git tag $tag_args testTag HEAD^ && + test_must_fail git -C ../child1 fetch origin tag testTag && + git -C ../child1 fetch --force origin tag testTag ) " }
Signature · 1 line
gitgitgadget
PATCH 2/2 fetch: clobber existing tags with --prune-tags
In reply to Orgad Shaneh via GitGitGadgetFrom: Orgad Shaneh <[email protected]>
This was documented but not implemented.
In the flag description:
prune local tags no longer on remote *and clobber changed tags*
In the documentation:
... to prune local tags that don't exist on the remote, *and force-update those tags that differ*.
--- builtin/fetch.c | 2 +- t/t5516-fetch-push.sh | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-)
builtin/fetch.c +1 -1
@@ -981,7 +981,7 @@ static int update_local_ref(struct ref *ref, starts_with(ref->name, "refs/tags/")) {struct ref_update_display_info *info; -if (force || ref->force) { +if (force || ref->force || prune_tags) {int r; r =s_update_ref ("updating tag" , ref, transaction,0 );
t/t5516-fetch-push.sh +8 -2
@@ -1092,7 +1092,7 @@ test_force_fetch_tag () { tag_type_description=$1 tag_args=$2 - test_expect_success "fetch will not clobber an existing $tag_type_description without --force" " + test_expect_success "fetch will not clobber an existing $tag_type_description without --force or --prune-tags" " mk_test testrepo heads/main && mk_child testrepo child1 && mk_child testrepo child2 &&
@@ -1108,7 +1108,13 @@ test_force_fetch_tag () { git -C ../child1 fetch origin '+refs/tags/*:refs/tags/*' && git tag $tag_args testTag HEAD^ && test_must_fail git -C ../child1 fetch origin tag testTag && - git -C ../child1 fetch --force origin tag testTag + git -C ../child1 fetch --force origin tag testTag && + git tag $tag_args testTag HEAD && + test_must_fail git -C ../child1 fetch origin tag testTag && + git -C ../child1 fetch --prune-tags origin tag testTag && + git tag $tag_args testTag HEAD^ && + test_must_fail git -C ../child1 fetch origin tag testTag && + git -C ../child1 -c fetch.prunetags=true fetch origin tag testTag ) " }
Signature · 1 line
gitgitgadget
Quoted 60 lines · Orgad Shaneh via GitGitGadget
From: Orgad Shaneh <[email protected]>
This was documented but not implemented.
In the flag description:
prune local tags no longer on remote *and clobber changed tags*In the documentation:
... to prune local tags that don't exist on the remote, *and force-update those tags that differ*.Signed-off-by Orgad Shaneh <[email protected]>--- builtin/fetch.c | 2 +- t/t5516-fetch-push.sh | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-)builtin/fetch.c +1
-1@@ -981,7 +981,7 @@ static int update_local_ref(struct ref *ref, starts_with(ref->name, "refs/tags/")) {struct ref_update_display_info *info; -if (force || ref->force) { +if (force || ref->force || prune_tags) {int r; r =s_update_ref ("updating tag" , ref, transaction,0 );t/t5516-fetch-push.sh +8
-3@@ -1092,7 +1092,7 @@ test_force_fetch_tag () { tag_type_description=$1 tag_args=$2 - test_expect_success "fetch will not clobber an existing $tag_type_description without --force" " + test_expect_success "fetch will not clobber an existing $tag_type_description without --force or --prune-tags" " mk_test testrepo heads/main && mk_child testrepo child1 && mk_child testrepo child2 &&@@ -1108,7 +1108,13 @@ test_force_fetch_tag () { git -C ../child1 fetch origin '+refs/tags/*:refs/tags/*' && git tag $tag_args testTag HEAD^ && test_must_fail git -C ../child1 fetch origin tag testTag && - git -C ../child1 fetch --force origin tag testTag + git -C ../child1 fetch --force origin tag testTag && + git tag $tag_args testTag HEAD && + test_must_fail git -C ../child1 fetch origin tag testTag && + git -C ../child1 fetch --prune-tags origin tag testTag && + git tag $tag_args testTag HEAD^ && + test_must_fail git -C ../child1 fetch origin tag testTag && + git -C ../child1 -c fetch.prunetags=true fetch origin tag testTag ) " } --
Quoted 1 line
gitgitgadget
Gently pinging this thread. I submitted this patch about a month ago and would appreciate any feedback once someone finds a moment to review it.
Thanks!
Quoted 3 lines · Orgad Shaneh via GitGitGadget
From: Orgad Shaneh <[email protected]>
This was documented but not implemented.
And instead what did the command do / how did the command behave?
It also is curious when it was "broken". It could be that it was broken from day one when 97716d21 (fetch: add a --prune-tags option and fetch.pruneTags config, 2018-02-09) was written, c1a7902f (Merge branch 'ab/fetch-prune', 2018-03-06) merged it, and Git 2.17 was shipped with it, but knowing Ævar (by the way where is he these days???), I somehow doubt it.
And unless it was broken from day one, we must find out if the change in behaviour was deliberate, in which case it would be the doucmentation and not the implementation that needs fixing.
Quoted 25 lines
In the flag description:
prune local tags no longer on remote *and clobber changed tags*In the documentation:
... to prune local tags that don't exist on the remote, *and force-update those tags that differ*.
...t/t5516-fetch-push.sh +1
-2@@ -1092,7 +1092,7 @@ test_force_fetch_tag () { tag_type_description=$1 tag_args=$2 - test_expect_success "fetch will not clobber an existing $tag_type_description without --force" " + test_expect_success "fetch will not clobber an existing $tag_type_description without --force or --prune-tags" " mk_test testrepo heads/main && mk_child testrepo child1 && mk_child testrepo child2 &&@@ -1108,7 +1108,13 @@ test_force_fetch_tag () { git -C ../child1 fetch origin '+refs/tags/*:refs/tags/*' && git tag $tag_args testTag HEAD^ && test_must_fail git -C ../child1 fetch origin tag testTag && - git -C ../child1 fetch --force origin tag testTag
t/t5516-fetch-push.sh test_force_fetch_tag () { · line 1120
Quoted 10 lines
t/t5516-fetch-push.sh +7
-0+ git -C ../child1 fetch --force origin tag testTag && + git tag $tag_args testTag HEAD && + test_must_fail git -C ../child1 fetch origin tag testTag && + git -C ../child1 fetch --prune-tags origin tag testTag && + git tag $tag_args testTag HEAD^ && + test_must_fail git -C ../child1 fetch origin tag testTag && + git -C ../child1 -c fetch.prunetags=true fetch origin tag testTag ) " }
None of the steps we see in the added test do not seem to check that --prune-tags does clobber existing tag that no longer exists on the other side. It only checks the "git fetch" command exits with status 0, but does not see if the tag actually went away after the operation is done.
Quoted 8 lines · Junio C Hamano
Quoted 3 lines · Orgad Shaneh via GitGitGadget
From: Orgad Shaneh <[email protected]>
This was documented but not implemented.
And instead what did the command do / how did the command behave?
Even when passing --prune-tags or setting fetch.pruneTags, git fetch fails to force-update tags, resulting in the following error:
! [rejected] testTag -> testTag (would clobber existing tag)
Furthermore, when a tag clobber is rejected, the entire fetch operation fails, preventing the update of other refs and even new tags.
Quoted 10 lines
It also is curious when it was "broken". It could be that it was broken from day one when
97716d21(fetch: add a --prune-tags option and fetch.pruneTags config, 2018-02-09) was written,c1a7902f(Merge branch 'ab/fetch-prune', 2018-03-06) merged it, and Git 2.17 was shipped with it, but knowing Ævar (by the way where is he these days???), I somehow doubt it.And unless it was broken from day one, we must find out if the change in behaviour was deliberate, in which case it would be the doucmentation and not the implementation that needs fixing.
I dug into the feature history and found:
1. The flag was added in 97716d21 (fetch: add a --prune-tags option and fetch.pruneTags config, 2018-02-09) as you mentioned.
2. Tag clobbering protection was added later in 0bc8d71b (fetch: stop clobbering existing tags without --force, 2018-08-31).
It appears the --prune-tags flag was overlooked in that later commit, either in its behavior or its documentation.
Since there is currently no way to suppress this error globally, if you consider the current behavior acceptable and prefer to fix the documentation, I suggest adding a fetch.force config to allow clobbering.
Quoted 15 lines
Quoted 4 lines
git -C ../child1 fetch origin '+refs/tags/*:refs/tags/*' && git tag $tag_args testTag HEAD^ && test_must_fail git -C ../child1 fetch origin tag testTag &&t/t5516-fetch-push.sh +0
-1- git -C ../child1 fetch --force origin tag testTagt/t5516-fetch-push.sh test_force_fetch_tag () { · line 1120
Quoted 10 lines
t/t5516-fetch-push.sh +7
-0+ git -C ../child1 fetch --force origin tag testTag && + git tag $tag_args testTag HEAD && + test_must_fail git -C ../child1 fetch origin tag testTag && + git -C ../child1 fetch --prune-tags origin tag testTag && + git tag $tag_args testTag HEAD^ && + test_must_fail git -C ../child1 fetch origin tag testTag && + git -C ../child1 -c fetch.prunetags=true fetch origin tag testTag ) " }
Quoted 5 lines
None of the steps we see in the added test do not seem to check that --prune-tags does clobber existing tag that no longer exists on the other side. It only checks the "git fetch" command exits with status 0, but does not see if the tag actually went away after the operation is done.
In these tests, the tag is being replaced rather than deleted. Existing tests for the pruning mechanism itself are located in t/t5510-fetch.sh.
Would you like me to add a check for the tag content itself to verify the update? I suppose I should do the same for the existing test cases in that block as well.
- Orgad
Quoted 9 lines · Orgad Shaneh
Quoted 6 lines · Junio C Hamano
None of the steps we see in the added test do not seem to check that --prune-tags does clobber existing tag that no longer exists on the other side. It only checks the "git fetch" command exits with status 0, but does not see if the tag actually went away after the operation is done.
Quoted 6 lines
In these tests, the tag is being replaced rather than deleted. Existing tests for the pruning mechanism itself are located in
t/t5510-fetch.sh.Would you like me to add a check for the tag content itself to verify the update? I suppose I should do the same for the existing test cases in that block as well.
Junio?
- Orgad
Quoted 10 lines · Orgad Shaneh
Quoted 9 lines · Orgad Shaneh
Quoted 6 lines · Junio C Hamano
None of the steps we see in the added test do not seem to check that --prune-tags does clobber existing tag that no longer exists on the other side. It only checks the "git fetch" command exits with status 0, but does not see if the tag actually went away after the operation is done.
Quoted 8 lines
Quoted 6 lines
In these tests, the tag is being replaced rather than deleted. Existing tests for the pruning mechanism itself are located in
t/t5510-fetch.sh.Would you like me to add a check for the tag content itself to verify the update? I suppose I should do the same for the existing test cases in that block as well.
Junio?
Sorry, but I do not have 6 month old discussions in my context window, so no immediate comment. I'll respond only after I swap the context back in but not today (yet).
Thanks.
Quoted 20 lines · Junio C Hamano
Quoted 17 lines · Orgad Shaneh
Quoted 15 lines · Orgad Shaneh
Quoted 6 lines · Junio C Hamano
None of the steps we see in the added test do not seem to check that --prune-tags does clobber existing tag that no longer exists on the other side. It only checks the "git fetch" command exits with status 0, but does not see if the tag actually went away after the operation is done.
In these tests, the tag is being replaced rather than deleted. Existing tests for the pruning mechanism itself are located in
t/t5510-fetch.sh.Would you like me to add a check for the tag content itself to verify the update? I suppose I should do the same for the existing test cases in that block as well.
Quoted 5 lines
Quoted 1 line
Junio?
Sorry, but I do not have 6 month old discussions in my context window, so no immediate comment. I'll respond only after I swap the context back in but not today (yet).
Maybe today? ;)
- Orgad