Change A File's Content In Every Git Branch

by Zach Briggs

Challenge: remove the second line from a given file across all local git branches. Bonus points for spending longer trying to figure out how to do it with a single command than just making 18 changes.

git filter-branch --tree-filter 'touch game_test.rb && sed -i.bak 2d game_test.rb && rm game_test.rb.bak'

 

  • We can run a command against every branch of a repo with
git filter-branch --tree-filter command 
  • Typically we see a find and replace pattern with sed such as 
sed s/find-me/replace-me/g  file >> another-file
  • Much to my delight we can just remove lines wholesale with the d flag. 
  • sed 2d file outputs the contents of file to standard out with the 2nd line deleted.
sed 2d file >> another-file 
  • Sed's -i flag allows us to operate on a file in place
sed -i pattern file
  • We need to create a backup file for OSX otherwise we get an error: 
sed -i.bak pattern file
  • Putting that together, we can delete the second line of a file without opening it with 
sed -i.bak 2d file
  • The && operator allows us to run two commands on the same line:
command && command
  • Since OSX forces us to create an unwanted backup file when we use the -i flag with sed, we'll need to remove it right after running sed. Let's do it in the same line: 
sed -i.bak 2d file && rm file.bak 
  • Not all of the branches have our target file which will make sed fail. Let's create the file first as a hack.  
touch file &&  sed -i.bak 2d file && rm file.bak
  • Now lets run a destructive command against every local branch!
git filter-branch --tree-filter 'sed -i.bak 2d file && rm file.bak'