git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 03/15] refs.c: use packed refs when deleting refs during a transaction

From
Junio C Hamano <gitster@pobox.com>
Date
Oct 22, 2014, 19:48 UTC
Message-ID
<xmqqy4s7homc.fsf@gitster.dls.corp.google.com>
In-Reply-To
<1413923820-14457-4-git-send-email-sahlberg@google.com>
Ronnie Sahlberg <sahlberg@google.com> writes:
> commit fb5fa1d338ce113b0fea3bb955b50bbb3e827805 upstream.
Huh?
Show 45 quoted lines
> Make the deletion of refs during a transaction more atomic.
> Start by first copying all loose refs we will be deleting to the packed
> refs file and then commit the packed refs file. Then re-lock the packed refs
> file to stop anyone else from modifying these refs and keep it locked until
> we are finished.
> Since all refs we are about to delete are now safely held in the packed refs
> file we can proceed to immediately unlink any corresponding loose refs
> and still be fully rollback-able.
>
> The exception is for refs that can not be resolved. Those refs are never
> added to the packed refs and will just be un-rollback-ably deleted during
> commit.
>
> By deleting all the loose refs at the start of the transaction we make make
> it possible to both delete one ref and then re-create a different ref in
> the same transaction even if the two refs would normally conflict.
>
> Example: rename m->m/m
>
> In that example we want to delete the file 'm' so that we make room so
> that we can create a directory with the same name in order to lock and
> write to the ref m/m and its lock-file m/m.lock.
>
> If there is a failure during the commit phase we can rollback without losing
> any refs since we have so far only deleted loose refs that that are
> guaranteed to also have a corresponding entry in the packed refs file.
> Once we have finished all updates for refs and their reflogs we can repack
> the packed refs file and remove the to-be-deleted refs from the packed refs,
> at which point all the deleted refs will disappear in one atomic rename
> operation.
>
> This also means that for an outside observer, deletion of multiple refs
> in a single transaction will look atomic instead of one ref being deleted
> at a time.
>
> In order to do all this we need to change the semantics for the
> repack_without_refs function so that we can lock the packed refs file,
> do other stuff, and later be able to call repack_without_refs with the
> lock already taken.
> This means we need some additional changes in remote.c to reflect the
> changes to the repack_without_refs semantics.
>
> Change-Id: I1e4f58050acaabc6bcfa3409fbc0c2b866bb59aa
> Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Show 6 quoted lines
> @@ -3821,23 +3824,109 @@ int transaction_commit(struct transaction *transaction,
> ...
> +	if (need_repack) {
> +		packed = get_packed_refs(&ref_cache);;
> +		sort_ref_dir(packed);
> +		if (commit_packed_refs()){
SP between "){".
> +			strbuf_addf(err, "unable to overwrite old ref-pack "
> +				    "file");

This is bending backwards sacrificing readability; 80-col limit is not that hard a limit. Split at the comma instead, perhaps?

			strbuf_addf(err,
				    "unable to overwrite old ref-pack file");
Show 8 quoted lines
> ...
> +		if (!update->lock) {
> +			int df_conflict = (errno == ENOTDIR);
> +
> +			strbuf_addf(err, "Cannot lock the ref '%s'.",
> +				    update->refname);
> +			ret = df_conflict ?
> +			  TRANSACTION_NAME_CONFLICT : 
A trailing SP here...
Show 10 quoted lines
> @@ -3860,6 +3953,16 @@ int transaction_commit(struct transaction *transaction,
>  			update->reflog_lock = update->orig_update->reflog_lock;
>  			continue;
>  		}
> +		if (log_all_ref_updates && !reflog_exists(update->refname) &&
> +		    create_reflog(update->refname)) {
> +			ret = -1;
> +			if (err)
> +				strbuf_addf(err, "Failed to setup reflog for "
> +					    "%s", update->refname);
Split after comma, perhaps?
Previous: Ronnie SahlbergNext: Ronnie Sahlberg
Message 7 of 27 in “ref-transaction-rename”
  1. 00/15 ref-transaction-renameRonnie Sahlberg, Oct 21, 2014
  2. 01/15 refs.c: allow passing raw git_committer_info as email to _update_reflogRonnie Sahlberg, Oct 21, 2014
  3. 02/15 refs.c: return error instead of dying when locking fails during transactionRonnie Sahlberg, Oct 21, 2014
  4. Jeff KingNov 11, 2014
  5. Ronnie SahlbergNov 11, 2014
  6. 03/15 refs.c: use packed refs when deleting refs during a transactionRonnie Sahlberg, Oct 21, 2014
  7. Junio C HamanoOct 22, 2014
  8. 04/15 refs.c: use a stringlist for repack_without_refsRonnie Sahlberg, Oct 21, 2014
  9. 05/15 refs.c: update rename_ref to use a transactionRonnie Sahlberg, Oct 21, 2014
  10. Junio C HamanoOct 28, 2014
  11. Junio C HamanoOct 28, 2014
  12. Ronnie SahlbergOct 28, 2014
  13. Junio C HamanoOct 28, 2014
  14. Ronnie SahlbergOct 29, 2014
  15. Junio C HamanoOct 29, 2014
  16. Ronnie SahlbergOct 30, 2014
  17. 06/15 refs.c: rollback the lockfile before we die() in repack_without_refsRonnie Sahlberg, Oct 21, 2014
  18. 07/15 refs.c: move reflog updates into its own functionRonnie Sahlberg, Oct 21, 2014
  19. 08/15 refs.c: write updates to packed refs when a transaction has more than one refRonnie Sahlberg, Oct 21, 2014
  20. 09/15 remote.c: use a transaction for deleting refsRonnie Sahlberg, Oct 21, 2014
  21. 10/15 refs.c: make repack_without_refs staticRonnie Sahlberg, Oct 21, 2014
  22. 11/15 refs.c: make the *_packed_refs functions staticRonnie Sahlberg, Oct 21, 2014
  23. 12/15 refs.c: replace the onerr argument in update_ref with a strbuf errRonnie Sahlberg, Oct 21, 2014
  24. 13/15 refs.c: make add_packed_ref return an error instead of calling dieRonnie Sahlberg, Oct 21, 2014
  25. 14/15 refs.c: make lock_packed_refs take an err argumentRonnie Sahlberg, Oct 21, 2014
  26. 15/15 refs.c: add an err argument to pack_refsRonnie Sahlberg, Oct 21, 2014
  27. Junio C HamanoOct 30, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.