Git Maintenance

Today I learned about the git maintenance command that runs tasks for regular maintenance of a git repo. If you run git maintenance start in a repo, git will create scheduled tasks to run at regular intervals to perform these tasks in the background like garbage collection. This will optimize and speed up the repo without having to tack them on occasionally as you run other commands. A particularly handy task it will run every hour is prefetch, where it does a git fetch but only pulls down the data and doesn’t update any refs. Then when you actually run git fetch or git pull, it completes almost instantly because it already has all the data. ...

Git ORIG_HEAD

Today I learned that ORIG_HEAD is a reference that git maintains to the previous commit HEAD pointed to before it “was modified in a drastic way”. The docs mention these operations as examples of when ORIG_HEAD is updated: (git am, git merge, git rebase, git reset) This is useful when you want to undo one of those operations. You can use git reset --hard ORIG_HEAD (or --keep) to put your branch back to where it was before the operation. ...

Git rebase.abbreviateCommands

This is probably a very niche use case, but I learned today that you can abbreviate commands that git populates in the todo list during an interactive rebase. So it’ll look like this: p deadbee The oneline of the commit p fa1afe1 The oneline of the next commit You can enable this with git config --global rebase.abbreviateCommands true. To be clear, you can always use the abbreviated commands, but since I use Vim to edit the list, it makes it slightly more convenient to edit the commands. ...

Git clean interactive

I just discovered the interactive mode of git clean. Git Clean is handy when you want to clear out anything from your local repository folder that isn’t tracked by git. This often includes build outputs and other generated files. This is useful if for instance Visual Studio is acting weird and you’re tempted to do a fresh clone to fix it. I have a git alias I use for this: cl = git clean -idx -e 'node_modules' ...

DeepGit blame

Today I learned that DeepGit is actually completely free even for commercial use. This is the best git blame utility I’ve come across because it lets you continue drilling down into the history of a line, kinda like a recursive blame. You do have to provide an email address to register but I think it’s worth it. It’s from the same developer of my preferred git client SmartGit but SmartGit does require a paid license for commercial use. ...

Easily reference upstream branch

Today I learned that you can reference the upstream branch in git with @{u}. I used this to make a convenient git alias reso for “reset to origin”: git config --global alias.reso "reset --keep @{u}" note: I’m using --keep instead of --hard because it’s a bit safer I use this when a branch I’ve pulled down has completely changed on the remote and I have no changes (for instance when reviewing a PR) and a pull would be messy (a reset is also much faster depending on the number of commits). ...

Git rerere

If you’ve ever had to abort a rebase or merge but didn’t want to waste the work you already did resolving merge conflicts, then you should enable the git rerere option: git global config rerere.enabled true It stands for Reuse Recorded Resolution, and it essentially remembers how you resolved a merge conflict and will automatically reapply if it sees it again. Resolving conflicts with git-rerere

git-absorb

One of my favorite git plugins is git-absorb (which is a port of Mercurial’s absorb). It basically helps you create --fixup commits automatically, which you can then use an interactive rebase with autoSquash to “absorb” them into your previous commits. I tend to use it when I’ve made a bunch of small tweaks to my feature branch, especially from automated feedback from a PR bot, I’ll then stage the changes and git-absorb will find the previous commit on my branch that also modified those same lines. ...

push.autoSetupRemote

Today I learned about the git config setting push.autoSetupRemote that was added in version 2.37.0. Like Tekin mentions in his post, I’ve had a git alias to do create my upstream branch but I still forget sometimes. To me this seems safe to enable by default with: git config --global --add --bool push.autoSetupRemote true and git will now set the upstream tracking branch for you!

--update-refs won't update a ref if it's currently checked out in a working directory

Today I learned that if you’re using the fairly new --update-refs feature of git to update multiple refs during a rebase, git won’t update a ref if it’s currently checked out in another working directory for that repo. This makes sense but git currently doesn’t give you any feedback that it wasn’t updated or why. It wasn’t until I tried to manually update it with a git branch --force that it told me the issue: ...