{"thread":{"id":"18495","subject":"checkout/update boiler plate for --filter-index?","startedAt":"2009-03-23T21:33:28Z","lastAt":"2009-03-24T07:43:01Z","messageCount":3,"participants":["Marcel Cary","Johannes Sixt","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"109107","messageId":"580660BE-FDAB-4947-B409-1E8D5CBEF8EE@earth.care2.com","threadId":"18495","inReplyTo":null,"subject":"checkout/update boiler plate for --filter-index?","fromName":"Marcel Cary","fromEmail":"marcel@earth.care2.com","sentAt":"2009-03-23T21:33:28Z","receivedAt":"2009-03-23T21:33:28Z","isPatch":false,"sender":{"key":"marcel@earth.care2.com","avatar":null},"body":"I'm trying to do a historical find-and-replace on my code:\n\ngit grep -F foo > files\ngit filter-branch --index-filter \"\n   cat `pwd`/files | xargs git checkout  --\n   cat `pwd`/files | xargs sed -i 's/foo/bar/g; '\n   cat `pwd`/files | xargs git update-index --\n\" ancestor..HEAD\n\nWhen I instead use --tree-filter and skip the checkout/update-index,  \nit works how I want (but it takes a while...).  But when I use --index- \nfilter, the resulting history shows the \"foo\" to \"bar\" change  \nhappening *after* new code is added, rather than originally adding  \n\"bar\".\n\nHow can I checkout just a few files and update them to take advantage  \nof the speed of index operations?\n\nMarcel\n"},{"id":"109159","messageId":"49C889E2.2080208@viscovery.net","threadId":"18495","inReplyTo":"580660BE-FDAB-4947-B409-1E8D5CBEF8EE@earth.care2.com","subject":"Re: checkout/update boiler plate for --filter-index?","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2009-03-24T07:21:06Z","receivedAt":"2009-03-24T07:21:06Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Marcel Cary schrieb:\n> I'm trying to do a historical find-and-replace on my code:\n> \n> git grep -F foo > files\n> git filter-branch --index-filter \"\n>   cat `pwd`/files | xargs git checkout  --\n>   cat `pwd`/files | xargs sed -i 's/foo/bar/g; '\n>   cat `pwd`/files | xargs git update-index --\n> \" ancestor..HEAD\n> \n> When I instead use --tree-filter and skip the checkout/update-index, it\n> works how I want (but it takes a while...).  But when I use\n> --index-filter, the resulting history shows the \"foo\" to \"bar\" change\n> happening *after* new code is added, rather than originally adding \"bar\".\n> \n> How can I checkout just a few files and update them to take advantage of\n> the speed of index operations?\n\nYou cannot do that with the index filter because you need actual blob\ncontents to operate on, but the index filter doesn't give you an\nopportunity to do that. The tree filter is the right filter to use. But\nyou neither need 'git checkout' nor 'git update-index' in the filter -\nfilter-branch calls them for you. (Oh, and get rid of that useless use of\ncat.)\n\n-- Hannes\n"},{"id":"109162","messageId":"20090324074301.GB32400@coredump.intra.peff.net","threadId":"18495","inReplyTo":"49C889E2.2080208@viscovery.net","subject":"Re: checkout/update boiler plate for --filter-index?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-24T07:43:01Z","receivedAt":"2009-03-24T07:43:01Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Mar 24, 2009 at 08:21:06AM +0100, Johannes Sixt wrote:\n\n> You cannot do that with the index filter because you need actual blob\n> contents to operate on, but the index filter doesn't give you an\n> opportunity to do that. The tree filter is the right filter to use. But\n> you neither need 'git checkout' nor 'git update-index' in the filter -\n> filter-branch calls them for you. (Oh, and get rid of that useless use of\n> cat.)\n\nWell, you _could_ do it as an index-filter, which has the potential to\nbe much faster if you are only operating only on a small subset of the\nfiles.  But it's much less readable. Something like (totally untested):\n\n  git filter-branch --index-filter '\n    for i in `cat /path/to/files`; do\n      hash=$(git cat-file :$i |\n             sed 's/foo/bar/' |\n             git hash-object -w --stdin)\n      git update-index --add --cacheinfo 100644 $hash $i\n    done\n  '\n\nI'm sure you could do even do it with a constant number of processes per\ncommit by using update-index --index-info, hash-object --stdin-paths,\nand cat-file --batch. But it would probably be even less readable. ;)\n\nPersonally, I would probably just do a tree-filter for simplicity unless\nthe repo size made it prohibitively slow.\n\n-Peff\n"}]}