On Tue, May 20, 2014 at 12:42 PM, Jonathan Nieder <[email protected]> wrote:
> Ronnie Sahlberg wrote:
>
>> Wrap all the ref updates inside a transaction to make the update atomic.
>
> Interesting.
>
> [...]
>> --- a/builtin/receive-pack.c
>> +++ b/builtin/receive-pack.c
>> @@ -46,6 +46,8 @@ static void *head_name_to_free;
>> static int sent_capabilities;
>> static int shallow_update;
>> static const char *alt_shallow_file;
>> +static struct strbuf err = STRBUF_INIT;
>
> I think it would be cleaner for err to be local. It isn't used for
> communication between functions.
Done.
>
> [...]
>> @@ -580,15 +581,9 @@ static const char *update(struct command *cmd, struct
>> shallow_info *si)
>> update_shallow_ref(cmd, si))
>> return "shallow error";
>>
>> - lock = lock_any_ref_for_update(namespaced_name, old_sha1,
>> - 0, NULL);
>> - if (!lock) {
>> - rp_error("failed to lock %s", name);
>> - return "failed to lock";
>> - }
>> - if (write_ref_sha1(lock, new_sha1, "push")) {
>> - return "failed to write"; /* error() already called */
>> - }
>> + if (ref_transaction_update(transaction, namespaced_name,
>> + new_sha1, old_sha1, 0, 1, &err))
>> + return "failed to update";
>
> The original used rp_error to send an error message immediately via
> sideband. This drops that --- intended?
Oops. I misread it as a normal error()
>
> The old error string shown on the push status line was was "failed to
> lock" or "failed to write" which makes it clear that the cause is
> contention or database problems or filesystem problems, respectively.
> After this change it would say "failed to update" which is about as
> clear as "failed".
I changed it to return xstrdup(err.buf) which should be as detailed as
we can get.
>
> Would it be safe to send err.buf as-is over the wire, or does it
> contain information or formatting that wouldn't be suitable for the
> client? (I haven't thought this through completely yet.) Is there
> some easy way to distinguish between failure to lock and failure to
> write? Or is there some one-size-fits-all error for this case?
I think err.buf is what we want.
>
> When the transaction fails, we need to make sure that all ref updates
> emit 'ng' and not 'ok' in receive-pack.c::report (see the example at
> the end of Documentation/technical/pack-protocol.txt for what this
> means). What error string should they use? Is there some way to make
> it clear to the user which ref was the culprit?
>
> What should happen when checks outside the ref transaction system
> cause a ref update to fail? I'm thinking of
>
> * per-ref 'update' hook (see githooks(5))
> * fast-forward check
> * ref creation/deletion checks
> * attempt to push to the currently checked out branch
>
> I think the natural thing to do would be to put each ref update in its
> own transaction to start so the semantics do not change right away.
> If there are obvious answers to all these questions, then a separate
> patch could combine all these into a single transaction; or if there
> are no obvious answers, we could make the single-transaction-per-push
> semantics optional (using a configuration variable or protocol
> capability or something) to make it possible to experiment.
I changed it to use one transaction per ref for now.
Please see the update ref-transactions branch.
Thanks!
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html