[RFD] Notes are independent: proposal for new notes implementation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Junio have noticed in one of threads about notes implementation in
git[*1*] that current notes implementation has (conceptual) problems:

[1] "Re: A generalization of git notes from blobs to trees - git metadata?"
    Message-ID: <7v8wb4aj4m.fsf@xxxxxxxxxxxxxxxxxxxxxxxx>
    http://permalink.gmane.org/gmane.comp.version-control.git/139252

    (its one of threads that IIRC started with implementing hand-rolled
    support for notes in gitweb by Giuseppe Bilotta)

Junio C Hamano <gitster@xxxxxxxxx> writes:
JH>
JH> It's [current notes implementation] like "keeping track of /etc" (or
JH> "your home directory").  It is a misguided thing to do because you
JH> are throwing in records of the states of totally unrelated things
JH> into a single history (e.g. "Why does it matter I added new user 
JH> frotz to /etc/passwd before I futzed with my sendmail configuration?
JH> ---It shouldn't matter; there shouldn't be ancestry relationships
JH> between these two changes").  I somehow feel that keeping track of
JH> the "growth of the bag of annotations to any and all commits" in a
JH> single history may be making the same mistake.

The proposed solution was to use custom merge strategy for notes.  But
what if the answer was to change implementation, decoupling history of
notes from each other, and keeping history of each note separate.

Let's simplify situation, and talk for now about single notes namespace
(refs/notes/commits), no fanout scheme, and plain blob notes.


In CURRENT notes implementation the notes ref (e.g. refs/notes/commits)
point to a commit object: the tip of history of all notes.  This commit
stores information about last change to any note; it's commit message is
"Annotate <SHA-1>".  It's tree contains mapping between notes and
annotated object: notes are stored as leafs in the tree, and their
pathnames are (representing) objects they are annotating.

This means for example that if in repository A somebody annotated
commits foo and bar creating notes in this order, and in repository B
somebody annotated bar and foo (creating notes in reverse order), then
merging those changes would require generating merge commit even if
those notes are identical.

 
 tree:                         <-- Annotate bar <-- refs/notes/commits
 <foo note SHA-1> <foo SHA-1>           |
 <bar note SHA-1> <bar SHA-1>           | (parent)
                                        |
                                        v
 tree:                         <-- Annotate foo
 <foo note SHA-1> <foo SHA-1>      (no parent)


The PROPOSED solution (with admittedly larger overhead) is to have notes
history stored in submodule-like fashion.  The notes ref would point to
the tree object.  In this tree each leaf would point to a *commit*
representing tip of history for a given note (like for submodules).
Each commit would contain tree, which would map note to annotated object
(it is extra level of indirection, needed because commit cannot point to
blob directly... unless multiple notes for the same commit in tree
structure got implemented, or tree annotations got implemented.)

This way history of each note is in kind of a separate branch, and notes
refs point to tree object representing branch hierarchy.

Merge conflict would appear only if notes for the same object would have
different contents or/and different history.

                  tree:                         <-- refs/notes/commits
    /------------ <foo hist SHA-1> <foo SHA-1> 
    |         /-- <bar hist SHA-1> <bar SHA-1> 
    |         |
    |         v
    |     Annotate bar --> tree:
    |     (no parent)      <bar note SHA-1> <bar SHA-1>
    v
  Annotate foo ----------> tree
  (no parent)              <foo note SHA-1> <foo SHA-1>

One thing that would need to be addressed is converting from older notes
implementation, but this should be doable.  The problem would be in
supporting both implementations in one repository; it might be not
possible.  Also this would break compatibility: older git versions
supporting notes wouldn't be able, I guess, to access new (proposed)
format.

There are probably numerous issues with proposed implementation, beside
breaking backward compatibility...


P.S. This shows why git tools (such as gitweb) should not access notes
directly, but use git-notes, %N / %N(<ref>) format specifier, and proposed
<object>^@{} / object^@{<ref>} or <object>^{notes} / <object>^{notes:<ref>}

-- 
Jakub Narebski
Poland
--
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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]