public inbox for git@vger.kernel.org 
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox•com>
To: Jonathan Nieder <jrnieder@gmail•com>
Cc: Ronnie Sahlberg <sahlberg@google•com>,
	git@vger•kernel.org, mhagger@alum•mit.edu
Subject: Re: [PATCH v8 00/44] Use ref transactions for all ref updates
Date: Thu, 15 May 2014 11:51:45 -0700	[thread overview]
Message-ID: <xmqqvbt6euym.fsf@gitster.dls.corp.google.com> (raw)
In-Reply-To: <20140515180618.GA26471@google.com> (Jonathan Nieder's message of "Thu, 15 May 2014 11:06:18 -0700")

Jonathan Nieder <jrnieder@gmail•com> writes:

> Ronnie Sahlberg wrote:
>
>> This patch series is based on next and expands on the transaction API.
>
> Thanks.  Will pick up in v8 where I left off with v6.
>
> Applies with just one minor conflict on top of a merge of
> mh/ref-transaction, rs/ref-update-check-errors-early, and
> rs/reflog-exists.  Here's an interdiff against version 6 for those
> following along.

The interdiffs look mostly sensible.  Thanks.

>> Version 8:
>>  - Updates after review by JN
>>  - Improve commit messages
>>  - Add a patch that adds an err argument to repack_without_refs
>>  - Add a patch that adds an err argument to delete_loose_ref
>>  - Better document that a _update/_delete/_create failure means the whole
>>    transaction has failed and needs rollback.
>>
>> Version 7:
>>  - Updated commit messages per JNs review comments.
>>  - Changed REF_ISPRUNING and REF_ISPACKONLY to be private flags and not
>>    exposed through refs.h
>
> diff --git a/builtin/commit.c b/builtin/commit.c
> index 0f4e1fc..07ccc97 100644
> --- a/builtin/commit.c
> +++ b/builtin/commit.c
> @@ -1684,7 +1684,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
>  				   0, !!current_head, sb.buf) ||
>  	    ref_transaction_commit(transaction, &err)) {
>  		rollback_index_files();
> -		die(_("HEAD: cannot update ref: %s"), err.buf);
> +		die("%s", err.buf);
>  	}
>  	ref_transaction_free(transaction);
>  
> diff --git a/builtin/replace.c b/builtin/replace.c
> index 47c360c..952b589 100644
> --- a/builtin/replace.c
> +++ b/builtin/replace.c
> @@ -163,7 +163,7 @@ static int replace_object(const char *object_ref, const char *replace_ref,
>  	    ref_transaction_update(transaction, ref, repl, prev,
>  				   0, !is_null_sha1(prev), NULL) ||
>  	    ref_transaction_commit(transaction, &err))
> -		die(_("%s: failed to replace ref: %s"), ref, err.buf);
> +		die("%s: failed to replace ref: %s", ref, err.buf);
>  
>  	ref_transaction_free(transaction);
>  	return 0;
> diff --git a/builtin/update-ref.c b/builtin/update-ref.c
> index c5aff92..bd7e96f 100644
> --- a/builtin/update-ref.c
> +++ b/builtin/update-ref.c
> @@ -228,7 +228,7 @@ static const char *parse_cmd_create(struct strbuf *input, const char *next)
>  
>  	if (ref_transaction_create(transaction, refname, new_sha1,
>  				   update_flags, msg))
> -		die("failed transaction create for %s", refname);
> +		die("cannot create ref '%s'", refname);
>  
>  	update_flags = 0;
>  	free(refname);
> diff --git a/refs.c b/refs.c
> index 302a2b3..ed93b75 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -29,6 +29,15 @@ static inline int bad_ref_char(int ch)
>  	return 0;
>  }
>  
> +/** Used as a flag to ref_transaction_delete when a loose ref is beeing
> + *  pruned.
> + */
> +#define REF_ISPRUNING	0x0100
> +/** Deletion of a ref that only exists as a packed ref in which case we do not
> + *  need to lock the loose ref during the transaction.
> + */
> +#define REF_ISPACKONLY	0x0200
> +
>  /*
>   * Try to read one refname component from the front of refname.  Return
>   * the length of the component found, or -1 if the component is not
> @@ -2447,12 +2456,12 @@ static int curate_packed_ref_fn(struct ref_entry *entry, void *cb_data)
>  	return 0;
>  }
>  
> -static int repack_without_refs(const char **refnames, int n)
> +static int repack_without_refs(const char **refnames, int n, struct strbuf *err)
>  {
>  	struct ref_dir *packed;
>  	struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
>  	struct string_list_item *ref_to_delete;
> -	int i, removed = 0;
> +	int i, ret, removed = 0;
>  
>  	/* Look for a packed ref */
>  	for (i = 0; i < n; i++)
> @@ -2465,6 +2474,9 @@ static int repack_without_refs(const char **refnames, int n)
>  
>  	if (lock_packed_refs(0)) {
>  		unable_to_lock_error(git_path("packed-refs"), errno);
> +		if (err)
> +			strbuf_addf(err, "cannot delete '%s' from packed refs",
> +				    refnames[i]);
>  		return error("cannot delete '%s' from packed refs", refnames[i]);
>  	}
>  	packed = get_packed_refs(&ref_cache);
> @@ -2490,20 +2502,28 @@ static int repack_without_refs(const char **refnames, int n)
>  	}
>  
>  	/* Write what remains */
> -	return commit_packed_refs();
> +	ret = commit_packed_refs();
> +	if (ret && err)
> +		strbuf_addf(err, "unable to overwrite old ref-pack file");
> +	return ret;
>  }
>  
> -static int delete_ref_loose(struct ref_lock *lock, int flag)
> +static int delete_ref_loose(struct ref_lock *lock, int flag, struct strbuf *err)
>  {
>  	if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) {
>  		/* loose */
> -		int err, i = strlen(lock->lk->filename) - 5; /* .lock */
> +		int res, i = strlen(lock->lk->filename) - 5; /* .lock */
>  
>  		lock->lk->filename[i] = 0;
> -		err = unlink_or_warn(lock->lk->filename);
> +		res = unlink_or_warn(lock->lk->filename);
>  		lock->lk->filename[i] = '.';
> -		if (err && errno != ENOENT)
> +		if (res && errno != ENOENT) {
> +			if (err)
> +				strbuf_addf(err,
> +					    "failed to delete loose ref '%s'",
> +					    lock->lk->filename);
>  			return 1;
> +		}
>  	}
>  	return 0;
>  }
> @@ -3483,7 +3503,7 @@ int ref_transaction_commit(struct ref_transaction *transaction,
>  						   delnames, delnum);
>  		if (!update->lock) {
>  			if (err)
> -				strbuf_addf(err ,"Cannot lock the ref '%s'.",
> +				strbuf_addf(err, "Cannot lock the ref '%s'.",
>  					    update->refname);
>  			ret = 1;
>  			goto cleanup;
> @@ -3516,13 +3536,14 @@ int ref_transaction_commit(struct ref_transaction *transaction,
>  			continue;
>  
>  		if (update->lock) {
> -			ret |= delete_ref_loose(update->lock, update->type);
> +			ret |= delete_ref_loose(update->lock, update->type,
> +						err);
>  			if (!(update->flags & REF_ISPRUNING))
>  				delnames[delnum++] = update->lock->ref_name;
>  		}
>  	}
>  
> -	ret |= repack_without_refs(delnames, delnum);
> +	ret |= repack_without_refs(delnames, delnum, err);
>  	for (i = 0; i < delnum; i++)
>  		unlink_or_warn(git_path("logs/%s", delnames[i]));
>  	clear_loose_ref_cache(&ref_cache);
> diff --git a/refs.h b/refs.h
> index 03b4a7e..0e6d416 100644
> --- a/refs.h
> +++ b/refs.h
> @@ -134,10 +134,6 @@ extern int peel_ref(const char *refname, unsigned char *sha1);
>  
>  /** Locks any ref (for 'HEAD' type refs). */
>  #define REF_NODEREF	0x01
> -/** Deleting a loose ref during prune */
> -#define REF_ISPRUNING	0x02
> -/** Deletion of a ref that only exists as a packed ref */
> -#define REF_ISPACKONLY	0x04
>  extern struct ref_lock *lock_any_ref_for_update(const char *refname,
>  						const unsigned char *old_sha1,
>  						int flags, int *type_p);
> @@ -240,6 +236,9 @@ void ref_transaction_rollback(struct ref_transaction *transaction);
>   * be deleted.  If have_old is true, then old_sha1 holds the value
>   * that the reference should have had before the update, or zeros if
>   * it must not have existed beforehand.
> + * Function returns 0 on success and non-zero on failure. A failure to update
> + * means that the transaction as a whole has failed and will need to be
> + * rolled back.
>   */
>  int ref_transaction_update(struct ref_transaction *transaction,
>  			   const char *refname,
> @@ -252,6 +251,9 @@ int ref_transaction_update(struct ref_transaction *transaction,
>   * that the reference should have after the update; it must not be the
>   * null SHA-1.  It is verified that the reference does not exist
>   * already.
> + * Function returns 0 on success and non-zero on failure. A failure to create
> + * means that the transaction as a whole has failed and will need to be
> + * rolled back.
>   */
>  int ref_transaction_create(struct ref_transaction *transaction,
>  			   const char *refname,
> @@ -262,6 +264,9 @@ int ref_transaction_create(struct ref_transaction *transaction,
>   * Add a reference deletion to transaction.  If have_old is true, then
>   * old_sha1 holds the value that the reference should have had before
>   * the update (which must not be the null SHA-1).
> + * Function returns 0 on success and non-zero on failure. A failure to delete
> + * means that the transaction as a whole has failed and will need to be
> + * rolled back.
>   */
>  int ref_transaction_delete(struct ref_transaction *transaction,
>  			   const char *refname,
> @@ -272,7 +277,7 @@ int ref_transaction_delete(struct ref_transaction *transaction,
>   * Commit all of the changes that have been queued in transaction, as
>   * atomically as possible.  Return a nonzero value if there is a
>   * problem. If err is non-NULL we will add an error string to it to explain
> - * why the transaction failed.
> + * why the transaction failed. The string does not end in newline.
>   */
>  int ref_transaction_commit(struct ref_transaction *transaction,
>  			   struct strbuf *err);

  reply	other threads:[~2014-05-15 18:52 UTC|newest]

Thread overview: 139+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-15 17:29 [PATCH v8 00/44] Use ref transactions for all ref updates Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 01/44] refs.c: constify the sha arguments for ref_transaction_create|delete|update Ronnie Sahlberg
2014-05-15 18:10   ` Jonathan Nieder
2014-05-15 17:29 ` [PATCH v8 02/44] refs.c: allow passing NULL to ref_transaction_free Ronnie Sahlberg
2014-05-15 18:15   ` Jonathan Nieder
2014-05-15 18:26     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 03/44] refs.c: add a strbuf argument to ref_transaction_commit for error logging Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 04/44] refs.c: add an err argument to repack_without_refs Ronnie Sahlberg
2014-05-15 18:38   ` Jonathan Nieder
2014-05-15 23:06     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 05/44] refs.c: make ref_update_reject_duplicates take a strbuf argument for errors Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 06/44] refs.c: add an err argument ro delete_loose_ref Ronnie Sahlberg
2014-05-15 19:04   ` Jonathan Nieder
2014-05-15 20:00     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 07/44] refs.c: make update_ref_write update a strbuf on failure Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 08/44] update-ref.c: log transaction error from the update_ref Ronnie Sahlberg
2014-05-15 19:23   ` Jonathan Nieder
2014-05-15 17:29 ` [PATCH v8 09/44] refs.c: remove the onerr argument to ref_transaction_commit Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 10/44] refs.c: change ref_transaction_update() to do error checking and return status Ronnie Sahlberg
2014-05-15 19:34   ` Jonathan Nieder
2014-05-15 22:09     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 11/44] refs.c: change ref_transaction_create " Ronnie Sahlberg
2014-05-15 19:44   ` Jonathan Nieder
2014-05-15 22:02     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 12/44] refs.c: ref_transaction_delete to check for error " Ronnie Sahlberg
2014-05-15 19:51   ` Jonathan Nieder
2014-05-15 22:01     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 13/44] tag.c: use ref transactions when doing updates Ronnie Sahlberg
2014-05-15 21:11   ` Jonathan Nieder
2014-05-15 22:27     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 14/44] replace.c: use the ref transaction functions for updates Ronnie Sahlberg
2014-05-15 21:18   ` Jonathan Nieder
2014-05-15 22:30     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 15/44] commit.c: use ref transactions " Ronnie Sahlberg
2014-05-15 21:21   ` Jonathan Nieder
2014-05-15 17:29 ` [PATCH v8 16/44] sequencer.c: use ref transactions for all ref updates Ronnie Sahlberg
2014-05-15 21:53   ` Jonathan Nieder
2014-05-15 17:29 ` [PATCH v8 17/44] fast-import.c: change update_branch to use ref transactions Ronnie Sahlberg
2014-05-15 21:47   ` Jonathan Nieder
2014-05-15 22:20     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 18/44] branch.c: use ref transaction for all ref updates Ronnie Sahlberg
2014-05-15 22:58   ` Jonathan Nieder
2014-05-15 17:29 ` [PATCH v8 19/44] refs.c: change update_ref to use a transaction Ronnie Sahlberg
2014-05-15 23:16   ` Jonathan Nieder
2014-05-15 17:29 ` [PATCH v8 20/44] refs.c: free the transaction before returning when number of updates is 0 Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 21/44] refs.c: ref_transaction_commit should not free the transaction Ronnie Sahlberg
2014-05-16  0:20   ` Jonathan Nieder
2014-05-16 15:02     ` Ronnie Sahlberg
2014-05-16 15:15       ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 22/44] fetch.c: clear errno before calling functions that might set it Ronnie Sahlberg
2014-05-16 18:33   ` Jonathan Nieder
2014-05-16 20:26     ` Ronnie Sahlberg
2014-05-16 23:04     ` Jeff King
2014-05-15 17:29 ` [PATCH v8 23/44] fetch.c: change s_update_ref to use a ref transaction Ronnie Sahlberg
2014-05-16 19:12   ` Jonathan Nieder
2014-05-16 22:22     ` Ronnie Sahlberg
2014-05-16 22:54   ` Jonathan Nieder
2014-05-19 16:58     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 24/44] fetch.c: use a single ref transaction for all ref updates Ronnie Sahlberg
2014-05-16 22:52   ` Jonathan Nieder
2014-05-19 16:56     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 25/44] receive-pack.c: use a reference transaction for updating the refs Ronnie Sahlberg
2014-05-20 19:42   ` Jonathan Nieder
2014-05-20 20:37     ` Ronnie Sahlberg
2014-05-21 18:50       ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 26/44] fast-import.c: use a ref transaction when dumping tags Ronnie Sahlberg
2014-05-20 20:38   ` Jonathan Nieder
2014-05-20 20:53     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 27/44] walker.c: use ref transaction for ref updates Ronnie Sahlberg
2014-05-21  0:46   ` Jonathan Nieder
2014-05-21 17:06     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 28/44] refs.c: make write_ref_sha1 static Ronnie Sahlberg
2014-05-21  0:51   ` Jonathan Nieder
2014-05-21 14:46     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 29/44] refs.c: make lock_ref_sha1 static Ronnie Sahlberg
2014-05-21  0:52   ` Jonathan Nieder
2014-05-15 17:29 ` [PATCH v8 30/44] refs.c: add transaction.status and track OPEN/CLOSED/ERROR Ronnie Sahlberg
2014-05-21 22:00   ` Jonathan Nieder
2014-05-21 22:11     ` Ronnie Sahlberg
2014-05-21 22:22       ` Jonathan Nieder
2014-05-22 17:15         ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 31/44] refs.c: remove the update_ref_lock function Ronnie Sahlberg
2014-05-21 22:01   ` Jonathan Nieder
2014-05-15 17:29 ` [PATCH v8 32/44] refs.c: remove the update_ref_write function Ronnie Sahlberg
2014-05-21 22:07   ` Jonathan Nieder
2014-05-22 16:49     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 33/44] refs.c: remove lock_ref_sha1 Ronnie Sahlberg
2014-05-21 22:09   ` Jonathan Nieder
2014-05-15 17:29 ` [PATCH v8 34/44] refs.c: make prune_ref use a transaction to delete the ref Ronnie Sahlberg
2014-05-21 23:01   ` Jonathan Nieder
2014-05-22 16:56     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 35/44] refs.c: make delete_ref use a transaction Ronnie Sahlberg
2014-05-21 23:22   ` Jonathan Nieder
2014-05-22 15:32     ` Ronnie Sahlberg
2014-05-22 16:31       ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 36/44] refs.c: pass the ref log message to _create/delete/update instead of _commit Ronnie Sahlberg
2014-05-21 23:47   ` Jonathan Nieder
2014-05-22 15:40     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 37/44] refs.c: pass NULL as *flags to read_ref_full Ronnie Sahlberg
2014-05-21 23:50   ` Jonathan Nieder
2014-05-15 17:29 ` [PATCH v8 38/44] refs.c: pack all refs before we start to rename a ref Ronnie Sahlberg
2014-05-21 23:57   ` Jonathan Nieder
2014-05-22 15:50     ` Ronnie Sahlberg
2014-05-22 17:51       ` Jonathan Nieder
2014-05-22 18:02         ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 39/44] refs.c: move the check for valid refname to lock_ref_sha1_basic Ronnie Sahlberg
2014-05-22  1:42   ` Jonathan Nieder
2014-05-22 17:28     ` Ronnie Sahlberg
2014-05-22 17:44       ` Jonathan Nieder
2014-05-22 17:57         ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 40/44] refs.c: call lock_ref_sha1_basic directly from commit Ronnie Sahlberg
2014-05-22 17:53   ` Jonathan Nieder
2014-05-15 17:29 ` [PATCH v8 41/44] refs.c: add a new flag for transaction delete for refs we know are packed only Ronnie Sahlberg
2014-05-22 18:17   ` Jonathan Nieder
2014-05-22 19:12     ` Ronnie Sahlberg
2014-05-22 22:53       ` Ronnie Sahlberg
2014-05-22 23:44         ` Jonathan Nieder
2014-05-22 23:53           ` Jonathan Nieder
2014-05-23 14:59             ` Ronnie Sahlberg
2014-05-23 18:24               ` Jonathan Nieder
2014-05-23 15:23   ` Michael Haggerty
2014-05-23 15:53     ` Jonathan Nieder
2014-05-23 21:45       ` Michael Haggerty
2014-05-27 18:27     ` Junio C Hamano
2014-05-28 14:21       ` Michael Haggerty
2014-05-28 16:58         ` Junio C Hamano
2014-05-28 22:23           ` Michael Haggerty
2014-05-15 17:29 ` [PATCH v8 42/44] refs.c: pass a skip list to name_conflict_fn Ronnie Sahlberg
2014-05-22 19:27   ` Jonathan Nieder
2014-05-27 18:37     ` Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 43/44] refs.c: make rename_ref use a transaction Ronnie Sahlberg
2014-05-15 17:29 ` [PATCH v8 44/44] refs.c: remove forward declaration of write_ref_sha1 Ronnie Sahlberg
2014-05-15 18:06 ` [PATCH v8 00/44] Use ref transactions for all ref updates Jonathan Nieder
2014-05-15 18:51   ` Junio C Hamano [this message]
2014-05-22 19:51 ` Jonathan Nieder
2014-05-22 19:58 ` Jonathan Nieder
2014-05-22 22:08 ` Jonathan Nieder
2014-05-22 23:08 ` Jonathan Nieder
2014-05-27 19:05   ` Ronnie Sahlberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqvbt6euym.fsf@gitster.dls.corp.google.com \
    --to=gitster@pobox$(echo .)com \
    --cc=git@vger$(echo .)kernel.org \
    --cc=jrnieder@gmail$(echo .)com \
    --cc=mhagger@alum$(echo .)mit.edu \
    --cc=sahlberg@google$(echo .)com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox