[PATCH 00/15] git-note: A mechanisim for providing free-form after-the-fact annotations on commits

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

 



On Thursday 10 May 2007, Linus Torvalds wrote:
> On Thu, 10 May 2007, Johan Herland wrote:
> > 
> > BTW, I'm wondering whether anybody has ever thought about allowing 
> > after-the-fact annotations on commits. Kinda like free-form 
> > continuations on the commit message. It would allow people to make 
> > notes on previous commits that were either forgotten at commit-time, or 
> > only became apparent after the commit was done.
> 
> We kind of have some of that.
> 
> Tag objects can be used that way, and the "grafts" file is a very special 
> case. 
> 
> But if you want to do it on a larger scale, you'd need something that is 
> really optimized for that. For example, git internally now has a notion of 
> "decorating" arbitrary objects with arbitrary data, and if you just had an 
> efficient file format to create such decorations (for blame or other 
> special ops), the *code* is easy to write. It's how
> 
> 	git log --decorate
> 
> works right now (the "data" is just the tag names, but you could make it 
> read other decorations, and the git data structures are very efficient, 
> and allow different types of decorations to be used independently of 
> each other).

I've been working on combining tag objects and --decorate into a useful
proof-of-concept that provides the after-the-fact commit annotations I
requested above, and here's the result:

<quote src="Documentation/git-note.txt">
A git note provides an after-the-fact text annotation associated with an
exiting object in the git object database. The note itself is also stored
in the database (as a special case of a tag object). Note object are therefore
-- as all other objects in the database -- immutable, i.e. once added they
cannot be edited, although they can be deleted.

As with regular tag objects, notes are useless unless they have a
corresponding reference stored in `.git/refs`. For notes, these references
are stored in a hierarchy under `.git/refs/notes`. For each object that has
one or more associated notes, there is a subdirectory under
`.git/refs/notes` named after the object identifier (SHA1 sum). The
object's subdirectory contains one file per note associated with that object.
The end result is that notes are easily accessible from the name/identifier
of the object they are associated with.

Note that deleting a note with `git-note -d` only deletes the reference to
the note. The note itself is still present in the object database, but will
be considered unreachable by gitlink:git-fsck[1], and may be removed with
gitlink:git-prune[1].
</quote>


Here are some more details from the design notes I based my work on:

- Notes must not run counter to the existing design (and design goals) of git

- A note is itself stored as a git tag object:
	- "object" has SHA1 of this note's object (as with regular tag objects)
	- "type" has type of this note's object (as with regular tag objects)
	- "tag" is fundamentally unimportant to the note. However, in order
	  to provide a unique tag name (so as not to be confused with any
	  other tag object) this is automatically set to "note-{$sha1}",
	  where {$sha1} is the SHA1 sum of the "object" and "tagger" fields
	  and the note message. If uniqueness of tag names within tag objects
	  is not important, we may consider dropping this
	- "tagger" has the note author and date (same as regular tag objects)
	- The rest of the tag object contains the note message, similar in
	  form to a commit message

- External mapping of objects to associated notes is kept below .git/refs/notes:
	- One file per note object (as with tag refs in .git/refs/tags)
	- Located at .git/refs/notes/{$object-sha1}/{$note-sha1}
	- File contains SHA1 of the note object (same as refs in .git/refs/tags)
	- Yes, this means that the filename (minus directory part) is identical
	  to the contents of the file

Some of the properties that result from the above decisions:

- A note is uniquely identified by its SHA1 sum (as are all other git objects)

- Notes are trivially packable

- The entire set of note refs can be fully recreated by trawling the object db
  for tag objects with the tag name field matching the "note-{$sha1}" pattern

- Notes behave like regular tags under clone/push/fetch

- Notes are automatically checked by fsck (although some extra checking has
  has been added)

- Little impact to existing git architecture


However, there are still some remaining questions:

- Is the creation of a unique tag name (i.e. the 'tag' field _inside_ the
  object) for note objects really necessary? Which parts of the system rely
  on these names to be unique across tag objects?

- Should notes have their own object type instead of piggy-backing on "tag"?

- What about having a note object type with minimal header fields, and make
  tags just a special case of a note object with an extra tag name header?

- What about notes on notes? How are tags on tags treated? How should they be
  treated?

- Currently noted objects (notees?) are treated as reachable from their
  associated notes, i.e. like tags. This means that an otherwise dangling
  object will not be detected and removed if it has associated notes.
  This may not be what we want. If not, the following needs to be done:
	- Notes should probably have their own object type at this point
	- An object is no longer considered reachable from the associated notes
	  This mostly affects git-fsck and git-prune, which should now be able
	  to remove dangling objects with notes


Finally, here's the shortlog of the patches that will follow this email:

Johan Herland (15):
      git-note: Add git-note command for adding/listing/deleting git notes
      git-note: (Documentation) Add git-note manual page
      git-note: (Administrivia) Add git-note to Makefile, .gitignore, etc.
      git-note: (Plumbing) Add plumbing-level support for git notes
      git-note: (Plumbing) Add support for git notes to git-rev-parse and git-show-ref
      git-note: (Documentation) Explain the new '--notes' option to git-rev-parse and git-show-ref
      git-note: (Almost plumbing) Add support for git notes to git-pack-refs and git-fsck
      git-note: (Decorations) Add note decorations to "git-{log,show,whatchanged} --decorate"
      git-note: (Documentation) Explain new behaviour of --decorate in git-{log,show,whatchanged}
      git-note: (Transfer) Teach git-clone how to clone notes
      git-note: (Transfer) Teach git-fetch to auto-follow notes
      git-note: (Transfer) Teach git-push to push notes when --all or --notes is given
      git-note: (Documentation) Explain the new --notes option to git-push
      git-note: (Tests) Add tests for git-note and associated functionality
      git-note: Add display of notes to gitk

 .gitignore                        |    3 +-
 Documentation/cmd-list.perl       |    5 +-
 Documentation/git-log.txt         |    3 +-
 Documentation/git-note.txt        |   95 ++++++++++++
 Documentation/git-push.txt        |    7 +-
 Documentation/git-rev-parse.txt   |    5 +-
 Documentation/git-show-ref.txt    |   14 +-
 Documentation/git-show.txt        |    4 +
 Documentation/git-whatchanged.txt |    4 +
 Makefile                          |    2 +-
 builtin-fetch--tool.c             |   11 ++
 builtin-fsck.c                    |   61 ++++++++
 builtin-log.c                     |  108 +++++++++++++-
 builtin-pack-refs.c               |    5 +-
 builtin-push.c                    |   20 ++-
 builtin-rev-parse.c               |    5 +
 builtin-show-ref.c                |   16 ++-
 commit.h                          |    7 +
 generate-cmdlist.sh               |    1 +
 git-clone.sh                      |    5 +-
 git-fetch.sh                      |   27 ++++
 git-note.sh                       |  227 +++++++++++++++++++++++++++
 git-parse-remote.sh               |    4 +-
 gitk                              |   38 +++++-
 log-tree.c                        |   67 ++++++++-
 refs.c                            |   20 +++
 refs.h                            |    4 +
 t/t3850-note.sh                   |  303 +++++++++++++++++++++++++++++++++++++
 28 files changed, 1033 insertions(+), 38 deletions(-)
 create mode 100644 Documentation/git-note.txt
 create mode 100755 git-note.sh
 create mode 100755 t/t3850-note.sh


Have fun!

...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

[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]

  Powered by Linux