17 Aug 2012
Some doco for my work mates, and others learners of git…
When I was starting with git (many moons ago), learning to pull from a remote repository was easy. But the book I read didn’t explain how to push to a remote repository. There was lots of doco on pushing to github, but I wanted to push and pull between my own repositories. When I pushed, I got messages saying warning: updating the current branch, and sometimes I’d have to manually clean up the remote branch - yuk.
localbox% git push remotebox master Counting objects: 1, done. Writing objects: 100% (1/1), 252 bytes, done. Total 1 (delta 0), reused 0 (delta 0) remote: warning: updating the current branch To firstname.lastname@example.org:/home/sonia/dotfiles f387640..13740c5 master -> master
Then I learned about bare repositories. Sweet, now I could cleanly push to (bare) remote repositories:
# convention with bare repositories is .git suffix remotebox% git clone --bare dotfiles dotfiles.git Cloning into bare repository 'dotfiles.git'... done.
But what if you want to push to a non-bare repo? Firewalls mean you often have to hop across several machines using ssh tunnels, and setting up bare repositories all over the place is ‘non-optimal’. Or, you want to push between laptops. Or, whatever…
Here’s a recipe - just push to a dummy branch (I usually call it ‘push’), then do a normal merge on the remote:
# I'm on localbox and I want to push to remotebox, which isn't bare # git br -a shows me all the remote branches: localbox% git br -a * master remotes/bourke/master remotes/bourke/foo remotes/bourke/bar # pushing to master, foo or bar will give problems, let's push to 'push' localbox% git push remotebox master:push Total 0 (delta 0), reused 0 (delta 0) To email@example.com:/home/sonia/dotfiles * [new branch] master -> push # let's look at that command: % git push remotebox master:push ^ ^ ^ remote | ^ from | to # ie I'm pushing from master branch to the push branch on remotebox
On the remotebox, merge in the push:
remotebox% git br -a # check all my branches * master foo bar push remotebox% git co master # checkout master remotebox% git merge push # merge push into master remotebox% git br -d push # cleanup
Et Voilà! Done.
After a bit more reading on git, I realised that there is another solution. You can push to any branch on a non-bare repository, as long as that branch isn’t currently checked out on the remote.
PS I have lots of shortcuts in my ~/.gitconfig, like co and br. Saves typing!
[color] ui = auto [color "branch"] current = green local = yellow remote = red [color "diff"] meta = blue bold frag = magenta bold old = red bold new = green bold [alias] ci = commit co = checkout st = status br = branch sb = show-branch sbs = show-branch --sha1-name gr = log --graph --oneline --left-right cl = clean -x -d -f dt = difftool difft = difftool [push] default = matching [receive] denyCurrentBranch = warn