Re: git-http-push and hooks
- From
Junio C Hamano <junkio@cox.net>
- Date
- Feb 7, 2006, 23:26 UTC
- Message-ID
- <7vpslysqcb.fsf@assigned-by-dhcp.cox.net>
- In-Reply-To
- <20060207224551.GB3833@reactrix.com>
Nick Hengeveld <nickh@reactrix.com> writes:
> What happens if someone else updates a ref and it no longer > matches your local ref? Should the push scan the remote > versions of all local refs and update whatever doesn't match?
If I and you clone from a shared repository at the same time, I did my development while you did your own on top of that same commit without pulling from the repository further, and I uploaded my changes to update the ref, what should happen to you once you are ready to push?
Is that what being asked?
If so, I think the sensible thing to do is to reject your push and suggest you to pull first, just like the git native protocol push does. That pull would end up first merging my changes to your work in your repository, and then you can push the result back to the shared repository. Otherwise you would lose my changes.
The criteria to allow a push is obviously not "no longer matches" because in the above scenario what both you and I fetched from the shared repository is something that is an ancestor of what each of us is trying to push. The first one should succeed -- it is pushing a new commit that is a descendant of what is currently the head of the shared repository. The latter one fails because at that time the head of the shared repository is not an ancestor of what you are trying to push.
If you are asking about a race, yes there is a race condition and you have to be careful. The native protocol does it like so (receive-pack.c):
1. At the shared repository grab the current head;
2. Examine what is being pushed. Is it a descendant of the one
we grabbed in the previous step? If not, reject. 3. Lock the ref, grab the current head again, make sure it is
still the same as what we got in the first step, update it
with what was pushed, and then unlock.I think you may be able to do a similar check on the client side, if DAV allows locking resources at least for a brief period.
If you are asking about updating local tracking branch for the remote ref after a successful push, I think that is an optional feature and is entirely up to you. For example, if your workflow is to fetch from the shared repository into origin, merge that into master, work on master, and then push the result to the master branch of the shared repository, you could update your origin with the commit you just pushed. This lets you pretend as if you fetched from there immediately after your successful push.
I think Cogito does it that way, but I personally found leaving the tracing ref as-is after a push more useful, so I left git-push not to do so. For example, leaving when to update "origin" up to me allows me do run "git log origin..master" to write the "what's new in git.git" message after I push. Of course the same thing can be done by running the git log before I push, so there is not much practical difference either way.