{"thread":{"id":"29911","subject":"problem with merging notes.","startedAt":"2012-03-11T17:17:02Z","lastAt":"2012-03-12T18:54:14Z","messageCount":6,"participants":["David Bremner","Michael Schubert","Johan Herland","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"186657","messageId":"87boo3m50x.fsf@zancas.localnet","threadId":"29911","inReplyTo":null,"subject":"problem with merging notes.","fromName":"David Bremner","fromEmail":"david@tethera.net","sentAt":"2012-03-11T17:17:02Z","receivedAt":"2012-03-11T17:17:02Z","isPatch":false,"sender":{"key":"david@tethera.net","avatar":null},"body":"\nHi;\n\nIt seems to me there is a bug (or at least some missing documentation)\nfor git notes merge --commit. If the working directory is\n.git/NOTES_MERGE_WORKTREE, then all notes for the conflicting commit are\nsilently dropped.\n\nA test script follows. Have I missed something?  \n\nDavid\n\nP.S. Please CC me, I'm not subscribed.\n\n\ntmpdir=$(mktemp -d)\ncd $tmpdir\ngit init\ngit commit --allow-empty -m'empty commit'\ngit notes add -m 'foo' HEAD\ngit notes --ref=other add -m 'bar' HEAD \ngit notes merge refs/notes/other\ncd .git/NOTES_MERGE_WORKTREE\necho \"foo\\nbar\\n\"> $(git rev-parse HEAD)\ngit notes merge --commit\ncd ../..\ngit notes list | wc -l\n"},{"id":"186660","messageId":"4F5CF0D8.8080904@elegosoft.com","threadId":"29911","inReplyTo":"87boo3m50x.fsf@zancas.localnet","subject":"Re: problem with merging notes.","fromName":"Michael Schubert","fromEmail":"mschub@elegosoft.com","sentAt":"2012-03-11T18:37:12Z","receivedAt":"2012-03-11T18:37:12Z","isPatch":false,"sender":{"key":"mschub@elegosoft.com","avatar":null},"body":"On 03/11/2012 06:17 PM, David Bremner wrote:\n> tmpdir=$(mktemp -d)\n> cd $tmpdir\n> git init\n> git commit --allow-empty -m'empty commit'\n> git notes add -m 'foo' HEAD\n> git notes --ref=other add -m 'bar' HEAD \n> git notes merge refs/notes/other\n> cd .git/NOTES_MERGE_WORKTREE\n> echo \"foo\\nbar\\n\"> $(git rev-parse HEAD)\n> git notes merge --commit\n\ncd back to your worktree *before* you call\n\"git notes merge --commit\" and it will work as expected.\n\nApparently, there's some path issue and git notes just\ncontinues doing half of its job. I'll check later.\n\n> cd ../..\n> git notes list | wc -l\n\nThanks.\n"},{"id":"186709","messageId":"1331564233-1969-1-git-send-email-johan@herland.net","threadId":"29911","inReplyTo":"87boo3m50x.fsf@zancas.localnet","subject":"[PATCH 1/2] t3310: Add testcase demonstrating failure to --commit from within another dir","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2012-03-12T14:57:12Z","receivedAt":"2012-03-12T14:57:12Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"Found-by: David Bremner <david@tethera.net>\nSigned-off-by: Johan Herland <johan@herland.net>\n---\n\n(sending again in the correct thread. Sorry for the screwup.)\n\nThis is a transcription of David's test script into a git test case.\n\nThanks to David for finding this issue.\n\n\nHave fun! :)\n\n...Johan\n\n t/t3310-notes-merge-manual-resolve.sh |   19 +++++++++++++++++++\n 1 file changed, 19 insertions(+)\n\ndiff --git a/t/t3310-notes-merge-manual-resolve.sh b/t/t3310-notes-merge-manual-resolve.sh\nindex 4367197..0c531c3 100755\n--- a/t/t3310-notes-merge-manual-resolve.sh\n+++ b/t/t3310-notes-merge-manual-resolve.sh\n@@ -553,4 +553,23 @@ test_expect_success 'resolve situation by aborting the notes merge' '\n \tverify_notes z\n '\n\n+cat >expect_notes <<EOF\n+foo\n+bar\n+EOF\n+\n+test_expect_failure 'switch cwd before committing notes merge' '\n+\tgit notes add -m foo HEAD &&\n+\tgit notes --ref=other add -m bar HEAD &&\n+\ttest_must_fail git notes merge refs/notes/other &&\n+\t(\n+\t\tcd .git/NOTES_MERGE_WORKTREE &&\n+\t\techo \"foo\" > $(git rev-parse HEAD) &&\n+\t\techo \"bar\" >> $(git rev-parse HEAD) &&\n+\t\tgit notes merge --commit\n+\t) &&\n+\tgit notes show HEAD > actual_notes &&\n+\ttest_cmp expect_notes actual_notes\n+'\n+\n test_done\n--\n1.7.9.2\n"},{"id":"186710","messageId":"1331564233-1969-2-git-send-email-johan@herland.net","threadId":"29911","inReplyTo":"1331564233-1969-1-git-send-email-johan@herland.net","subject":"[PATCH 2/2] notes-merge: use opendir/readdir instead of using read_directory()","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2012-03-12T14:57:13Z","receivedAt":"2012-03-12T14:57:13Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"notes_merge_commit() only needs to list all entries (non-recursively)\nunder a directory, which can be easily accomplished with\nopendir/readdir and would be more lightweight than read_directory().\n\nread_directory() is designed to list paths inside a working\ndirectory. Using it outside of its scope may lead to undesired effects.\n\nApparently, one of the undesired effects of read_directory() is that it\ndoesn't deal with being given absolute paths. This creates problems for\nnotes_merge_commit() when git_path() returns an absolute path, which\nhappens when the current working directory is in a subdirectory of the\n.git directory.\n\nOriginally-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nUpdated-by:  Johan Herland <johan@herland.net>\nSigned-off-by: Johan Herland <johan@herland.net>\n---\n\n(sending again in the correct thread. Sorry for the screwup.)\n\nThis is a resurrection of pclouds' patch 2/11 in a patch series sent\nlast October for rewriting read_directory(). This patch doesn't\nactually touch read_directory(), but instead rewrites\nnotes_merge_commit() to use opendir()/readdir() instead of\nread_directory(). Since the usage of read_directory() is what caused\nthe bug that David found (in the previous patch), this rewrite happens\nto fix that bug as well.\n\n\nHave fun! :)\n\n...Johan\n\n notes-merge.c                         |   50 ++++++++++++++++++++-------------\n t/t3310-notes-merge-manual-resolve.sh |    2 +-\n 2 files changed, 31 insertions(+), 21 deletions(-)\n\ndiff --git a/notes-merge.c b/notes-merge.c\nindex fb0832f..3a16af2 100644\n--- a/notes-merge.c\n+++ b/notes-merge.c\n@@ -687,51 +687,60 @@ int notes_merge_commit(struct notes_merge_options *o,\n {\n \t/*\n \t * Iterate through files in .git/NOTES_MERGE_WORKTREE and add all\n-\t * found notes to 'partial_tree'. Write the updates notes tree to\n+\t * found notes to 'partial_tree'. Write the updated notes tree to\n \t * the DB, and commit the resulting tree object while reusing the\n \t * commit message and parents from 'partial_commit'.\n \t * Finally store the new commit object SHA1 into 'result_sha1'.\n \t */\n-\tstruct dir_struct dir;\n-\tchar *path = xstrdup(git_path(NOTES_MERGE_WORKTREE \"/\"));\n-\tint path_len = strlen(path), i;\n+\tDIR *dir;\n+\tstruct dirent *e;\n+\tstruct strbuf path = STRBUF_INIT;\n \tchar *msg = strstr(partial_commit->buffer, \"\\n\\n\");\n \tstruct strbuf sb_msg = STRBUF_INIT;\n+\tint baselen;\n\n+\tstrbuf_addstr(&path, git_path(NOTES_MERGE_WORKTREE));\n \tif (o->verbosity >= 3)\n-\t\tprintf(\"Committing notes in notes merge worktree at %.*s\\n\",\n-\t\t\tpath_len - 1, path);\n+\t\tprintf(\"Committing notes in notes merge worktree at %s\\n\",\n+\t\t\tpath.buf);\n\n \tif (!msg || msg[2] == '\\0')\n \t\tdie(\"partial notes commit has empty message\");\n \tmsg += 2;\n\n-\tmemset(&dir, 0, sizeof(dir));\n-\tread_directory(&dir, path, path_len, NULL);\n-\tfor (i = 0; i < dir.nr; i++) {\n-\t\tstruct dir_entry *ent = dir.entries[i];\n+\tdir = opendir(path.buf);\n+\tif (!dir)\n+\t\tdie_errno(\"could not open %s\", path.buf);\n+\n+\tstrbuf_addch(&path, '/');\n+\tbaselen = path.len;\n+\twhile ((e = readdir(dir)) != NULL) {\n \t\tstruct stat st;\n-\t\tconst char *relpath = ent->name + path_len;\n \t\tunsigned char obj_sha1[20], blob_sha1[20];\n\n-\t\tif (ent->len - path_len != 40 || get_sha1_hex(relpath, obj_sha1)) {\n+\t\tif (is_dot_or_dotdot(e->d_name))\n+\t\t\tcontinue;\n+\n+\t\tif (strlen(e->d_name) != 40 || get_sha1_hex(e->d_name, obj_sha1)) {\n \t\t\tif (o->verbosity >= 3)\n-\t\t\t\tprintf(\"Skipping non-SHA1 entry '%s'\\n\",\n-\t\t\t\t\t\t\t\tent->name);\n+\t\t\t\tprintf(\"Skipping non-SHA1 entry '%s%s'\\n\",\n+\t\t\t\t\tpath.buf, e->d_name);\n \t\t\tcontinue;\n \t\t}\n\n+\t\tstrbuf_addstr(&path, e->d_name);\n \t\t/* write file as blob, and add to partial_tree */\n-\t\tif (stat(ent->name, &st))\n-\t\t\tdie_errno(\"Failed to stat '%s'\", ent->name);\n-\t\tif (index_path(blob_sha1, ent->name, &st, HASH_WRITE_OBJECT))\n-\t\t\tdie(\"Failed to write blob object from '%s'\", ent->name);\n+\t\tif (stat(path.buf, &st))\n+\t\t\tdie_errno(\"Failed to stat '%s'\", path.buf);\n+\t\tif (index_path(blob_sha1, path.buf, &st, HASH_WRITE_OBJECT))\n+\t\t\tdie(\"Failed to write blob object from '%s'\", path.buf);\n \t\tif (add_note(partial_tree, obj_sha1, blob_sha1, NULL))\n \t\t\tdie(\"Failed to add resolved note '%s' to notes tree\",\n-\t\t\t    ent->name);\n+\t\t\t    path.buf);\n \t\tif (o->verbosity >= 4)\n \t\t\tprintf(\"Added resolved note for object %s: %s\\n\",\n \t\t\t\tsha1_to_hex(obj_sha1), sha1_to_hex(blob_sha1));\n+\t\tstrbuf_setlen(&path, baselen);\n \t}\n\n \tstrbuf_attach(&sb_msg, msg, strlen(msg), strlen(msg) + 1);\n@@ -740,7 +749,8 @@ int notes_merge_commit(struct notes_merge_options *o,\n \tif (o->verbosity >= 4)\n \t\tprintf(\"Finalized notes merge commit: %s\\n\",\n \t\t\tsha1_to_hex(result_sha1));\n-\tfree(path);\n+\tstrbuf_release(&path);\n+\tclosedir(dir);\n \treturn 0;\n }\n\ndiff --git a/t/t3310-notes-merge-manual-resolve.sh b/t/t3310-notes-merge-manual-resolve.sh\nindex 0c531c3..d6d6ac6 100755\n--- a/t/t3310-notes-merge-manual-resolve.sh\n+++ b/t/t3310-notes-merge-manual-resolve.sh\n@@ -558,7 +558,7 @@ foo\n bar\n EOF\n\n-test_expect_failure 'switch cwd before committing notes merge' '\n+test_expect_success 'switch cwd before committing notes merge' '\n \tgit notes add -m foo HEAD &&\n \tgit notes --ref=other add -m bar HEAD &&\n \ttest_must_fail git notes merge refs/notes/other &&\n--\n1.7.9.2\n"},{"id":"186753","messageId":"7vr4wxsmrt.fsf@alter.siamese.dyndns.org","threadId":"29911","inReplyTo":"1331564233-1969-1-git-send-email-johan@herland.net","subject":"Re: [PATCH 1/2] t3310: Add testcase demonstrating failure to --commit from within another dir","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-03-12T18:21:42Z","receivedAt":"2012-03-12T18:21:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johan Herland <johan@herland.net> writes:\n\n> Found-by: David Bremner <david@tethera.net>\n> Signed-off-by: Johan Herland <johan@herland.net>\n\nCould you clarify what \"from within another dir\" means on the subject?\n\nWhat was the expected usage?\n\n\tThe 'git notes merge' command expected to be run from the\n        working tree of the project being annotated, and did not\n        anticipate getting run inside $GIT_DIR/.  However, because\n        we use $GIT_DIR/NOTES_MERGE_WORKTREE as a temporary working\n        space for the user to work on resolving conflicts, it is not\n        unreasonable for a user to run \"git notes merge --commit\"\n        there.\n\nIs that the issue?\n\n> ---\n>\n> (sending again in the correct thread. Sorry for the screwup.)\n>\n> This is a transcription of David's test script into a git test case.\n>\n> Thanks to David for finding this issue.\n>\n>\n> Have fun! :)\n>\n> ...Johan\n>\n>  t/t3310-notes-merge-manual-resolve.sh |   19 +++++++++++++++++++\n>  1 file changed, 19 insertions(+)\n>\n> diff --git a/t/t3310-notes-merge-manual-resolve.sh b/t/t3310-notes-merge-manual-resolve.sh\n> index 4367197..0c531c3 100755\n> --- a/t/t3310-notes-merge-manual-resolve.sh\n> +++ b/t/t3310-notes-merge-manual-resolve.sh\n> @@ -553,4 +553,23 @@ test_expect_success 'resolve situation by aborting the notes merge' '\n>  \tverify_notes z\n>  '\n>\n> +cat >expect_notes <<EOF\n> +foo\n> +bar\n> +EOF\n> +\n> +test_expect_failure 'switch cwd before committing notes merge' '\n> +\tgit notes add -m foo HEAD &&\n> +\tgit notes --ref=other add -m bar HEAD &&\n> +\ttest_must_fail git notes merge refs/notes/other &&\n> +\t(\n> +\t\tcd .git/NOTES_MERGE_WORKTREE &&\n> +\t\techo \"foo\" > $(git rev-parse HEAD) &&\n> +\t\techo \"bar\" >> $(git rev-parse HEAD) &&\n> +\t\tgit notes merge --commit\n> +\t) &&\n> +\tgit notes show HEAD > actual_notes &&\n> +\ttest_cmp expect_notes actual_notes\n> +'\n> +\n>  test_done\n> --\n> 1.7.9.2\n"},{"id":"186759","messageId":"CALKQrgeXSwG6n41CDwmoyHWrU5CnQMBtoPdFmGqh1gZqeMzNqA@mail.gmail.com","threadId":"29911","inReplyTo":"7vr4wxsmrt.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/2] t3310: Add testcase demonstrating failure to --commit from within another dir","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2012-03-12T18:54:14Z","receivedAt":"2012-03-12T18:54:14Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Mon, Mar 12, 2012 at 19:21, Junio C Hamano <gitster@pobox.com> wrote:\n> Johan Herland <johan@herland.net> writes:\n>\n>> Found-by: David Bremner <david@tethera.net>\n>> Signed-off-by: Johan Herland <johan@herland.net>\n>\n> Could you clarify what \"from within another dir\" means on the subject?\n>\n> What was the expected usage?\n>\n>        The 'git notes merge' command expected to be run from the\n>        working tree of the project being annotated, and did not\n>        anticipate getting run inside $GIT_DIR/.  However, because\n>        we use $GIT_DIR/NOTES_MERGE_WORKTREE as a temporary working\n>        space for the user to work on resolving conflicts, it is not\n>        unreasonable for a user to run \"git notes merge --commit\"\n>        there.\n>\n> Is that the issue?\n\nThat is exactly the issue. Thanks for the clear wording.\n\nFeel free to update the commit message accordingly.\n\n\n...Johan\n\n>> ---\n>>\n>> (sending again in the correct thread. Sorry for the screwup.)\n>>\n>> This is a transcription of David's test script into a git test case.\n>>\n>> Thanks to David for finding this issue.\n>>\n>>\n>> Have fun! :)\n>>\n>> ...Johan\n>>\n>>  t/t3310-notes-merge-manual-resolve.sh |   19 +++++++++++++++++++\n>>  1 file changed, 19 insertions(+)\n>>\n>> diff --git a/t/t3310-notes-merge-manual-resolve.sh b/t/t3310-notes-merge-manual-resolve.sh\n>> index 4367197..0c531c3 100755\n>> --- a/t/t3310-notes-merge-manual-resolve.sh\n>> +++ b/t/t3310-notes-merge-manual-resolve.sh\n>> @@ -553,4 +553,23 @@ test_expect_success 'resolve situation by aborting the notes merge' '\n>>       verify_notes z\n>>  '\n>>\n>> +cat >expect_notes <<EOF\n>> +foo\n>> +bar\n>> +EOF\n>> +\n>> +test_expect_failure 'switch cwd before committing notes merge' '\n>> +     git notes add -m foo HEAD &&\n>> +     git notes --ref=other add -m bar HEAD &&\n>> +     test_must_fail git notes merge refs/notes/other &&\n>> +     (\n>> +             cd .git/NOTES_MERGE_WORKTREE &&\n>> +             echo \"foo\" > $(git rev-parse HEAD) &&\n>> +             echo \"bar\" >> $(git rev-parse HEAD) &&\n>> +             git notes merge --commit\n>> +     ) &&\n>> +     git notes show HEAD > actual_notes &&\n>> +     test_cmp expect_notes actual_notes\n>> +'\n>> +\n>>  test_done\n>> --\n>> 1.7.9.2\n\n\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"}]}