All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Jim Hill <gjthill@gmail.com>
Cc: Junio Hamano <gitster@pobox.com>, git@vger.kernel.org
Subject: Re: [PATCH 1/2] add_to_alternates_file: don't add duplicate paths
Date: Mon, 1 Jun 2015 06:51:42 -0400	[thread overview]
Message-ID: <20150601105142.GC31792@peff.net> (raw)
In-Reply-To: <1433096123-14420-2-git-send-email-gjthill@gmail.com>

On Sun, May 31, 2015 at 11:15:22AM -0700, Jim Hill wrote:

> Check for an existing match before appending a path to the alternates
> file.  Beyond making git look smart to anyone checking the alternates
> file, this removes the last use of hold_lock_file_for_append.

Makes sense. We don't catch _all_ cases here (e.g., we do not bother to
see if "foo" is a symlink to "bar"), but we at least catch the obvious
ones.

>  void add_to_alternates_file(const char *reference)
>  {
> -	struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
> [...]
> +	static struct lock_file lock = {0};

This seems like an unrelated change. I don't mind it in general, but it
should probably go in a separate patch.

> -	int fd = hold_lock_file_for_append(lock, git_path("objects/info/alternates"), LOCK_DIE_ON_ERROR);
>  	char *alt = mkpath("%s\n", reference);
> +	char *alts = git_path("objects/info/alternates");

A minor nit, but I found "alts" and "alt" to be a little bit similar
while reading. I wonder if "our_alts" or "alts_files" would be a little
more clear.

> +	struct strbuf altdata = STRBUF_INIT;
> +	struct string_list lines = STRING_LIST_INIT_NODUP;
> +
> +	if (strbuf_read_file(&altdata, alts, 0) < 0)
> +		if (errno != ENOENT)
> +			die("alternates file unreadable");

Hmm, so we read the whole content in, then split it into a string list
of lines.  Might it be simpler to just read it line by line and compare
as we go? Like (totally untested);

  FILE *in, *out;
  ...

  out = fdopen_lock_file(&lock, "w");
  if (!out)
	die_errno("unable to fdopen alternates lockfile");

  in = fopen(alts, "r");
  if (in) {
	struct strbuf line = STRBUF_INIT;
	int found = 0;

	while (strbuf_getline(&line, in, '\n') != EOF) {
		if (!strcmp(reference, line.buf)) {
			found = 1;
			break;
		}
		fprintf_or_die(out, "%s\n", line.buf);
	}

	strbuf_release(&line);
	fclose(in);

	if (found) {
		rollback_lock_file(&lock);
		return;
	}

  }
  else if (errno != ENOENT)
	  die_errno("unable to read alternates file");

  fprintf_or_die(out, "%s\n", reference);
  /* commit_lock_file, etc; it takes care of the fclose() */


Note that I also fdopen'd the output file, which makes the newline
handling a little easier (I think you can even drop the "alt" variable).
That's optional, and you could use strbuf_getwholeline to retain the
original newlines. But...

> +	strbuf_complete_line(&altdata);

This seems like a nice bugfix that you didn't mention. With the earlier
code, if your alternates file was missing a trailing newline, we would
produce a bogus output. So it makes sense to do (either this way, or the
way I showed above). I think it probably goes in the same commit (it's
part of the refactoring), but you may want to mention it in the commit
message.

> +cleanup:
> +	strbuf_reset(&altdata);

I think you want strbuf_release() here (though it goes away if you
follow my suggestion above).

> diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
> index 3e783fc..cd9fa34 100755
> --- a/t/t5700-clone-reference.sh
> +++ b/t/t5700-clone-reference.sh
> @@ -29,11 +29,11 @@ git prune'
>  cd "$base_dir"
>  
>  test_expect_success 'cloning with reference (-l -s)' \
> -'git clone -l -s --reference B A C'
> +'git clone -l -s --reference B --reference A --reference B A C'
>  
>  cd "$base_dir"
>  
> -test_expect_success 'existence of info/alternates' \
> +test_expect_success 'existence of info/alternates, no duplicates' \
>  'test_line_count = 2 C/.git/objects/info/alternates'

Generally we prefer a new separate test rather than trying to take over
an existing one (i.e., just add a new one with the clone and line-count
test together).

-Peff

  reply	other threads:[~2015-06-01 10:51 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-31 18:15 [PATCH 0/2] don't add duplicate paths to info/alternates Jim Hill
2015-05-31 18:15 ` [PATCH 1/2] add_to_alternates_file: don't add duplicate paths Jim Hill
2015-06-01 10:51   ` Jeff King [this message]
2015-05-31 18:15 ` [PATCH 2/2] remove hold_lock_file_for_append Jim Hill
2015-06-01 10:53 ` [PATCH 0/2] don't add duplicate paths to info/alternates Jeff King

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=20150601105142.GC31792@peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=gjthill@gmail.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.