notes: allow merging from arbitrary references

Create a new expansion function, expand_loose_notes_ref which will first
check whether the ref can be found using get_sha1. If it can't be found
then it will fallback to using expand_notes_ref. The content of the
strbuf will not be changed if the notes ref can be located using
get_sha1. Otherwise, it may be updated as done by expand_notes_ref.

Since we now support merging from non-notes refs, remove the test case
associated with that behavior. Add a test case for merging from a
non-notes ref.

Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Reviewed-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jacob Keller
2015-12-29 14:40:28 -08:00
committed by Junio C Hamano
parent 28274d02c4
commit b3715b7522
4 changed files with 29 additions and 12 deletions

View File

@ -806,7 +806,7 @@ static int merge(int argc, const char **argv, const char *prefix)
o.local_ref = default_notes_ref(); o.local_ref = default_notes_ref();
strbuf_addstr(&remote_ref, argv[0]); strbuf_addstr(&remote_ref, argv[0]);
expand_notes_ref(&remote_ref); expand_loose_notes_ref(&remote_ref);
o.remote_ref = remote_ref.buf; o.remote_ref = remote_ref.buf;
t = init_notes_check("merge"); t = init_notes_check("merge");

10
notes.c
View File

@ -1303,3 +1303,13 @@ void expand_notes_ref(struct strbuf *sb)
else else
strbuf_insert(sb, 0, "refs/notes/", 11); strbuf_insert(sb, 0, "refs/notes/", 11);
} }
void expand_loose_notes_ref(struct strbuf *sb)
{
unsigned char object[20];
if (get_sha1(sb->buf, object)) {
/* fallback to expand_notes_ref */
expand_notes_ref(sb);
}
}

View File

@ -294,4 +294,11 @@ void string_list_add_refs_from_colon_sep(struct string_list *list,
/* Expand inplace a note ref like "foo" or "notes/foo" into "refs/notes/foo" */ /* Expand inplace a note ref like "foo" or "notes/foo" into "refs/notes/foo" */
void expand_notes_ref(struct strbuf *sb); void expand_notes_ref(struct strbuf *sb);
/*
* Similar to expand_notes_ref, but will check whether the ref can be located
* via get_sha1 first, and only falls back to expand_notes_ref in the case
* where get_sha1 fails.
*/
void expand_loose_notes_ref(struct strbuf *sb);
#endif #endif

View File

@ -18,7 +18,9 @@ test_expect_success setup '
git notes add -m "Notes on 1st commit" 1st && git notes add -m "Notes on 1st commit" 1st &&
git notes add -m "Notes on 2nd commit" 2nd && git notes add -m "Notes on 2nd commit" 2nd &&
git notes add -m "Notes on 3rd commit" 3rd && git notes add -m "Notes on 3rd commit" 3rd &&
git notes add -m "Notes on 4th commit" 4th git notes add -m "Notes on 4th commit" 4th &&
# Copy notes to remote-notes
git fetch . refs/notes/*:refs/remote-notes/origin/*
' '
commit_sha1=$(git rev-parse 1st^{commit}) commit_sha1=$(git rev-parse 1st^{commit})
@ -66,7 +68,9 @@ test_expect_success 'verify initial notes (x)' '
' '
cp expect_notes_x expect_notes_y cp expect_notes_x expect_notes_y
cp expect_notes_x expect_notes_v
cp expect_log_x expect_log_y cp expect_log_x expect_log_y
cp expect_log_x expect_log_v
test_expect_success 'fail to merge empty notes ref into empty notes ref (z => y)' ' test_expect_success 'fail to merge empty notes ref into empty notes ref (z => y)' '
test_must_fail git -c "core.notesRef=refs/notes/y" notes merge z test_must_fail git -c "core.notesRef=refs/notes/y" notes merge z
@ -84,16 +88,12 @@ test_expect_success 'fail to merge into various non-notes refs' '
test_must_fail git -c "core.notesRef=refs/notes/foo^{bar" notes merge x test_must_fail git -c "core.notesRef=refs/notes/foo^{bar" notes merge x
' '
test_expect_success 'fail to merge various non-note-trees' ' test_expect_success 'merge non-notes ref into empty notes ref (remote-notes/origin/x => v)' '
git config core.notesRef refs/notes/y && git config core.notesRef refs/notes/v &&
test_must_fail git notes merge refs/notes && git notes merge refs/remote-notes/origin/x &&
test_must_fail git notes merge refs/notes/ && verify_notes v &&
test_must_fail git notes merge refs/notes/dir && # refs/remote-notes/origin/x and v should point to the same notes commit
test_must_fail git notes merge refs/notes/dir/ && test "$(git rev-parse refs/remote-notes/origin/x)" = "$(git rev-parse refs/notes/v)"
test_must_fail git notes merge refs/heads/master &&
test_must_fail git notes merge x: &&
test_must_fail git notes merge x:foo &&
test_must_fail git notes merge foo^{bar
' '
test_expect_success 'merge notes into empty notes ref (x => y)' ' test_expect_success 'merge notes into empty notes ref (x => y)' '