{"thread":{"id":"12779","subject":"[PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","startedAt":"2008-03-20T17:02:29Z","lastAt":"2008-03-26T15:47:09Z","messageCount":23,"participants":["Brandon Casey","Johannes Schindelin","Junio C Hamano","Eyvind Bernhardsen"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"72530","messageId":"47E298A5.6050508@nrlssc.navy.mil","threadId":"12779","inReplyTo":"1206031893-29599-1-git-send-email-casey@nrlssc.navy.mil","subject":"[PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-03-20T17:02:29Z","receivedAt":"2008-03-20T17:02:29Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"Add support for creating a new tag object and retaining the tag message,\nauthor, and date when rewriting tags. The gpg signature, if one exists,\nwill be stripped.\n\nThis adds nearly proper tag name filtering to filter-branch. Proper tag\nname filtering would include the ability to change the tagger, tag date,\ntag message, and _not_ strip a gpg signature if the tag did not change.\n\nSigned-off-by: Brandon Casey <casey@nrlssc.navy.mil>\n---\n\n\nI went back and forth over stripping the gpg signature or just leaving\nit intact and creating a new tag with the invalid signature. I ended\nup stripping it, and printing a message saying it was stripped along\nwith the original tag object's sha1.\n\nPortability comments?\n\n-brandon\n\n\n Documentation/git-filter-branch.txt |   14 ++++++++++----\n git-filter-branch.sh                |   14 ++++++++++++--\n t/t7003-filter-branch.sh            |   32 ++++++++++++++++++++++++++++++++\n 3 files changed, 54 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt\nindex 543a1cf..9364919 100644\n--- a/Documentation/git-filter-branch.txt\n+++ b/Documentation/git-filter-branch.txt\n@@ -132,10 +132,16 @@ use \"--tag-name-filter cat\" to simply update the tags.  In this\n case, be very careful and make sure you have the old tags\n backed up in case the conversion has run afoul.\n +\n-Note that there is currently no support for proper rewriting of\n-tag objects; in layman terms, if the tag has a message or signature\n-attached, the rewritten tag won't have it.  Sorry.  (It is by\n-definition impossible to preserve signatures at any rate.)\n+Nearly proper rewriting of tag objects is supported. If the tag has\n+a message attached, a new tag object will be created with the same message,\n+author, and timestamp. If the tag has a signature attached, the\n+signature will be stripped. It is by definition impossible to preserve\n+signatures. The reason this is \"nearly\" proper, is because ideally if\n+the tag did not change (points to the same object, has the same name, etc.)\n+it should retain any signature. That is not the case, signatures will always\n+be removed, buyer beware. There is also no support for changing the\n+author or timestamp (or the tag message for that matter). Tags which point\n+to other tags will be rewritten to point to the underlying commit.\n \n --subdirectory-filter <directory>::\n \tOnly look at the history which touches the given subdirectory.\ndiff --git a/git-filter-branch.sh b/git-filter-branch.sh\nindex 22b6ed4..12d5a25 100755\n--- a/git-filter-branch.sh\n+++ b/git-filter-branch.sh\n@@ -406,8 +406,18 @@ if [ \"$filter_tag_name\" ]; then\n \t\techo \"$ref -> $new_ref ($sha1 -> $new_sha1)\"\n \n \t\tif [ \"$type\" = \"tag\" ]; then\n-\t\t\t# Warn that we are not rewriting the tag object itself.\n-\t\t\twarn \"unreferencing tag object $sha1t\"\n+\t\t\tnew_sha1=$(git cat-file tag \"$ref\" | \\\n+\t\t\t\tsed -e \"1c\\object $new_sha1\" \\\n+\t\t\t\t    -e '2c\\type commit'      \\\n+\t\t\t\t    -e \"3c\\tag $new_ref\"     \\\n+\t\t\t\t    -e '/^-----BEGIN PGP SIGNATURE-----/Q' | \\\n+\t\t\t\tgit mktag) ||\n+\t\t\t\tdie \"Could not create new tag object for $ref\"\n+\t\t\tif git cat-file tag \"$ref\" | \\\n+\t\t\t   grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1\n+\t\t\tthen\n+\t\t\t\twarn \"gpg signature stripped from tag object $sha1t\"\n+\t\t\tfi\n \t\tfi\n \n \t\tgit update-ref \"refs/tags/$new_ref\" \"$new_sha1\" ||\ndiff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh\nindex 6827249..1daaf54 100755\n--- a/t/t7003-filter-branch.sh\n+++ b/t/t7003-filter-branch.sh\n@@ -203,4 +203,36 @@ test_expect_success 'Subdirectory filter with disappearing trees' '\n \ttest $(git rev-list master | wc -l) = 3\n '\n \n+test_expect_success 'Tag name filtering retains tag message' '\n+\tgit tag -m atag T &&\n+\tgit cat-file tag T > expect &&\n+\tgit filter-branch -f --tag-name-filter cat &&\n+\tgit cat-file tag T > actual &&\n+\tgit diff expect actual\n+'\n+\n+faux_gpg_tag='object XXXXXX\n+type commit\n+tag S\n+tagger T A Gger <tagger@example.com> 1206026339 -0500\n+\n+This is a faux gpg signed tag.\n+-----BEGIN PGP SIGNATURE-----\n+Version: FauxGPG v0.0.0 (FAUX/Linux)\n+\n+gdsfoewhxu/6l06f1kxyxhKdZkrcbaiOMtkJUA9ITAc1mlamh0ooasxkH1XwMbYQ\n+acmwXaWET20H0GeAGP+7vow=\n+=agpO\n+-----END PGP SIGNATURE-----\n+'\n+test_expect_success 'Tag name filtering strips gpg signature' '\n+\tsha1=$(git rev-parse HEAD) &&\n+\tsha1t=$(echo \"$faux_gpg_tag\" | sed -e s/XXXXXX/$sha1/ | git mktag) &&\n+\tgit update-ref \"refs/tags/S\" \"$sha1t\" &&\n+\techo \"$faux_gpg_tag\" | sed -e s/XXXXXX/$sha1/ | head -n 6 > expect &&\n+\tgit filter-branch -f --tag-name-filter cat &&\n+\tgit cat-file tag S > actual &&\n+\tgit diff expect actual\n+'\n+\n test_done\n-- \n1.5.4.4.481.g5075\n"},{"id":"72532","messageId":"alpine.LSU.1.00.0803201812560.4124@racer.site","threadId":"12779","inReplyTo":"47E298A5.6050508@nrlssc.navy.mil","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-20T17:14:45Z","receivedAt":"2008-03-20T17:14:45Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 20 Mar 2008, Brandon Casey wrote:\n\n> Add support for creating a new tag object and retaining the tag message, \n> author, and date when rewriting tags. The gpg signature, if one exists, \n> will be stripped.\n> \n> This adds nearly proper tag name filtering to filter-branch. Proper tag \n> name filtering would include the ability to change the tagger, tag date, \n> tag message, and _not_ strip a gpg signature if the tag did not change.\n\nI think such a change in semantics merits a new option.  Maybe \neven something like\n\n\t\"--rewrite-tags=(strip-signatures|redo-signatures|no-signed)\"\n\nor some such.  But maybe not; to rewrite a tag, you have to specify it \nexplicitely (or implicitely with --all).\n\nCiao,\nDscho\n"},{"id":"72534","messageId":"47E2A10F.1010703@nrlssc.navy.mil","threadId":"12779","inReplyTo":"alpine.LSU.1.00.0803201812560.4124@racer.site","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-03-20T17:38:23Z","receivedAt":"2008-03-20T17:38:23Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"Johannes Schindelin wrote:\n> Hi,\n> \n> On Thu, 20 Mar 2008, Brandon Casey wrote:\n> \n>> Add support for creating a new tag object and retaining the tag message, \n>> author, and date when rewriting tags. The gpg signature, if one exists, \n>> will be stripped.\n>>\n>> This adds nearly proper tag name filtering to filter-branch. Proper tag \n>> name filtering would include the ability to change the tagger, tag date, \n>> tag message, and _not_ strip a gpg signature if the tag did not change.\n> \n> I think such a change in semantics merits a new option.\n\nI had understood the current behavior to be a shortcoming rather than\ndesirable behavior.\n\nThe change this patch introduces is not the stripping of the gpg signature,\nit is the new ability to _retain_ the properties of a tag object. Current\nbehavior discards everything, including the signature.\n\nIf people expect the current behavior and would not welcome this new behavior,\nthen maybe a new option is needed, but I'm not convinced yet. I'm thinking\nthat maybe converting a tag object into a light-weight tag should be the special\noperation (if that is desirable).\n\n-brandon\n"},{"id":"72858","messageId":"7vr6e01xja.fsf@gitster.siamese.dyndns.org","threadId":"12779","inReplyTo":"alpine.LSU.1.00.0803201812560.4124@racer.site","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-24T05:49:45Z","receivedAt":"2008-03-24T05:49:45Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> On Thu, 20 Mar 2008, Brandon Casey wrote:\n>\n>> Add support for creating a new tag object and retaining the tag message, \n>> author, and date when rewriting tags. The gpg signature, if one exists, \n>> will be stripped.\n>> \n>> This adds nearly proper tag name filtering to filter-branch. Proper tag \n>> name filtering would include the ability to change the tagger, tag date, \n>> tag message, and _not_ strip a gpg signature if the tag did not change.\n>\n> I think such a change in semantics merits a new option.\n\nIt is a different story if the fix is a good one, or has room for\nimprovement.  For example, the sed script that knows what is on the first\nand second line and relies on that knowledge to use 1c...2c... looked very\nfragile to me.\n\nHowever, at least to me, this looked like an attempt for a pure \"fix\".\n\nIf you tell filter-branch to filter a branch A and a tag T, as the command\nis advertised to rewrite positive refs that were given from the command\nline, isn't it natural to expect that the command would attempt its best\neffort to rewrite such a tag object?\n"},{"id":"72870","messageId":"alpine.LSU.1.00.0803241152050.4353@racer.site","threadId":"12779","inReplyTo":"7vr6e01xja.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-24T10:53:41Z","receivedAt":"2008-03-24T10:53:41Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 23 Mar 2008, Junio C Hamano wrote:\n\n> If you tell filter-branch to filter a branch A and a tag T, as the \n> command is advertised to rewrite positive refs that were given from the \n> command line, isn't it natural to expect that the command would attempt \n> its best effort to rewrite such a tag object?\n\nThe thing is: signed tags cannot be rewritten.  As simple as that.  They \ncould be recreated if the committer happens to be the original tagger, but \neven then, it is a rewrite of _tags_, which are _not_ supposed to be \nmoving targets.\n\nSo it was very much on purpose to disallow rewriting them by default.\n\nCiao,\nDscho\n"},{"id":"72897","messageId":"7viqzc18j9.fsf@gitster.siamese.dyndns.org","threadId":"12779","inReplyTo":"alpine.LSU.1.00.0803241152050.4353@racer.site","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-24T14:49:46Z","receivedAt":"2008-03-24T14:49:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Hi,\n>\n> On Sun, 23 Mar 2008, Junio C Hamano wrote:\n>\n>> If you tell filter-branch to filter a branch A and a tag T, as the \n>> command is advertised to rewrite positive refs that were given from the \n>> command line, isn't it natural to expect that the command would attempt \n>> its best effort to rewrite such a tag object?\n>\n> The thing is: signed tags cannot be rewritten.\n\nI know that, and you know I know that if you read what you responded again\n;-)\n\nAnd I think stripping of gpg signature part is a reasonable best effort\nfor the command, _when_ the user told a signed tag to be rewritten.\n"},{"id":"72902","messageId":"alpine.LSU.1.00.0803241609540.4353@racer.site","threadId":"12779","inReplyTo":"7viqzc18j9.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-24T15:10:43Z","receivedAt":"2008-03-24T15:10:43Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 24 Mar 2008, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > On Sun, 23 Mar 2008, Junio C Hamano wrote:\n> >\n> >> If you tell filter-branch to filter a branch A and a tag T, as the \n> >> command is advertised to rewrite positive refs that were given from \n> >> the command line, isn't it natural to expect that the command would \n> >> attempt its best effort to rewrite such a tag object?\n> >\n> > The thing is: signed tags cannot be rewritten.\n> \n> I know that, and you know I know that if you read what you responded \n> again ;-)\n> \n> And I think stripping of gpg signature part is a reasonable best effort \n> for the command, _when_ the user told a signed tag to be rewritten.\n\nYes.\n\nBUT.\n\nYou can say \"--all\", and I actually expect quite a few people to do \nexactly that.  And then you cannot really say \"the user explicitely asked \nto have that signed tag rewritten\".\n\nCiao,\nDscho\n"},{"id":"72909","messageId":"47E7D818.7090501@nrlssc.navy.mil","threadId":"12779","inReplyTo":"alpine.LSU.1.00.0803241609540.4353@racer.site","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-03-24T16:34:32Z","receivedAt":"2008-03-24T16:34:32Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"Johannes Schindelin wrote:\n> Hi,\n> \n> On Mon, 24 Mar 2008, Junio C Hamano wrote:\n> \n>> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>>\n>>> On Sun, 23 Mar 2008, Junio C Hamano wrote:\n>>>\n>>>> If you tell filter-branch to filter a branch A and a tag T, as the \n>>>> command is advertised to rewrite positive refs that were given from \n>>>> the command line, isn't it natural to expect that the command would \n>>>> attempt its best effort to rewrite such a tag object?\n>>> The thing is: signed tags cannot be rewritten.\n>> I know that, and you know I know that if you read what you responded \n>> again ;-)\n>>\n>> And I think stripping of gpg signature part is a reasonable best effort \n>> for the command, _when_ the user told a signed tag to be rewritten.\n> \n> Yes.\n> \n> BUT.\n> \n> You can say \"--all\", and I actually expect quite a few people to do \n> exactly that.  And then you cannot really say \"the user explicitely asked \n> to have that signed tag rewritten\".\n\nThat sounds like saying that specifying \"HEAD\" as the revision (_and_\nusing --tag-name-filter) is not explicitly asking for tags to be rewritten.\n?\n\nAside from that, wouldn't the signed tag currently be rewritten? With current\ngit, if I have a signed tag named \"my_signed_release\", and I can verify its\nauthenticity using 'git tag -v my_signed_release', and then I run filter-branch\nwith '--tag-name-filter cat', my previously signed tag is replaced with a light\nweight tag and of course 'git tag -v my_signed_release' fails.\n\nI don't see how the situation for signed tags changes much. The current state\nis that the signature cannot be preserved, so if \"new\" signed tags are desired,\nthey must be handled specially. On the other hand, the situation for unsigned\ntags becomes much easier, assuming you want to retain the tag properties. Aren't\nunsigned tags more common than signed ones?\n\nSo right now, tags matching the refspec are rewritten. They are currently\nrewritten with a lightweight tag. I don't think you have explained what is\nwrong with defaulting to creating a new tag object which retains as much\ninformation from the original tag object as possible. In other words, why\nwould a user _not_ expect that the tag filter would preserve the tag message?\n\nCan you describe some scenario where a user would use --tag-name-filter and\nwould prefer the creation of new light-weight tags over tag objects? I can't\nimagine one in my own situation. Maybe there is some example in your own\nworkflow?\n\n-brandon\n"},{"id":"72913","messageId":"47E7DAC7.9020607@nrlssc.navy.mil","threadId":"12779","inReplyTo":"47E7D818.7090501@nrlssc.navy.mil","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-03-24T16:45:59Z","receivedAt":"2008-03-24T16:45:59Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"Brandon Casey wrote:\n> Johannes Schindelin wrote:\n>> Hi,\n>>\n>> On Mon, 24 Mar 2008, Junio C Hamano wrote:\n>>\n>>> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>>>\n>>>> On Sun, 23 Mar 2008, Junio C Hamano wrote:\n>>>>\n>>>>> If you tell filter-branch to filter a branch A and a tag T, as the \n>>>>> command is advertised to rewrite positive refs that were given from \n>>>>> the command line, isn't it natural to expect that the command would \n>>>>> attempt its best effort to rewrite such a tag object?\n>>>> The thing is: signed tags cannot be rewritten.\n>>> I know that, and you know I know that if you read what you responded \n>>> again ;-)\n>>>\n>>> And I think stripping of gpg signature part is a reasonable best effort \n>>> for the command, _when_ the user told a signed tag to be rewritten.\n>> Yes.\n>>\n>> BUT.\n>>\n>> You can say \"--all\", and I actually expect quite a few people to do \n>> exactly that.  And then you cannot really say \"the user explicitely asked \n>> to have that signed tag rewritten\".\n> \n> That sounds like saying that specifying \"HEAD\" as the revision (_and_\n> using --tag-name-filter) is not explicitly asking for tags to be rewritten.\n\nMaybe that should be qualified. I think your statement is similar to my\nexample and so \"not explicitly asking for tags\" (by your definition) since\nneither explicitly named the tags to be rewritten on the command line.\n\nIn both cases, tag objects would currently be replaced by lightweight tags\nwhen --tag-name-filter is used.\n\n-brandon\n"},{"id":"72912","messageId":"alpine.LSU.1.00.0803241745240.4353@racer.site","threadId":"12779","inReplyTo":"47E7D818.7090501@nrlssc.navy.mil","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-24T16:46:27Z","receivedAt":"2008-03-24T16:46:27Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 24 Mar 2008, Brandon Casey wrote:\n\n> So right now, tags matching the refspec are rewritten. They are currently\n> rewritten with a lightweight tag.\n\nThat is unintended.  My understanding of a tag was always that it is \nsomething immutable.  I mean, _really_ immutable.  If you released a \ncertain version, then that is tagged.  You must not rewrite the tag.  \nEver.\n\nCiao,\nDscho\n"},{"id":"72917","messageId":"47E7DFAD.4060209@nrlssc.navy.mil","threadId":"12779","inReplyTo":"alpine.LSU.1.00.0803241745240.4353@racer.site","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-03-24T17:06:53Z","receivedAt":"2008-03-24T17:06:53Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"Johannes Schindelin wrote:\n> Hi,\n> \n> On Mon, 24 Mar 2008, Brandon Casey wrote:\n> \n>> So right now, tags matching the refspec are rewritten. They are currently\n>> rewritten with a lightweight tag.\n> \n> That is unintended.  My understanding of a tag was always that it is \n> something immutable.  I mean, _really_ immutable.  If you released a \n> certain version, then that is tagged.  You must not rewrite the tag.  \n> Ever.\n\nThen what is the intended behavior for --tag-name-filter?\n\n-brandon\n"},{"id":"72919","messageId":"alpine.LSU.1.00.0803241812230.4353@racer.site","threadId":"12779","inReplyTo":"47E7DFAD.4060209@nrlssc.navy.mil","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-24T17:14:51Z","receivedAt":"2008-03-24T17:14:51Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 24 Mar 2008, Brandon Casey wrote:\n\n> Johannes Schindelin wrote:\n> \n> > On Mon, 24 Mar 2008, Brandon Casey wrote:\n> > \n> >> So right now, tags matching the refspec are rewritten. They are \n> >> currently rewritten with a lightweight tag.\n> > \n> > That is unintended.  My understanding of a tag was always that it is \n> > something immutable.  I mean, _really_ immutable.  If you released a \n> > certain version, then that is tagged.  You must not rewrite the tag.  \n> > Ever.\n> \n> Then what is the intended behavior for --tag-name-filter?\n\nTo be honest, I wanted to rip that part out before posting the initial \nfilter-branch patches, and forgot/was too lazy.\n\nIMO there should be clean semantics first, and a default mode that does \n_not_ rewrite tags at all first.\n\nMaybe something as in fast-export.\n\nCiao,\nDscho\n"},{"id":"72928","messageId":"47E7F4E3.8050406@nrlssc.navy.mil","threadId":"12779","inReplyTo":"alpine.LSU.1.00.0803241812230.4353@racer.site","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-03-24T18:37:23Z","receivedAt":"2008-03-24T18:37:23Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"Johannes Schindelin wrote:\n> Hi,\n> \n> On Mon, 24 Mar 2008, Brandon Casey wrote:\n> \n>> Johannes Schindelin wrote:\n>>\n>>> On Mon, 24 Mar 2008, Brandon Casey wrote:\n>>>\n>>>> So right now, tags matching the refspec are rewritten. They are \n>>>> currently rewritten with a lightweight tag.\n>>> That is unintended.  My understanding of a tag was always that it is \n>>> something immutable.  I mean, _really_ immutable.  If you released a \n>>> certain version, then that is tagged.  You must not rewrite the tag.  \n>>> Ever.\n>> Then what is the intended behavior for --tag-name-filter?\n> \n> To be honest, I wanted to rip that part out before posting the initial \n> filter-branch patches, and forgot/was too lazy.\n> \n> IMO there should be clean semantics first, and a default mode that does \n> _not_ rewrite tags at all first.\n\nThere isn't really a \"default\" mode for --tag-name-filter, a script must\nalways be supplied. The name of the option (--tag- _name_ -filter) implies\nthat it is intended for changing the names of tags. If the user decides\nnot to change the name, then I think the user would expect the old tag to\nbe replaced.\n\nSo the user could choose to:\n\n          Rewrite tag ref: --tag-name-filter cat\n                        or\n Give new tags a new name: --tag-name-filter 'sed -e s/$/.new/'\n                        or\n       Save original tags: --tag-name-filter 'sed -e s/$/.orig/'\n     Then create new ones: --tag-name-filter 'sed -e s/\\.orig$//' [plus additional filtering]\n\nMore precise control over tag filtering should probably have an option\nwith a different name like --tag-filter, at which point --tag-name-filter\ncould be deprecated.\n\n-brandon\n"},{"id":"72932","messageId":"47E7FACD.7020409@nrlssc.navy.mil","threadId":"12779","inReplyTo":"7vr6e01xja.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/2] filter-branch.sh: support nearly proper tag name filtering","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-03-24T19:02:37Z","receivedAt":"2008-03-24T19:02:37Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"Junio C Hamano wrote:\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n>> On Thu, 20 Mar 2008, Brandon Casey wrote:\n>>\n>>> Add support for creating a new tag object and retaining the tag message, \n>>> author, and date when rewriting tags. The gpg signature, if one exists, \n>>> will be stripped.\n>>>\n>>> This adds nearly proper tag name filtering to filter-branch. Proper tag \n>>> name filtering would include the ability to change the tagger, tag date, \n>>> tag message, and _not_ strip a gpg signature if the tag did not change.\n>> I think such a change in semantics merits a new option.\n> \n> It is a different story if the fix is a good one, or has room for\n> improvement.  For example, the sed script that knows what is on the first\n> and second line and relies on that knowledge to use 1c...2c... looked very\n> fragile to me.\n\nThis tag format is described in the documentation for git-mktag as follows:\n\n   Tag Format\n   ----------\n   A tag signature file has a very simple fixed format: four lines of\n\n     object <sha1>\n     type <typename>\n     tag <tagname>\n     tagger <tagger>\n\n   followed by some 'optional' free-form message (some tags created\n   [...]\n\nSo, as long as git-cat-file succeeds, shouldn't we get this format piped\nto sed? The type is hard coded to \"commit\", since $new_ref will always be\na commit (the old tag could have referenced another tag), otherwise the\nearlier rev-parse would have failed.\n\nThe portion that strips the signature, does rely on the fact that git-tag\nalways adds the signature to the end of the tag object. Rather than\nstripping only between the pgp BEGIN and END markers. And the 'Q' directive\nmay not be portable, but I really don't know.\n\nSuggestions?\n\n-brandon\n"},{"id":"72953","messageId":"263C0D8D-0454-402A-B65C-08E91F7BD5C7@orakel.ntnu.no","threadId":"12779","inReplyTo":"alpine.LSU.1.00.0803241609540.4353@racer.site","subject":"filter-branch --all?","fromName":"Eyvind Bernhardsen","fromEmail":"eyvind-git@orakel.ntnu.no","sentAt":"2008-03-24T21:22:46Z","receivedAt":"2008-03-24T21:22:46Z","isPatch":false,"sender":{"key":"eyvind.bernhardsen@gmail.com","avatar":"https://avatars.githubusercontent.com/u/106762?v=4"},"body":"On 24. mars. 2008, at 16.10, Johannes Schindelin wrote:\n\n[Regarding filter-branch rewriting tags]\n\n> You can say \"--all\", and I actually expect quite a few people to do\n> exactly that.  And then you cannot really say \"the user explicitely  \n> asked\n> to have that signed tag rewritten\".\n\n\nSorry to hijack the thread.  I've seen you mention using \"--all\" to  \nfilter-branch everything before, but I can't get it to work:\n\n\n\t% git filter-branch --all\n\tUsage: /usr/local/bin/git-filter-branch [--env-filter <command>] [-- \ntree-filter <command>] [--index-filter <command>] [--parent-filter  \n<command>] [--msg-filter <command>] [--commit-filter <command>] [--tag- \nname-filter <command>] [--subdirectory-filter <directory>] [--original  \n<namespace>] [-d <directory>] [-f | --force] [<rev-list options>...]\n\n\nI'm trying to rewrite history to match .git/info/grafts without going  \nthrough every graft, hence the lack of an actual filter command.   \nThinking that might be the problem, I also tried the \"update-index -- \nremove <filename>\" example, but it wouldn't let me use \"--all\" either:\n\n\n\t% git filter-branch --index-filter 'git update-index --remove RELEASE- \nNOTES' --all\n\tUsage: /usr/local/bin/git-filter-branch [--env-filter <command>] [-- \ntree-filter <command>] [--index-filter <command>] [--parent-filter  \n<command>] [--msg-filter <command>] [--commit-filter <command>] [--tag- \nname-filter <command>] [--subdirectory-filter <directory>] [--original  \n<namespace>] [-d <directory>] [-f | --force] [<rev-list options>...]\n\n\nas opposed to:\n\n\n\t% git filter-branch --index-filter 'git update-index --remove RELEASE- \nNOTES' HEAD\n\tRewrite 266da463b4e59eaf06287b36b6435b8218db9f40 (611/4040)\n\t^C\n\n\ngit version 1.5.5.rc0.10.g7881f.dirty (the dirtiness is in git- \nsubmodule.sh, and I've tried it with older, cleaner versions).\n\nAm I just stupid and/or crazy, or does it not work?\n-- \nEyvind Bernhardsen\n"},{"id":"72955","messageId":"47E81E0C.8050609@nrlssc.navy.mil","threadId":"12779","inReplyTo":"263C0D8D-0454-402A-B65C-08E91F7BD5C7@orakel.ntnu.no","subject":"Re: filter-branch --all?","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-03-24T21:33:00Z","receivedAt":"2008-03-24T21:33:00Z","isPatch":false,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"Eyvind Bernhardsen wrote:\n> On 24. mars. 2008, at 16.10, Johannes Schindelin wrote:\n> \n> [Regarding filter-branch rewriting tags]\n> \n>> You can say \"--all\", and I actually expect quite a few people to do\n>> exactly that.  And then you cannot really say \"the user explicitely asked\n>> to have that signed tag rewritten\".\n> \n> \n> Sorry to hijack the thread.  I've seen you mention using \"--all\" to\n> filter-branch everything before, but I can't get it to work:\n> \n> \n>     % git filter-branch --all\n\nTry\n\n    git filter-branch -- --all\n\nIt is actually an option to rev-parse.\n\n-brandon\n"},{"id":"72957","messageId":"8845199E-BDBE-4CFB-8E74-DCF36D1CC9EB@orakel.ntnu.no","threadId":"12779","inReplyTo":"47E81E0C.8050609@nrlssc.navy.mil","subject":"Re: filter-branch --all?","fromName":"Eyvind Bernhardsen","fromEmail":"eyvind-git@orakel.ntnu.no","sentAt":"2008-03-24T21:44:39Z","receivedAt":"2008-03-24T21:44:39Z","isPatch":false,"sender":{"key":"eyvind.bernhardsen@gmail.com","avatar":"https://avatars.githubusercontent.com/u/106762?v=4"},"body":"On 24. mars. 2008, at 22.33, Brandon Casey wrote:\n> Try\n>\n>    git filter-branch -- --all\n>\n> It is actually an option to rev-parse.\n\nThat works!  Thanks.\n\nI managed to figure out that \"--all\" is a rev-parse option, but it  \nnever occurred to me to protect it with a \"--\".\n-- \nEyvind Bernhardsen\n"},{"id":"72960","messageId":"47E8267D.5000405@nrlssc.navy.mil","threadId":"12779","inReplyTo":"47E7FACD.7020409@nrlssc.navy.mil","subject":"[PATCH] filter-branch.sh: support nearly proper tag name filtering","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-03-24T22:09:01Z","receivedAt":"2008-03-24T22:09:01Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"Add support for creating a new tag object and retaining the tag message,\nauthor, and date when rewriting tags. The gpg signature, if one exists,\nwill be stripped.\n\nThis adds nearly proper tag name filtering to filter-branch. Proper tag\nname filtering would include the ability to change the tagger, tag date,\ntag message, and _not_ strip a gpg signature if the tag did not change.\n\nSigned-off-by: Brandon Casey <casey@nrlssc.navy.mil>\n---\n\n\nI learned that the 'Q' command to sed is not portable, and most versions\nof sed require a newline after 'c\\' like commands.\n\nHere is an updated patch which should be portable. Nothing else has been\nchanged.\n\nHere's the diff from the previous patch...\n\n  --- a/git-filter-branch.sh\n  +++ b/git-filter-branch.sh\n  @@ -406,11 +406,16 @@ if [ \"$filter_tag_name\" ]; then\n                  echo \"$ref -> $new_ref ($sha1 -> $new_sha1)\"\n \n                  if [ \"$type\" = \"tag\" ]; then\n  -                       new_sha1=$(git cat-file tag \"$ref\" | \\\n  -                               sed -e \"1c\\object $new_sha1\" \\\n  -                                   -e '2c\\type commit'      \\\n  -                                   -e \"3c\\tag $new_ref\"     \\\n  -                                   -e '/^-----BEGIN PGP SIGNATURE-----/Q' | \\\n  +                       new_sha1=$(git cat-file tag \"$ref\" |\n  +                               sed -n \\\n  +                                   -e \"1c\\\n  +                                       object $new_sha1\" \\\n  +                                   -e \"2c\\\n  +                                       type commit\" \\\n  +                                   -e \"3c\\\n  +                                       tag $new_ref\" \\\n  +                                   -e '/^-----BEGIN PGP SIGNATURE-----/q' \\\n  +                                   -e 'p' |\n                                  git mktag) ||\n                                  die \"Could not create new tag object for $ref\"\n                          if git cat-file tag \"$ref\" | \\\n\n\n-brandon\n\n\n Documentation/git-filter-branch.txt |   14 ++++++++++----\n git-filter-branch.sh                |   19 +++++++++++++++++--\n t/t7003-filter-branch.sh            |   32 ++++++++++++++++++++++++++++++++\n 3 files changed, 59 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt\nindex 543a1cf..9364919 100644\n--- a/Documentation/git-filter-branch.txt\n+++ b/Documentation/git-filter-branch.txt\n@@ -132,10 +132,16 @@ use \"--tag-name-filter cat\" to simply update the tags.  In this\n case, be very careful and make sure you have the old tags\n backed up in case the conversion has run afoul.\n +\n-Note that there is currently no support for proper rewriting of\n-tag objects; in layman terms, if the tag has a message or signature\n-attached, the rewritten tag won't have it.  Sorry.  (It is by\n-definition impossible to preserve signatures at any rate.)\n+Nearly proper rewriting of tag objects is supported. If the tag has\n+a message attached, a new tag object will be created with the same message,\n+author, and timestamp. If the tag has a signature attached, the\n+signature will be stripped. It is by definition impossible to preserve\n+signatures. The reason this is \"nearly\" proper, is because ideally if\n+the tag did not change (points to the same object, has the same name, etc.)\n+it should retain any signature. That is not the case, signatures will always\n+be removed, buyer beware. There is also no support for changing the\n+author or timestamp (or the tag message for that matter). Tags which point\n+to other tags will be rewritten to point to the underlying commit.\n \n --subdirectory-filter <directory>::\n \tOnly look at the history which touches the given subdirectory.\ndiff --git a/git-filter-branch.sh b/git-filter-branch.sh\nindex 22b6ed4..3da3ccd 100755\n--- a/git-filter-branch.sh\n+++ b/git-filter-branch.sh\n@@ -406,8 +406,23 @@ if [ \"$filter_tag_name\" ]; then\n \t\techo \"$ref -> $new_ref ($sha1 -> $new_sha1)\"\n \n \t\tif [ \"$type\" = \"tag\" ]; then\n-\t\t\t# Warn that we are not rewriting the tag object itself.\n-\t\t\twarn \"unreferencing tag object $sha1t\"\n+\t\t\tnew_sha1=$(git cat-file tag \"$ref\" |\n+\t\t\t\tsed -n \\\n+\t\t\t\t    -e \"1c\\\n+\t\t\t\t\tobject $new_sha1\" \\\n+\t\t\t\t    -e \"2c\\\n+\t\t\t\t\ttype commit\" \\\n+\t\t\t\t    -e \"3c\\\n+\t\t\t\t\ttag $new_ref\" \\\n+\t\t\t\t    -e '/^-----BEGIN PGP SIGNATURE-----/q' \\\n+\t\t\t\t    -e 'p' |\n+\t\t\t\tgit mktag) ||\n+\t\t\t\tdie \"Could not create new tag object for $ref\"\n+\t\t\tif git cat-file tag \"$ref\" | \\\n+\t\t\t   grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1\n+\t\t\tthen\n+\t\t\t\twarn \"gpg signature stripped from tag object $sha1t\"\n+\t\t\tfi\n \t\tfi\n \n \t\tgit update-ref \"refs/tags/$new_ref\" \"$new_sha1\" ||\ndiff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh\nindex 6827249..1daaf54 100755\n--- a/t/t7003-filter-branch.sh\n+++ b/t/t7003-filter-branch.sh\n@@ -203,4 +203,36 @@ test_expect_success 'Subdirectory filter with disappearing trees' '\n \ttest $(git rev-list master | wc -l) = 3\n '\n \n+test_expect_success 'Tag name filtering retains tag message' '\n+\tgit tag -m atag T &&\n+\tgit cat-file tag T > expect &&\n+\tgit filter-branch -f --tag-name-filter cat &&\n+\tgit cat-file tag T > actual &&\n+\tgit diff expect actual\n+'\n+\n+faux_gpg_tag='object XXXXXX\n+type commit\n+tag S\n+tagger T A Gger <tagger@example.com> 1206026339 -0500\n+\n+This is a faux gpg signed tag.\n+-----BEGIN PGP SIGNATURE-----\n+Version: FauxGPG v0.0.0 (FAUX/Linux)\n+\n+gdsfoewhxu/6l06f1kxyxhKdZkrcbaiOMtkJUA9ITAc1mlamh0ooasxkH1XwMbYQ\n+acmwXaWET20H0GeAGP+7vow=\n+=agpO\n+-----END PGP SIGNATURE-----\n+'\n+test_expect_success 'Tag name filtering strips gpg signature' '\n+\tsha1=$(git rev-parse HEAD) &&\n+\tsha1t=$(echo \"$faux_gpg_tag\" | sed -e s/XXXXXX/$sha1/ | git mktag) &&\n+\tgit update-ref \"refs/tags/S\" \"$sha1t\" &&\n+\techo \"$faux_gpg_tag\" | sed -e s/XXXXXX/$sha1/ | head -n 6 > expect &&\n+\tgit filter-branch -f --tag-name-filter cat &&\n+\tgit cat-file tag S > actual &&\n+\tgit diff expect actual\n+'\n+\n test_done\n-- \n1.5.4.4.481.g5075\n"},{"id":"72961","messageId":"47E827CA.5010201@nrlssc.navy.mil","threadId":"12779","inReplyTo":"47E8267D.5000405@nrlssc.navy.mil","subject":"Re: [PATCH] filter-branch.sh: support nearly proper tag name filtering","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-03-24T22:14:34Z","receivedAt":"2008-03-24T22:14:34Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"\nI probably should have called this v2. Sorry.\n\n-brandon\n"},{"id":"72992","messageId":"7v63vbr4eq.fsf@gitster.siamese.dyndns.org","threadId":"12779","inReplyTo":"47E8267D.5000405@nrlssc.navy.mil","subject":"Re: [PATCH] filter-branch.sh: support nearly proper tag name filtering","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-25T01:14:21Z","receivedAt":"2008-03-25T01:14:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Brandon Casey <casey@nrlssc.navy.mil> writes:\n\n> I learned that the 'Q' command to sed is not portable, and most versions\n> of sed require a newline after 'c\\' like commands.\n\nBoth true.  If you want to be portable to esoteric ones (I suffered AIX\nwhile hacking on autoconf long time ago), sed is a bitch to get right.\n\nWhat I meant with my earlier comment was that it would have been more\nrobust if you did a sequence of:\n\n\ts/type .*/type $newtype/\n        s/object .*/object $newobject/\n\ninstead of relying on the order in the existing objects, but I should have\nbeen more explicit about c\\ as well.\n"},{"id":"73047","messageId":"47E91DF0.5070302@nrlssc.navy.mil","threadId":"12779","inReplyTo":"7v63vbr4eq.fsf@gitster.siamese.dyndns.org","subject":"[PATCH v3] filter-branch.sh: support nearly proper tag name filtering","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-03-25T15:44:48Z","receivedAt":"2008-03-25T15:44:48Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"Add support for creating a new tag object and retaining the tag message,\nauthor, and date when rewriting tags. The gpg signature, if one exists,\nwill be stripped.\n\nThis adds nearly proper tag name filtering to filter-branch. Proper tag\nname filtering would include the ability to change the tagger, tag date,\ntag message, and _not_ strip a gpg signature if the tag did not change.\n\nSigned-off-by: Brandon Casey <casey@nrlssc.navy.mil>\n---\n\n\nJunio C Hamano wrote:\n> What I meant with my earlier comment was that it would have been more\n> robust if you did a sequence of:\n> \n> \ts/type .*/type $newtype/\n>         s/object .*/object $newobject/\n> \n> instead of relying on the order in the existing objects, but I should have\n> been more explicit about c\\ as well.\n\nYep, that is better. This version implementing your suggestions won't silently\ncreate a valid tag from one that mktag would have barfed on.\n\nIf you think the strict ordering that mktag requires could be relaxed in the\nfuture, then the line number addresses in sed could be changed to ranges\nlike:\n\n\t-e \"1,4s/^object ..*/object $newobject/\"\n\nOf course, if we use ranges, we may have to worry about matching against\nthe tag body if the header gets any longer.\n\n-brandon\n\n\n Documentation/git-filter-branch.txt |   14 ++++++++++----\n git-filter-branch.sh                |   16 ++++++++++++++--\n t/t7003-filter-branch.sh            |   32 ++++++++++++++++++++++++++++++++\n 3 files changed, 56 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt\nindex 2a78549..9d11b41 100644\n--- a/Documentation/git-filter-branch.txt\n+++ b/Documentation/git-filter-branch.txt\n@@ -133,10 +133,16 @@ use \"--tag-name-filter cat\" to simply update the tags.  In this\n case, be very careful and make sure you have the old tags\n backed up in case the conversion has run afoul.\n +\n-Note that there is currently no support for proper rewriting of\n-tag objects; in layman terms, if the tag has a message or signature\n-attached, the rewritten tag won't have it.  Sorry.  (It is by\n-definition impossible to preserve signatures at any rate.)\n+Nearly proper rewriting of tag objects is supported. If the tag has\n+a message attached, a new tag object will be created with the same message,\n+author, and timestamp. If the tag has a signature attached, the\n+signature will be stripped. It is by definition impossible to preserve\n+signatures. The reason this is \"nearly\" proper, is because ideally if\n+the tag did not change (points to the same object, has the same name, etc.)\n+it should retain any signature. That is not the case, signatures will always\n+be removed, buyer beware. There is also no support for changing the\n+author or timestamp (or the tag message for that matter). Tags which point\n+to other tags will be rewritten to point to the underlying commit.\n \n --subdirectory-filter <directory>::\n \tOnly look at the history which touches the given subdirectory.\ndiff --git a/git-filter-branch.sh b/git-filter-branch.sh\nindex 22b6ed4..05f7c7b 100755\n--- a/git-filter-branch.sh\n+++ b/git-filter-branch.sh\n@@ -406,8 +406,20 @@ if [ \"$filter_tag_name\" ]; then\n \t\techo \"$ref -> $new_ref ($sha1 -> $new_sha1)\"\n \n \t\tif [ \"$type\" = \"tag\" ]; then\n-\t\t\t# Warn that we are not rewriting the tag object itself.\n-\t\t\twarn \"unreferencing tag object $sha1t\"\n+\t\t\tnew_sha1=$(git cat-file tag \"$ref\" |\n+\t\t\t\tsed -n \\\n+\t\t\t\t    -e \"1s/^object ..*/object $new_sha1/\"  \\\n+\t\t\t\t    -e '2s/^type ..*/type commit/'         \\\n+\t\t\t\t    -e \"3s/^tag ..*/tag $new_ref/\"         \\\n+\t\t\t\t    -e '/^-----BEGIN PGP SIGNATURE-----/q' \\\n+\t\t\t\t    -e 'p' |\n+\t\t\t\tgit mktag) ||\n+\t\t\t\tdie \"Could not create new tag object for $ref\"\n+\t\t\tif git cat-file tag \"$ref\" | \\\n+\t\t\t   grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1\n+\t\t\tthen\n+\t\t\t\twarn \"gpg signature stripped from tag object $sha1t\"\n+\t\t\tfi\n \t\tfi\n \n \t\tgit update-ref \"refs/tags/$new_ref\" \"$new_sha1\" ||\ndiff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh\nindex 6827249..1daaf54 100755\n--- a/t/t7003-filter-branch.sh\n+++ b/t/t7003-filter-branch.sh\n@@ -203,4 +203,36 @@ test_expect_success 'Subdirectory filter with disappearing trees' '\n \ttest $(git rev-list master | wc -l) = 3\n '\n \n+test_expect_success 'Tag name filtering retains tag message' '\n+\tgit tag -m atag T &&\n+\tgit cat-file tag T > expect &&\n+\tgit filter-branch -f --tag-name-filter cat &&\n+\tgit cat-file tag T > actual &&\n+\tgit diff expect actual\n+'\n+\n+faux_gpg_tag='object XXXXXX\n+type commit\n+tag S\n+tagger T A Gger <tagger@example.com> 1206026339 -0500\n+\n+This is a faux gpg signed tag.\n+-----BEGIN PGP SIGNATURE-----\n+Version: FauxGPG v0.0.0 (FAUX/Linux)\n+\n+gdsfoewhxu/6l06f1kxyxhKdZkrcbaiOMtkJUA9ITAc1mlamh0ooasxkH1XwMbYQ\n+acmwXaWET20H0GeAGP+7vow=\n+=agpO\n+-----END PGP SIGNATURE-----\n+'\n+test_expect_success 'Tag name filtering strips gpg signature' '\n+\tsha1=$(git rev-parse HEAD) &&\n+\tsha1t=$(echo \"$faux_gpg_tag\" | sed -e s/XXXXXX/$sha1/ | git mktag) &&\n+\tgit update-ref \"refs/tags/S\" \"$sha1t\" &&\n+\techo \"$faux_gpg_tag\" | sed -e s/XXXXXX/$sha1/ | head -n 6 > expect &&\n+\tgit filter-branch -f --tag-name-filter cat &&\n+\tgit cat-file tag S > actual &&\n+\tgit diff expect actual\n+'\n+\n test_done\n-- \n1.5.5.rc1.1.gb5ed86.dirty\n"},{"id":"73123","messageId":"7vmyolgbor.fsf@gitster.siamese.dyndns.org","threadId":"12779","inReplyTo":"47E91DF0.5070302@nrlssc.navy.mil","subject":"Re: [PATCH v3] filter-branch.sh: support nearly proper tag name filtering","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-26T07:57:08Z","receivedAt":"2008-03-26T07:57:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Brandon Casey <casey@nrlssc.navy.mil> writes:\n\n> If you think the strict ordering that mktag requires could be relaxed in the\n> future, then the line number addresses in sed could be changed to ranges\n> like:\n>\n> \t-e \"1,4s/^object ..*/object $newobject/\"\n>\n> Of course, if we use ranges, we may have to worry about matching against\n> the tag body if the header gets any longer.\n\nI do not think you have to worry if you did this:\n\n        1,/^$/{\n                s/object .*/object $newobject/\n                s/type .*/type $newtype/\n                ...\n        }\n"},{"id":"73139","messageId":"47EA6FFD.1090805@nrlssc.navy.mil","threadId":"12779","inReplyTo":"7vmyolgbor.fsf@gitster.siamese.dyndns.org","subject":"[PATCH v4] filter-branch.sh: support nearly proper tag name filtering","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-03-26T15:47:09Z","receivedAt":"2008-03-26T15:47:09Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"Add support for creating a new tag object and retaining the tag message,\nauthor, and date when rewriting tags. The gpg signature, if one exists,\nwill be stripped.\n\nThis adds nearly proper tag name filtering to filter-branch. Proper tag\nname filtering would include the ability to change the tagger, tag date,\ntag message, and _not_ strip a gpg signature if the tag did not change.\n\nSigned-off-by: Brandon Casey <casey@nrlssc.navy.mil>\n---\n\n\nJunio C Hamano wrote:\n> Brandon Casey <casey@nrlssc.navy.mil> writes:\n>> Of course, if we use ranges, we may have to worry about matching against\n>> the tag body if the header gets any longer.\n> \n> I do not think you have to worry if you did this:\n> \n>         1,/^$/{\n>                 s/object .*/object $newobject/\n>                 s/type .*/type $newtype/\n>                 ...\n>         }\n\nI am a sed light-weight. Thanks for teaching.\n\n-brandon\n\n\n Documentation/git-filter-branch.txt |   14 ++++++++++----\n git-filter-branch.sh                |   18 ++++++++++++++++--\n t/t7003-filter-branch.sh            |   32 ++++++++++++++++++++++++++++++++\n 3 files changed, 58 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt\nindex 2a78549..9d11b41 100644\n--- a/Documentation/git-filter-branch.txt\n+++ b/Documentation/git-filter-branch.txt\n@@ -133,10 +133,16 @@ use \"--tag-name-filter cat\" to simply update the tags.  In this\n case, be very careful and make sure you have the old tags\n backed up in case the conversion has run afoul.\n +\n-Note that there is currently no support for proper rewriting of\n-tag objects; in layman terms, if the tag has a message or signature\n-attached, the rewritten tag won't have it.  Sorry.  (It is by\n-definition impossible to preserve signatures at any rate.)\n+Nearly proper rewriting of tag objects is supported. If the tag has\n+a message attached, a new tag object will be created with the same message,\n+author, and timestamp. If the tag has a signature attached, the\n+signature will be stripped. It is by definition impossible to preserve\n+signatures. The reason this is \"nearly\" proper, is because ideally if\n+the tag did not change (points to the same object, has the same name, etc.)\n+it should retain any signature. That is not the case, signatures will always\n+be removed, buyer beware. There is also no support for changing the\n+author or timestamp (or the tag message for that matter). Tags which point\n+to other tags will be rewritten to point to the underlying commit.\n \n --subdirectory-filter <directory>::\n \tOnly look at the history which touches the given subdirectory.\ndiff --git a/git-filter-branch.sh b/git-filter-branch.sh\nindex 22b6ed4..ee90660 100755\n--- a/git-filter-branch.sh\n+++ b/git-filter-branch.sh\n@@ -406,8 +406,22 @@ if [ \"$filter_tag_name\" ]; then\n \t\techo \"$ref -> $new_ref ($sha1 -> $new_sha1)\"\n \n \t\tif [ \"$type\" = \"tag\" ]; then\n-\t\t\t# Warn that we are not rewriting the tag object itself.\n-\t\t\twarn \"unreferencing tag object $sha1t\"\n+\t\t\tnew_sha1=$(git cat-file tag \"$ref\" |\n+\t\t\t\tsed -n \\\n+\t\t\t\t    -e \"1,/^$/{\n+\t\t\t\t\t  s/^object .*/object $new_sha1/\n+\t\t\t\t\t  s/^type .*/type commit/\n+\t\t\t\t\t  s/^tag .*/tag $new_ref/\n+\t\t\t\t\t}\" \\\n+\t\t\t\t    -e '/^-----BEGIN PGP SIGNATURE-----/q' \\\n+\t\t\t\t    -e 'p' |\n+\t\t\t\tgit mktag) ||\n+\t\t\t\tdie \"Could not create new tag object for $ref\"\n+\t\t\tif git cat-file tag \"$ref\" | \\\n+\t\t\t   grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1\n+\t\t\tthen\n+\t\t\t\twarn \"gpg signature stripped from tag object $sha1t\"\n+\t\t\tfi\n \t\tfi\n \n \t\tgit update-ref \"refs/tags/$new_ref\" \"$new_sha1\" ||\ndiff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh\nindex 6827249..1daaf54 100755\n--- a/t/t7003-filter-branch.sh\n+++ b/t/t7003-filter-branch.sh\n@@ -203,4 +203,36 @@ test_expect_success 'Subdirectory filter with disappearing trees' '\n \ttest $(git rev-list master | wc -l) = 3\n '\n \n+test_expect_success 'Tag name filtering retains tag message' '\n+\tgit tag -m atag T &&\n+\tgit cat-file tag T > expect &&\n+\tgit filter-branch -f --tag-name-filter cat &&\n+\tgit cat-file tag T > actual &&\n+\tgit diff expect actual\n+'\n+\n+faux_gpg_tag='object XXXXXX\n+type commit\n+tag S\n+tagger T A Gger <tagger@example.com> 1206026339 -0500\n+\n+This is a faux gpg signed tag.\n+-----BEGIN PGP SIGNATURE-----\n+Version: FauxGPG v0.0.0 (FAUX/Linux)\n+\n+gdsfoewhxu/6l06f1kxyxhKdZkrcbaiOMtkJUA9ITAc1mlamh0ooasxkH1XwMbYQ\n+acmwXaWET20H0GeAGP+7vow=\n+=agpO\n+-----END PGP SIGNATURE-----\n+'\n+test_expect_success 'Tag name filtering strips gpg signature' '\n+\tsha1=$(git rev-parse HEAD) &&\n+\tsha1t=$(echo \"$faux_gpg_tag\" | sed -e s/XXXXXX/$sha1/ | git mktag) &&\n+\tgit update-ref \"refs/tags/S\" \"$sha1t\" &&\n+\techo \"$faux_gpg_tag\" | sed -e s/XXXXXX/$sha1/ | head -n 6 > expect &&\n+\tgit filter-branch -f --tag-name-filter cat &&\n+\tgit cat-file tag S > actual &&\n+\tgit diff expect actual\n+'\n+\n test_done\n-- \n1.5.4.4.481.g5075\n"}]}