On 2016-08-03 3:54 PM, Junio C Hamano wrote:
Jeff King <peff@xxxxxxxx> writes:
I agree it would be a good property to have. I think it's hard to do
atomically, though. Certainly we can wait to tell the other side "your
push has been recorded" until after the hook is run. But we would
already have updated the refs locally at that point (and we must -- that
is part of the interface to the post-receive hooks, that the refs are
already in place). So would we roll-back the ref update then? Even that
suffers from power failures, etc.
So I'm not sure if making it truly atomic is all the feasible.
As long as the requirement is that post- hook must see the updated
ref in place, I do not think it is feasible to give "the hook always
runs once" guarantee, without cooperation by other parts of the flow
(think: pulling the power at an arbitrary point in the process).
A receiving repository can implement it all in the userland, I would
think, though:
* A pre-receive hook records the intention to update a ref (from
what old commit to what new commit), and does not return until
that record is securely in a database;
* A post-receive hook checks the entry in the database above (it
_must_ find one), and atomically does its thing and marks the
entry "done";
* A separate sweeper scans the database for entries not yet marked
as "done", sees if the ref has been already updated, and
atomically does its thing and marks the entry "done" (the same
can be done as part of a post-receive for previously pushed
commit that pre-receive recorded but did not manage to run
post-receive before the power was pulled or the user did \C-c).
As you originally described, the non-atomicity is not new; as long
as we have necessary hooks in place on the git-core side for
repositories that want a stronger guarantee, I do not think there is
any more thing we need to do on this topic. If we can narrow the
window in a non-intrusive way, that would be a good thing to do,
though.
<snip>
I certainly understand not being able to make it atomic when faced with
say "pulling the power at an arbitrary point in the process". That seems
to me almost along the lines of disaster recovery contingency plans. But
could we not guarantee that if there is no problem on the receiving end,
that "IF a commit is received and the ref updated, THEN the post-receive
hook is guaranteed to run".
The not-so-uncommon situation where I saw this was where a user had
second-thoughts and hit Ctrl-C in the middle of a push. The push went
through --the ref was updated-- but the post-receive hooks were not run.
Steve
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html