{"thread":{"id":"39936","subject":"Question about git filter-branch with signed commits","startedAt":"2015-07-25T20:17:28Z","lastAt":"2015-07-26T01:24:04Z","messageCount":3,"participants":["Adam Liter","Jacob Keller"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"266773","messageId":"5085A037-0E20-4FA4-B553-E54345F4FAA5@gmail.com","threadId":"39936","inReplyTo":null,"subject":"Question about git filter-branch with signed commits","fromName":"Adam Liter","fromEmail":"adam.liter@gmail.com","sentAt":"2015-07-25T20:17:28Z","receivedAt":"2015-07-25T20:17:28Z","isPatch":false,"sender":{"key":"adam.liter@gmail.com","avatar":null},"body":"Hello,\n\nI'm trying to clean up the commit history of a git repository by \nremoving certain files. The repository contains signed commits, and when \nI try to use git filter-branch, the PGP signature is converted to the \nfirst line of the commit message.\n\nIs this the expected behavior? If so, is there something that I can do \nto prevent this from happening?\n\nI'm using git v. 2.4.6. I tried reducing the behavior to a simple case. \nI asked about this on Stack Overflow \n(http://stackoverflow.com/q/31552774/2571049), but the question hasn't \nreally gotten any uptake, so I thought I would try asking here too.\n\nIn trying to reproduce the behavior in a minimal way, I did the \nfollowing:\n\nmkdir pgp-git-test\ncd pgp-git-test\ngit init\ntouch a.txt\ngit add a.txt\ngit commit -m \"Add a.txt\" -S\ntouch b.txt\ngit add b.txt\ngit commit -m \"Add b.txt\" -S\ngit filter-branch --index-filter 'git rm --cached --ignore-unmatch \na.txt' --prune-empty HEAD\ngit log --oneline --decorate\nb4efdf0 (HEAD -> master)  iQIcBAABCgAGBQJVrvqHAAoJ [...] -----END PGP \nSIGNATURE-----\n9f82e63  iQIcBAABCgAGBQJVrvp7AAoJ [...]  -----END PGP SIGNATURE-----\n\nAs can be seen after running git log --oneline --decorate, the PGP \nsignature has become the first line of the commit. The rest of the \ncommit message is still there, but it's on a line below the PGP \nsignature.\n\nHow can I prevent this from happening when using git filter-branch?\n\nAlso, one thing that I was a bit surprised about when trying to create \nthis minimal example is that the first commit is still there. Does \nanyone know why the commit history still contains the first commit, \nsince the first commit only involved the file a.txt and since I passed \n--prune-empty to git filter-branch? Shouldn't this commit have been \neliminated from the log?\n\nThanks in advance for the help! I'm relatively new to git, so apologies \nfor bugging you all if this is a trivial error on my part. Thanks!\n\nBest,\nAdam Liter\n"},{"id":"266777","messageId":"CA+P7+xo+0cb38qjAJwrOtRahDwWgSvG+-5-6XAF6BpRSvnMXgw@mail.gmail.com","threadId":"39936","inReplyTo":"5085A037-0E20-4FA4-B553-E54345F4FAA5@gmail.com","subject":"Re: Question about git filter-branch with signed commits","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2015-07-25T22:50:03Z","receivedAt":"2015-07-25T22:50:03Z","isPatch":false,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Sat, Jul 25, 2015 at 1:17 PM, Adam Liter <adam.liter@gmail.com> wrote:\n> Hello,\n>\n> I'm trying to clean up the commit history of a git repository by removing\n> certain files. The repository contains signed commits, and when I try to use\n> git filter-branch, the PGP signature is converted to the first line of the\n> commit message.\n>\n\nIt should be possible to craft a filter that removes the signatures\nentirely. It is not possible to craft a filter-branch which retains\nthe signatures in any *valid* form, though you could re-create new\nsignatures assuming you have all the private keys (ie: you're the one\nwho signed all the commits).\n\nYou can't keep the signatures alone, because then they wouldn't be\nvalid, since the data they signed is not the same now. Normally\nsignatures are used so that you can verify \"yes, so-and-so is the\nperson who did this thing and no one else could have faked it).\n\n> Is this the expected behavior? If so, is there something that I can do to\n> prevent this from happening?\n\nI'm not sure why it's putting the first line at the top of the commit.\n\n>\n> I'm using git v. 2.4.6. I tried reducing the behavior to a simple case. I\n> asked about this on Stack Overflow\n> (http://stackoverflow.com/q/31552774/2571049), but the question hasn't\n> really gotten any uptake, so I thought I would try asking here too.\n>\n> In trying to reproduce the behavior in a minimal way, I did the following:\n>\n> mkdir pgp-git-test\n> cd pgp-git-test\n> git init\n> touch a.txt\n> git add a.txt\n> git commit -m \"Add a.txt\" -S\n> touch b.txt\n> git add b.txt\n> git commit -m \"Add b.txt\" -S\n> git filter-branch --index-filter 'git rm --cached --ignore-unmatch a.txt'\n> --prune-empty HEAD\n> git log --oneline --decorate\n> b4efdf0 (HEAD -> master)  iQIcBAABCgAGBQJVrvqHAAoJ [...] -----END PGP\n> SIGNATURE-----\n> 9f82e63  iQIcBAABCgAGBQJVrvp7AAoJ [...]  -----END PGP SIGNATURE-----\n>\n> As can be seen after running git log --oneline --decorate, the PGP signature\n> has become the first line of the commit. The rest of the commit message is\n> still there, but it's on a line below the PGP signature.\n>\n> How can I prevent this from happening when using git filter-branch?\n\nYou probably need to run all the commits through a filter first which\nstrips out all signature info, and then re-write the commits to remove\nthe file. You can't leave the signatures in there alone, as they would\nno longer be valid, and people who try to verify them would fail.\n\n>\n> Also, one thing that I was a bit surprised about when trying to create this\n> minimal example is that the first commit is still there. Does anyone know\n> why the commit history still contains the first commit, since the first\n> commit only involved the file a.txt and since I passed --prune-empty to git\n> filter-branch? Shouldn't this commit have been eliminated from the log?\n>\n\nI'm not sure about this part, sorry.\n\n> Thanks in advance for the help! I'm relatively new to git, so apologies for\n> bugging you all if this is a trivial error on my part. Thanks!\n>\n> Best,\n> Adam Liter\n\nRegards,\nJake\n"},{"id":"266778","messageId":"9A494528-F43E-4FEE-A31F-FB8B1E85A1AD@gmail.com","threadId":"39936","inReplyTo":"CA+P7+xo+0cb38qjAJwrOtRahDwWgSvG+-5-6XAF6BpRSvnMXgw@mail.gmail.com","subject":"Re: Question about git filter-branch with signed commits","fromName":"Adam Liter","fromEmail":"adam.liter@gmail.com","sentAt":"2015-07-26T01:24:04Z","receivedAt":"2015-07-26T01:24:04Z","isPatch":false,"sender":{"key":"adam.liter@gmail.com","avatar":null},"body":">> I'm trying to clean up the commit history of a git repository by \n>> removing\n>> certain files. The repository contains signed commits, and when I try \n>> to use\n>> git filter-branch, the PGP signature is converted to the first line \n>> of the\n>> commit message.\n>\n> It should be possible to craft a filter that removes the signatures\n> entirely. It is not possible to craft a filter-branch which retains\n> the signatures in any *valid* form, though you could re-create new\n> signatures assuming you have all the private keys (ie: you're the one\n> who signed all the commits).\n>\n> You can't keep the signatures alone, because then they wouldn't be\n> valid, since the data they signed is not the same now. Normally\n> signatures are used so that you can verify \"yes, so-and-so is the\n> person who did this thing and no one else could have faked it).\n\nAh, okay, that makes sense.\n\n>> Is this the expected behavior? If so, is there something that I can \n>> do to\n>> prevent this from happening?\n>\n> I'm not sure why it's putting the first line at the top of the commit.\n>\n>> I'm using git v. 2.4.6. I tried reducing the behavior to a simple \n>> case. I\n>> asked about this on Stack Overflow\n>> (http://stackoverflow.com/q/31552774/2571049), but the question \n>> hasn't\n>> really gotten any uptake, so I thought I would try asking here too.\n>>\n>> In trying to reproduce the behavior in a minimal way, I did the \n>> following:\n>>\n>> mkdir pgp-git-test\n>> cd pgp-git-test\n>> git init\n>> touch a.txt\n>> git add a.txt\n>> git commit -m \"Add a.txt\" -S\n>> touch b.txt\n>> git add b.txt\n>> git commit -m \"Add b.txt\" -S\n>> git filter-branch --index-filter 'git rm --cached --ignore-unmatch \n>> a.txt'\n>> --prune-empty HEAD\n>> git log --oneline --decorate\n>> b4efdf0 (HEAD -> master)  iQIcBAABCgAGBQJVrvqHAAoJ [...] -----END PGP\n>> SIGNATURE-----\n>> 9f82e63  iQIcBAABCgAGBQJVrvp7AAoJ [...]  -----END PGP SIGNATURE-----\n>>\n>> As can be seen after running git log --oneline --decorate, the PGP \n>> signature\n>> has become the first line of the commit. The rest of the commit \n>> message is\n>> still there, but it's on a line below the PGP signature.\n>>\n>> How can I prevent this from happening when using git filter-branch?\n>\n> You probably need to run all the commits through a filter first which\n> strips out all signature info, and then re-write the commits to remove\n> the file. You can't leave the signatures in there alone, as they would\n> no longer be valid, and people who try to verify them would fail.\n\nDo you know of a good way to do this? I'm pretty new to git, and I \nhaven't had much luck searching online or looking through the \ndocumentation for ideas of how to even filter out the PGP signatures \nbefore filtering out a certain file from the commit history.\n\nIf you could even point me in the right direction, I would really \nappreciate it. Do you think there is a way to do this all automatically, \nso that it would be possible to keep track of which commits have had \ntheir signatures removed and then resign them after filtering out the \nfile (I am the one who signed the commits originally), or would that be \nimpossible since the SHA-1 hashes of the commits will change?\n\n>> Also, one thing that I was a bit surprised about when trying to \n>> create this\n>> minimal example is that the first commit is still there. Does anyone \n>> know\n>> why the commit history still contains the first commit, since the \n>> first\n>> commit only involved the file a.txt and since I passed --prune-empty \n>> to git\n>> filter-branch? Shouldn't this commit have been eliminated from the \n>> log?\n>\n> I'm not sure about this part, sorry.\n\nNo worries. Thanks for your help and your initial response. I appreciate \nit!\n\n>> Thanks in advance for the help! I'm relatively new to git, so \n>> apologies for\n>> bugging you all if this is a trivial error on my part. Thanks!\n>>\n>> Best,\n>> Adam Liter\n>\n> Regards,\n> Jake\n"}]}