[PATCH 12/20] receive-pack.c: use a reference transaction for updating the refs

2014-08-26 Thread Jonathan Nieder
From: Ronnie Sahlberg sahlb...@google.com
Date: Mon, 28 Apr 2014 14:36:15 -0700

Wrap all the ref updates inside a transaction.

In the new API there is no distinction between failure to lock and
failure to write a ref.  Both can be permanent (e.g., a ref
refs/heads/topic is blocking creation of the lock file
refs/heads/topic/1.lock) or transient (e.g., file system full) and
there's no clear difference in how the client should respond, so
replace the two statuses failed to lock and failed to write with
a single status failed to update ref.  In both cases a more
detailed message is sent by sideband to diagnose the problem.

Example, before:

 error: there are still refs under 'refs/heads/topic'
 remote: error: failed to lock refs/heads/topic
 To foo
  ! [remote rejected] HEAD - topic (failed to lock)

After:

 error: there are still refs under 'refs/heads/topic'
 remote: error: Cannot lock the ref 'refs/heads/topic'.
 To foo
  ! [remote rejected] HEAD - topic (failed to update ref)

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
Signed-off-by: Jonathan Nieder jrnie...@gmail.com
---
 builtin/receive-pack.c | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index c323081..224fadc 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -475,7 +475,6 @@ static const char *update(struct command *cmd, struct 
shallow_info *si)
const char *namespaced_name;
unsigned char *old_sha1 = cmd-old_sha1;
unsigned char *new_sha1 = cmd-new_sha1;
-   struct ref_lock *lock;
 
/* only refs/... are allowed */
if (!starts_with(name, refs/) || check_refname_format(name + 5, 0)) {
@@ -576,19 +575,27 @@ static const char *update(struct command *cmd, struct 
shallow_info *si)
return NULL; /* good */
}
else {
+   struct strbuf err = STRBUF_INIT;
+   struct ref_transaction *transaction;
+
if (shallow_update  si-shallow_ref[cmd-index] 
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 */
+   transaction = ref_transaction_begin(err);
+   if (!transaction ||
+   ref_transaction_update(transaction, namespaced_name,
+  new_sha1, old_sha1, 0, 1, err) ||
+   ref_transaction_commit(transaction, push, err)) {
+   ref_transaction_free(transaction);
+
+   rp_error(%s, err.buf);
+   strbuf_release(err);
+   return failed to update ref;
}
+
+   ref_transaction_free(transaction);
+   strbuf_release(err);
return NULL; /* good */
}
 }
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/20] receive-pack.c: use a reference transaction for updating the refs

2014-07-15 Thread Ronnie Sahlberg
Wrap all the ref updates inside a transaction.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 builtin/receive-pack.c | 96 +-
 1 file changed, 63 insertions(+), 33 deletions(-)

diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index c323081..91099ad 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -194,7 +194,7 @@ static void write_head_info(void)
 
 struct command {
struct command *next;
-   const char *error_string;
+   char *error_string;
unsigned int skip_update:1,
 did_not_exist:1;
int index;
@@ -468,19 +468,18 @@ static int update_shallow_ref(struct command *cmd, struct 
shallow_info *si)
return 0;
 }
 
-static const char *update(struct command *cmd, struct shallow_info *si)
+static char *update(struct command *cmd, struct shallow_info *si)
 {
const char *name = cmd-ref_name;
struct strbuf namespaced_name_buf = STRBUF_INIT;
const char *namespaced_name;
unsigned char *old_sha1 = cmd-old_sha1;
unsigned char *new_sha1 = cmd-new_sha1;
-   struct ref_lock *lock;
 
/* only refs/... are allowed */
if (!starts_with(name, refs/) || check_refname_format(name + 5, 0)) {
rp_error(refusing to create funny ref '%s' remotely, name);
-   return funny refname;
+   return xstrdup(funny refname);
}
 
strbuf_addf(namespaced_name_buf, %s%s, get_git_namespace(), name);
@@ -498,20 +497,20 @@ static const char *update(struct command *cmd, struct 
shallow_info *si)
rp_error(refusing to update checked out branch: %s, 
name);
if (deny_current_branch == DENY_UNCONFIGURED)
refuse_unconfigured_deny();
-   return branch is currently checked out;
+   return xstrdup(branch is currently checked out);
}
}
 
if (!is_null_sha1(new_sha1)  !has_sha1_file(new_sha1)) {
error(unpack should have generated %s, 
  but I can't find it!, sha1_to_hex(new_sha1));
-   return bad pack;
+   return xstrdup(bad pack);
}
 
if (!is_null_sha1(old_sha1)  is_null_sha1(new_sha1)) {
if (deny_deletes  starts_with(name, refs/heads/)) {
rp_error(denying ref deletion for %s, name);
-   return deletion prohibited;
+   return xstrdup(deletion prohibited);
}
 
if (!strcmp(namespaced_name, head_name)) {
@@ -526,7 +525,7 @@ static const char *update(struct command *cmd, struct 
shallow_info *si)
if (deny_delete_current == DENY_UNCONFIGURED)

refuse_unconfigured_deny_delete_current();
rp_error(refusing to delete the current 
branch: %s, name);
-   return deletion of the current branch 
prohibited;
+   return xstrdup(deletion of the current branch 
prohibited);
}
}
}
@@ -544,19 +543,19 @@ static const char *update(struct command *cmd, struct 
shallow_info *si)
old_object-type != OBJ_COMMIT ||
new_object-type != OBJ_COMMIT) {
error(bad sha1 objects for %s, name);
-   return bad ref;
+   return xstrdup(bad ref);
}
old_commit = (struct commit *)old_object;
new_commit = (struct commit *)new_object;
if (!in_merge_bases(old_commit, new_commit)) {
rp_error(denying non-fast-forward %s
  (you should pull first), name);
-   return non-fast-forward;
+   return xstrdup(non-fast-forward);
}
}
if (run_update_hook(cmd)) {
rp_error(hook declined to update %s, name);
-   return hook declined;
+   return xstrdup(hook declined);
}
 
if (is_null_sha1(new_sha1)) {
@@ -571,24 +570,32 @@ static const char *update(struct command *cmd, struct 
shallow_info *si)
}
if (delete_ref(namespaced_name, old_sha1, 0)) {
rp_error(failed to delete %s, name);
-   return failed to delete;
+   return xstrdup(failed to delete);
}
return NULL; /* good */
}
else {
+   struct strbuf err = STRBUF_INIT;
+   struct ref_transaction *transaction;
+
if (shallow_update  si-shallow_ref[cmd-index] 
update_shallow_ref(cmd, si))
-   return shallow error;
-
-