Subject: Pushing to a non-bare repository

From: Steven Grimm <[email-masked]>
Date: Fri, 02 Feb 2007 19:01:28 -0800

This keeps coming up as I introduce people to git. In previous 
discussions, the conclusion often seems to be that users don't really 
know what they want the semantics to be. So here's what I want. I think 
it's actually not that complicated to get something that'll be far more 
useful than what we have today.

1. If the target repo has a branch other than the target branch checked 
out, allow the push and don't touch the working copy. (By "allow the 
push" here I mean proceed with the existing push behavior, which might 
still error out if, e.g., the target branch has commits that aren't in 
the local repo yet.)

2. If the target repo has the target branch checked out and the working 
copy equals its head, allow the push and reset the working copy to the 
newly created head. Basically this is equivalent to a simple 
fast-forward pull in the other direction.

3. If the target repo has the target branch checked out and there are 
uncommitted edits, block the push and return an error indicating the 
target repo is being edited and can't be pushed to until the edits are 
undone or committed.

That's it. No merging of local edits in the target, just the same 
semantics as a push to a bare repo (in case 1) or a fast-forward 
operation with no merging (case 2). Would it be even nicer to have some 
automatic merge magic in case 3? Maybe, but cases 1 and 2 are still very 
useful without it.

In particular, those two cases would completely cover the two situations 
where I most often want to push to a checked-out parent: a common 
integration area that we can browse manually or point a Web server or a 
compiler at as a source directory, and (more important to me) a 
bidirectional sync mechanism between my laptop and my server, where I 
want to commit my changes then send them to the other side to continue 
working. Right now git requires me to set up a dummy parent repository 
that both my laptop and my server repositories are clones of, and I have 
to run an extra "pull" after each push to get the changes where I want 
them. No purpose is served by that parent repository except to satisfy 
git's requirement that a push target has to be bare.

Another place where the current situation is a bit weak is when I want 
to clone someone's repo to help them fix a bug. If I clone it onto my 
laptop, I end up having to email diffs back; our corporate network 
doesn't allow us to make TCP connections to our laptops, only from our 
laptops, so it is impossible for the other person to log onto the server 
and pull from my clone. If I could push back to a topic branch in the 
other person's repo, they could merge my change into their working copy 
at their leisure.

Is this actually more complicated than the above? What am I missing?

-Steve