Re: git filter-branch doesn't dereference annotated tags
- From
Grégory Pakosz <gpakosz@visionobjects.com>
- Date
- Jan 1, 2013, 20:20 UTC
- Message-ID
- <CAC_01E3VWtsFd8ww+7W8DMhRAs4WgHf=bm+xoh9wszCkb-DfUA@mail.gmail.com>
- In-Reply-To
- <7vfw2kbs4h.fsf@alter.siamese.dyndns.org>
Show 5 quoted lines
> Yeah, but in that case it appears to me that you told the command to > rewrite the tag itself and the history behind the commit the tag > refers to, but the end result did not rewrite the tag itself and > left the tag pointing at the original history. >
The problem exhibits at the point git filter-branch updates the references. I indeed asked to rewrite tagged commits by passing --tag-name-filter cat
Show 5 quoted lines
> The "$rewritten" variable being empty in this codepath tells me that > the command decided that it *does* want to delete the tag, but as > J6t mentioned in his review, it is unclear to me what is expected by > the user. >
The history behind the commit the tag refers to is empty after filtering has been applied. As a user, I expected the tag to be removed: it's not illogical, all tags that pointed to history that has been entirely filtered out should go away imho. --tag-name-filter doesn't allow to deleted tags as J6t mentioned and I'm not surre what the new contract would be: empty tag name to delete a tag so if $(map $sha1) yields '' I can decided to delete the tag?
If the tag wasn't an annotated one, I guess it would have been successfully deleted which exhibits a different behavior between annotated and lightweight tags.
Show 6 quoted lines
> If the command and the filters you gave the command decided the tag > should be removed, then not being able to delete it is a problem and > the code you patched that compares the object name of the tag and > the object name of the commit the tag refers to is certainly doing a > wrong comparison. >
That's what I believe. The index and commit filters are made to keep only a couple of directories and get rid of the rest. Those directories didn't exist early in the history. Commits in that early part of the history were tagged with annotated tags.
> But I have this suspicion that you did not want to remove the tag in > the first place. >
The tag pointed to something the filters decided to throw out. Since I want tags to be updated, it doesn't make much sense to keep it and I'm expecting its deletion.
It appears to me that the suggested fix doing test $(git cat-file -t "$ref") = 'tag' && sha1=$(git rev-parse "$ref") so that $sha1 is obtained again from the tag ref but without dereferencing recursively should only apply if --tag-name-filter has been provided. What do you think?
Show 9 quoted lines
> The application of "map" shell function to obtain > $rewritten is done on the unwrapped object name by passing "$ref^0" > to rev-parse, but perhaps that "^0" is the real source of the > problem instead, so that it checks what new object the original > annotated tag was rewritten to? If the tag object was rewritten, > either to empty to signal its removal or to a new object name, then > we do want to update-ref it, but the decision should be made on its > object name, not the object name of the commit it points at? >
Are you suggesting $sha1 should be obtained differently before entering case "$rewritten" ? That would mean changing sha1=$(git rev-parse "$ref"^0) at line 376 to something like $(git cat-file -t "$ref") = 'tag' && sha1=$(git rev-parse "$ref") || sha1=$(git rev-parse "$ref^0") ?
Gregory