Add a script to edit/inspect notes
authorJohannes Schindelin <Johannes.Schindelin@gmx.de>
Fri, 9 Oct 2009 10:21:58 +0000 (12:21 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 20 Oct 2009 01:59:42 +0000 (18:59 -0700)
The script 'git notes' allows you to edit and show commit notes, by
calling either

git notes show <commit>

or

git notes edit <commit>

This patch has been improved by the following contributions:
- Tor Arne Vestbø: fix printing of multi-line notes
- Michael J Gruber: test and handle empty notes gracefully
- Thomas Rast:
  - only clean up message file when editing
  - use GIT_EDITOR and core.editor over VISUAL/EDITOR
  - t3301: fix confusing quoting in test for valid notes ref
  - t3301: use test_must_fail instead of !
  - refuse to edit notes outside refs/notes/
- Junio C Hamano: tests: fix "export var=val"
- Christian Couder: documentation: fix 'linkgit' macro in "git-notes.txt"
- Johan Herland: minor cleanup and bugfixing in git-notes.sh (v2)

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Tor Arne Vestbø <tavestbo@trolltech.com>
Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
.gitignore
Documentation/git-notes.txt [new file with mode: 0644]
Makefile
command-list.txt
git-notes.sh [new file with mode: 0755]
t/t3301-notes.sh [new file with mode: 0755]

index 51a37b1af7ab927b98e2764e755b130080bfc9e3..cbafa64b44905ec61a643b1b1b3dfe3c04ff3e38 100644 (file)
@@ -86,6 +86,7 @@ git-mktag
 git-mktree
 git-name-rev
 git-mv
+git-notes
 git-pack-redundant
 git-pack-objects
 git-pack-refs
diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt
new file mode 100644 (file)
index 0000000..7136016
--- /dev/null
@@ -0,0 +1,46 @@
+git-notes(1)
+============
+
+NAME
+----
+git-notes - Add/inspect commit notes
+
+SYNOPSIS
+--------
+[verse]
+'git-notes' (edit | show) [commit]
+
+DESCRIPTION
+-----------
+This command allows you to add notes to commit messages, without
+changing the commit.  To discern these notes from the message stored
+in the commit object, the notes are indented like the message, after
+an unindented line saying "Notes:".
+
+To disable commit notes, you have to set the config variable
+core.notesRef to the empty string.  Alternatively, you can set it
+to a different ref, something like "refs/notes/bugzilla".  This setting
+can be overridden by the environment variable "GIT_NOTES_REF".
+
+
+SUBCOMMANDS
+-----------
+
+edit::
+       Edit the notes for a given commit (defaults to HEAD).
+
+show::
+       Show the notes for a given commit (defaults to HEAD).
+
+
+Author
+------
+Written by Johannes Schindelin <johannes.schindelin@gmx.de>
+
+Documentation
+-------------
+Documentation by Johannes Schindelin
+
+GIT
+---
+Part of the linkgit:git[7] suite
index 9a6a729868d89166f106b4eeb7b8e2b69c08c625..8d7cec79d9097c2d822a329a862700940c04441f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -321,6 +321,7 @@ SCRIPT_SH += git-merge-one-file.sh
 SCRIPT_SH += git-merge-resolve.sh
 SCRIPT_SH += git-mergetool.sh
 SCRIPT_SH += git-mergetool--lib.sh
+SCRIPT_SH += git-notes.sh
 SCRIPT_SH += git-parse-remote.sh
 SCRIPT_SH += git-pull.sh
 SCRIPT_SH += git-quiltimport.sh
index fb03a2ebb5d51f46d00fad3b3f6b1794d4fdad2b..4296941b68f981577306afbe4b0e5eca685c6e25 100644 (file)
@@ -74,6 +74,7 @@ git-mktag                               plumbingmanipulators
 git-mktree                              plumbingmanipulators
 git-mv                                  mainporcelain common
 git-name-rev                            plumbinginterrogators
+git-notes                               mainporcelain
 git-pack-objects                        plumbingmanipulators
 git-pack-redundant                      plumbinginterrogators
 git-pack-refs                           ancillarymanipulators
diff --git a/git-notes.sh b/git-notes.sh
new file mode 100755 (executable)
index 0000000..f06c254
--- /dev/null
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+USAGE="(edit | show) [commit]"
+. git-sh-setup
+
+test -n "$3" && usage
+
+test -z "$1" && usage
+ACTION="$1"; shift
+
+test -z "$GIT_NOTES_REF" && GIT_NOTES_REF="$(git config core.notesref)"
+test -z "$GIT_NOTES_REF" && GIT_NOTES_REF="refs/notes/commits"
+
+COMMIT=$(git rev-parse --verify --default HEAD "$@") ||
+die "Invalid commit: $@"
+
+case "$ACTION" in
+edit)
+       if [ "${GIT_NOTES_REF#refs/notes/}" = "$GIT_NOTES_REF" ]; then
+               die "Refusing to edit notes in $GIT_NOTES_REF (outside of refs/notes/)"
+       fi
+
+       MSG_FILE="$GIT_DIR/new-notes-$COMMIT"
+       GIT_INDEX_FILE="$MSG_FILE.idx"
+       export GIT_INDEX_FILE
+
+       trap '
+               test -f "$MSG_FILE" && rm "$MSG_FILE"
+               test -f "$GIT_INDEX_FILE" && rm "$GIT_INDEX_FILE"
+       ' 0
+
+       GIT_NOTES_REF= git log -1 $COMMIT | sed "s/^/#/" > "$MSG_FILE"
+
+       CURRENT_HEAD=$(git show-ref "$GIT_NOTES_REF" | cut -f 1 -d ' ')
+       if [ -z "$CURRENT_HEAD" ]; then
+               PARENT=
+       else
+               PARENT="-p $CURRENT_HEAD"
+               git read-tree "$GIT_NOTES_REF" || die "Could not read index"
+               git cat-file blob :$COMMIT >> "$MSG_FILE" 2> /dev/null
+       fi
+
+       core_editor="$(git config core.editor)"
+       ${GIT_EDITOR:-${core_editor:-${VISUAL:-${EDITOR:-vi}}}} "$MSG_FILE"
+
+       grep -v ^# < "$MSG_FILE" | git stripspace > "$MSG_FILE".processed
+       mv "$MSG_FILE".processed "$MSG_FILE"
+       if [ -s "$MSG_FILE" ]; then
+               BLOB=$(git hash-object -w "$MSG_FILE") ||
+                       die "Could not write into object database"
+               git update-index --add --cacheinfo 0644 $BLOB $COMMIT ||
+                       die "Could not write index"
+       else
+               test -z "$CURRENT_HEAD" &&
+                       die "Will not initialise with empty tree"
+               git update-index --force-remove $COMMIT ||
+                       die "Could not update index"
+       fi
+
+       TREE=$(git write-tree) || die "Could not write tree"
+       NEW_HEAD=$(echo Annotate $COMMIT | git commit-tree $TREE $PARENT) ||
+               die "Could not annotate"
+       git update-ref -m "Annotate $COMMIT" \
+               "$GIT_NOTES_REF" $NEW_HEAD $CURRENT_HEAD
+;;
+show)
+       git rev-parse -q --verify "$GIT_NOTES_REF":$COMMIT > /dev/null ||
+               die "No note for commit $COMMIT."
+       git show "$GIT_NOTES_REF":$COMMIT
+;;
+*)
+       usage
+esac
diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
new file mode 100755 (executable)
index 0000000..73e53be
--- /dev/null
@@ -0,0 +1,114 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Johannes E. Schindelin
+#
+
+test_description='Test commit notes'
+
+. ./test-lib.sh
+
+cat > fake_editor.sh << \EOF
+echo "$MSG" > "$1"
+echo "$MSG" >& 2
+EOF
+chmod a+x fake_editor.sh
+VISUAL=./fake_editor.sh
+export VISUAL
+
+test_expect_success 'cannot annotate non-existing HEAD' '
+       (MSG=3 && export MSG && test_must_fail git notes edit)
+'
+
+test_expect_success setup '
+       : > a1 &&
+       git add a1 &&
+       test_tick &&
+       git commit -m 1st &&
+       : > a2 &&
+       git add a2 &&
+       test_tick &&
+       git commit -m 2nd
+'
+
+test_expect_success 'need valid notes ref' '
+       (MSG=1 GIT_NOTES_REF=/ && export MSG GIT_NOTES_REF &&
+        test_must_fail git notes edit) &&
+       (MSG=2 GIT_NOTES_REF=/ && export MSG GIT_NOTES_REF &&
+        test_must_fail git notes show)
+'
+
+test_expect_success 'refusing to edit in refs/heads/' '
+       (MSG=1 GIT_NOTES_REF=refs/heads/bogus &&
+        export MSG GIT_NOTES_REF &&
+        test_must_fail git notes edit)
+'
+
+test_expect_success 'refusing to edit in refs/remotes/' '
+       (MSG=1 GIT_NOTES_REF=refs/remotes/bogus &&
+        export MSG GIT_NOTES_REF &&
+        test_must_fail git notes edit)
+'
+
+# 1 indicates caught gracefully by die, 128 means git-show barked
+test_expect_success 'handle empty notes gracefully' '
+       git notes show ; test 1 = $?
+'
+
+test_expect_success 'create notes' '
+       git config core.notesRef refs/notes/commits &&
+       MSG=b1 git notes edit &&
+       test ! -f .git/new-notes &&
+       test 1 = $(git ls-tree refs/notes/commits | wc -l) &&
+       test b1 = $(git notes show) &&
+       git show HEAD^ &&
+       test_must_fail git notes show HEAD^
+'
+
+cat > expect << EOF
+commit 268048bfb8a1fb38e703baceb8ab235421bf80c5
+Author: A U Thor <author@example.com>
+Date:   Thu Apr 7 15:14:13 2005 -0700
+
+    2nd
+
+Notes:
+    b1
+EOF
+
+test_expect_success 'show notes' '
+       ! (git cat-file commit HEAD | grep b1) &&
+       git log -1 > output &&
+       test_cmp expect output
+'
+test_expect_success 'create multi-line notes (setup)' '
+       : > a3 &&
+       git add a3 &&
+       test_tick &&
+       git commit -m 3rd &&
+       MSG="b3
+c3c3c3c3
+d3d3d3" git notes edit
+'
+
+cat > expect-multiline << EOF
+commit 1584215f1d29c65e99c6c6848626553fdd07fd75
+Author: A U Thor <author@example.com>
+Date:   Thu Apr 7 15:15:13 2005 -0700
+
+    3rd
+
+Notes:
+    b3
+    c3c3c3c3
+    d3d3d3
+EOF
+
+printf "\n" >> expect-multiline
+cat expect >> expect-multiline
+
+test_expect_success 'show multi-line notes' '
+       git log -2 > output &&
+       test_cmp expect-multiline output
+'
+
+test_done