Present Perfect


Picture Gallery
Present Perfect

git workflow question

Filed under: GStreamer,Hacking,Python,Twisted — Thomas @ 22:34


I'm trying to integrate git into my workflow. I've been reading documentation and tutorials (there sure are a lot), but I'm not sure they cover the use case I want to try and implement. So I'm explaining it here in the hopes that some experienced gits will be able to show me the way.

The basic use case is simple: I want to hack on GStreamer, which uses git, from various computers (laptop, work machine, home machine), and have my private and/or public hacking in sync between those three machines.

Basically, when I create a branch on my laptop, hack in it, commit stuff, and push it out to my private or public repo, I then want to pull all those changes on my home desktop and continue hacking.

It looks like I should be able to do it with a magic combination of a bare repository on some server, and the right incantation of git remote add lines on all of my machines. But so far, my experiments have only led me to some abomination of a bare repository where my home machine sees a branch created on my laptop with the name 'thomas' as a branch named 'private/thomas'. In other words, the names don't match up. And for now it looks like the content doesn't match up either; I somehow merged the thomas branch into my master on my home desktop. Also, it looks like pulls from that private bare repo end up as an actual commit, which seems a bit messy.

I'll retry my experiment to see if I might have screwed something up, but in the meantime, if you recognize the use case I'm going for and know how to implement it, feel free to throw me a bone.


  1. Hi,
    remote and local branch can have different names. If you want them to be the same, you’ll have to git branch –track $name orgin/$name
    http://stackoverflow.com/questions/520650/how-do-you-make-an-existing-git-branch-track-a-remote-branch explains it better.

    Comment by tahorg — 2009-03-30 @ 23:08

  2. Did you create a local branch that tracks the remote branch? You aren’t supposed to do any work on remote branches and I don’t even know what happens if you do (it should warn you anyways). It seems like that might be your problem, but perhaps I’m misunderstanding the issue.

    Comment by Joel — 2009-03-30 @ 23:40

  3. Setting up a remote repository:
    (It seems you’ve pretty much done this.)

    Probably the easiest way to work with remote branches is to use git_remote_branch, or “grb” for short:

    grb makes it so easy to deal with remote branches that you may wind up with a few of ’em for different features. I wish that vanilla git’s remote branching was this easy by default. At least grb “fixes” this sore spot.

    When you’re ready to share stuff with yourself (essentially), just git push it up to your remote repo, then git pull on the other machines. For sanity’s sake, you should probably keep the local tracking branch’s name consistent across the machines. (:

    If your remote’s name is is “private” (if you did something like “git remote add private ssh://server/path/foo.git”), then private/thomas is the brach as it exists on the remote. Then, for the local representation of it, you probably did something like “git checkout -tb thomas private/thomas”.

    The only branches you REALLY care about (from a development point of view) are the local branches, since git is a distributed content management system.

    You sync up your local branches with the remote branches with a “git fetch” and either a merge or rebase. (Doing a “git pull” is essentially shorthand for a fetch and merge in one step.)

    When you’re ready to share your local branch with the remote repository, you do a “git push”. You can specify “git push private thomas” to push your “thomas” branch to the your remote “private” repo explicitly. This way, you know exactly what goes where… of course, you could also do a “git push –dry-run” to get a preview of what a “git push” without specifying the branch or remote would do.

    Hopefully my comment was at least somewhat useful and what you were looking for (and not *too* git-jargony). (:

    Comment by Garrett LeSage — 2009-03-30 @ 23:48

  4. If you really want a private one I think gitosis is quick and easy, http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way

    Or you could create a repo on GitHub and just sync to that from all of your machines.

    Comment by jcopenha — 2009-03-31 @ 01:38

  5. I think the answer to your specific question is: to check out the branch for the first time on your desktop, do:

    git checkout thomas -b private/thomas


    git checkout private/thomas

    As for the more general question of keeping several local machines in sync, I end up scp’ing working directories between my laptop and desktop a lot. :-/

    Comment by Dan — 2009-03-31 @ 01:59

  6. First: I promise I’m not trying to start a flame war or troll. :-)

    bzr makes what you’re wanting to do *trivial.* I know git does a lot that bzr can’t do at all, but keeping pushing and merging repos between a desktop, a laptop, and some servers is something I do many times everyday with bzr.

    I was just wondering how easy it might be to use something like bzr-fastimport[1] to create a bzr repo and just use bzr’s push & merge commands between as many computers as you like. Looks like git-bzr[2] might be able to easily import your changes back into git (although I’m not a git user and a bit fuzzy on how you submit patches upstream…).

    Good luck!

    [1] http://bazaar-vcs.org/BzrFastImport
    [2] http://github.com/pieter/git-bzr/tree/master

    Comment by Michael Schurter — 2009-03-31 @ 03:18

  7. A very short walkthrough:

    Generate an upstream repository:
    andres@alap2:/tmp$ mkdir /tmp/remote
    andres@alap2:/tmp$ cd /tmp/remote/
    andres@alap2:/tmp/remote$ git init –bare
    Initialized empty Git repository in /tmp/remote/
    andres@alap2:/tmp/remote$ cd ../

    Local clone:
    andres@alap2:/tmp$ git clone /tmp/remote local
    Initialized empty Git repository in /tmp/local/.git/
    warning: You appear to have cloned an empty repository.
    andres@alap2:/tmp$ cd local/
    andres@alap2:/tmp/local$ ls
    andres@alap2:/tmp/local$ git
    andres@alap2:/tmp/local$ echo “first commit” > foo
    andres@alap2:/tmp/local$ git add foo
    andres@alap2:/tmp/local$ git commit -m “Hey”
    [master (root-commit) ca4ee85] Hey
    1 files changed, 1 insertions(+), 0 deletions(-)
    create mode 100644 foo

    Publish to your private upstream repository:
    andres@alap2:/tmp/local$ git push origin master
    Counting objects: 3, done.
    Writing objects: 100% (3/3), 216 bytes, done.
    Total 3 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (3/3), done.
    To /tmp/remote
    * [new branch] master -> master
    andres@alap2:/tmp/local$ git fetch
    andres@alap2:/tmp/local$ git branch
    * master
    andres@alap2:/tmp/local$ git branch -r

    Do a second clone “on another machine”:
    andres@alap2:/tmp/local$ cd /tmp/
    andres@alap2:/tmp$ git clone /tmp/remote local2
    Initialized empty Git repository in /tmp/local2/.git/
    andres@alap2:/tmp$ cd local2/
    andres@alap2:/tmp/local2$ ls
    andres@alap2:/tmp/local2$ echo “yet another foo sighted” >> foo
    andres@alap2:/tmp/local2$ git add foo
    andres@alap2:/tmp/local2$ git commit -m “bar”
    [master 3ddd750] bar
    1 files changed, 1 insertions(+), 0 deletions(-)
    andres@alap2:/tmp/local2$ git push
    Counting objects: 5, done.
    Writing objects: 100% (3/3), 268 bytes, done.
    Total 3 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (3/3), done.
    To /tmp/remote
    ca4ee85..3ddd750 master -> master
    Ok, we published our own changes…

    Lets see if we can incorporate them on the other clone:
    andres@alap2:/tmp/local2$ cd /tmp/local
    andres@alap2:/tmp/local$ git fetch
    Unpacking objects: 100% (3/3), done.
    remote: Counting objects: 5, done.
    remote: Total 3 (delta 0), reused 0 (delta 0)
    From /tmp/remote
    ca4ee85..3ddd750 master -> origin/master
    andres@alap2:/tmp/local$ cat foo
    first commit
    andres@alap2:/tmp/local$ git merge origin/master
    Updating ca4ee85..3ddd750
    Fast forward
    foo | 1 +
    1 files changed, 1 insertions(+), 0 deletions(-)
    andres@alap2:/tmp/local$ cat foo
    first commit
    yet another foo sighted

    Comment by Andres Freund — 2009-03-31 @ 08:35

  8. As usual, judging from the answers, git is for Vulcans only, as Mr Spolsky pointed out…

    (I’ve been trying to simply have a backup via push to an external drive now and then and this is also not really covered in any docs, nor does it really work. In bzr, it was “bzr push /path”).

    Comment by Stoffe — 2009-03-31 @ 09:45

  9. Stoffe: what about “git push –all ” didn’t work?

    Comment by Steven Walter — 2009-04-02 @ 20:17

RSS feed for comments on this post. TrackBack URL

Leave a comment