All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johan Herland <johan@herland.net>
To: Jonathan Nieder <jrnieder@gmail.com>
Cc: git@vger.kernel.org, bebarino@gmail.com, gitster@pobox.com
Subject: Re: [PATCH 08/18] git notes merge: Initial implementation handling trivial merges only
Date: Thu, 21 Oct 2010 04:12:54 +0200	[thread overview]
Message-ID: <201010210412.54383.johan@herland.net> (raw)
In-Reply-To: <20101009172955.GB17799@burratino>

On Saturday 09 October 2010, Jonathan Nieder wrote:
> Johan Herland wrote:
> > Jonathan Nieder wrote:
> >> I would find it easier to read
> >> 
> >> 	if (o->verbosity >= DEFAULT_VERBOSITY)
> >> 	
> >> 		fprintf(stderr, ...)
> >> 
> >> unless there are going to be a huge number of messages.
> > 
> > The current version is modeled on the show() and output() functions in
> > merge-recursive.c. I think that works better in this situation.
> > Or maybe you have a better solution for merge-recursive.c as well?
> 
> Hmm --- isn't the point of output() that it indents to the appropriate
> level to portray a recursive merge?
> 
> Similarly, show() prevents those confusing messages from the internal
> merge between ancestors from being printed when the user is not
> interested.
> 
> But if you think they are important abstractions to maintain, I won't
> stop you. :)

I see. I still find the OUTPUT() macro more readable, but I've amended
the patch to eliminate the extraneous show() function. Hence, you'll
find this in the next iteration:

#define OUTPUT(o, v, ...) \
	do { \
		if ((o)->verbosity >= (v)) { \
			printf(__VA_ARGS__); \
			puts(""); \
		} \
	} while (0)

> >>> +
> >>> +	if (!o->local_ref || get_sha1(o->local_ref, local_sha1)) {
> >>> +		/* empty notes ref => assume empty notes tree */
> 
> [...]
> 
> > I'm not sure when you think we should (or shouldn't) error out.
> 
> get_sha1() can return -1 in the following cases:
> 
>  - starts with :/, regex does not match.
>  - starts with :, entry not present in index
>  - in form <rev>:<path>, <path> does not exist in <rev>
>  - in form <rev>^, <rev> does not exist or that parent does not
>    exist
>  - tag being used as commit points to a tree instead
>  - et c.

I see. I didn't take these into account when I wrote the code.

> Especially if the caller tries
> 
> 	git notes merge 'afjkdlsa^{gobbledeegook'
> 
> I would not like the merge to succeed.

Agreed, but I believe that command currently returns:

  fatal: Could not parse commit 'refs/notes/afjkdlsa^{gobbledeegook'.

(or using afjkdlsa^{gobbledeegook as "our" side of the merge):

  fatal: Cannot lock the ref 'refs/notes/afjkdlsa^{gobbledeegook'.

> So as I see it, there are four cases:
> 
>  - get_sha1() succeeds and returns a commit ==> merge that rev
>  - get_sha1() succeeds and returns a non-commit ==> fail
>  - get_sha1() fails, but resolve_ref() indicates a ref valid
>    for writing ==> merge empty tree
>  - get_sha1() fails, invalid refname ==> fail
> 
> The current code does not notice case 4, does it?

My tests indicate that case 4 does fail (correctly). However I also
agree that this is not at all clear from the current code, so I've
rewritten this code to something that is hopefully more straightforward
(this is the next iteration):

	/* Dereference o->local_ref into local_sha1 */
	if (!resolve_ref(o->local_ref, local_sha1, 0, NULL))
		die("Failed to resolve local notes ref '%s'", o->local_ref);
	else if (!check_ref_format(o->local_ref) && is_null_sha1(local_sha1))
		local = NULL; /* local_sha1 == null_sha1 indicates unborn ref */
	else if (!(local = lookup_commit_reference(local_sha1)))
		die("Could not parse local commit %s (%s)",
		    sha1_to_hex(local_sha1), o->local_ref);
	trace_printf("\tlocal commit: %.7s\n", sha1_to_hex(local_sha1));

	/* Dereference o->remote_ref into remote_sha1 */
	if (get_sha1(o->remote_ref, remote_sha1)) {
		/*
		 * Failed to get remote_sha1. If o->remote_ref looks like an
		 * unborn ref, perform the merge using an empty notes tree.
		 */
		if (!check_ref_format(o->remote_ref)) {
			hashclr(remote_sha1);
			remote = NULL;
		}
		else
			die("Failed to resolve remote notes ref '%s'",
			    o->remote_ref);
	}
	else if (!(remote = lookup_commit_reference(remote_sha1)))
		die("Could not parse remote commit %s (%s)",
		    sha1_to_hex(remote_sha1), o->remote_ref);
	trace_printf("\tremote commit: %.7s\n", sha1_to_hex(remote_sha1));

I've also added more testcases for expected failures.

> > I guess this becomes a discussion of whether we should model notes
> > merges on the 'resolve' merge strategy or the 'recursive' merge
> > strategy. Without having studied each strategy in-depth, I don't know
> > how much "better" 'recursive' is than 'resolve', especially not from
> > the POV of notes merges.
> 
> I think 'resolve' should be good enough for now.  We can always add
> 'recursive' later.

My thoughts exactly.

> > If you look at the notes_merge() docs in notes-merge.h by the
> > end of this series, you'll see the following return values:
> > 
> > 0: Merge trivially succeeded in an existing commit (e.g. fast-forward).
> > 
> > 1: Merge successfully completes a merge commit (i.e. no conflicts).
> > 
> > -1: Merge results is conflicts.
> 
> What kind of caller would care about the distinction between 1 and -1
> here (just curious)?

Any caller who cares about the merge at all, I'd imagine

If 1 (or 0) the merge is complete, and there's nothing more to be done
(expect updating the notes ref, of course).

If -1, there are conflicts checked out in .git/NOTES_MERGE_WORKTREE,
and the user must be told to fix them and commit the conflict
resolution.

See the last part of builtin/notes.c:merge() at the end of this series
for an example.


...Johan

-- 
Johan Herland, <johan@herland.net>
www.herland.net

  reply	other threads:[~2010-10-21  2:13 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-29  0:23 [PATCH 00/18] git notes merge Johan Herland
2010-09-29  0:23 ` [PATCH 01/18] (trivial) notes.h: Minor documentation fixes to copy_notes() Johan Herland
2010-10-05 14:55   ` Jonathan Nieder
2010-10-05 15:22     ` Johan Herland
2010-10-05 15:26       ` Jonathan Nieder
2010-09-29  0:23 ` [PATCH 02/18] notes.h: Make default_notes_ref() available in notes API Johan Herland
2010-09-29  0:23 ` [PATCH 03/18] notes.h/c: Clarify the handling of notes objects that are == null_sha1 Johan Herland
2010-10-05 15:21   ` Jonathan Nieder
2010-10-05 22:30     ` Johan Herland
2010-09-29  0:23 ` [PATCH 04/18] notes.h/c: Propagate combine_notes_fn return value to add_note() and beyond Johan Herland
2010-10-05 15:38   ` Jonathan Nieder
2010-10-06 19:40     ` Johan Herland
2010-09-29  0:23 ` [PATCH 05/18] (trivial) t3303: Indent with tabs instead of spaces for consistency Johan Herland
2010-09-29  0:23 ` [PATCH 06/18] notes.c: Use two newlines (instead of one) when concatenating notes Johan Herland
2010-09-29  0:23 ` [PATCH 07/18] builtin/notes.c: Split notes ref DWIMmery into a separate function Johan Herland
2010-10-05 15:50   ` Jonathan Nieder
2010-10-07 13:56     ` Johan Herland
2010-09-29  0:23 ` [PATCH 08/18] git notes merge: Initial implementation handling trivial merges only Johan Herland
2010-10-07  4:37   ` Test script style (Re: [PATCH 08/18] git notes merge: Initial implementation handling trivial merges only) Jonathan Nieder
2010-10-07  4:57     ` Junio C Hamano
2010-10-07  6:24   ` [PATCH 08/18] git notes merge: Initial implementation handling trivial merges only Jonathan Nieder
2010-10-08 23:55     ` Johan Herland
2010-10-09 17:29       ` Jonathan Nieder
2010-10-21  2:12         ` Johan Herland [this message]
2010-09-29  0:23 ` [PATCH 09/18] builtin/notes.c: Refactor creation of notes commits Johan Herland
2010-09-29  0:23 ` [PATCH 10/18] git notes merge: Handle real, non-conflicting notes merges Johan Herland
2010-09-29 16:20   ` Ævar Arnfjörð Bjarmason
2010-09-29 23:25     ` Johan Herland
2010-09-29  0:23 ` [PATCH 11/18] git notes merge: Add automatic conflict resolvers (ours, theirs, union) Johan Herland
2010-10-02  9:14   ` Stephen Boyd
2010-10-04 15:10     ` Johan Herland
2010-09-29  0:23 ` [PATCH 12/18] Documentation: Preliminary docs on 'git notes merge' Johan Herland
2010-10-02  8:55   ` Stephen Boyd
2010-10-04 15:15     ` Johan Herland
2010-09-29  0:23 ` [PATCH 13/18] git notes merge: Manual conflict resolution, part 1/2 Johan Herland
2010-09-29  0:23 ` [PATCH 14/18] git notes merge: Manual conflict resolution, part 2/2 Johan Herland
2010-09-29 16:19   ` Ævar Arnfjörð Bjarmason
2010-09-29 23:37     ` Johan Herland
2010-09-29  0:23 ` [PATCH 15/18] git notes merge: List conflicting notes in notes merge commit message Johan Herland
2010-09-29  0:23 ` [PATCH 16/18] git notes merge: --commit should fail if underlying notes ref has moved Johan Herland
2010-09-29  0:23 ` [PATCH 17/18] git notes merge: Add another auto-resolving strategy: "cat_sort_uniq" Johan Herland
2010-09-29  0:23 ` [PATCH 18/18] git notes merge: Add testcases for merging notes trees at different fanouts Johan Herland
2010-09-29 14:56 ` [PATCH 00/18] git notes merge Sverre Rabbelier
2010-09-29 15:16   ` Johan Herland
2010-09-29 15:20     ` Sverre Rabbelier
2010-09-29 16:04       ` Johan Herland

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=201010210412.54383.johan@herland.net \
    --to=johan@herland.net \
    --cc=bebarino@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jrnieder@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.