Add a script to edit/inspect notes

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>
This commit is contained in:
Johannes Schindelin 2009-10-09 12:21:58 +02:00 committed by Junio C Hamano
parent a97a74686d
commit 65d9fb487f
6 changed files with 236 additions and 0 deletions

1
.gitignore vendored
View 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

View File

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

View File

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

View 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

73
git-notes.sh Executable file
View File

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

114
t/t3301-notes.sh Executable file
View File

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