git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCHv3 00/21] git notes merge
@ 2010-10-09  1:08 Johan Herland
  2010-10-09  1:08 ` [PATCHv3 01/21] notes.c: Hexify SHA1 in die() message from init_notes() Johan Herland
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Johan Herland @ 2010-10-09  1:08 UTC (permalink / raw)
  To: git; +Cc: johan, jrnieder, bebarino, avarab, gitster

Hi,

This is the 3rd iteration of the 'git notes merge' patch series.

Changes between v2 and v3:

- Add initial patch fixing a missing sha1_to_hex() call in die() message
  from init_notes().

- (Ævar Arnfjörð Bjarmason) Don't use C99 comments.

- (Ævar Arnfjörð Bjarmason) Fix nonsense sentence in --commit description

- (Stephen Boyd) Use correct option name

- (Stephen Boyd) Remove unbalanced '('

- (Jonathan Nieder) Split the function reordering from (then) patch
  #3 into a separate patch (now patch #4), preceding the rest of the
  original patch (now patch #5). Also, clarify the behavioural change
  of that patch in its commit message.
  
- (Jonathan Nieder) Describe in the commit message how existing callers
  of add_note() are modified to deal with add_note()'s return value.

- (Jonathan Nieder) Add patch implementing 'git notes get-ref'


To be done in later series:

- Handle merging of notes trees with non-notes

- Allow notes merge strategies to be specified (per (group of?) notes
  ref) in the config


Some open questions:

- Sverre Rabbelier suggests renaming 'git notes merge --reset' to
  'git notes merge --abort'. I sort of agree, but would want some
  consistency with 'git merge', e.g. by providing 'git merge --abort'
  as an alias to 'git reset --merge'.

- Should we refuse to finalize a notes merge when conflict markers
  present in .git/NOTES_MERGE_WORKTREE? Since add/commit in regular
  merges does NOT do this, I have not implemented it for notes merge.

- When resolving notes merge conflicts, you can add/remove files/notes
  in .git/NOTES_MERGE_WORKTREE; 'git notes merge --commit' does not
  check that the notes have any relationship to the notes originally
  put there by 'git notes merge'. Should we warn about removed and
  added notes in .git/NOTES_MERGE_WORKTREE? Currently we don't, and
  I'm not sure it's worth it. Users can always review the merge commit
  afterwards.

- Fetching and pushing note refs:
  - Add refs/notes/* to default fetch refspec?
  - A way to specify (at clone time) which refspec(s) to set up?
  - A way for the remote repo to hint at which refspecs you might want
    to set up (by default?)


Have fun! :)

...Johan


Johan Herland (21):
  notes.c: Hexify SHA1 in die() message from init_notes()
  (trivial) notes.h: Minor documentation fixes to copy_notes()
  notes.h: Make default_notes_ref() available in notes API
  notes.c: Reorder functions in preparation for next commit
  notes.h/c: Clarify the handling of notes objects that are == null_sha1
  notes.h/c: Propagate combine_notes_fn return value to add_note() and beyond
  (trivial) t3303: Indent with tabs instead of spaces for consistency
  notes.c: Use two newlines (instead of one) when concatenating notes
  builtin/notes.c: Split notes ref DWIMmery into a separate function
  git notes merge: Initial implementation handling trivial merges only
  builtin/notes.c: Refactor creation of notes commits.
  git notes merge: Handle real, non-conflicting notes merges
  git notes merge: Add automatic conflict resolvers (ours, theirs, union)
  Documentation: Preliminary docs on 'git notes merge'
  git notes merge: Manual conflict resolution, part 1/2
  git notes merge: Manual conflict resolution, part 2/2
  git notes merge: List conflicting notes in notes merge commit message
  git notes merge: --commit should fail if underlying notes ref has moved
  git notes merge: Add another auto-resolving strategy: "cat_sort_uniq"
  git notes merge: Add testcases for merging notes trees at different fanouts
  Provide 'git notes get-ref' to easily retrieve current notes ref

 Documentation/git-notes.txt           |   85 ++++-
 Makefile                              |    2 +
 builtin.h                             |    2 +-
 builtin/notes.c                       |  268 +++++++++++--
 notes-cache.c                         |    3 +-
 notes-merge.c                         |  718 +++++++++++++++++++++++++++++++++
 notes-merge.h                         |   97 +++++
 notes.c                               |  274 +++++++++-----
 notes.h                               |   47 ++-
 t/t3301-notes.sh                      |   23 +
 t/t3303-notes-subtrees.sh             |   19 +-
 t/t3308-notes-merge.sh                |  327 +++++++++++++++
 t/t3309-notes-merge-auto-resolve.sh   |  647 +++++++++++++++++++++++++++++
 t/t3310-notes-merge-manual-resolve.sh |  556 +++++++++++++++++++++++++
 t/t3311-notes-merge-fanout.sh         |  436 ++++++++++++++++++++
 t/t3404-rebase-interactive.sh         |    1 +
 t/t9301-fast-import-notes.sh          |    5 +
 17 files changed, 3367 insertions(+), 143 deletions(-)
 create mode 100644 notes-merge.c
 create mode 100644 notes-merge.h
 create mode 100755 t/t3308-notes-merge.sh
 create mode 100755 t/t3309-notes-merge-auto-resolve.sh
 create mode 100755 t/t3310-notes-merge-manual-resolve.sh
 create mode 100755 t/t3311-notes-merge-fanout.sh

-- 
1.7.3.1.104.g92b87a

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCHv3 01/21] notes.c: Hexify SHA1 in die() message from init_notes()
  2010-10-09  1:08 [PATCHv3 00/21] git notes merge Johan Herland
@ 2010-10-09  1:08 ` Johan Herland
  2010-10-09  1:08 ` [PATCHv3 02/21] (trivial) notes.h: Minor documentation fixes to copy_notes() Johan Herland
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Johan Herland @ 2010-10-09  1:08 UTC (permalink / raw)
  To: git; +Cc: johan, jrnieder, bebarino, avarab, gitster

Signed-off-by: Johan Herland <johan@herland.net>
---

Found this while testing other aspects of this series.

...Johan

 notes.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/notes.c b/notes.c
index 1978244..bb03eb0 100644
--- a/notes.c
+++ b/notes.c
@@ -940,7 +940,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
 		return;
 	if (get_tree_entry(object_sha1, "", sha1, &mode))
 		die("Failed to read notes tree referenced by %s (%s)",
-		    notes_ref, object_sha1);
+		    notes_ref, sha1_to_hex(object_sha1));
 
 	hashclr(root_tree.key_sha1);
 	hashcpy(root_tree.val_sha1, sha1);
-- 
1.7.3.1.104.g92b87a

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv3 02/21] (trivial) notes.h: Minor documentation fixes to copy_notes()
  2010-10-09  1:08 [PATCHv3 00/21] git notes merge Johan Herland
  2010-10-09  1:08 ` [PATCHv3 01/21] notes.c: Hexify SHA1 in die() message from init_notes() Johan Herland
@ 2010-10-09  1:08 ` Johan Herland
  2010-10-09  1:08 ` [PATCHv3 03/21] notes.h: Make default_notes_ref() available in notes API Johan Herland
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Johan Herland @ 2010-10-09  1:08 UTC (permalink / raw)
  To: git; +Cc: johan, jrnieder, bebarino, avarab, gitster

Signed-off-by: Johan Herland <johan@herland.net>
---
 notes.h |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/notes.h b/notes.h
index 65fc3a6..c0288b0 100644
--- a/notes.h
+++ b/notes.h
@@ -104,6 +104,10 @@ const unsigned char *get_note(struct notes_tree *t,
  * Copy a note from one object to another in the given notes_tree.
  *
  * Fails if the to_obj already has a note unless 'force' is true.
+ *
+ * IMPORTANT: The changes made by copy_note() to the given notes_tree structure
+ * are not persistent until a subsequent call to write_notes_tree() returns
+ * zero.
  */
 int copy_note(struct notes_tree *t,
 	      const unsigned char *from_obj, const unsigned char *to_obj,
@@ -149,6 +153,7 @@ int copy_note(struct notes_tree *t,
  * notes tree) from within the callback:
  * - add_note()
  * - remove_note()
+ * - copy_note()
  * - free_notes()
  */
 typedef int each_note_fn(const unsigned char *object_sha1,
-- 
1.7.3.1.104.g92b87a

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv3 03/21] notes.h: Make default_notes_ref() available in notes API
  2010-10-09  1:08 [PATCHv3 00/21] git notes merge Johan Herland
  2010-10-09  1:08 ` [PATCHv3 01/21] notes.c: Hexify SHA1 in die() message from init_notes() Johan Herland
  2010-10-09  1:08 ` [PATCHv3 02/21] (trivial) notes.h: Minor documentation fixes to copy_notes() Johan Herland
@ 2010-10-09  1:08 ` Johan Herland
  2010-10-09  1:08 ` [PATCHv3 04/21] notes.c: Reorder functions in preparation for next commit Johan Herland
  2010-10-09 11:28 ` [PATCHv3 00/21] git notes merge Sverre Rabbelier
  4 siblings, 0 replies; 8+ messages in thread
From: Johan Herland @ 2010-10-09  1:08 UTC (permalink / raw)
  To: git; +Cc: johan, jrnieder, bebarino, avarab, gitster

Signed-off-by: Johan Herland <johan@herland.net>
---
 notes.c |    2 +-
 notes.h |   14 ++++++++++++++
 2 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/notes.c b/notes.c
index bb03eb0..d71c0a3 100644
--- a/notes.c
+++ b/notes.c
@@ -898,7 +898,7 @@ static int notes_display_config(const char *k, const char *v, void *cb)
 	return 0;
 }
 
-static const char *default_notes_ref(void)
+const char *default_notes_ref(void)
 {
 	const char *notes_ref = NULL;
 	if (!notes_ref)
diff --git a/notes.h b/notes.h
index c0288b0..20db42f 100644
--- a/notes.h
+++ b/notes.h
@@ -44,6 +44,20 @@ extern struct notes_tree {
 } default_notes_tree;
 
 /*
+ * Return the default notes ref.
+ *
+ * The default notes ref is the notes ref that is used when notes_ref == NULL
+ * is passed to init_notes().
+ *
+ * This the first of the following to be defined:
+ * 1. The '--ref' option to 'git notes', if given
+ * 2. The $GIT_NOTES_REF environment variable, if set
+ * 3. The value of the core.notesRef config variable, if set
+ * 4. GIT_NOTES_DEFAULT_REF (i.e. "refs/notes/commits")
+ */
+const char *default_notes_ref(void);
+
+/*
  * Flags controlling behaviour of notes tree initialization
  *
  * Default behaviour is to initialize the notes tree from the tree object
-- 
1.7.3.1.104.g92b87a

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv3 04/21] notes.c: Reorder functions in preparation for next commit
  2010-10-09  1:08 [PATCHv3 00/21] git notes merge Johan Herland
                   ` (2 preceding siblings ...)
  2010-10-09  1:08 ` [PATCHv3 03/21] notes.h: Make default_notes_ref() available in notes API Johan Herland
@ 2010-10-09  1:08 ` Johan Herland
  2010-10-13 21:59   ` Junio C Hamano
  2010-10-09 11:28 ` [PATCHv3 00/21] git notes merge Sverre Rabbelier
  4 siblings, 1 reply; 8+ messages in thread
From: Johan Herland @ 2010-10-09  1:08 UTC (permalink / raw)
  To: git; +Cc: johan, jrnieder, bebarino, avarab, gitster

This patch introduces no functional change. It consists solely of reordering
functions in notes.c to avoid use-before-declaration errors after applying
the next commit in this series.

Signed-off-by: Johan Herland <johan@herland.net>
---
 notes.c |  146 +++++++++++++++++++++++++++++++-------------------------------
 1 files changed, 73 insertions(+), 73 deletions(-)

diff --git a/notes.c b/notes.c
index d71c0a3..bfb3ea5 100644
--- a/notes.c
+++ b/notes.c
@@ -150,6 +150,79 @@ static struct leaf_node *note_tree_find(struct notes_tree *t,
 }
 
 /*
+ * How to consolidate an int_node:
+ * If there are > 1 non-NULL entries, give up and return non-zero.
+ * Otherwise replace the int_node at the given index in the given parent node
+ * with the only entry (or a NULL entry if no entries) from the given tree,
+ * and return 0.
+ */
+static int note_tree_consolidate(struct int_node *tree,
+	struct int_node *parent, unsigned char index)
+{
+	unsigned int i;
+	void *p = NULL;
+
+	assert(tree && parent);
+	assert(CLR_PTR_TYPE(parent->a[index]) == tree);
+
+	for (i = 0; i < 16; i++) {
+		if (GET_PTR_TYPE(tree->a[i]) != PTR_TYPE_NULL) {
+			if (p) /* more than one entry */
+				return -2;
+			p = tree->a[i];
+		}
+	}
+
+	/* replace tree with p in parent[index] */
+	parent->a[index] = p;
+	free(tree);
+	return 0;
+}
+
+/*
+ * To remove a leaf_node:
+ * Search to the tree location appropriate for the given leaf_node's key:
+ * - If location does not hold a matching entry, abort and do nothing.
+ * - Replace the matching leaf_node with a NULL entry (and free the leaf_node).
+ * - Consolidate int_nodes repeatedly, while walking up the tree towards root.
+ */
+static void note_tree_remove(struct notes_tree *t, struct int_node *tree,
+		unsigned char n, struct leaf_node *entry)
+{
+	struct leaf_node *l;
+	struct int_node *parent_stack[20];
+	unsigned char i, j;
+	void **p = note_tree_search(t, &tree, &n, entry->key_sha1);
+
+	assert(GET_PTR_TYPE(entry) == 0); /* no type bits set */
+	if (GET_PTR_TYPE(*p) != PTR_TYPE_NOTE)
+		return; /* type mismatch, nothing to remove */
+	l = (struct leaf_node *) CLR_PTR_TYPE(*p);
+	if (hashcmp(l->key_sha1, entry->key_sha1))
+		return; /* key mismatch, nothing to remove */
+
+	/* we have found a matching entry */
+	free(l);
+	*p = SET_PTR_TYPE(NULL, PTR_TYPE_NULL);
+
+	/* consolidate this tree level, and parent levels, if possible */
+	if (!n)
+		return; /* cannot consolidate top level */
+	/* first, build stack of ancestors between root and current node */
+	parent_stack[0] = t->root;
+	for (i = 0; i < n; i++) {
+		j = GET_NIBBLE(i, entry->key_sha1);
+		parent_stack[i + 1] = CLR_PTR_TYPE(parent_stack[i]->a[j]);
+	}
+	assert(i == n && parent_stack[i] == tree);
+	/* next, unwind stack until note_tree_consolidate() is done */
+	while (i > 0 &&
+	       !note_tree_consolidate(parent_stack[i], parent_stack[i - 1],
+				      GET_NIBBLE(i - 1, entry->key_sha1)))
+		i--;
+}
+
+/*
  * To insert a leaf_node:
  * Search to the tree location appropriate for the given leaf_node's key:
  * - If location is unused (NULL), store the tweaked pointer directly there
@@ -229,79 +302,6 @@ static void note_tree_insert(struct notes_tree *t, struct int_node *tree,
 	note_tree_insert(t, new_node, n + 1, entry, type, combine_notes);
 }
 
-/*
- * How to consolidate an int_node:
- * If there are > 1 non-NULL entries, give up and return non-zero.
- * Otherwise replace the int_node at the given index in the given parent node
- * with the only entry (or a NULL entry if no entries) from the given tree,
- * and return 0.
- */
-static int note_tree_consolidate(struct int_node *tree,
-	struct int_node *parent, unsigned char index)
-{
-	unsigned int i;
-	void *p = NULL;
-
-	assert(tree && parent);
-	assert(CLR_PTR_TYPE(parent->a[index]) == tree);
-
-	for (i = 0; i < 16; i++) {
-		if (GET_PTR_TYPE(tree->a[i]) != PTR_TYPE_NULL) {
-			if (p) /* more than one entry */
-				return -2;
-			p = tree->a[i];
-		}
-	}
-
-	/* replace tree with p in parent[index] */
-	parent->a[index] = p;
-	free(tree);
-	return 0;
-}
-
-/*
- * To remove a leaf_node:
- * Search to the tree location appropriate for the given leaf_node's key:
- * - If location does not hold a matching entry, abort and do nothing.
- * - Replace the matching leaf_node with a NULL entry (and free the leaf_node).
- * - Consolidate int_nodes repeatedly, while walking up the tree towards root.
- */
-static void note_tree_remove(struct notes_tree *t, struct int_node *tree,
-		unsigned char n, struct leaf_node *entry)
-{
-	struct leaf_node *l;
-	struct int_node *parent_stack[20];
-	unsigned char i, j;
-	void **p = note_tree_search(t, &tree, &n, entry->key_sha1);
-
-	assert(GET_PTR_TYPE(entry) == 0); /* no type bits set */
-	if (GET_PTR_TYPE(*p) != PTR_TYPE_NOTE)
-		return; /* type mismatch, nothing to remove */
-	l = (struct leaf_node *) CLR_PTR_TYPE(*p);
-	if (hashcmp(l->key_sha1, entry->key_sha1))
-		return; /* key mismatch, nothing to remove */
-
-	/* we have found a matching entry */
-	free(l);
-	*p = SET_PTR_TYPE(NULL, PTR_TYPE_NULL);
-
-	/* consolidate this tree level, and parent levels, if possible */
-	if (!n)
-		return; /* cannot consolidate top level */
-	/* first, build stack of ancestors between root and current node */
-	parent_stack[0] = t->root;
-	for (i = 0; i < n; i++) {
-		j = GET_NIBBLE(i, entry->key_sha1);
-		parent_stack[i + 1] = CLR_PTR_TYPE(parent_stack[i]->a[j]);
-	}
-	assert(i == n && parent_stack[i] == tree);
-	/* next, unwind stack until note_tree_consolidate() is done */
-	while (i > 0 &&
-	       !note_tree_consolidate(parent_stack[i], parent_stack[i - 1],
-				      GET_NIBBLE(i - 1, entry->key_sha1)))
-		i--;
-}
-
 /* Free the entire notes data contained in the given tree */
 static void note_tree_free(struct int_node *tree)
 {
-- 
1.7.3.1.104.g92b87a

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCHv3 00/21] git notes merge
  2010-10-09  1:08 [PATCHv3 00/21] git notes merge Johan Herland
                   ` (3 preceding siblings ...)
  2010-10-09  1:08 ` [PATCHv3 04/21] notes.c: Reorder functions in preparation for next commit Johan Herland
@ 2010-10-09 11:28 ` Sverre Rabbelier
  4 siblings, 0 replies; 8+ messages in thread
From: Sverre Rabbelier @ 2010-10-09 11:28 UTC (permalink / raw)
  To: Johan Herland; +Cc: git, jrnieder, bebarino, avarab, gitster

Heya,

On Sat, Oct 9, 2010 at 03:08, Johan Herland <johan@herland.net> wrote:
> - Fetching and pushing note refs:
>  - Add refs/notes/* to default fetch refspec?

Or at least add a '--notes[=<notes namespace>]' to fetch, pull, and push.

>  - A way to specify (at clone time) which refspec(s) to set up?

How would that look like?

>  - A way for the remote repo to hint at which refspecs you might want
>    to set up (by default?)

I assume this would be a generic mechanism of sorts? Are there any
other use cases for this other than notes?

-- 
Cheers,

Sverre Rabbelier

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCHv3 04/21] notes.c: Reorder functions in preparation for next commit
  2010-10-09  1:08 ` [PATCHv3 04/21] notes.c: Reorder functions in preparation for next commit Johan Herland
@ 2010-10-13 21:59   ` Junio C Hamano
  2010-10-13 22:20     ` Jonathan Nieder
  0 siblings, 1 reply; 8+ messages in thread
From: Junio C Hamano @ 2010-10-13 21:59 UTC (permalink / raw)
  To: Johan Herland; +Cc: git, jrnieder, bebarino, avarab

Hmm, why doesn't this patch apply?  What is this series based on?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCHv3 04/21] notes.c: Reorder functions in preparation for next commit
  2010-10-13 21:59   ` Junio C Hamano
@ 2010-10-13 22:20     ` Jonathan Nieder
  0 siblings, 0 replies; 8+ messages in thread
From: Jonathan Nieder @ 2010-10-13 22:20 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johan Herland, git, bebarino, avarab

Junio C Hamano wrote:

> What is this series based on?

e93487d, if I remember correctly.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-10-13 22:23 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-09  1:08 [PATCHv3 00/21] git notes merge Johan Herland
2010-10-09  1:08 ` [PATCHv3 01/21] notes.c: Hexify SHA1 in die() message from init_notes() Johan Herland
2010-10-09  1:08 ` [PATCHv3 02/21] (trivial) notes.h: Minor documentation fixes to copy_notes() Johan Herland
2010-10-09  1:08 ` [PATCHv3 03/21] notes.h: Make default_notes_ref() available in notes API Johan Herland
2010-10-09  1:08 ` [PATCHv3 04/21] notes.c: Reorder functions in preparation for next commit Johan Herland
2010-10-13 21:59   ` Junio C Hamano
2010-10-13 22:20     ` Jonathan Nieder
2010-10-09 11:28 ` [PATCHv3 00/21] git notes merge Sverre Rabbelier

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).