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

Re: [PATCH 08/18] git notes merge: Initial implementation handling trivial merges only

From
Johan Herland <johan@herland.net>
Date
Oct 21, 2010, 02:12 UTC
Message-ID
<201010210412.54383.johan@herland.net>
In-Reply-To
<20101009172955.GB17799@burratino>
On Saturday 09 October 2010, Jonathan Nieder wrote:
Show 23 quoted lines
> 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)
Show 17 quoted lines
> >>> +
> >>> +	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.
Show 5 quoted lines
> 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'.
Show 9 quoted lines
> 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.
Show 8 quoted lines
> > 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.
Show 11 quoted lines
> > 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
Previous: Jonathan NiederNext: Johan Herland
Message 24 of 46 in “git notes merge”
  1. 00/18 git notes mergeJohan Herland, Sep 29, 2010
  2. 01/18 (trivial) notes.h: Minor documentation fixes to copy_notes()Johan Herland, Sep 29, 2010
  3. Jonathan NiederOct 5, 2010
  4. Johan HerlandOct 5, 2010
  5. Jonathan NiederOct 5, 2010
  6. 02/18 notes.h: Make default_notes_ref() available in notes APIJohan Herland, Sep 29, 2010
  7. 03/18 notes.h/c: Clarify the handling of notes objects that are == null_sha1Johan Herland, Sep 29, 2010
  8. Jonathan NiederOct 5, 2010
  9. Johan HerlandOct 5, 2010
  10. 04/18 notes.h/c: Propagate combine_notes_fn return value to add_note() and beyondJohan Herland, Sep 29, 2010
  11. Jonathan NiederOct 5, 2010
  12. Johan HerlandOct 6, 2010
  13. 05/18 (trivial) t3303: Indent with tabs instead of spaces for consistencyJohan Herland, Sep 29, 2010
  14. 06/18 notes.c: Use two newlines (instead of one) when concatenating notesJohan Herland, Sep 29, 2010
  15. 07/18 builtin/notes.c: Split notes ref DWIMmery into a separate functionJohan Herland, Sep 29, 2010
  16. Jonathan NiederOct 5, 2010
  17. Johan HerlandOct 7, 2010
  18. 08/18 git notes merge: Initial implementation handling trivial merges onlyJohan Herland, Sep 29, 2010
  19. Test script style (Re: [PATCH 08/18] git notes merge: Initial implementation handling trivial merges only)Jonathan Nieder, Oct 7, 2010
  20. Junio C HamanoOct 7, 2010
  21. Jonathan NiederOct 7, 2010
  22. Johan HerlandOct 8, 2010
  23. Jonathan NiederOct 9, 2010
  24. Johan HerlandOct 21, 2010
  25. 09/18 builtin/notes.c: Refactor creation of notes commits.Johan Herland, Sep 29, 2010
  26. 10/18 git notes merge: Handle real, non-conflicting notes mergesJohan Herland, Sep 29, 2010
  27. Ævar Arnfjörð BjarmasonSep 29, 2010
  28. Johan HerlandSep 29, 2010
  29. 11/18 git notes merge: Add automatic conflict resolvers (ours, theirs, union)Johan Herland, Sep 29, 2010
  30. Stephen BoydOct 2, 2010
  31. Johan HerlandOct 4, 2010
  32. 12/18 Documentation: Preliminary docs on 'git notes merge'Johan Herland, Sep 29, 2010
  33. Stephen BoydOct 2, 2010
  34. Johan HerlandOct 4, 2010
  35. 13/18 git notes merge: Manual conflict resolution, part 1/2Johan Herland, Sep 29, 2010
  36. 14/18 git notes merge: Manual conflict resolution, part 2/2Johan Herland, Sep 29, 2010
  37. Ævar Arnfjörð BjarmasonSep 29, 2010
  38. Johan HerlandSep 29, 2010
  39. 15/18 git notes merge: List conflicting notes in notes merge commit messageJohan Herland, Sep 29, 2010
  40. 16/18 git notes merge: --commit should fail if underlying notes ref has movedJohan Herland, Sep 29, 2010
  41. 17/18 git notes merge: Add another auto-resolving strategy: "cat_sort_uniq"Johan Herland, Sep 29, 2010
  42. 18/18 git notes merge: Add testcases for merging notes trees at different fanoutsJohan Herland, Sep 29, 2010
  43. Sverre RabbelierSep 29, 2010
  44. Johan HerlandSep 29, 2010
  45. Sverre RabbelierSep 29, 2010
  46. Johan HerlandSep 29, 2010

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.