Update 2015-07-29

The git-new-workdir script has been superseded by the git-worktree command added in Git 2.5. The post below is for historical reference.




The git.git Repo has a little folder inside it called contrib. It’s a place for everything that a Git user might find useful, but (for various reasons) isn’t in Git itself already.

Below are the 3 things from contrib I use. But even if you don’t have any use for these, you might find something useful in there, and if it’s only examples on how to write a hook, or a new porcelain command for Git.

git-new-workdir

When you want to switch to another branch in Git, you simply say git checkout branchname. But there’s a small problem with this approach: If you want to switch to another branch, but still have a lot of unsaved changes, then the switch might fail. Or you might want to have two separate branches checked out at the same time.

One solution to this is to simply create another local clone of your repository. Git automatically uses hard links when you clone locally, so cloning is very fast. But there is one problem with this: You now have another, separate repository you need to keep up to date.

This is where git-new-workdir comes in. Instead of doing a full-blown clone of your repository, it simply sets up a new working directory (with its own index) for you. The actual repository itself is shared between the original and the new working directory. This means: If you update one repository, the new commits are instantly visible in all other working directories as well. Create a new commit or branch in one of your working directories, they’re instantly available in all working directories.

Note: Even though the commits are automatically there, Git won’t update the working copy if you’ve got the same branch checked out. You’ll have to do that for yourself.

To install, simply stick the script (which can be found under contrib/workdir/) somewhere in your $PATH and make it executable. Run it without any arguments to see its usage, and run

git-new-workdir path/to/repository/ path/to/new/workdir

to get a new working directory. You can optionally specify a branch which will then be automatically checked out after setting everything up.

pre-auto-gc-battery

git gc can be a quite CPU-intensive and potentially long-running operation, especially if your repository is already quite large. So naturally you’d want to avoid it if you are using a laptop and currently under battery power.

Before doing anything, git gc checks if a pre-auto-gc hook is available, and executes it to see wether it should run or not. pre-auto-gc-battery, found under contrib/hooks is such a hook that checks wether you’re running on battery power or not. To install, just stick it somewhere you like, make sure it’s executable (chmod a+x pre-auto-gc-battery) and then link it in every repo you want by running

ln -sf path/to/pre-auto-gc-battery .git/hooks/pre-auto-gc

Currently there doesn’t seem to be a way to define global hooks for Git (i.e. hooks that are the same for every repo), so you’ll have to modify each repo yourself.

git-completion.bash

As the name already implies, this files adds git command completion to bash. To install, copy this file anywhere you like to (say, ~/.git-completion.sh), and add source ~/.git-completion.sh (assuming you put it there of course) to your .bashrc. Then source your bashrc or restart your shells, and you should be able to auto-complete

  • local and remote branch/tag names
  • remote names
  • git subcommands, like git submodule

Completion even works for any aliases you’ve defined.

It actually does a bit more than that, so check out the source for more info.

If you’ve aliased git to a shorter command like me, then completion won’t work for that shorter command, unless you also add the following line to bashrc as well:

# Assuming you've aliased 'git' to 'g'
complete -o default -o nospace -F _git g