Subject: Re: git push to a non-bare repository

From: "Shawn O. Pearce" <[email-masked]>
Date: Sun, 18 Mar 2007 22:56:03 -0400

Theodore Tso <[email-masked]> wrote:
> On Sun, Mar 18, 2007 at 10:21:43PM -0400, Shawn O. Pearce wrote:
> > Junio C Hamano <[email-masked]> wrote:
> > > Theodore Tso <[email-masked]> writes:
> > > 
> > > > Is it at all possible to figure out <commit-id-before-the-push>?  It
> > > > seems the answer is no, and I suspect that's a bug.
> > > 
> > > Doesn't update hook get pre- and post- commit object name?
> > 
> > Yes, and the same is true in the new post-receive hook.
> 
> In my comments, I was observing that *after* the push had succeeded,
> there was no way to find the commit-id-before-the-push, since neither
> the reflog nor ORIG_HEAD is getting updated.  Is there a good reason
> why not?  Would you accept a patch which caused the reflog and
> possibly ORIG_HEAD to be updated on the remote side of the push?

The reflog does update if the log file exists during a push (err,
actually during receive-pack).  Or if core.logAllRefUpdates is set
to true.  Now this isn't the default in a bare repository, but it
should be the default in a repository with a working directory.
So the case we are talking about should be seeing the reflog update.
 
> When I was talking about a hook to enforce the BitKeeper semantics,
> the question is whether we have enough to enforce the following:
> 
> 	* Only accept the push if it will result in a fast-forward
> 		merge (and if not, tell the user to do a git pull, merge
> 		locally, and then redo the git push)

Yes, the update hook can detect this.  Actually receive-pack by
default rejects *all* non-fast-forward pushes, even if the client
side uses --force.

> 	* Only accept the push if there are no locally modified files
> 		that would be affected when the working directory is
> 		updated to reflect the new HEAD

The update hook could also perform this check; test if the ref
being updated is the current branch, and if so, verify the index and
working directory is clean.  That's a simple run of git-symbolic-ref
(to get the current branch) and git-runstatus (to check the index
and working directory), is it not?

If git-runstatus exits to indicate the tree is clean (nothing to
commit) then a simple `read-tree -m -u HEAD $new` should update
the working directory and index, right?

-- 
Shawn.