How do you start working on a remote git repository? You clone it from an URL with git clone <url>
. Great! Now let’s say a month later you want to clone the same repository on a different machine. What was the URL again?
Over the years I have amassed so many git repositories with varying upstream servers that this has become a regular struggle for me. To make things worse I also use different git identities (name and email) for work and hobby projects. So after I have somehow acquired the URL I also need to remember to set up the right git identity.
Surely there must be a better way?
write down your remote URLs in a txt file
Then the URL changes and I forget to update the file.
completely sync your repositories with
rsync
I fear forgetting to pull or push and loosing data.
use git submodules to avoid having to remember URLs
Since submodules are meant for dependencies they always point to a specific commit, which we don’t want … we always want the latest version.
global git config with path-based conditional includes to automatically configure git identity
This restricts where you can put your .git
directories and identity changes made with git config
are not synchronized (they just override the global config).
Introducing git config linker (gcl)
The solution I eventually came up with is to:
- have all repositories in one directory (I use
~/repos
) - move the config files of the repositories to a
gitconfigs
git repo, leaving a symbolic link behind
This means that all of your repository git configurations are tracked centrally (including all git remotes and your git identity). To make this convenient I wrote a Python script which grew to 200 lines and has the following usage:
git config linker (gcl):
gcl status check the status of the directories in .
gcl link <repo>... move <repo>/.git/config to gitconfigs/<repo>
(leaving a symlink behind)
gcl clone list all configs that are not cloned
gcl clone <config>... clone a repository using gitconfigs/<config>
gcl mv <src> <dest> rename a repo and its config and update the symlink
gcl unlink <repo>... undo "gcl link <repo>"
(only needed if you want to stop using gcl)
You can check out the script at https://git.push-f.com/tools/tree/gcl
It also shows you which repositories have no remotes, unpushed commits or a dirty working tree.
Example session
Setup:
$ mkdir ~/repos
$ cd ~/repos
$ git init gitconfigs
Let’s clone a repo:
$ git clone https://git.push-f.com/tools
$ gcl status
unlinked repos:
(link with "gcl link <name>...")
gitconfigs NO REMOTE
tools
Let’s link the repo:
$ gcl link tools
$ gcl status
unlinked repos:
(link with "gcl link <name>...")
gitconfigs NO REMOTE, DIRTY
linked repos:
tools
Let’s simulate cloning the repo on a different machine:
$ rm -r tools
$ gcl clone
uncloned configs:
(clone with "gcl clone <name>...")
tools
gcl clone
lists all configs that are not cloned.
$ gcl clone tools
$ gcl status
unlinked repos:
(link with "gcl link <name>...")
gitconfigs NO REMOTE, DIRTY
linked repos:
tools