{"thread":{"id":"38228","subject":"fast-import's notemodify doesn't work the same as git notes","startedAt":"2014-12-23T00:06:11Z","lastAt":"2014-12-23T00:06:11Z","messageCount":1,"participants":["Mike Hommey"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"253978","messageId":"20141223000611.GB10980@glandium.org","threadId":"38228","inReplyTo":null,"subject":"fast-import's notemodify doesn't work the same as git notes","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2014-12-23T00:06:11Z","receivedAt":"2014-12-23T00:06:11Z","isPatch":false,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"Hi,\n\nThere are two major differences between adding notes with fast-import\nand git notes, one of which is a serious problem:\n\n- fast-import doesn't want to add notes for non commits, while git notes\n  does.\n\n- fast-import and git notes have different, conflicting fanouts:\n  - take e.g. the git repo (there needs to be a lot of commits to start\n    to see the problem)\n  - run the following to create notes for every commit:\n      (echo 'blob';\n       echo 'mark :1';\n       echo 'data 0';\n       echo 'commit refs/notes/foo';\n       echo 'committer <foo> 0 +0000';\n       echo 'data 0';\n       git rev-list --all | awk '{print \"N :1\", $1}';\n       echo) | git fast-import\n  - pick a random commit. I'll pick\n    bbcefffcea9789e4a1a2023a1c778e2c07db77a7 as it is current master as\n    of writing. Take the first two characters of that sha1, and look at\n    the ls-tree:\n      git ls-tree refs/notes/foo bb/\n    You'll see a number of blobs.\n  - Now, remove the note for that commit with git notes:\n      git notes --ref foo remove bbcefffcea9789e4a1a2023a1c778e2c07db77a7\n  - ls-tree again, you'll now see a number of trees instead of blobs,\n    because git notes will have done a fanout. -> git notes does fanouts\n    for much less items than fast-import does.\n  - Re-add a note for that commit with fast-import:\n      git fast-import <<EOF\n      blob\n      mark :1\n      data 0\n      commit refs/notes/foo\n      committer <foo> 0 +0000\n      data 0\n      from refs/notes/foo^0\n      N :1 bbcefffcea9789e4a1a2023a1c778e2c07db77a7\n\n      EOF\n  - ls-tree again, and you'll see a number of trees and *one* blob, for\n    bb/cefffcea9789e4a1a2023a1c778e2c07db77a7\n  - See the thread starting with 20141126004242.GA13915@glandium.org,\n    this type of notes branch make things very slow.\n  - Now, if you take an even bigger repository (as long as there are more\n    than 65536 commits, that's good ; I guess the linux kernel\n    qualifies, I've been checking with a mozilla-central clone), and\n    create exactly 65535 notes with git fast-import, you'll end up with\n    a 1-level tree (2/38). Add one more note, and the entire tree turns\n    into a 2-level tree (2/2/36). git notes would only add a level to\n    the tree containing the added note. git notes's behavior scales\n    better, because think about what happens on the next fanout with\n    fast-import... adding one note would need to create millions of trees.\n\nCheers,\n\nMike\n"}]}