All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Nieder <jrnieder@gmail.com>
To: Michael Haggerty <mhagger@alum.mit.edu>
Cc: "Junio C Hamano" <gitster@pobox.com>,
	"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>,
	"Stefan Beller" <sbeller@google.com>, "Jeff King" <peff@peff.net>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
	"David Turner" <novalis@novalis.org>,
	"Brandon Williams" <bmwill@google.com>,
	git@vger.kernel.org, "Dave Walker" <dawalker@google.com>
Subject: Re: [PATCH] packed_ref_store: handle a packed-refs file that is a symlink
Date: Wed, 26 Jul 2017 17:18:12 -0700	[thread overview]
Message-ID: <20170727001812.GI13924@aiede.mtv.corp.google.com> (raw)
In-Reply-To: <d0da02a8b6f0272fa70ae3b1dc80fee6c6ee8d18.1501111803.git.mhagger@alum.mit.edu>

Hi,

Michael Haggerty wrote:

> One of the tricks that `contrib/workdir/git-new-workdir` plays is to
> making `packed-refs` in the new workdir a symlink to the `packed-refs`
> file in the original repository. Before
> 42dfa7ecef ("commit_packed_refs(): use a staging file separate from
> the lockfile", 2017-06-23), a lockfile was used as the staging file,
> and because the `LOCK_NO_DEREF` was not used, the pointed-to file was
> locked and modified.
>
> But after that commit, the staging file was created using a tempfile,
> with the end result that rewriting the `packed-refs` file in the
> workdir overwrote the symlink rather than the original `packed-refs`
> file.
>
> Change `commit_packed_refs()` to use `get_locked_file_path()` to find
> the path of the file that it should overwrite. Since that path was
> properly resolved when the lockfile was created, this restores the
> pre-42dfa7ecef behavior.
>
> Also add a test case to document this use case and prevent a
> regression like this from recurring.
>
> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>

Reported-by: Dave Walker <dawalker@google.com>

[...]
>  refs/packed-backend.c | 24 ++++++++++++++++++------
>  t/t3210-pack-refs.sh  | 15 +++++++++++++++
>  2 files changed, 33 insertions(+), 6 deletions(-)

The patch looks good, except for one nit marked below (*).  I'll apply
it locally and ask people to test it, probably tomorrow morning.

Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>

Thanks for writing it.  Patch left unsnipped for reference.

> diff --git a/refs/packed-backend.c b/refs/packed-backend.c
> index a28befbfa3..59e7d1a509 100644
> --- a/refs/packed-backend.c
> +++ b/refs/packed-backend.c
> @@ -610,19 +610,27 @@ int commit_packed_refs(struct ref_store *ref_store, struct strbuf *err)
>  	struct packed_ref_cache *packed_ref_cache =
>  		get_packed_ref_cache(refs);
>  	int ok;
> +	int ret = -1;
>  	struct strbuf sb = STRBUF_INIT;
>  	FILE *out;
>  	struct ref_iterator *iter;
> +	char *packed_refs_path;
>  
>  	if (!is_lock_file_locked(&refs->lock))
>  		die("BUG: commit_packed_refs() called when unlocked");
>  
> -	strbuf_addf(&sb, "%s.new", refs->path);
> +	/*
> +	 * If packed-refs is a symlink, we want to overwrite the
> +	 * symlinked-to file, not the symlink itself. Also, put the
> +	 * staging file next to it:
> +	 */
> +	packed_refs_path = get_locked_file_path(&refs->lock);
> +	strbuf_addf(&sb, "%s.new", packed_refs_path);
>  	if (create_tempfile(&refs->tempfile, sb.buf) < 0) {
>  		strbuf_addf(err, "unable to create file %s: %s",
>  			    sb.buf, strerror(errno));
>  		strbuf_release(&sb);
> -		return -1;
> +		goto out;
>  	}
>  	strbuf_release(&sb);
>  
> @@ -660,17 +668,21 @@ int commit_packed_refs(struct ref_store *ref_store, struct strbuf *err)
>  		goto error;
>  	}
>  
> -	if (rename_tempfile(&refs->tempfile, refs->path)) {
> +	if (rename_tempfile(&refs->tempfile, packed_refs_path)) {
>  		strbuf_addf(err, "error replacing %s: %s",
>  			    refs->path, strerror(errno));
> -		return -1;
> +		goto out;
>  	}
>  
> -	return 0;
> +	ret = 0;
> +	goto out;
>  
>  error:
>  	delete_tempfile(&refs->tempfile);
> -	return -1;
> +
> +out:
> +	free(packed_refs_path);
> +	return ret;
>  }
>  
>  /*
> diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh
> index 2bb4b25ed9..0d8a03e2a9 100755
> --- a/t/t3210-pack-refs.sh
> +++ b/t/t3210-pack-refs.sh
> @@ -238,4 +238,19 @@ test_expect_success 'retry acquiring packed-refs.lock' '
>  	git -c core.packedrefstimeout=3000 pack-refs --all --prune
>  '
>  
> +test_expect_success 'pack symlinked packed-refs' '

(*) Does this need a SYMLINKS prereq to avoid trouble on Windows?

> +	# First make sure that symlinking works when reading:
> +	git update-ref refs/heads/loosy refs/heads/master &&
> +	git for-each-ref >all-refs-before &&
> +	mv .git/packed-refs .git/my-deviant-packed-refs &&
> +	ln -s my-deviant-packed-refs .git/packed-refs &&
> +	git for-each-ref >all-refs-linked &&
> +	test_cmp all-refs-before all-refs-linked &&
> +	git pack-refs --all --prune &&
> +	git for-each-ref >all-refs-packed &&
> +	test_cmp all-refs-before all-refs-packed &&
> +	test -h .git/packed-refs &&
> +	test "$(readlink .git/packed-refs)" = "my-deviant-packed-refs"
> +'
> +
>  test_done

  parent reply	other threads:[~2017-07-27  0:18 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-01 18:30 [PATCH v3 00/30] Create a reference backend for packed refs Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 01/30] t1408: add a test of stale packed refs covered by loose refs Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 02/30] add_packed_ref(): teach function to overwrite existing refs Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 03/30] packed_ref_store: new struct Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 04/30] packed_ref_store: move `packed_refs_path` here Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 05/30] packed_ref_store: move `packed_refs_lock` member here Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 06/30] clear_packed_ref_cache(): take a `packed_ref_store *` parameter Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 07/30] validate_packed_ref_cache(): " Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 08/30] get_packed_ref_cache(): " Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 09/30] get_packed_refs(): " Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 10/30] add_packed_ref(): " Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 11/30] lock_packed_refs(): " Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 12/30] commit_packed_refs(): " Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 13/30] rollback_packed_refs(): " Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 14/30] get_packed_ref(): " Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 15/30] repack_without_refs(): " Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 16/30] packed_peel_ref(): new function, extracted from `files_peel_ref()` Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 17/30] packed_ref_store: support iteration Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 18/30] packed_read_raw_ref(): new function, replacing `resolve_packed_ref()` Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 19/30] packed-backend: new module for handling packed references Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 20/30] packed_ref_store: make class into a subclass of `ref_store` Michael Haggerty
2017-07-01 18:30 ` [PATCH v3 21/30] commit_packed_refs(): report errors rather than dying Michael Haggerty
2017-07-01 18:31 ` [PATCH v3 22/30] commit_packed_refs(): use a staging file separate from the lockfile Michael Haggerty
2017-07-01 18:31 ` [PATCH v3 23/30] packed_refs_lock(): function renamed from lock_packed_refs() Michael Haggerty
2017-07-01 18:31 ` [PATCH v3 24/30] packed_refs_lock(): report errors via a `struct strbuf *err` Michael Haggerty
2017-07-01 18:31 ` [PATCH v3 25/30] packed_refs_unlock(), packed_refs_is_locked(): new functions Michael Haggerty
2017-07-01 18:31 ` [PATCH v3 26/30] clear_packed_ref_cache(): don't protest if the lock is held Michael Haggerty
2017-07-01 18:31 ` [PATCH v3 27/30] commit_packed_refs(): remove call to `packed_refs_unlock()` Michael Haggerty
2017-07-01 18:31 ` [PATCH v3 28/30] repack_without_refs(): don't lock or unlock the packed refs Michael Haggerty
2017-07-01 18:31 ` [PATCH v3 29/30] t3210: add some tests of bogus packed-refs file contents Michael Haggerty
2017-07-01 18:31 ` [PATCH v3 30/30] read_packed_refs(): die if `packed-refs` contains bogus data Michael Haggerty
2017-07-05  9:12 ` [PATCH v3 00/30] Create a reference backend for packed refs Jeff King
2017-07-20 23:05   ` Stefan Beller
2017-07-20 23:20     ` Jonathan Nieder
2017-07-26 23:39       ` [PATCH] packed_ref_store: handle a packed-refs file that is a symlink Michael Haggerty
2017-07-27  0:15         ` Stefan Beller
2017-07-27  0:18         ` Jonathan Nieder [this message]
2017-07-27 11:12           ` Michael Haggerty
2017-07-27 17:19         ` Junio C Hamano
2017-07-27 18:28           ` Jeff King
2017-07-27 19:40             ` Junio C Hamano
2017-07-28  6:07               ` Michael Haggerty
2021-05-31 14:18         ` Ævar Arnfjörð Bjarmason
2021-06-03 19:39           ` Jeff King
2021-06-03 19:58             ` [PATCH] t: use portable wrapper for readlink(1) Jeff King
2021-06-04 21:09               ` Ævar Arnfjörð Bjarmason
2021-06-03 20:23             ` [PATCH] packed_ref_store: handle a packed-refs file that is a symlink Felipe Contreras
2021-06-03 21:08               ` Jeff King
2021-06-03 22:25                 ` Felipe Contreras
2021-06-04 21:37                 ` Ævar Arnfjörð Bjarmason
2021-06-05  1:07                   ` Felipe Contreras
2021-06-04 21:12             ` Ævar Arnfjörð Bjarmason

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=20170727001812.GI13924@aiede.mtv.corp.google.com \
    --to=jrnieder@gmail.com \
    --cc=avarab@gmail.com \
    --cc=bmwill@google.com \
    --cc=dawalker@google.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=mhagger@alum.mit.edu \
    --cc=novalis@novalis.org \
    --cc=pclouds@gmail.com \
    --cc=peff@peff.net \
    --cc=sbeller@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.