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'