On Tue, Feb 11, 2014 at 6:23 PM, Joachim Breitner <mail@xxxxxxxxxxxxxxxxxxx> wrote: > Hi, > > judging from the documentation I got the impression that I can pass any > git object has to "git note -C <hash>" and it would stored as-is. But it > seems the objects gets mangled somehow... ...well... the documentation does not say "any object", it actually explicitly says "blob object"... ;) > (I want to attach a commit object as a note, to reference the history of > a feature before the final cleanup rebase. For that I turn the reflog > into a series of commits, and the final commit is the one I want to > store there.) > > $ mkdir foo > $ cd foo/ > $ echo foo > a > $ git init > Initialisierte leeres Git-Repository in /tmp/foo/.git/ > $ git add a > $ git commit -m 'A commit' > [master (Basis-Commit) 3d7de37] A commit > 1 file changed, 1 insertion(+) > create mode 100644 a > $ echo foo2 > a > $ git commit -m 'A commit 2' -a > [master e1bfac4] A commit 2 > 1 file changed, 1 insertion(+), 1 deletion(-) > $ git notes --ref history add -C 3d7de37 e1bfac4 > $ git ls-tree notes/history > 100644 blob 5b73d5152e6207e3a2b67e57ca3a2cb94d12061e e1bfac434ebd3135a3784f6fc802f235098eebd0 > > I was expecting 3d7de37 to be referenced here. > > Is that a bug, or is storing commits as notes not supported? I guess it depends on your POV... The current documentation says "blob object", and what actually happens (in builtin/notes.c) is that the given object (3d7de37 in your example) is read into a strbuf (in parse_reuse_arg()) and stored back into a note object (in create_note()), without preserving the object type ("blob" type is hardcoded). This means an incoming blob object (as documented) will be preserved (i.e. reuse the same SHA-1), but for any other object type, the object bits will be read, and stored back into a blob object. This is why your commit (or any other non-blob) ends up with a different SHA-1 when stored as a note: It is the same bytes, but in a blob object instead of a commit object. There is currently no way the "git notes" commands will allow you to store the 3d7de37 commit object directly as a note. There is also (AFAICS) no easy workaround (git fast-import could've been a workaround if it did not already require the first N/notemodify argument to be a blob object). The best alternative, off the top of my head, would be to write your own program using the notes.h API to manipulate the notes tree directly (or - suboptimally - use other low-level Git operations to do the same). However before you go there, let's take a step back, and look at what the result would look like (if you were allowed to store a commit object directly as a note): You would have a notes ref "refs/notes/history" whose tree would contain an entry named e1bfac434ebd3135a3784f6fc802f235098eebd0 pointing to a _commit_ (3d7de37...). Obviously, it would not make sense to use refs/notes/history while displaying the commit log ("git log --notes=history"), as the raw commit object would be shown in the log. However, more fundamentally: a tree referring to a _commit_ is usually how Git stores _submodule_ links (i.e. which revision of the named submodule is to be used by this super-repo tree), and I'm (off the top of my head) not at all sure that such a submodule link in a notes tree is handled "sanely" by Git - or even that it makes sense at all. For one, I'm not sure that Git requires (or even expects) the commit object referenced by a tree to be present in the same object DB. So if you share your notes, I don't know whether or not the fetch/push machinery will include the commit object in the shared notes... These are questions that should be answered before we decide whether using commits directly as notes makes sense. If we do figure out that storing commits as note objects is desirable (and does not have too nasty side-effects), then I am not opposed to fixing builtin/notes.c to preserve type of the object passed in -C. Certainly, the current behavior for non-blobs (i.e. copy the object bytes, but not the object type) is probably not useful to anyone... That said, there may be other ways to solve your immediate problem: Instead of storing the commit object directly as a note, you could store the commit SHA-1 into a blob, and use that as the blob object. That would also allow you to store multiple commits in the note for e1bfac4 (in case you had several cleanup rebases leading to the final commit), or you could store other kinds of metadata in the same note. Or do you have a requirement that the reflog history (presumably reachable from 3d7de37) need to be shared (or otherwise kept reachable)? In that case, you might be better off using an explicit ref to keep that history alive; e.g. you could create refs/history/e1bfac4 to point to 3d7de37 ("git update-ref refs/history/e1bfac4 3d7de37"), and keep everything alive/reachable/shareable that way... Hope this helps, ...Johan -- Johan Herland, <johan@xxxxxxxxxxx> www.herland.net -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html