DEV Community

Discussion on: 10 Git Tricks to Save Your Time and Sanity

Collapse
 
ahferroin7 profile image
Austin S. Hemmelgarn • Edited

Two other big ones come to mind that I often see underutilized, but find indispensable on a regular basis:

Interactively stage individual parts of files for a commit

Sometimes, you end up fixing bugs in nearby code that you didn't notice until you were testing something else. Or maybe you end up needing to split out a big bunch of changes into separate logical steps. Or perhaps you just forgot to commit something before starting on the next thing.

In any case, you can use:

git add -i

It will bring up a menu-based interface to step through individual hunks of the current set of changes to the working tree and let you select only the parts you want to include in the commit.

Rearrange (or completely rewrite) the history of a branch

git rebase also has an interactive mode (also enabled with the -i switch). You can use this to edit history back to a certain commit without moving the branch you're on by running:

git rebase -i <commit>

The commit you specify should be the last one before the commit you want to start editing things at. Just like a normal rebase, you can specify a tag or a branch name instead of a commit here (or use a commit-like form like HEAD~8). This will open an editor with a list of instructions to git for how to perform the rebase (it defaults to what it would do if you were doing a regular rebase), as well as some comments below that explaining what each instruction means.

Things you can do with this include:

  • Change the order of commits. Just reorder them in the list that shows up when you start the interactive rebase.
  • Completely remove commits from history. Just remove the lines for those commits from the list, or change the pick at the beginning of the lines to drop.
  • Insert completely new commits. Add a break to the list where you want to put the new commit, the rebase will stop there and drop to a shell, where you can make your code changes and commit them just like normal, then run git rebase --continue to resume the rebase. You can also use this to merge branches or cherry pick commits into arbitrary locations in your history.
  • Amend commits arbitrarily far back in the history. Replace pick with edit, the commit will be applied, but the rebase will stop immediately afterwards so you can use git commit --amend to update the commit. This is essentially a shorter form of adding a break after the commit.
  • Squash commits. Put the line for the commit you want to squash right after the one you want to squash it into, then replace the pick with squash.
  • Meld fixes into the commit they fix. Same as squashing, just use fixup instead of squash and it will just use the commit message from the first commit as-is instead of prompting you to enter a new one for the single commit it produces.
  • Split commits. Mark the commit you want to split to be amended, then run git reset HEAD~ when the rebase stops to let you amend that commit. This will remove that commit from the history, but leave all the changes it made to the working tree in place, and you can then split them out into new commits however you want (possibly using git add -i to simplify the process).
  • Verify the code state between commits. You can add a line starting with exec wherever you want in the sequence of commands. The rebase process will pass the rest of that line to the shell to be run as a command (essentially, it calls sh -c followed by the rest of the line) at that point during the rebase, and will stop the rebase if the command fails (just like if a merge failed) so that you can investigate what happened and either cancel the rebase or continue it as you see fit.