Git development
 help / color / mirror / Atom feed
* Re: GIT on MinGW problem
From: Han-Wen Nienhuys @ 2007-05-27 17:04 UTC (permalink / raw)
  To: git; +Cc: Johannes Sixt
In-Reply-To: <Pine.LNX.4.64.0705271149450.4648@racer.site>

Johannes Schindelin escreveu:

>>       ((Tcl_Obj **) objv) += (async + 3);
> 
> Ah yes, I was using MinGW's own GCC, which is GCC 3.something.
> 
> It is a new "feature" of GCC 4.x to disallow constructs like these. 
> (Probably because GCC people think that other people are not intelligent 
> enough to understand such constructs, and therefore prohibit their use.)

I very much doubt that. GCC uses type information to determine whether 
pointers might be aliased.  I think disallowing such constructs helps with
compiler optimization.

-- 
 Han-Wen Nienhuys - hanwen@xs4all.nl - http://www.xs4all.nl/~hanwen

^ permalink raw reply

* Re: [PATCH] Don't ignore write failure from git-diff, git-log, etc.
From: Linus Torvalds @ 2007-05-27 16:17 UTC (permalink / raw)
  To: Jim Meyering; +Cc: git
In-Reply-To: <87odk6y6cd.fsf@rho.meyering.net>



On Sun, 27 May 2007, Jim Meyering wrote:
> 
> I have to disagree.  There may be precedent for hiding EPIPE errors,
> but that is not the norm among command line tools wrt piped stdout.

.. and this is a PROBLEM. Which is why I think your patch was really 
wrong.

I don't know how many people remember all the _stupid_ problems we had 
exactly because many versions of bash are crap, crap, crap, and people 
(including you) don't realize that EPIPE is _different_ from other write 
errors.

Just do a google search for

	"broken pipe" bash

and not only will you see a lot of complaints, but the #5 entry is a 
complaint for a git issue that we had tons of problems with. See for 
example

	http://www.gelato.unsw.edu.au/archives/git/0504/2602.html

The reason? Some _idiotic_ versions of bash don't have DONT_REPORT_SIGPIPE 
on by default. 

So I do get upset when people then make the same error with git.

> Do you really want git-log to continue to do this?
> 
>     $ (trap '' PIPE; git-log; echo $? >&2 ) | :
>     0
> 
> With my patch, it does this:
> 
>     $ (trap '' PIPE; ./git-log; echo $? >&2 ) | :
>     fatal: write failure on standard output: Broken pipe
>     128

That error return is fine. The annoying error report, however, is NOT.

For _exactly_ the same reason that a bash that doesn't have 
DONT_REPORT_SIGPIPE enabled is a piece of crap.

And your arguments that "others do it wrong, so we can too" is so broken 
as to be really really sad. If you cannot see the serious problem with 
that argument, I don't know what to tell you.

Try this:

	trap '' PIPE; ./git-log | head

and dammit, if you get an error message from that, your program is BROKEN.

And if you cannot understand that, then I don't even know what to say.

But _exiting_ is fine. It's the bogus error reporting that isn't. The 
above command like should NOT cause the user to have to skip stderr - 
because no error happened!

(Whether the error code is 0 or some error, I dunno. I'd argue that if you 
ignore SIGPIPE, you'd probably also want to do "exit(0)" for EPIPE, but 
it's not nearly as annoying as writing bogus error messages to stderr.

			Linus

^ permalink raw reply

* Re: [PATCH 1/3] Lazily open pack index files on demand
From: Dana How @ 2007-05-27 16:06 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Shawn O. Pearce, Junio C Hamano, git, danahow
In-Reply-To: <alpine.LFD.0.99.0705271110550.3366@xanadu.home>

On 5/27/07, Nicolas Pitre <nico@cam.org> wrote:
> BTW I think the Newton-Raphson based index lookup approach should be
> revived at some point.
Yes.

 I think if we figure out the statistics we could win big.
I thought about it a bit when it was first discussed
but need to return to it.

Thanks,
-- 
Dana L. How  danahow@gmail.com  +1 650 804 5991 cell

^ permalink raw reply

* Re: [RFH] QGit: how to cram a patch in a crowded screen
From: Marco Costalba @ 2007-05-27 15:56 UTC (permalink / raw)
  To: Jan Hudec; +Cc: Andy Parkins, git, Pavel Roskin
In-Reply-To: <20070527153852.GA30365@efreet.light.src>

On 5/27/07, Jan Hudec <bulb@ucw.cz> wrote:
> On Sat, May 26, 2007 at 22:44:28 +0200, Marco Costalba wrote:
> > On 5/26/07, Andy Parkins <andyparkins@gmail.com> wrote:
> > >
> > >For example, the log view widget would show:
> > >
> > ><Header>
> > ><Log Message>
> > ><Patch>
> > >
> > >All visually distinct to improve searching by eye (perhaps including
> > >clear separators between files patched).  Then the file list could
> > >include a "<header>" psuedo-file that would jump back to the top of the
> > >viewer.
> >
> > This seems really gitk like. Not that I don' t like it, but _if_ it's
> > possible I would prefer something a little bit more original.
>
> IMHO there's no point in being original.

True. But there's no point also in avoiding experimenting a little bit.

I've pushed some patches to use different ways to switch between diff
and messages, please read the last patch log message for a summary of
the changes.

If interested give it a try. it would be grat to hear your comment on that also.

Thanks
Marco

P.S: Perhaps the current gitk way is the best, but you'll never know
if you never try something different.

^ permalink raw reply

* Re: [RFH] QGit: how to cram a patch in a crowded screen
From: Jan Hudec @ 2007-05-27 15:38 UTC (permalink / raw)
  To: Marco Costalba; +Cc: Andy Parkins, git, Pavel Roskin
In-Reply-To: <e5bfff550705261344l604543e7h64c20c1fc0979f20@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 904 bytes --]

On Sat, May 26, 2007 at 22:44:28 +0200, Marco Costalba wrote:
> On 5/26/07, Andy Parkins <andyparkins@gmail.com> wrote:
> >
> >For example, the log view widget would show:
> >
> ><Header>
> ><Log Message>
> ><Patch>
> >
> >All visually distinct to improve searching by eye (perhaps including
> >clear separators between files patched).  Then the file list could
> >include a "<header>" psuedo-file that would jump back to the top of the
> >viewer.
> 
> This seems really gitk like. Not that I don' t like it, but _if_ it's
> possible I would prefer something a little bit more original.

IMHO there's no point in being original. The gitk way works well, because it
requires only one action -- scrolling -- throughout reading of the whole
commit (description + patch). With any kind of tabs, there's always an extra
action for switching.

-- 
						 Jan 'Bulb' Hudec <bulb@ucw.cz>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH 1/3] Lazily open pack index files on demand
From: Nicolas Pitre @ 2007-05-27 15:36 UTC (permalink / raw)
  To: Martin Koegler; +Cc: Dana How, Shawn O. Pearce, Junio C Hamano, git
In-Reply-To: <20070527104600.GA23554@auto.tuwien.ac.at>

On Sun, 27 May 2007, Martin Koegler wrote:

> Dana How wrote:
> > (1c) Do not deltify naughty blobs.  Naughty blobs are those
> >      blobs marked "nodelta" or very large blobs.
> 
> I don't like the idea to exclude any blobs from delta by default, if
> the delta could be done.

It won't happen by default.

> If the "very large blobs" are text files with
> very few difference, they deltifiy very well.
> 
> Additionlly, how do you want to define "very large blobs"? 

This is indeed a per repository attribute that is highly dependent on 
your data set.


Nicolas

^ permalink raw reply

* Re: [PATCH 1/3] Lazily open pack index files on demand
From: Nicolas Pitre @ 2007-05-27 15:29 UTC (permalink / raw)
  To: Dana How; +Cc: Shawn O. Pearce, Junio C Hamano, git
In-Reply-To: <56b7f5510705262140rea5e1e5r49bdd5e99c466daa@mail.gmail.com>

On Sat, 26 May 2007, Dana How wrote:

> On 5/26/07, Shawn O. Pearce <spearce@spearce.org> wrote:
> > In pack v4 we're likely to move the SHA-1 table from the .idx file
> > into the front of the .pack file.  This makes the .idx file hold
> > only the offsets and the CRC checkums of each object.  If we start
> > making a super index, we have to duplicate the SHA-1 table twice
> > (once in the .pack, again in the super index).
> Hmm, hopefully the SHA-1 table can go at the _end_
> since with split packs that's the only time we know the number
> of objects in the pack... ;-)

Hmmm good point to consider.


Nicolas

^ permalink raw reply

* Re: [PATCH 1/3] Lazily open pack index files on demand
From: Nicolas Pitre @ 2007-05-27 15:26 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Dana How, Junio C Hamano, git
In-Reply-To: <20070527033429.GY28023@spearce.org>

On Sat, 26 May 2007, Shawn O. Pearce wrote:

> Dana How <danahow@gmail.com> wrote:
> > Shawn:  When I first saw the index-loading code,  my first
> > thought was that all the index tables should be
> > merged (easy since sorted) so callers only need to do one search.
> 
> Yes; in fact this has been raised on the list before.  The general
> idea was to create some sort of "super index" that had a list of
> all objects and which packfile they could be found in.  This way the
> running process doesn't have to search multiple indexes, and the
> process doesn't have to be responsible for the merging itself.
> 
> See the thing is, if you read all of every .idx file on a simple
> `git-log` operation you've already lost.  The number of trees and
> blobs tends to far outweigh the number of commits and they really
> outweigh the number of commits the average user looks at in a
> `git-log` session before they abort their pager.  So sorting all
> of the available .idx files before we produce even the first commit
> is a horrible thing to do.

There is also the question of memory footprint.  If you have a global 
index, then for each object you need to have a tupple containing SHA1 + 
pack offset + reference to corresponding pack.  Right now we only need 
SHA1 + pack offset.

BTW I think the Newton-Raphson based index lookup approach should be 
revived at some point.


Nicolas

^ permalink raw reply

* Re: [PATCH v3] Prevent megablobs from gunking up git packs
From: Nicolas Pitre @ 2007-05-27 15:09 UTC (permalink / raw)
  To: Dana How; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <56b7f5510705262246o54a38a44xc0c261c4b4161155@mail.gmail.com>

On Sat, 26 May 2007, Dana How wrote:

> I've been discussing these plans with IT here since they maintain
> everything else.
> They would like any part of the database that is going to be reorganized
> and replaced to be backed up first.  If only (1) is available,  and I
> repack every
> night,  then I need to back up the entire repository every night as well.

Why so?  The initial repack would create a set of packs where the last 
packs to be produced will contain large blobs that you don't have to 
ever repack.  Or maybe you produce large blobs every day and you want to 
prevent those from entering the pack up front?

> If I use (2) or (3),  then I back up just the repacked portion each night,
> back up the kept packs only when they are repacked (on a slower schedule),
> and/or back up the loose blobs on a similar schedule.
> 
> Besides this back up issue,  I simply don't want to have to repack _all_
> of such a large repository each night.  With (1), nightly repacks get longer
> and longer, and harder to schedule.
> 
> I think the minimum features needed to support (2) and (3) are the same:
> (a) An easy way to prevent loose blobs exceeding some size limit
>     from migrating into "nice" packs;
> (b) A way to prevent packed objects from being copied when
>     (i) they no longer meet the (new or reduced) size limit AND
>     (ii) they exist in some other safe form in the repository.
> The behavior of --max-blob-size=N in this patch provides both of these
> while deleting other behavior people didn't like.
> 
> You mentioned "incoherency" above;
> I'm not too sure how to proceed on that.
> If you have a more coherent way to provide (a) and (b) above,
> please let me know.

I think it boils down to a question of proper wordings.  Describing this 
as max-blob-size is misleading if in the end you still can end up with 
larger blobs in your pack.  I think there are two solutions to this 
incoherency: either the feature is called something else to reflect the 
fact that it concerns itself only with migration of loose blobs into the 
packed space (I cannot come up with a good name though), or the whole 
pack-objects process is aborted with an error whenever the max-blob-size 
condition cannot be satisfied due to large blobs existing in packed form 
only indicating that a separate extraction of large blobs process is 
required.


Nicolas

^ permalink raw reply

* Re: [PATCH] Add -Wdeclaration-after-statement to CFLAGS to help enforce the instructions in SubmittingPatches
From: Morten Welinder @ 2007-05-27 14:58 UTC (permalink / raw)
  To: Johan Herland
  Cc: git, Johannes Schindelin, Junio C Hamano, Martin Waitz,
	Shawn O. Pearce
In-Reply-To: <200705271639.35267.johan@herland.net>

> Why not automatically enforce it by putting -Wdeclaration-after-statement
> in the Makefile?

Because -Wdeclaration-after-statement regretably is a fairly new thing.

M.

^ permalink raw reply

* Re: [PATCH 1/3] Lazily open pack index files on demand
From: Nicolas Pitre @ 2007-05-27 14:41 UTC (permalink / raw)
  To: Dana How; +Cc: Junio C Hamano, Shawn O. Pearce, git
In-Reply-To: <56b7f5510705262131g2d4186a0q605abbcea624d42d@mail.gmail.com>

On Sat, 26 May 2007, Dana How wrote:

> On 5/26/07, Nicolas Pitre <nico@cam.org> wrote:
> > In other words, I think the naughty blob could simply be recognized as
> > such and be referenced in a special list instead of being written out
> > initially.  Then when everything is believed to be written, the special
> > list can be walked to force write those naughty blob at last.  No need
> > to modify the current object order.
> This works as long as a naughty blob can't be a delta base for a nice blob
> (causing it to be pushed out early by the recursion in write_one()).
> I think that's a reasonable and understandable restriction.

Sure.  Or the delta can inherit the naughty property if its base is also 
naughty, which solves the problem nicely.


Nicolas

^ permalink raw reply

* [PATCH] Add -Wdeclaration-after-statement to CFLAGS to help enforce the instructions in SubmittingPatches
From: Johan Herland @ 2007-05-27 14:39 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Junio C Hamano, Martin Waitz,
	Shawn O. Pearce
In-Reply-To: <Pine.LNX.4.64.0705211347540.6410@racer.site>

Signed-off-by: Johan Herland <johan@herland.net>
---
On Monday 21 May 2007, Johannes Schindelin wrote:
> 
> We do not appreciate C99 initializers, declarations after statements,
> or "0" instead of "NULL".
>
> [...]
> 
> +Also, variables have to be declared at the beginning of the block
> +(you can check this with gcc, using the -Wdeclaration-after-statement
> +option).

Why not automatically enforce it by putting -Wdeclaration-after-statement
in the Makefile?

It should probably be protected by some GCC if-ery, but then again, so should this:

CC = gcc


Have fun!

...Johan


 Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index 29243c6..4e91516 100644
--- a/Makefile
+++ b/Makefile
@@ -135,7 +135,7 @@ uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
 
 # CFLAGS and LDFLAGS are for the users to override from the command line.
 
-CFLAGS = -g -O2 -Wall
+CFLAGS = -g -O2 -Wall -Wdeclaration-after-statement
 LDFLAGS =
 ALL_CFLAGS = $(CFLAGS)
 ALL_LDFLAGS = $(LDFLAGS)
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 15/15] git-note: Add display of notes to gitk
From: Johan Herland @ 2007-05-27 14:17 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

Teach gitk to display notes below the commit message similarly to how
notes are displayed when using --decorate with git-{log,show,whatchanged}.

Signed-off-by: Johan Herland <johan@herland.net>
---
 gitk |   38 +++++++++++++++++++++++++++++++++++---
 1 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/gitk b/gitk
index a57e84c..7bed56b 100755
--- a/gitk
+++ b/gitk
@@ -303,7 +303,7 @@ proc getcommit {id} {
 }
 
 proc readrefs {} {
-    global tagids idtags headids idheads tagcontents
+    global tagids idtags idnotes headids idheads tagcontents
     global otherrefids idotherrefs mainhead
 
     foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
@@ -318,7 +318,7 @@ proc readrefs {} {
 	if {[regexp {^remotes/.*/HEAD$} $path match]} {
 	    continue
 	}
-	if {![regexp {^(tags|heads)/(.*)$} $path match type name]} {
+	if {![regexp {^(tags|notes|heads)/(.*)$} $path match type name]} {
 	    set type others
 	    set name $path
 	}
@@ -341,6 +341,18 @@ proc readrefs {} {
 	    catch {
 	        set tagcontents($name) [exec git cat-file tag $id]
 	    }
+	} elseif { $type == "notes" } {
+	    puts stderr "note name = '$name', id = '$id'"
+	    lappend idnotes($id) $name
+	    set obj {}
+	    set type {}
+	    set tag {}
+	    catch {
+		set commit [exec git rev-parse "$id^0"]
+		if {$commit != $id} {
+		    lappend idnotes($commit) $id
+		}
+	    }
 	} elseif { $type == "heads" } {
 	    set headids($name) $id
 	    lappend idheads($id) $name
@@ -3864,7 +3876,7 @@ proc selectline {l isnew} {
     global displayorder linehtag linentag linedtag
     global canvy0 linespc parentlist childlist
     global currentid sha1entry
-    global commentend idtags linknum
+    global commentend idtags idnotes linknum
     global mergemax numcommits pending_select
     global cmitmode desc_tags anc_tags showneartags allcommits desc_heads
 
@@ -4009,6 +4021,26 @@ proc selectline {l isnew} {
     $ctext insert end "\n"
     appendwithlinks [lindex $info 5] {comment}
 
+    if {[info exists idnotes($id)]} {
+	$ctext insert end "\nNotes:\n"
+	set notes [exec git note -l "$id"]
+	# strip first line.
+	set firstLineEnd [string first "\n" $notes]
+	if {$firstLineEnd < 0} {
+	    # should never happen...
+	    set hdrend 0
+	}
+	set newnotes [string range $notes [expr {$firstLineEnd + 1}] end]
+	# Indent everything by 4 spaces
+	set notes {}
+	foreach line [split $newnotes "\n"] {
+	    append notes "    $line\n"
+	}
+	# Append to $ctext with auto-highlighting of SHA1 IDs.
+	appendwithlinks $notes {comment}
+	$ctext insert end "\n"
+    }
+
     $ctext tag delete Comments
     $ctext tag remove found 1.0 end
     $ctext conf -state disabled
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 14/15] git-note: (Tests) Add tests for git-note and associated functionality
From: Johan Herland @ 2007-05-27 14:16 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

This test script add tests for:
- git-note (including -l and -d options)
- State of note/tag objects
- git-show-ref --notes
- git-for-each-ref refs/notes
- git-{log,show,whatchanged} --decorate

Signed-off-by: Johan Herland <johan@herland.net>
---
 t/t3850-note.sh |  303 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 303 insertions(+), 0 deletions(-)
 create mode 100755 t/t3850-note.sh

diff --git a/t/t3850-note.sh b/t/t3850-note.sh
new file mode 100755
index 0000000..f737f7c
--- /dev/null
+++ b/t/t3850-note.sh
@@ -0,0 +1,303 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Johan Herland
+#
+
+test_description='Test of git-note'
+
+. ./test-lib.sh
+
+
+# Prepare repo and create some notes
+
+test_expect_success 'Preparing for test' '
+	echo "foo" > foo &&
+	git-add foo &&
+	test_tick &&
+	git-commit -m "Initial commit" &&
+	echo "bar" >> foo
+	test_tick &&
+	git-commit -m "Second commit" foo
+'
+test_expect_success 'Testing git-note -m' '
+	test_tick &&
+	git-note -m "spam"
+'
+test_expect_success 'Testing git-note -F' '
+	echo "spam spam" > note.msg &&
+	test_tick &&
+	git-note -F note.msg
+'
+test_expect_success 'Testing git-note <commit>' '
+	test_tick &&
+	git-note -m "spam spam spam" 301711b66fe71164f646b798706a2c1f7024da8d
+'
+
+# At this point we should have:
+# - commit @ 301711b66fe71164f646b798706a2c1f7024da8d ("Initial commit")
+#   - note @ 93bbbc95a42852552494327537263d475aac1789 ("spam spam spam")
+# - commit @ 9671cbee7ad26528645b2665c8f74d39a6288864 ("Second commit")
+#   - note @ 1245491fece5910086bc1870a4a746256f8a7ecf ("spam")
+#   - note @ 466f861dde008d3905d320225eebef727665a3f0 ("spam spam")
+
+# Verify note objects
+
+test_expect_success 'Testing git-cat-file tag <note>' '
+	cat > note.expect << EOF &&
+object 9671cbee7ad26528645b2665c8f74d39a6288864
+type commit
+tag note-14669883eb004f12636307269f537d59eb143125
+tagger C O Mitter <committer@example.com> 1112912113 -0700
+
+spam
+EOF
+	git-cat-file tag 1245491fece5910086bc1870a4a746256f8a7ecf > note.output &&
+	cmp note.expect note.output &&
+	cat > note.expect << EOF &&
+object 9671cbee7ad26528645b2665c8f74d39a6288864
+type commit
+tag note-ad2099b641be660c4e616bf0b46dcaca391764af
+tagger C O Mitter <committer@example.com> 1112912173 -0700
+
+spam spam
+EOF
+	git-cat-file tag 466f861dde008d3905d320225eebef727665a3f0 > note.output &&
+	cmp note.expect note.output &&
+	cat > note.expect << EOF &&
+object 301711b66fe71164f646b798706a2c1f7024da8d
+type commit
+tag note-c1afd1d9a4e2df7efbb29ff88e50e866e88eb108
+tagger C O Mitter <committer@example.com> 1112912233 -0700
+
+spam spam spam
+EOF
+	git-cat-file tag 93bbbc95a42852552494327537263d475aac1789 > note.output &&
+	cmp note.expect note.output
+'
+
+# Verify output from git-note -l
+
+test_expect_success 'Testing git-note -l' '
+	cat > note.expect << EOF &&
+=== Notes on commit 9671cbe (Second commit) by A U Thor <author@example.com> on Thu, 7 Apr 2005 15:14:13 -0700
+
+--- by C O Mitter <committer@example.com> Thu Apr 7 15:15:13 2005 -0700
+spam
+
+--- by C O Mitter <committer@example.com> Thu Apr 7 15:16:13 2005 -0700
+spam spam
+
+=== Notes on commit 301711b (Initial commit) by A U Thor <author@example.com> on Thu, 7 Apr 2005 15:13:13 -0700
+
+--- by C O Mitter <committer@example.com> Thu Apr 7 15:17:13 2005 -0700
+spam spam spam
+EOF
+	git-note -l > note.output &&
+	cmp note.expect note.output
+'
+test_expect_success 'Testing git-note -l <commit>' '
+	cat > note.expect << EOF &&
+=== Notes on commit 9671cbe (Second commit) by A U Thor <author@example.com> on Thu, 7 Apr 2005 15:14:13 -0700
+
+--- by C O Mitter <committer@example.com> Thu Apr 7 15:15:13 2005 -0700
+spam
+
+--- by C O Mitter <committer@example.com> Thu Apr 7 15:16:13 2005 -0700
+spam spam
+EOF
+	git-note -l 9671cbee7ad26528645b2665c8f74d39a6288864 > note.output &&
+	cmp note.expect note.output &&
+	cat > note.expect << EOF &&
+=== Notes on commit 301711b (Initial commit) by A U Thor <author@example.com> on Thu, 7 Apr 2005 15:13:13 -0700
+
+--- by C O Mitter <committer@example.com> Thu Apr 7 15:17:13 2005 -0700
+spam spam spam
+EOF
+	git-note -l 301711b66fe71164f646b798706a2c1f7024da8d > note.output &&
+	cmp note.expect note.output
+'
+test_expect_success 'Testing git-note -l <note> <note> <note>' '
+	cat > note.expect << EOF &&
+
+=== Note 93bbbc95a42852552494327537263d475aac1789
+
+--- by C O Mitter <committer@example.com> Thu Apr 7 15:17:13 2005 -0700
+spam spam spam
+
+=== Note 466f861dde008d3905d320225eebef727665a3f0
+
+--- by C O Mitter <committer@example.com> Thu Apr 7 15:16:13 2005 -0700
+spam spam
+
+=== Note 1245491fece5910086bc1870a4a746256f8a7ecf
+
+--- by C O Mitter <committer@example.com> Thu Apr 7 15:15:13 2005 -0700
+spam
+EOF
+	git-note -l 93bbbc95a42852552494327537263d475aac1789 \
+	            466f861dde008d3905d320225eebef727665a3f0 \
+	            1245491fece5910086bc1870a4a746256f8a7ecf > note.output &&
+	cmp note.expect note.output
+'
+
+# Verify that notes show up in git-show-ref and git-for-each-ref
+
+test_expect_success 'Testing git-show-ref with notes' '
+	cat > note.expect << EOF &&
+9671cbee7ad26528645b2665c8f74d39a6288864 refs/heads/master
+93bbbc95a42852552494327537263d475aac1789 refs/notes/301711b66fe71164f646b798706a2c1f7024da8d/93bbbc95a42852552494327537263d475aac1789
+1245491fece5910086bc1870a4a746256f8a7ecf refs/notes/9671cbee7ad26528645b2665c8f74d39a6288864/1245491fece5910086bc1870a4a746256f8a7ecf
+466f861dde008d3905d320225eebef727665a3f0 refs/notes/9671cbee7ad26528645b2665c8f74d39a6288864/466f861dde008d3905d320225eebef727665a3f0
+EOF
+	git-show-ref > note.output &&
+	cmp note.expect note.output
+'
+test_expect_success 'Testing git-show-ref --notes' '
+	cat > note.expect << EOF &&
+93bbbc95a42852552494327537263d475aac1789 refs/notes/301711b66fe71164f646b798706a2c1f7024da8d/93bbbc95a42852552494327537263d475aac1789
+1245491fece5910086bc1870a4a746256f8a7ecf refs/notes/9671cbee7ad26528645b2665c8f74d39a6288864/1245491fece5910086bc1870a4a746256f8a7ecf
+466f861dde008d3905d320225eebef727665a3f0 refs/notes/9671cbee7ad26528645b2665c8f74d39a6288864/466f861dde008d3905d320225eebef727665a3f0
+EOF
+	git-show-ref --notes > note.output &&
+	cmp note.expect note.output
+'
+test_expect_success 'Testing git-for-each-ref refs/notes' '
+	cat > note.expect << EOF &&
+93bbbc95a42852552494327537263d475aac1789 tag	refs/notes/301711b66fe71164f646b798706a2c1f7024da8d/93bbbc95a42852552494327537263d475aac1789
+1245491fece5910086bc1870a4a746256f8a7ecf tag	refs/notes/9671cbee7ad26528645b2665c8f74d39a6288864/1245491fece5910086bc1870a4a746256f8a7ecf
+466f861dde008d3905d320225eebef727665a3f0 tag	refs/notes/9671cbee7ad26528645b2665c8f74d39a6288864/466f861dde008d3905d320225eebef727665a3f0
+EOF
+	git-for-each-ref refs/notes > note.output &&
+	cmp note.expect note.output
+'
+
+# Verify output from git-log/git-show/git-whatchanged --decorate
+
+test_expect_success 'Testing git-log --decorate' '
+	cat > note.expect << EOF &&
+commit 9671cbee7ad26528645b2665c8f74d39a6288864 (refs/heads/master)
+Author: A U Thor <author@example.com>
+Date:   Thu Apr 7 15:14:13 2005 -0700
+
+    Second commit
+
+Notes:
+
+    --- by C O Mitter <committer@example.com> Thu Apr 7 15:15:13 2005 -0700
+    spam
+
+    --- by C O Mitter <committer@example.com> Thu Apr 7 15:16:13 2005 -0700
+    spam spam
+
+commit 301711b66fe71164f646b798706a2c1f7024da8d
+Author: A U Thor <author@example.com>
+Date:   Thu Apr 7 15:13:13 2005 -0700
+
+    Initial commit
+
+Notes:
+
+    --- by C O Mitter <committer@example.com> Thu Apr 7 15:17:13 2005 -0700
+    spam spam spam
+EOF
+	git-log --decorate > note.output &&
+	cmp note.expect note.output
+'
+test_expect_success 'Testing git-show --decorate' '
+	cat > note.expect << EOF &&
+commit 9671cbee7ad26528645b2665c8f74d39a6288864 (refs/heads/master)
+Author: A U Thor <author@example.com>
+Date:   Thu Apr 7 15:14:13 2005 -0700
+
+    Second commit
+
+Notes:
+
+    --- by C O Mitter <committer@example.com> Thu Apr 7 15:15:13 2005 -0700
+    spam
+
+    --- by C O Mitter <committer@example.com> Thu Apr 7 15:16:13 2005 -0700
+    spam spam
+
+diff --git a/foo b/foo
+index 257cc56..3bd1f0e 100644
+--- a/foo
++++ b/foo
+@@ -1 +1,2 @@
+ foo
++bar
+EOF
+	git-show --decorate > note.output &&
+	cmp note.expect note.output
+'
+test_expect_success 'Testing git-whatchanged --decorate' '
+	cat > note.expect << EOF &&
+commit 9671cbee7ad26528645b2665c8f74d39a6288864 (refs/heads/master)
+Author: A U Thor <author@example.com>
+Date:   Thu Apr 7 15:14:13 2005 -0700
+
+    Second commit
+
+Notes:
+
+    --- by C O Mitter <committer@example.com> Thu Apr 7 15:15:13 2005 -0700
+    spam
+
+    --- by C O Mitter <committer@example.com> Thu Apr 7 15:16:13 2005 -0700
+    spam spam
+
+:100644 100644 257cc56... 3bd1f0e... M	foo
+
+commit 301711b66fe71164f646b798706a2c1f7024da8d
+Author: A U Thor <author@example.com>
+Date:   Thu Apr 7 15:13:13 2005 -0700
+
+    Initial commit
+
+Notes:
+
+    --- by C O Mitter <committer@example.com> Thu Apr 7 15:17:13 2005 -0700
+    spam spam spam
+
+:000000 100644 0000000... 257cc56... A	foo
+EOF
+	git-whatchanged --decorate > note.output &&
+	cmp note.expect note.output
+'
+
+# Verify successful removal of notes
+
+test_expect_success 'Testing git-note -d <note>' '
+	cat > note.expect << EOF &&
+Deleting note 93bbbc95a42852552494327537263d475aac1789
+EOF
+	git-note -d 93bbbc95a42852552494327537263d475aac1789 > note.output &&
+	cmp note.expect note.output
+'
+test_expect_success 'Verify repo state after git-note -d <note>' '
+	cat > note.expect << EOF &&
+1245491fece5910086bc1870a4a746256f8a7ecf refs/notes/9671cbee7ad26528645b2665c8f74d39a6288864/1245491fece5910086bc1870a4a746256f8a7ecf
+466f861dde008d3905d320225eebef727665a3f0 refs/notes/9671cbee7ad26528645b2665c8f74d39a6288864/466f861dde008d3905d320225eebef727665a3f0
+EOF
+	git-show-ref --notes > note.output &&
+	cmp note.expect note.output
+'
+test_expect_success 'Testing git-note -d <commit>' '
+	cat > note.expect << EOF &&
+Deleting note 1245491fece5910086bc1870a4a746256f8a7ecf associated with commit 9671cbee7ad26528645b2665c8f74d39a6288864
+Deleting note 466f861dde008d3905d320225eebef727665a3f0 associated with commit 9671cbee7ad26528645b2665c8f74d39a6288864
+EOF
+	git-note -d 9671cbee7ad26528645b2665c8f74d39a6288864 > note.output &&
+	cmp note.expect note.output
+'
+test_expect_success 'Verify repo state after git-note -d <commit>' '
+	cat > note.expect << EOF &&
+EOF
+	git-show-ref --notes > note.output
+	test "$?" == "1" &&
+	cmp note.expect note.output
+'
+
+# Testing of clone/fetch/push?
+
+test_done
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 13/15] git-note: (Documentation) Explain the new --notes option to git-push
From: Johan Herland @ 2007-05-27 14:16 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

Signed-off-by: Johan Herland <johan@herland.net>
---
 Documentation/git-push.txt |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index e9ad106..2e98844 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -9,7 +9,7 @@ git-push - Update remote refs along with associated objects
 SYNOPSIS
 --------
 [verse]
-'git-push' [--all] [--tags] [--receive-pack=<git-receive-pack>]
+'git-push' [--all] [--tags] [--notes] [--receive-pack=<git-receive-pack>]
            [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]
 
 DESCRIPTION
@@ -69,6 +69,11 @@ the remote repository.
 	addition to refspecs explicitly listed on the command
 	line.
 
+\--notes::
+	All refs under `$GIT_DIR/refs/notes` are pushed, in
+	addition to refspecs explicitly listed on the command
+	line.
+
 \--receive-pack=<git-receive-pack>::
 	Path to the 'git-receive-pack' program on the remote
 	end.  Sometimes useful when pushing to a remote
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 12/15] git-note: (Transfer) Teach git-push to push notes when --all or --notes is given
From: Johan Herland @ 2007-05-27 14:15 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

As with tags, git-push will not push notes by default. However, if --all
or --notes (new) is given, git-push will now push notes (similary to tags,
if --all or --tags is given).

Signed-off-by: Johan Herland <johan@herland.net>
---
 builtin-push.c |   20 ++++++++++++--------
 1 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/builtin-push.c b/builtin-push.c
index cb78401..e3d6a21 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -8,9 +8,9 @@
 
 #define MAX_URI (16)
 
-static const char push_usage[] = "git-push [--all] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
+static const char push_usage[] = "git-push [--all] [--tags] [--notes] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
 
-static int all, tags, force, thin = 1, verbose;
+static int all, tags, notes, force, thin = 1, verbose;
 static const char *receivepack;
 
 #define BUF_SIZE (2084)
@@ -32,7 +32,8 @@ static int expand_one_ref(const char *ref, const unsigned char *sha1, int flag,
 	/* Ignore the "refs/" at the beginning of the refname */
 	ref += 5;
 
-	if (!prefixcmp(ref, "tags/"))
+	if ((tags  && !prefixcmp(ref, "tags/")) ||
+	    (notes && !prefixcmp(ref, "notes/")))
 		add_refspec(xstrdup(ref));
 	return 0;
 }
@@ -49,9 +50,8 @@ static void expand_refspecs(void)
 		 */
 		return;
 	}
-	if (!tags)
-		return;
-	for_each_ref(expand_one_ref, NULL);
+	if (tags || notes)
+		for_each_ref(expand_one_ref, NULL);
 }
 
 struct wildcard_cb {
@@ -141,7 +141,7 @@ static int get_remotes_uri(const char *repo, const char *uri[MAX_URI])
 {
 	int n = 0;
 	FILE *f = fopen(git_path("remotes/%s", repo), "r");
-	int has_explicit_refspec = refspec_nr || all || tags;
+	int has_explicit_refspec = refspec_nr || all || tags || notes;
 
 	if (!f)
 		return -1;
@@ -227,7 +227,7 @@ static int get_config_remotes_uri(const char *repo, const char *uri[MAX_URI])
 	config_repo = repo;
 	config_current_uri = 0;
 	config_uri = uri;
-	config_get_refspecs = !(refspec_nr || all || tags);
+	config_get_refspecs = !(refspec_nr || all || tags || notes);
 	config_get_receivepack = (receivepack == NULL);
 
 	git_config(get_remote_config);
@@ -388,6 +388,10 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 			tags = 1;
 			continue;
 		}
+		if (!strcmp(arg, "--notes")) {
+			notes = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--force") || !strcmp(arg, "-f")) {
 			force = 1;
 			continue;
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 11/15] git-note: (Transfer) Teach git-fetch to auto-follow notes
From: Johan Herland @ 2007-05-27 14:15 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

This causes git-fetch to auto-follow notes in the same fashion that tags
are auto-followed by default.

Pretty much all the code in this patch is about doing the same thing for
notes as what is already done for tags.

Signed-off-by: Johan Herland <johan@herland.net>
---
 builtin-fetch--tool.c |   11 +++++++++++
 git-fetch.sh          |   27 +++++++++++++++++++++++++++
 git-parse-remote.sh   |    4 ++--
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c
index ed4d5de..71ddc6d 100644
--- a/builtin-fetch--tool.c
+++ b/builtin-fetch--tool.c
@@ -82,6 +82,8 @@ static int update_local_ref(const char *name,
 		/* new ref */
 		if (!strncmp(name, "refs/tags/", 10))
 			msg = "storing tag";
+		else if (!strncmp(name, "refs/notes/", 11))
+			msg = "storing note";
 		else
 			msg = "storing head";
 		fprintf(stderr, "* %s: storing %s\n",
@@ -103,6 +105,11 @@ static int update_local_ref(const char *name,
 		show_new(type, sha1_new);
 		return update_ref("updating tag", name, sha1_new, NULL);
 	}
+	else if (!strncmp(name, "refs/notes/", 11)) {
+		fprintf(stderr, "* %s: updating with %s\n", name, note);
+		show_new(type, sha1_new);
+		return update_ref("updating note", name, sha1_new, NULL);
+	}
 
 	current = lookup_commit_reference(sha1_old);
 	updated = lookup_commit_reference(sha1_new);
@@ -163,6 +170,10 @@ static int append_fetch_head(FILE *fp,
 		kind = "tag";
 		what = remote_name + 10;
 	}
+	else if (!strncmp(remote_name, "refs/notes/", 11)) {
+		kind = "note";
+		what = remote_name + 11;
+	}
 	else if (!strncmp(remote_name, "refs/remotes/", 13)) {
 		kind = "remote branch";
 		what = remote_name + 13;
diff --git a/git-fetch.sh b/git-fetch.sh
index 0e05cf1..a2a7874 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -353,6 +353,33 @@ case "$no_tags$tags" in
 	esac
 esac
 
+# automated note following
+case "" in # --notes and --no-notes options?
+'')
+	case "$reflist" in
+	*:refs/*)
+		# effective only when we are following remote branch
+		# using local tracking branch.
+		notelist=$(IFS='	' &&
+		echo "$ls_remote_result" |
+		git-show-ref --exclude-existing=refs/notes/ |
+		while read sha1 name
+		do
+			git-cat-file -t "$sha1" >/dev/null 2>&1 || continue
+			echo >&2 "Auto-following $name"
+			echo ".${name}:${name}"
+		done)
+	esac
+	case "$notelist" in
+	'') ;;
+	?*)
+		# do not deepen a shallow tree when following notes
+		shallow_depth=
+		fetch_main "$notelist" || exit ;;
+	esac
+esac
+
+
 # If the original head was empty (i.e. no "master" yet), or
 # if we were told not to worry, we do not have to check.
 case "$orig_head" in
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 0506b12..95dcc10 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -144,13 +144,13 @@ canon_refs_list_for_fetch () {
 		case "$remote" in
 		'' | HEAD ) remote=HEAD ;;
 		refs/*) ;;
-		heads/* | tags/* | remotes/* ) remote="refs/$remote" ;;
+		heads/* | tags/* | notes/* | remotes/* ) remote="refs/$remote" ;;
 		*) remote="refs/heads/$remote" ;;
 		esac
 		case "$local" in
 		'') local= ;;
 		refs/*) ;;
-		heads/* | tags/* | remotes/* ) local="refs/$local" ;;
+		heads/* | tags/* | notes/* | remotes/* ) local="refs/$local" ;;
 		*) local="refs/heads/$local" ;;
 		esac
 
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 10/15] git-note: (Transfer) Teach git-clone how to clone notes
From: Johan Herland @ 2007-05-27 14:15 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

This patch causes git notes to be cloned in the same way that tags are
cloned.

Signed-off-by: Johan Herland <johan@herland.net>
---
 git-clone.sh |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/git-clone.sh b/git-clone.sh
index fdd354f..6bb2fd5 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -57,7 +57,7 @@ Perhaps git-update-server-info needs to be run there?"
 		*^*)	continue;;
 		esac
 		case "$bare,$name" in
-		yes,* | ,heads/* | ,tags/*) ;;
+		yes,* | ,heads/* | ,tags/* | ,notes/*) ;;
 		*)	continue ;;
 		esac
 		if test -n "$use_separate_remote" &&
@@ -320,6 +320,7 @@ then
 		branch_top="heads"
 	fi
 	tag_top="tags"
+	note_top="notes"
 	while read sha1 name
 	do
 		case "$name" in
@@ -331,6 +332,8 @@ then
 			destname="refs/$branch_top/${name#refs/heads/}" ;;
 		refs/tags/*)
 			destname="refs/$tag_top/${name#refs/tags/}" ;;
+		refs/notes/*)
+			destname="refs/$note_top/${name#refs/notes/}" ;;
 		*)
 			continue ;;
 		esac
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 09/15] git-note: (Documentation) Explain new behaviour of --decorate in git-{log,show,whatchanged}
From: Johan Herland @ 2007-05-27 14:14 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

The addition of git notes to --decorate output is noted on the git-log
manual page. In addition, the --decorate documentation is copied to the
git-show and git-whatchanged manual pages, where any mention of --decorate
have been missing until now.

Signed-off-by: Johan Herland <johan@herland.net>
---
 Documentation/git-log.txt         |    3 ++-
 Documentation/git-show.txt        |    4 ++++
 Documentation/git-whatchanged.txt |    4 ++++
 3 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt
index 0f353f6..1168372 100644
--- a/Documentation/git-log.txt
+++ b/Documentation/git-log.txt
@@ -52,7 +52,8 @@ include::pretty-options.txt[]
 	See also gitlink:git-reflog[1].
 
 --decorate::
-    Print out the ref names of any commits that are shown.
+	Print out the ref names and notes associated with any commits that are
+	shown.
 
 <paths>...::
 	Show only commits that affect the specified paths.
diff --git a/Documentation/git-show.txt b/Documentation/git-show.txt
index 34c5caf..a31ba6b 100644
--- a/Documentation/git-show.txt
+++ b/Documentation/git-show.txt
@@ -38,6 +38,10 @@ OPTIONS
 	For a more complete list of ways to spell object names, see
 	"SPECIFYING REVISIONS" section in gitlink:git-rev-parse[1].
 
+--decorate::
+	Print out the ref names and notes associated with any commits that are
+	shown.
+
 include::pretty-options.txt[]
 
 
diff --git a/Documentation/git-whatchanged.txt b/Documentation/git-whatchanged.txt
index 399bff3..3f77b3d 100644
--- a/Documentation/git-whatchanged.txt
+++ b/Documentation/git-whatchanged.txt
@@ -43,6 +43,10 @@ OPTIONS
 	<format> can be one of 'raw', 'medium', 'short', 'full',
 	and 'oneline'.
 
+--decorate::
+	Print out the ref names and notes associated with any commits that are
+	shown.
+
 -m::
 	By default, differences for merge commits are not shown.
 	With this flag, show differences to that commit from all
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 08/15] git-note: (Decorations) Add note decorations to "git-{log,show,whatchanged} --decorate"
From: Johan Herland @ 2007-05-27 14:14 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

Introduce the concept of note decorations (supplementing the existing
name decorations), and teach the code handling the --decorate option
how to display note decorations.

The result is that notes are displayed below the commit message for
these commands:
- git-log --decorate
- git-show --decorate
- git-whatchanged --decorate

Signed-off-by: Johan Herland <johan@herland.net>
---
 builtin-log.c |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 commit.h      |    7 ++++
 log-tree.c    |   67 +++++++++++++++++++++++++++++++++--
 3 files changed, 178 insertions(+), 4 deletions(-)

diff --git a/builtin-log.c b/builtin-log.c
index 3744712..ee10f2a 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -20,6 +20,108 @@ static int default_show_root = 1;
 /* this is in builtin-diff.c */
 void add_head(struct rev_info *revs);
 
+static int get_note_decoration_data(const char *data, unsigned long data_len, const char **author, unsigned long *author_len, const char **date, unsigned long *date_len, const char **msg, unsigned long *msg_len)
+{
+	/*
+	 * Set author, date and msg pointers to their appropriate positions
+	 * within the given data buffer (tag object data). Also set the
+	 * appropriate lengths, respectively.
+	 */
+	const char *p, *q, *end = data + data_len;
+	if (!data || !data_len)
+		return 1;
+	p = data;
+	end = data + data_len;
+	do {
+		if (end - p >= 7 && !memcmp("tagger ", p, 7)) {
+			*author = p + 7;
+			if ((q = memchr(*author, '>', end - *author))) {
+				*author_len = ++q - *author;
+				*date = ++q;
+				q = memchr(*date, '\n', end - *date);
+				*date_len = q ? q - *date : 0;
+			}
+			else if ((q = memchr(*author, '\n', end - *author)))
+				*author_len = q - *author;
+			else
+				*author_len = 0;
+		}
+		else if (end - p >= 1 && !memcmp("\n", p, 1)) {
+			*msg = ++p;
+			*msg_len = end - *msg;
+			break;
+		}
+		p = memchr(p, '\n', end - p);
+	} while (p++);
+	return 0;
+}
+
+static int add_note_decoration(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
+{
+	struct object *obj;
+	struct tag *note;
+	struct note_decoration *res;
+	enum object_type data_type;
+	char *data;
+	const char   *author = "",   *date = "",   *msg = "";
+	unsigned long author_len = 0, date_len = 0, msg_len = 0;
+	unsigned long note_len, data_len;
+	unsigned long time = 0;
+
+	/* Get object pointed to by note */
+	obj = parse_object(sha1);
+	if (!obj)
+		return 0;
+	if (obj->type != OBJ_TAG)
+		return 0;
+
+	note = (struct tag *)obj;
+	obj = note->tagged;
+	if (!obj)
+		return 0;
+
+	/* Generate note decoration from note data */
+	data = read_sha1_file(note->object.sha1, &data_type, &data_len);
+	if (!data || !data_len)
+		return 0;
+	if (data_type != OBJ_TAG) {
+		free(data);
+		return 0; /* should not happen */
+	}
+
+	if (get_note_decoration_data(data,  data_len,
+			&author, &author_len, &date, &date_len, &msg, &msg_len))
+	{
+		free(data);
+		return 0; /* should not happen */
+	}
+	if (date && *date && date_len) { /* Found date; prettify it */
+		char *tz_p, *end;
+		int tz;
+		time = strtoul(date, &tz_p, 10);
+		tz = strtol(tz_p, &end, 10);
+		if (end - date > date_len) {
+			free(data);
+			return 0; /* overflowed; should not happen */
+		}
+		date = show_date(time, tz, DATE_NORMAL);
+		date_len = strlen(date);
+	}
+	note_len = 10 + author_len + date_len + msg_len;
+	res = xmalloc(sizeof(struct note_decoration) + note_len);
+	snprintf(res->note, note_len + 1, "\n--- by %.*s %.*s\n%.*s",
+			(int) author_len, author,
+			(int)   date_len,   date,
+			(int)    msg_len,    msg);
+	res->sort_hint = time;
+
+	/* Add note decoration to object that note points to */
+	res->next = add_decoration(&note_decoration, obj, res);
+
+	free(data);
+	return 0;
+}
+
 static void add_name_decoration(const char *prefix, const char *name, struct object *obj)
 {
 	int plen = strlen(prefix);
@@ -35,6 +137,8 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in
 	struct object *obj = parse_object(sha1);
 	if (!obj)
 		return 0;
+	if (!prefixcmp(refname, "refs/notes/"))
+		return 0; /* notes shouldn't show up here */
 	add_name_decoration("", refname, obj);
 	while (obj->type == OBJ_TAG) {
 		obj = ((struct tag *)obj)->tagged;
@@ -67,8 +171,10 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
 			else
 				git_log_output_encoding = "";
 		} else if (!strcmp(arg, "--decorate")) {
-			if (!decorate)
+			if (!decorate) {
 				for_each_ref(add_ref_decoration, NULL);
+				for_each_note_ref(add_note_decoration, NULL);
+			}
 			decorate = 1;
 		} else
 			die("unrecognized argument: %s", arg);
diff --git a/commit.h b/commit.h
index 86e8dca..93cac79 100644
--- a/commit.h
+++ b/commit.h
@@ -28,6 +28,13 @@ struct name_decoration {
 	struct name_decoration *next;
 	char name[1];
 };
+/* While we can decorate any object with a note, it's only used for commits.. */
+extern struct decoration note_decoration;
+struct note_decoration {
+	struct note_decoration *next;
+	unsigned long sort_hint;
+	char note[1];
+};
 
 struct commit *lookup_commit(const unsigned char *sha1);
 struct commit *lookup_commit_reference(const unsigned char *sha1);
diff --git a/log-tree.c b/log-tree.c
index 4bef909..dccaca2 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -5,6 +5,7 @@
 #include "reflog-walk.h"
 
 struct decoration name_decoration = { "object names" };
+struct decoration note_decoration = { "object notes" };
 
 static void show_parents(struct commit *commit, int abbrev)
 {
@@ -15,7 +16,7 @@ static void show_parents(struct commit *commit, int abbrev)
 	}
 }
 
-static void show_decorations(struct commit *commit)
+static void show_name_decorations(struct commit *commit)
 {
 	const char *prefix;
 	struct name_decoration *decoration;
@@ -32,6 +33,65 @@ static void show_decorations(struct commit *commit)
 	putchar(')');
 }
 
+static int compare_note_decorations(const void *a, const void *b)
+{
+	const struct note_decoration *na = *((const struct note_decoration **) a);
+	const struct note_decoration *nb = *((const struct note_decoration **) b);
+	if (na->sort_hint < nb->sort_hint)
+		return -1;
+	else if (na->sort_hint == nb->sort_hint)
+		return 0;
+	return 1;
+}
+
+static void show_note_decorations(struct commit *commit)
+{
+	struct note_decoration *decoration;
+	struct note_decoration **decoArray;
+	unsigned int numDecorations = 0, i;
+
+	decoration = lookup_decoration(&note_decoration, &commit->object);
+	if (!decoration)
+		return;
+
+	/* Sort notes */
+	while (decoration) {
+		++numDecorations;
+		decoration = decoration->next;
+	}
+	decoration = lookup_decoration(&note_decoration, &commit->object);
+	decoArray = xmalloc(sizeof(struct note_decoration *) * numDecorations);
+	i = 0;
+	while (decoration) {
+		decoArray[i++] = decoration;
+		decoration = decoration->next;
+	}
+	qsort(decoArray, numDecorations, sizeof(struct note_decoration *), compare_note_decorations);
+
+	/* Print notes */
+	puts("\nNotes:");
+	for (i = 0; i < numDecorations; ++i) {
+		const char *p, *q;
+		decoration = decoArray[i];
+		p = decoration->note;
+		while (1) {
+			/* print everything indented by 4 spaces */
+			q = strchr(p, '\n');
+			if (!q)
+				q = p + strlen(p);
+			if (q - p)
+				printf("    %.*s\n", q - p, p);
+			else
+				printf("\n");
+			if (!*q || !*(q + 1))
+				break;
+			p = q + 1;
+		}
+	}
+
+	free(decoArray);
+}
+
 /*
  * Search for "^[-A-Za-z]+: [^@]+@" pattern. It usually matches
  * Signed-off-by: and Acked-by: lines.
@@ -155,7 +215,7 @@ void show_log(struct rev_info *opt, const char *sep)
 		fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
 		if (opt->parents)
 			show_parents(commit, abbrev_commit);
-		show_decorations(commit);
+		show_name_decorations(commit);
 		putchar(opt->diffopt.line_termination);
 		return;
 	}
@@ -260,7 +320,7 @@ void show_log(struct rev_info *opt, const char *sep)
 			printf(" (from %s)",
 			       diff_unique_abbrev(parent->object.sha1,
 						  abbrev_commit));
-		show_decorations(commit);
+		show_name_decorations(commit);
 		printf("%s",
 		       diff_get_color(opt->diffopt.color_diff, DIFF_RESET));
 		putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n');
@@ -286,6 +346,7 @@ void show_log(struct rev_info *opt, const char *sep)
 		len = append_signoff(this_header, sizeof(this_header), len,
 				     opt->add_signoff);
 	printf("%s%s%s", this_header, extra, sep);
+	show_note_decorations(commit);
 }
 
 int log_tree_diff_flush(struct rev_info *opt)
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 07/15] git-note: (Almost plumbing) Add support for git notes to git-pack-refs and git-fsck
From: Johan Herland @ 2007-05-27 14:13 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

Teach git-pack-refs to pack note refs in the same way that regular
tag refs are packed. Also, make sure to clean up empty subdirs in
refs/notes after packing note refs.

Teach git-fsck some extra checking of note refs.

Signed-off-by: Johan Herland <johan@herland.net>
---
 builtin-fsck.c      |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++
 builtin-pack-refs.c |    5 +++-
 2 files changed, 65 insertions(+), 1 deletions(-)

diff --git a/builtin-fsck.c b/builtin-fsck.c
index cbbcaf0..edbb976 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -522,9 +522,70 @@ static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int f
 	return 0;
 }
 
+static int fsck_handle_note_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
+{
+	/*
+	 * - Verify that refname has format $object/$note
+	 * - Verify that contents of $object/$note == $note
+	 * - Verify that $object/$note references a tag object
+	 * - Verify that the tag object points to $object
+	 * - Verify that $object exists. (already done by fsck_tag())
+	 */
+	 /* Even on error, we still return 0 to keep for_each_ref() going. */
+
+	const char *object_name = refname;
+	const char *note_name = strchr(object_name, '/');
+	size_t object_name_len, note_name_len;
+	unsigned char object_sha1[20], note_sha1[20];
+	struct object *note_obj;
+	struct tag *note;
+
+	if (!note_name) {
+		error("%s: invalid note refname; missing note part", refname);
+		return 0;
+	}
+	object_name_len = note_name - object_name;
+	note_name_len = strlen(++note_name);
+	if (object_name_len != 40 || get_sha1_hex(object_name, object_sha1)) {
+		error("%s: invalid note refname; object part not valid SHA1 sum", refname);
+		return 0;
+	}
+	if (note_name_len != 40 || get_sha1_hex(note_name, note_sha1)) {
+		error("%s: invalid note refname; note part not valid SHA1 sum", refname);
+		return 0;
+	}
+	if (hashcmp(note_sha1, sha1)) {
+		error("%s: invalid note ref; note part not identical to note's SHA1 sum (%s)",
+			refname, sha1_to_hex(sha1));
+		return 0;
+	}
+	note_obj = lookup_object(sha1);
+	if (!note_obj) { /* Couldn't find note object... */
+		if (!has_sha1_file(sha1)) /* ...and it's not hidden in a pack */
+			error("%s: invalid note ref; must point at a valid object",
+				refname);
+		return 0; /* Return even if in a pack. */
+	}
+	if (note_obj->type != OBJ_TAG) {
+		error("%s: invalid note ref; must point at tag object (type == %s)",
+			refname, typename(note_obj->type));
+		return 0;
+	}
+	note = (struct tag *) parse_object(sha1);
+	if (hashcmp(note->tagged->sha1, object_sha1)) {
+		error("%s: invalid note ref; "
+			"object part not identical to tagged object (%s)",
+			refname, sha1_to_hex(note->tagged->sha1));
+		return 0;
+	}
+
+	return 0;
+}
+
 static void get_default_heads(void)
 {
 	for_each_ref(fsck_handle_ref, NULL);
+	for_each_note_ref(fsck_handle_note_ref, NULL);
 	if (include_reflogs)
 		for_each_reflog(fsck_handle_reflog, NULL);
 
diff --git a/builtin-pack-refs.c b/builtin-pack-refs.c
index 1952950..57b9fee 100644
--- a/builtin-pack-refs.c
+++ b/builtin-pack-refs.c
@@ -39,6 +39,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
 	if ((flags & REF_ISSYMREF))
 		return 0;
 	is_tag_ref = !prefixcmp(path, "refs/tags/");
+	is_tag_ref |= !prefixcmp(path, "refs/notes/");
 
 	/* ALWAYS pack refs that were already packed or are tags */
 	if (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref && !(flags & REF_ISPACKED))
@@ -109,8 +110,10 @@ static int pack_refs(unsigned int flags)
 		die("failed to write ref-pack file (%s)", strerror(errno));
 	if (commit_lock_file(&packed) < 0)
 		die("unable to overwrite old ref-pack file (%s)", strerror(errno));
-	if (cbdata.flags & PACK_REFS_PRUNE)
+	if (cbdata.flags & PACK_REFS_PRUNE) {
 		prune_refs(cbdata.ref_to_prune);
+		cleanup_notes_subdirs();
+	}
 	return 0;
 }
 
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 06/15] git-note: (Documentation) Explain the new '--notes' option to git-rev-parse and git-show-ref
From: Johan Herland @ 2007-05-27 14:13 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

Signed-off-by: Johan Herland <johan@herland.net>
---
 Documentation/git-rev-parse.txt |    5 ++++-
 Documentation/git-show-ref.txt  |   14 +++++++-------
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 7757abe..7d36011 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -73,8 +73,11 @@ OPTIONS
 --tags::
 	Show tag refs found in `$GIT_DIR/refs/tags`.
 
+--notes::
+	Show note refs found in `$GIT_DIR/refs/notes`.
+
 --remotes::
-	Show tag refs found in `$GIT_DIR/refs/remotes`.
+	Show refs found in `$GIT_DIR/refs/remotes`.
 
 --show-prefix::
 	When the command is invoked from a subdirectory, show the
diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt
index 2355aa5..7e204f0 100644
--- a/Documentation/git-show-ref.txt
+++ b/Documentation/git-show-ref.txt
@@ -9,7 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'git-show-ref' [-q|--quiet] [--verify] [-h|--head] [-d|--dereference]
-	     [-s|--hash] [--abbrev] [--tags] [--heads] [--] <pattern>...
+	     [-s|--hash] [--abbrev] [--tags] [--heads] [--notes] [--] <pattern>...
 'git-show-ref' --exclude-existing[=pattern]
 
 DESCRIPTION
@@ -33,16 +33,16 @@ OPTIONS
 
 	Show the HEAD reference.
 
---tags, --heads::
+--heads, --tags, --notes::
 
-	Limit to only "refs/heads" and "refs/tags", respectively.  These
-	options are not mutually exclusive; when given both, references stored
-	in "refs/heads" and "refs/tags" are displayed.
+	Limit to only "refs/heads", "refs/tags" and "refs/notes", respectively.
+	These options are not mutually exclusive; when given more than one,
+	references classified as any of them are displayed.
 
 -d, --dereference::
 
-	Dereference tags into object IDs as well. They will be shown with "^{}"
-	appended.
+	Dereference tags and notes into object IDs as well. They will be shown
+	with "^{}" appended.
 
 -s, --hash::
 
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 05/15] git-note: (Plumbing) Add support for git notes to git-rev-parse and git-show-ref
From: Johan Herland @ 2007-05-27 14:12 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

Teach git-rev-parse and git-show-ref to show notes by adding a '--notes'
option. The '--notes' option is analogous to the '--tags' option for the
respective commands.

Signed-off-by: Johan Herland <johan@herland.net>
---
 builtin-rev-parse.c |    5 +++++
 builtin-show-ref.c  |   16 +++++++++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 37addb2..4ab88af 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -43,6 +43,7 @@ static int is_rev_argument(const char *arg)
 		"--max-count=",
 		"--min-age=",
 		"--no-merges",
+		"--notes",
 		"--objects",
 		"--objects-edge",
 		"--parents",
@@ -310,6 +311,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				for_each_tag_ref(show_reference, NULL);
 				continue;
 			}
+			if (!strcmp(arg, "--notes")) {
+				for_each_note_ref(show_reference, NULL);
+				continue;
+			}
 			if (!strcmp(arg, "--remotes")) {
 				for_each_remote_ref(show_reference, NULL);
 				continue;
diff --git a/builtin-show-ref.c b/builtin-show-ref.c
index 9463ff0..8a7d0e7 100644
--- a/builtin-show-ref.c
+++ b/builtin-show-ref.c
@@ -4,10 +4,11 @@
 #include "tag.h"
 #include "path-list.h"
 
-static const char show_ref_usage[] = "git show-ref [-q|--quiet] [--verify] [-h|--head] [-d|--dereference] [-s|--hash[=<length>]] [--abbrev[=<length>]] [--tags] [--heads] [--] [pattern*] < ref-list";
+static const char show_ref_usage[] = "git show-ref [-q|--quiet] [--verify] [-h|--head] [-d|--dereference] [-s|--hash[=<length>]] [--abbrev[=<length>]] [--tags] [--heads] [--notes] [--] [pattern*] < ref-list";
 
 static int deref_tags = 0, show_head = 0, tags_only = 0, heads_only = 0,
-	found_match = 0, verify = 0, quiet = 0, hash_only = 0, abbrev = 0;
+	notes_only = 0, found_match = 0, verify = 0, quiet = 0, hash_only = 0,
+	abbrev = 0;
 static const char **pattern;
 
 static void show_one(const char *refname, const unsigned char *sha1)
@@ -25,11 +26,12 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo
 	const char *hex;
 	unsigned char peeled[20];
 
-	if (tags_only || heads_only) {
+	if (tags_only || heads_only || notes_only) {
 		int match;
 
-		match = heads_only && !prefixcmp(refname, "refs/heads/");
-		match |= tags_only && !prefixcmp(refname, "refs/tags/");
+		match  = heads_only && !prefixcmp(refname, "refs/heads/");
+		match |= tags_only  && !prefixcmp(refname, "refs/tags/");
+		match |= notes_only && !prefixcmp(refname, "refs/notes/");
 		if (!match)
 			return 0;
 	}
@@ -213,6 +215,10 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix)
 			heads_only = 1;
 			continue;
 		}
+		if (!strcmp(arg, "--notes")) {
+			notes_only = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--exclude-existing"))
 			return exclude_existing(NULL);
 		if (!prefixcmp(arg, "--exclude-existing="))
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 04/15] git-note: (Plumbing) Add plumbing-level support for git notes
From: Johan Herland @ 2007-05-27 14:11 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

This patch declares and implements two functions:

1. for_each_note_ref() - for iterating over note references in refs/notes.
   This is analogous to for_each_tag_ref(), for_each_branch_ref() and
   for_each_remote_ref(), which is already present.

2. cleanup_notes_subdirs() - a convenience function for removing empty
   subdirectories from refs/notes. These subdirectories would otherwise be
   left behind after removing notes, or after packing note refs.

The above functions will be used by subsequent git-note patches.

Signed-off-by: Johan Herland <johan@herland.net>
---
 refs.c |   20 ++++++++++++++++++++
 refs.h |    4 ++++
 2 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/refs.c b/refs.c
index 2ae3235..f0abfcd 100644
--- a/refs.c
+++ b/refs.c
@@ -569,6 +569,11 @@ int for_each_tag_ref(each_ref_fn fn, void *cb_data)
 	return do_for_each_ref("refs/tags/", fn, 10, cb_data);
 }
 
+int for_each_note_ref(each_ref_fn fn, void *cb_data)
+{
+	return do_for_each_ref("refs/notes/", fn, 11, cb_data);
+}
+
 int for_each_branch_ref(each_ref_fn fn, void *cb_data)
 {
 	return do_for_each_ref("refs/heads/", fn, 11, cb_data);
@@ -1433,3 +1438,18 @@ int for_each_reflog(each_ref_fn fn, void *cb_data)
 {
 	return do_for_each_reflog("", fn, cb_data);
 }
+
+void cleanup_notes_subdirs ()
+{
+	DIR *dir = opendir(git_path("refs/notes/"));
+
+	if (dir) {
+		struct dirent *de;
+		while ((de = readdir(dir)) != NULL) {
+			if (de->d_name[0] == '.')
+				continue;
+			rmdir(git_path("refs/notes/%s", de->d_name));
+		}
+		closedir(dir);
+	}
+}
diff --git a/refs.h b/refs.h
index f234eb7..6175bfb 100644
--- a/refs.h
+++ b/refs.h
@@ -21,6 +21,7 @@ typedef int each_ref_fn(const char *refname, const unsigned char *sha1, int flag
 extern int head_ref(each_ref_fn, void *);
 extern int for_each_ref(each_ref_fn, void *);
 extern int for_each_tag_ref(each_ref_fn, void *);
+extern int for_each_note_ref(each_ref_fn, void *);
 extern int for_each_branch_ref(each_ref_fn, void *);
 extern int for_each_remote_ref(each_ref_fn, void *);
 
@@ -64,4 +65,7 @@ extern int rename_ref(const char *oldref, const char *newref, const char *logmsg
 /** resolve ref in nested "gitlink" repository */
 extern int resolve_gitlink_ref(const char *name, const char *refname, unsigned char *result);
 
+/** clean up empty subdirs below "refs/notes/" */
+extern void cleanup_notes_subdirs();
+
 #endif /* REFS_H */
-- 
1.5.2.101.gee49f

^ permalink raw reply related

* [PATCH 03/15] git-note: (Administrivia) Add git-note to Makefile, .gitignore, etc.
From: Johan Herland @ 2007-05-27 14:11 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <200705271608.02122.johan@herland.net>

Teach Makefile, .gitignore, Documentation/cmd-list.perl and
generate-cmdlist.sh on the existence of the git-note command.

The patch also does some unrelated whitespace cleanup in
Documentation/cmd-list.perl and an alphabetizing fix in .gitignore,
just to keep things neat and tidy.

Signed-off-by: Johan Herland <johan@herland.net>
---
 .gitignore                  |    3 ++-
 Documentation/cmd-list.perl |    5 +++--
 Makefile                    |    2 +-
 generate-cmdlist.sh         |    1 +
 4 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/.gitignore b/.gitignore
index 4dc0c39..0f34b94 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,8 +82,9 @@ git-merge-subtree
 git-mergetool
 git-mktag
 git-mktree
-git-name-rev
 git-mv
+git-name-rev
+git-note
 git-pack-redundant
 git-pack-objects
 git-pack-refs
diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl
index 443802a..dc7e8b3 100755
--- a/Documentation/cmd-list.perl
+++ b/Documentation/cmd-list.perl
@@ -103,13 +103,13 @@ git-diff-files                          plumbinginterrogators
 git-diff-index                          plumbinginterrogators
 git-diff                                mainporcelain
 git-diff-tree                           plumbinginterrogators
-git-fast-import				ancillarymanipulators
+git-fast-import                         ancillarymanipulators
 git-fetch                               mainporcelain
 git-fetch-pack                          synchingrepositories
 git-fmt-merge-msg                       purehelpers
 git-for-each-ref                        plumbinginterrogators
 git-format-patch                        mainporcelain
-git-fsck	                        ancillaryinterrogators
+git-fsck                                ancillaryinterrogators
 git-gc                                  mainporcelain
 git-get-tar-commit-id                   ancillaryinterrogators
 git-grep                                mainporcelain
@@ -140,6 +140,7 @@ git-mktag                               plumbingmanipulators
 git-mktree                              plumbingmanipulators
 git-mv                                  mainporcelain
 git-name-rev                            plumbinginterrogators
+git-note                                mainporcelain
 git-pack-objects                        plumbingmanipulators
 git-pack-redundant                      plumbinginterrogators
 git-pack-refs                           ancillarymanipulators
diff --git a/Makefile b/Makefile
index 29243c6..c2f9f22 100644
--- a/Makefile
+++ b/Makefile
@@ -209,7 +209,7 @@ SCRIPT_SH = \
 	git-applymbox.sh git-applypatch.sh git-am.sh \
 	git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
 	git-merge-resolve.sh git-merge-ours.sh \
-	git-lost-found.sh git-quiltimport.sh
+	git-lost-found.sh git-quiltimport.sh git-note.sh
 
 SCRIPT_PERL = \
 	git-add--interactive.perl \
diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh
index 975777f..0a37fd0 100755
--- a/generate-cmdlist.sh
+++ b/generate-cmdlist.sh
@@ -26,6 +26,7 @@ init
 log
 merge
 mv
+note
 prune
 pull
 push
-- 
1.5.2.101.gee49f

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox