summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/lib-httpd.sh29
-rwxr-xr-xt/t0001-init.sh19
-rwxr-xr-xt/t1007-hash-object.sh18
-rwxr-xr-xt/t1304-default-acl.sh23
-rwxr-xr-xt/t1509-root-worktree.sh249
-rw-r--r--t/t1509/excludes14
-rwxr-xr-xt/t1509/prepare-chroot.sh38
-rwxr-xr-xt/t3020-ls-files-error-unmatch.sh8
-rwxr-xr-xt/t3301-notes.sh909
-rwxr-xr-xt/t3303-notes-subtrees.sh28
-rwxr-xr-xt/t3304-notes-mixed.sh36
-rwxr-xr-xt/t3305-notes-fanout.sh95
-rwxr-xr-xt/t3306-notes-prune.sh94
-rwxr-xr-xt/t3400-rebase.sh17
-rwxr-xr-xt/t3404-rebase-interactive.sh69
-rwxr-xr-xt/t3506-cherry-pick-ff.sh98
-rwxr-xr-xt/t3507-cherry-pick-conflict.sh198
-rwxr-xr-xt/t3800-mktag.sh10
-rwxr-xr-xt/t4013-diff-various.sh6
-rw-r--r--t/t4013/diff.log_-m_-p_--first-parent_master100
-rw-r--r--t/t4013/diff.log_-m_-p_master200
-rw-r--r--t/t4013/diff.log_-p_--first-parent_master78
-rw-r--r--t/t4013/diff.show_--first-parent_master30
-rw-r--r--t/t4013/diff.show_-c_master36
-rw-r--r--t/t4013/diff.show_-m_master93
-rwxr-xr-xt/t4014-format-patch.sh52
-rwxr-xr-xt/t4041-diff-submodule.sh32
-rwxr-xr-xt/t4103-apply-binary.sh36
-rwxr-xr-xt/t4200-rerere.sh70
-rwxr-xr-xt/t4253-am-keep-cr-dos.sh96
-rwxr-xr-xt/t5407-post-rewrite-hook.sh199
-rwxr-xr-xt/t5505-remote.sh47
-rwxr-xr-xt/t5510-fetch.sh7
-rwxr-xr-xt/t5516-fetch-push.sh50
-rwxr-xr-xt/t5540-http-push.sh3
-rwxr-xr-xt/t5541-http-push.sh22
-rwxr-xr-xt/t5601-clone.sh2
-rwxr-xr-xt/t6006-rev-list-format.sh2
-rwxr-xr-xt/t6023-merge-file.sh43
-rwxr-xr-xt/t6200-fmt-merge-msg.sh196
-rwxr-xr-xt/t7002-grep.sh52
-rwxr-xr-xt/t7103-reset-bare.sh25
-rwxr-xr-xt/t7110-reset-merge.sh116
-rwxr-xr-xt/t7111-reset-table.sh8
-rwxr-xr-xt/t7201-co.sh69
-rwxr-xr-xt/t7401-submodule-summary.sh7
-rwxr-xr-xt/t7501-commit.sh12
-rwxr-xr-xt/t7506-status-submodule.sh105
-rwxr-xr-xt/t9001-send-email.sh66
-rwxr-xr-xt/t9119-git-svn-info.sh3
-rwxr-xr-xt/t9150-svk-mergetickets.sh1
-rwxr-xr-xt/t9151-svn-mergeinfo.sh16
-rw-r--r--t/t9151/make-svnmerge-dump89
-rw-r--r--t/t9151/svn-mergeinfo.dump578
-rwxr-xr-xt/t9501-gitweb-standalone-http-status.sh7
-rwxr-xr-xt/t9600-cvsimport.sh36
-rw-r--r--t/test-lib.sh16
57 files changed, 4238 insertions, 320 deletions
diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index 28aff887b5..da4b8d5a6f 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -131,3 +131,32 @@ stop_httpd() {
"$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \
-f "$TEST_PATH/apache.conf" $HTTPD_PARA -k stop
}
+
+test_http_push_nonff() {
+ REMOTE_REPO=$1
+ LOCAL_REPO=$2
+ BRANCH=$3
+
+ test_expect_success 'non-fast-forward push fails' '
+ cd "$REMOTE_REPO" &&
+ HEAD=$(git rev-parse --verify HEAD) &&
+
+ cd "$LOCAL_REPO" &&
+ git checkout $BRANCH &&
+ echo "changed" > path2 &&
+ git commit -a -m path2 --amend &&
+
+ !(git push -v origin >output 2>&1) &&
+ (cd "$REMOTE_REPO" &&
+ test $HEAD = $(git rev-parse --verify HEAD))
+ '
+
+ test_expect_success 'non-fast-forward push show ref status' '
+ grep "^ ! \[rejected\][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" output
+ '
+
+ test_expect_success 'non-fast-forward push shows help message' '
+ grep "To prevent you from losing history, non-fast-forward updates were rejected" \
+ output
+ '
+}
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 5386504790..675773479a 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -167,6 +167,25 @@ test_expect_success 'init with --template (blank)' '
! test -f template-blank/.git/info/exclude
'
+test_expect_success 'init with init.templatedir set' '
+ mkdir templatedir-source &&
+ echo Content >templatedir-source/file &&
+ (
+ HOME="`pwd`" &&
+ export HOME &&
+ test_config="${HOME}/.gitconfig" &&
+ git config -f "$test_config" init.templatedir "${HOME}/templatedir-source" &&
+ mkdir templatedir-set &&
+ cd templatedir-set &&
+ unset GIT_CONFIG_NOGLOBAL &&
+ unset GIT_TEMPLATE_DIR &&
+ NO_SET_GIT_TEMPLATE_DIR=t &&
+ export NO_SET_GIT_TEMPLATE_DIR &&
+ git init
+ ) &&
+ test_cmp templatedir-source/file templatedir-set/.git/file
+'
+
test_expect_success 'init --bare/--shared overrides system/global config' '
(
HOME="`pwd`" &&
diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh
index fd98e445bf..dd32432d62 100755
--- a/t/t1007-hash-object.sh
+++ b/t/t1007-hash-object.sh
@@ -65,10 +65,6 @@ test_expect_success "Can't use --path with --stdin-paths" '
echo example | test_must_fail git hash-object --stdin-paths --path=foo
'
-test_expect_success "Can't use --stdin-paths with --no-filters" '
- echo example | test_must_fail git hash-object --stdin-paths --no-filters
-'
-
test_expect_success "Can't use --path with --no-filters" '
test_must_fail git hash-object --no-filters --path=foo
'
@@ -141,6 +137,20 @@ test_expect_success 'check that --no-filters option works' '
git config --unset core.autocrlf
'
+test_expect_success 'check that --no-filters option works with --stdin-paths' '
+ echo fooQ | tr Q "\\015" >file0 &&
+ cp file0 file1 &&
+ echo "file0 -crlf" >.gitattributes &&
+ echo "file1 crlf" >>.gitattributes &&
+ git config core.autocrlf true &&
+ file0_sha=$(git hash-object file0) &&
+ file1_sha=$(git hash-object file1) &&
+ test "$file0_sha" != "$file1_sha" &&
+ nofilters_file1=$(echo "file1" | git hash-object --stdin-paths --no-filters) &&
+ test "$file0_sha" = "$nofilters_file1" &&
+ git config --unset core.autocrlf
+'
+
pop_repo
for args in "-w --stdin" "--stdin -w"; do
diff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh
index cc30be4a65..055ad00f77 100755
--- a/t/t1304-default-acl.sh
+++ b/t/t1304-default-acl.sh
@@ -20,34 +20,23 @@ if ! setfacl -m u:root:rwx .; then
test_done
fi
-modebits () {
- ls -l "$1" | sed -e 's|^\(..........\).*|\1|'
-}
-
check_perms_and_acl () {
- actual=$(modebits "$1") &&
- case "$actual" in
- -r--r-----*)
- : happy
- ;;
- *)
- echo "Got permission '$actual', expected '-r--r-----'"
- false
- ;;
- esac &&
+ test -r "$1" &&
getfacl "$1" > actual &&
grep -q "user:root:rwx" actual &&
grep -q "user:${LOGNAME}:rwx" actual &&
- grep -q "mask::r--" actual &&
+ egrep "mask::?r--" actual > /dev/null 2>&1 &&
grep -q "group::---" actual || false
}
dirs_to_set="./ .git/ .git/objects/ .git/objects/pack/"
test_expect_success 'Setup test repo' '
+ setfacl -m d:u::rwx,d:g::---,d:o:---,d:m:rwx $dirs_to_set &&
+ setfacl -m m:rwx $dirs_to_set &&
setfacl -m u:root:rwx $dirs_to_set &&
- setfacl -d -m u:"$LOGNAME":rwx $dirs_to_set &&
- setfacl -d -m u:root:rwx $dirs_to_set &&
+ setfacl -m d:u:"$LOGNAME":rwx $dirs_to_set &&
+ setfacl -m d:u:root:rwx $dirs_to_set &&
touch file.txt &&
git add file.txt &&
diff --git a/t/t1509-root-worktree.sh b/t/t1509-root-worktree.sh
new file mode 100755
index 0000000000..5322a3bf97
--- /dev/null
+++ b/t/t1509-root-worktree.sh
@@ -0,0 +1,249 @@
+#!/bin/sh
+
+test_description='Test Git when git repository is located at root
+
+This test requires write access in root. Do not bother if you do not
+have a throwaway chroot or VM.
+
+Script t1509/prepare-chroot.sh may help you setup chroot, then you
+can chroot in and execute this test from there.
+'
+
+. ./test-lib.sh
+
+test_cmp_val() {
+ echo "$1" > expected
+ echo "$2" > result
+ test_cmp expected result
+}
+
+test_vars() {
+ test_expect_success "$1: gitdir" '
+ test_cmp_val "'"$2"'" "$(git rev-parse --git-dir)"
+ '
+
+ test_expect_success "$1: worktree" '
+ test_cmp_val "'"$3"'" "$(git rev-parse --show-toplevel)"
+ '
+
+ test_expect_success "$1: prefix" '
+ test_cmp_val "'"$4"'" "$(git rev-parse --show-prefix)"
+ '
+}
+
+test_foobar_root() {
+ test_expect_success 'add relative' '
+ test -z "$(cd / && git ls-files)" &&
+ git add foo/foome &&
+ git add foo/bar/barme &&
+ git add me &&
+ ( cd / && git ls-files --stage ) > result &&
+ test_cmp /ls.expected result &&
+ rm "$(git rev-parse --git-dir)/index"
+ '
+
+ test_expect_success 'add absolute' '
+ test -z "$(cd / && git ls-files)" &&
+ git add /foo/foome &&
+ git add /foo/bar/barme &&
+ git add /me &&
+ ( cd / && git ls-files --stage ) > result &&
+ test_cmp /ls.expected result &&
+ rm "$(git rev-parse --git-dir)/index"
+ '
+
+}
+
+test_foobar_foo() {
+ test_expect_success 'add relative' '
+ test -z "$(cd / && git ls-files)" &&
+ git add foome &&
+ git add bar/barme &&
+ git add ../me &&
+ ( cd / && git ls-files --stage ) > result &&
+ test_cmp /ls.expected result &&
+ rm "$(git rev-parse --git-dir)/index"
+ '
+
+ test_expect_success 'add absolute' '
+ test -z "$(cd / && git ls-files)" &&
+ git add /foo/foome &&
+ git add /foo/bar/barme &&
+ git add /me &&
+ ( cd / && git ls-files --stage ) > result &&
+ test_cmp /ls.expected result &&
+ rm "$(git rev-parse --git-dir)/index"
+ '
+}
+
+test_foobar_foobar() {
+ test_expect_success 'add relative' '
+ test -z "$(cd / && git ls-files)" &&
+ git add ../foome &&
+ git add barme &&
+ git add ../../me &&
+ ( cd / && git ls-files --stage ) > result &&
+ test_cmp /ls.expected result &&
+ rm "$(git rev-parse --git-dir)/index"
+ '
+
+ test_expect_success 'add absolute' '
+ test -z "$(cd / && git ls-files)" &&
+ git add /foo/foome &&
+ git add /foo/bar/barme &&
+ git add /me &&
+ ( cd / && git ls-files --stage ) > result &&
+ test_cmp /ls.expected result &&
+ rm "$(git rev-parse --git-dir)/index"
+ '
+}
+
+if ! test_have_prereq POSIXPERM || ! [ -w / ]; then
+ say "Dangerous test skipped. Read this test if you want to execute it"
+ test_done
+fi
+
+if [ "$IKNOWWHATIAMDOING" != "YES" ]; then
+ say "You must set env var IKNOWWHATIAMDOING=YES in order to run this test"
+ test_done
+fi
+
+if [ "$UID" = 0 ]; then
+ say "No you can't run this with root"
+ test_done
+fi
+
+ONE_SHA1=d00491fd7e5bb6fa28c517a0bb32b8b506539d4d
+
+test_expect_success 'setup' '
+ rm -rf /foo
+ mkdir /foo &&
+ mkdir /foo/bar &&
+ echo 1 > /foo/foome &&
+ echo 1 > /foo/bar/barme &&
+ echo 1 > /me
+'
+
+say "GIT_DIR absolute, GIT_WORK_TREE set"
+
+test_expect_success 'go to /' 'cd /'
+
+cat >ls.expected <<EOF
+100644 $ONE_SHA1 0 foo/bar/barme
+100644 $ONE_SHA1 0 foo/foome
+100644 $ONE_SHA1 0 me
+EOF
+
+export GIT_DIR="$TRASH_DIRECTORY/.git"
+export GIT_WORK_TREE=/
+
+test_vars 'abs gitdir, root' "$GIT_DIR" "/" ""
+test_foobar_root
+
+test_expect_success 'go to /foo' 'cd /foo'
+
+test_vars 'abs gitdir, foo' "$GIT_DIR" "/" "foo/"
+test_foobar_foo
+
+test_expect_success 'go to /foo/bar' 'cd /foo/bar'
+
+test_vars 'abs gitdir, foo/bar' "$GIT_DIR" "/" "foo/bar/"
+test_foobar_foobar
+
+say "GIT_DIR relative, GIT_WORK_TREE set"
+
+test_expect_success 'go to /' 'cd /'
+
+export GIT_DIR="$(echo $TRASH_DIRECTORY|sed 's,^/,,')/.git"
+export GIT_WORK_TREE=/
+
+test_vars 'rel gitdir, root' "$GIT_DIR" "/" ""
+test_foobar_root
+
+test_expect_success 'go to /foo' 'cd /foo'
+
+export GIT_DIR="../$TRASH_DIRECTORY/.git"
+export GIT_WORK_TREE=/
+
+test_vars 'rel gitdir, foo' "$TRASH_DIRECTORY/.git" "/" "foo/"
+test_foobar_foo
+
+test_expect_success 'go to /foo/bar' 'cd /foo/bar'
+
+export GIT_DIR="../../$TRASH_DIRECTORY/.git"
+export GIT_WORK_TREE=/
+
+test_vars 'rel gitdir, foo/bar' "$TRASH_DIRECTORY/.git" "/" "foo/bar/"
+test_foobar_foobar
+
+say "GIT_DIR relative, GIT_WORK_TREE relative"
+
+test_expect_success 'go to /' 'cd /'
+
+export GIT_DIR="$(echo $TRASH_DIRECTORY|sed 's,^/,,')/.git"
+export GIT_WORK_TREE=.
+
+test_vars 'rel gitdir, root' "$GIT_DIR" "/" ""
+test_foobar_root
+
+test_expect_success 'go to /' 'cd /foo'
+
+export GIT_DIR="../$TRASH_DIRECTORY/.git"
+export GIT_WORK_TREE=..
+
+test_vars 'rel gitdir, foo' "$TRASH_DIRECTORY/.git" "/" "foo/"
+test_foobar_foo
+
+test_expect_success 'go to /foo/bar' 'cd /foo/bar'
+
+export GIT_DIR="../../$TRASH_DIRECTORY/.git"
+export GIT_WORK_TREE=../..
+
+test_vars 'rel gitdir, foo/bar' "$TRASH_DIRECTORY/.git" "/" "foo/bar/"
+test_foobar_foobar
+
+say ".git at root"
+
+unset GIT_DIR
+unset GIT_WORK_TREE
+
+test_expect_success 'go to /' 'cd /'
+test_expect_success 'setup' '
+ rm -rf /.git
+ echo "Initialized empty Git repository in /.git/" > expected &&
+ git init > result &&
+ test_cmp expected result
+'
+
+test_vars 'auto gitdir, root' ".git" "/" ""
+test_foobar_root
+
+test_expect_success 'go to /foo' 'cd /foo'
+test_vars 'auto gitdir, foo' "/.git" "/" "foo/"
+test_foobar_foo
+
+test_expect_success 'go to /foo/bar' 'cd /foo/bar'
+test_vars 'auto gitdir, foo/bar' "/.git" "/" "foo/bar/"
+test_foobar_foobar
+
+test_expect_success 'cleanup' 'rm -rf /.git'
+
+say "auto bare gitdir"
+
+# DESTROYYYYY!!!!!
+test_expect_success 'setup' '
+ rm -rf /refs /objects /info /hooks
+ rm /*
+ cd / &&
+ echo "Initialized empty Git repository in /" > expected &&
+ git init --bare > result &&
+ test_cmp expected result
+'
+
+test_vars 'auto gitdir, root' "." "" ""
+
+test_expect_success 'go to /foo' 'cd /foo'
+
+test_vars 'auto gitdir, root' "/" "" ""
+
+test_done
diff --git a/t/t1509/excludes b/t/t1509/excludes
new file mode 100644
index 0000000000..d4d21d31a9
--- /dev/null
+++ b/t/t1509/excludes
@@ -0,0 +1,14 @@
+*.o
+*~
+*.bak
+*.c
+*.h
+.git
+contrib
+Documentation
+git-gui
+gitk-git
+gitweb
+t/t4013
+t/t5100
+t/t5515
diff --git a/t/t1509/prepare-chroot.sh b/t/t1509/prepare-chroot.sh
new file mode 100755
index 0000000000..c5334a8fa4
--- /dev/null
+++ b/t/t1509/prepare-chroot.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+die() {
+ echo >&2 "$@"
+ exit 1
+}
+
+xmkdir() {
+ while [ -n "$1" ]; do
+ [ -d "$1" ] || mkdir "$1" || die "Unable to mkdir $1"
+ shift
+ done
+}
+
+R="$1"
+
+[ -n "$R" ] || die "Usage: prepare-chroot.sh <root>"
+[ -x git ] || die "This script needs to be executed at git source code's top directory"
+[ -x /bin/busybox ] || die "You need busybox"
+
+xmkdir "$R" "$R/bin" "$R/etc" "$R/lib" "$R/dev"
+[ -c "$R/dev/null" ] || die "/dev/null is missing. Do mknod $R/dev/null c 1 3 && chmod 666 $R/dev/null"
+echo "root:x:0:0:root:/:/bin/sh" > "$R/etc/passwd"
+echo "$(id -nu):x:$(id -u):$(id -g)::$(pwd)/t:/bin/sh" >> "$R/etc/passwd"
+echo "root::0:root" > "$R/etc/group"
+echo "$(id -ng)::$(id -g):$(id -nu)" >> "$R/etc/group"
+
+[ -x "$R/bin/busybox" ] || cp /bin/busybox "$R/bin/busybox"
+[ -x "$R/bin/sh" ] || ln -s /bin/busybox "$R/bin/sh"
+[ -x "$R/bin/su" ] || ln -s /bin/busybox "$R/bin/su"
+
+mkdir -p "$R$(pwd)"
+rsync --exclude-from t/t1509/excludes -Ha . "$R$(pwd)"
+ldd git | grep '/' | sed 's,.*\s\(/[^ ]*\).*,\1,' | while read i; do
+ mkdir -p "$R$(dirname $i)"
+ cp "$i" "$R/$i"
+done
+echo "Execute this in root: 'chroot $R /bin/su - $(id -nu)'"
diff --git a/t/t3020-ls-files-error-unmatch.sh b/t/t3020-ls-files-error-unmatch.sh
index f4066cbc09..a7d8187169 100755
--- a/t/t3020-ls-files-error-unmatch.sh
+++ b/t/t3020-ls-files-error-unmatch.sh
@@ -11,9 +11,11 @@ line.
'
. ./test-lib.sh
-touch foo bar
-git update-index --add foo bar
-git commit -m "add foo bar"
+test_expect_success 'setup' '
+ touch foo bar &&
+ git update-index --add foo bar &&
+ git commit -m "add foo bar"
+'
test_expect_success \
'git ls-files --error-unmatch should fail with unmatched path.' \
diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index 714626d2d6..64f32ad94d 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -13,11 +13,11 @@ echo "$MSG" > "$1"
echo "$MSG" >& 2
EOF
chmod a+x fake_editor.sh
-VISUAL=./fake_editor.sh
-export VISUAL
+GIT_EDITOR=./fake_editor.sh
+export GIT_EDITOR
test_expect_success 'cannot annotate non-existing HEAD' '
- (MSG=3 && export MSG && test_must_fail git notes edit)
+ (MSG=3 && export MSG && test_must_fail git notes add)
'
test_expect_success setup '
@@ -33,18 +33,18 @@ test_expect_success setup '
test_expect_success 'need valid notes ref' '
(MSG=1 GIT_NOTES_REF=/ && export MSG GIT_NOTES_REF &&
- test_must_fail git notes edit) &&
+ test_must_fail git notes add) &&
(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/' '
+test_expect_success 'refusing to add notes in refs/heads/' '
(MSG=1 GIT_NOTES_REF=refs/heads/bogus &&
export MSG GIT_NOTES_REF &&
- test_must_fail git notes edit)
+ test_must_fail git notes add)
'
-test_expect_success 'refusing to edit in refs/remotes/' '
+test_expect_success 'refusing to edit notes in refs/remotes/' '
(MSG=1 GIT_NOTES_REF=refs/remotes/bogus &&
export MSG GIT_NOTES_REF &&
test_must_fail git notes edit)
@@ -55,10 +55,64 @@ test_expect_success 'handle empty notes gracefully' '
git notes show ; test 1 = $?
'
+test_expect_success 'show non-existent notes entry with %N' '
+ for l in A B
+ do
+ echo "$l"
+ done >expect &&
+ git show -s --format='A%n%NB' >output &&
+ test_cmp expect output
+'
+
test_expect_success 'create notes' '
git config core.notesRef refs/notes/commits &&
- MSG=b1 git notes edit &&
- test ! -f .git/new-notes &&
+ MSG=b4 git notes add &&
+ test ! -f .git/NOTES_EDITMSG &&
+ test 1 = $(git ls-tree refs/notes/commits | wc -l) &&
+ test b4 = $(git notes show) &&
+ git show HEAD^ &&
+ test_must_fail git notes show HEAD^
+'
+
+test_expect_success 'show notes entry with %N' '
+ for l in A b4 B
+ do
+ echo "$l"
+ done >expect &&
+ git show -s --format='A%n%NB' >output &&
+ test_cmp expect output
+'
+
+cat >expect <<EOF
+d423f8c refs/notes/commits@{0}: notes: Notes added by 'git notes add'
+EOF
+
+test_expect_success 'create reflog entry' '
+ git reflog show refs/notes/commits >output &&
+ test_cmp expect output
+'
+
+test_expect_success 'edit existing notes' '
+ MSG=b3 git notes edit &&
+ test ! -f .git/NOTES_EDITMSG &&
+ test 1 = $(git ls-tree refs/notes/commits | wc -l) &&
+ test b3 = $(git notes show) &&
+ git show HEAD^ &&
+ test_must_fail git notes show HEAD^
+'
+
+test_expect_success 'cannot add note where one exists' '
+ ! MSG=b2 git notes add &&
+ test ! -f .git/NOTES_EDITMSG &&
+ test 1 = $(git ls-tree refs/notes/commits | wc -l) &&
+ test b3 = $(git notes show) &&
+ git show HEAD^ &&
+ test_must_fail git notes show HEAD^
+'
+
+test_expect_success 'can overwrite existing note with "git notes add -f"' '
+ MSG=b1 git notes add -f &&
+ test ! -f .git/NOTES_EDITMSG &&
test 1 = $(git ls-tree refs/notes/commits | wc -l) &&
test b1 = $(git notes show) &&
git show HEAD^ &&
@@ -81,6 +135,7 @@ test_expect_success 'show notes' '
git log -1 > output &&
test_cmp expect output
'
+
test_expect_success 'create multi-line notes (setup)' '
: > a3 &&
git add a3 &&
@@ -88,7 +143,7 @@ test_expect_success 'create multi-line notes (setup)' '
git commit -m 3rd &&
MSG="b3
c3c3c3c3
-d3d3d3" git notes edit
+d3d3d3" git notes add
'
cat > expect-multiline << EOF
@@ -111,19 +166,16 @@ test_expect_success 'show multi-line notes' '
git log -2 > output &&
test_cmp expect-multiline output
'
-test_expect_success 'create -m and -F notes (setup)' '
+test_expect_success 'create -F notes (setup)' '
: > a4 &&
git add a4 &&
test_tick &&
git commit -m 4th &&
echo "xyzzy" > note5 &&
- git notes edit -m spam -F note5 -m "foo
-bar
-baz"
+ git notes add -F note5
'
-whitespace=" "
-cat > expect-m-and-F << EOF
+cat > expect-F << EOF
commit 15023535574ded8b1a89052b32673f84cf9582b8
Author: A U Thor <author@example.com>
Date: Thu Apr 7 15:16:13 2005 -0700
@@ -131,21 +183,15 @@ Date: Thu Apr 7 15:16:13 2005 -0700
4th
Notes:
- spam
-$whitespace
xyzzy
-$whitespace
- foo
- bar
- baz
EOF
-printf "\n" >> expect-m-and-F
-cat expect-multiline >> expect-m-and-F
+printf "\n" >> expect-F
+cat expect-multiline >> expect-F
-test_expect_success 'show -m and -F notes' '
+test_expect_success 'show -F notes' '
git log -3 > output &&
- test_cmp expect-m-and-F output
+ test_cmp expect-F output
'
cat >expect << EOF
@@ -165,13 +211,7 @@ test_expect_success 'git log --pretty=raw does not show notes' '
cat >>expect <<EOF
Notes:
- spam
-$whitespace
xyzzy
-$whitespace
- foo
- bar
- baz
EOF
test_expect_success 'git log --show-notes' '
git log -1 --pretty=raw --show-notes >output &&
@@ -180,17 +220,17 @@ test_expect_success 'git log --show-notes' '
test_expect_success 'git log --no-notes' '
git log -1 --no-notes >output &&
- ! grep spam output
+ ! grep xyzzy output
'
test_expect_success 'git format-patch does not show notes' '
git format-patch -1 --stdout >output &&
- ! grep spam output
+ ! grep xyzzy output
'
test_expect_success 'git format-patch --show-notes does show notes' '
git format-patch --show-notes -1 --stdout >output &&
- grep spam output
+ grep xyzzy output
'
for pretty in \
@@ -203,8 +243,805 @@ do
esac
test_expect_success "git show $pretty does$not show notes" '
git show $p >output &&
- eval "$negate grep spam output"
+ eval "$negate grep xyzzy output"
'
done
+test_expect_success 'create -m notes (setup)' '
+ : > a5 &&
+ git add a5 &&
+ test_tick &&
+ git commit -m 5th &&
+ git notes add -m spam -m "foo
+bar
+baz"
+'
+
+whitespace=" "
+cat > expect-m << EOF
+commit bd1753200303d0a0344be813e504253b3d98e74d
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:17:13 2005 -0700
+
+ 5th
+
+Notes:
+ spam
+$whitespace
+ foo
+ bar
+ baz
+EOF
+
+printf "\n" >> expect-m
+cat expect-F >> expect-m
+
+test_expect_success 'show -m notes' '
+ git log -4 > output &&
+ test_cmp expect-m output
+'
+
+test_expect_success 'remove note with add -f -F /dev/null (setup)' '
+ git notes add -f -F /dev/null
+'
+
+cat > expect-rm-F << EOF
+commit bd1753200303d0a0344be813e504253b3d98e74d
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:17:13 2005 -0700
+
+ 5th
+EOF
+
+printf "\n" >> expect-rm-F
+cat expect-F >> expect-rm-F
+
+test_expect_success 'verify note removal with -F /dev/null' '
+ git log -4 > output &&
+ test_cmp expect-rm-F output &&
+ ! git notes show
+'
+
+test_expect_success 'do not create empty note with -m "" (setup)' '
+ git notes add -m ""
+'
+
+test_expect_success 'verify non-creation of note with -m ""' '
+ git log -4 > output &&
+ test_cmp expect-rm-F output &&
+ ! git notes show
+'
+
+cat > expect-combine_m_and_F << EOF
+foo
+
+xyzzy
+
+bar
+
+zyxxy
+
+baz
+EOF
+
+test_expect_success 'create note with combination of -m and -F' '
+ echo "xyzzy" > note_a &&
+ echo "zyxxy" > note_b &&
+ git notes add -m "foo" -F note_a -m "bar" -F note_b -m "baz" &&
+ git notes show > output &&
+ test_cmp expect-combine_m_and_F output
+'
+
+test_expect_success 'remove note with "git notes remove" (setup)' '
+ git notes remove HEAD^ &&
+ git notes remove
+'
+
+cat > expect-rm-remove << EOF
+commit bd1753200303d0a0344be813e504253b3d98e74d
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:17:13 2005 -0700
+
+ 5th
+
+commit 15023535574ded8b1a89052b32673f84cf9582b8
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:16:13 2005 -0700
+
+ 4th
+EOF
+
+printf "\n" >> expect-rm-remove
+cat expect-multiline >> expect-rm-remove
+
+test_expect_success 'verify note removal with "git notes remove"' '
+ git log -4 > output &&
+ test_cmp expect-rm-remove output &&
+ ! git notes show HEAD^
+'
+
+cat > expect << EOF
+c18dc024e14f08d18d14eea0d747ff692d66d6a3 1584215f1d29c65e99c6c6848626553fdd07fd75
+c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 268048bfb8a1fb38e703baceb8ab235421bf80c5
+EOF
+
+test_expect_success 'list notes with "git notes list"' '
+ git notes list > output &&
+ test_cmp expect output
+'
+
+test_expect_success 'list notes with "git notes"' '
+ git notes > output &&
+ test_cmp expect output
+'
+
+cat > expect << EOF
+c18dc024e14f08d18d14eea0d747ff692d66d6a3
+EOF
+
+test_expect_success 'list specific note with "git notes list <object>"' '
+ git notes list HEAD^^ > output &&
+ test_cmp expect output
+'
+
+cat > expect << EOF
+EOF
+
+test_expect_success 'listing non-existing notes fails' '
+ test_must_fail git notes list HEAD > output &&
+ test_cmp expect output
+'
+
+cat > expect << EOF
+Initial set of notes
+
+More notes appended with git notes append
+EOF
+
+test_expect_success 'append to existing note with "git notes append"' '
+ git notes add -m "Initial set of notes" &&
+ git notes append -m "More notes appended with git notes append" &&
+ git notes show > output &&
+ test_cmp expect output
+'
+
+cat > expect_list << EOF
+c18dc024e14f08d18d14eea0d747ff692d66d6a3 1584215f1d29c65e99c6c6848626553fdd07fd75
+c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 268048bfb8a1fb38e703baceb8ab235421bf80c5
+4b6ad22357cc8a1296720574b8d2fbc22fab0671 bd1753200303d0a0344be813e504253b3d98e74d
+EOF
+
+test_expect_success '"git notes list" does not expand to "git notes list HEAD"' '
+ git notes list > output &&
+ test_cmp expect_list output
+'
+
+test_expect_success 'appending empty string does not change existing note' '
+ git notes append -m "" &&
+ git notes show > output &&
+ test_cmp expect output
+'
+
+test_expect_success 'git notes append == add when there is no existing note' '
+ git notes remove HEAD &&
+ test_must_fail git notes list HEAD &&
+ git notes append -m "Initial set of notes
+
+More notes appended with git notes append" &&
+ git notes show > output &&
+ test_cmp expect output
+'
+
+test_expect_success 'appending empty string to non-existing note does not create note' '
+ git notes remove HEAD &&
+ test_must_fail git notes list HEAD &&
+ git notes append -m "" &&
+ test_must_fail git notes list HEAD
+'
+
+test_expect_success 'create other note on a different notes ref (setup)' '
+ : > a6 &&
+ git add a6 &&
+ test_tick &&
+ git commit -m 6th &&
+ GIT_NOTES_REF="refs/notes/other" git notes add -m "other note"
+'
+
+cat > expect-other << EOF
+commit 387a89921c73d7ed72cd94d179c1c7048ca47756
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:18:13 2005 -0700
+
+ 6th
+
+Notes (other):
+ other note
+EOF
+
+cat > expect-not-other << EOF
+commit 387a89921c73d7ed72cd94d179c1c7048ca47756
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:18:13 2005 -0700
+
+ 6th
+EOF
+
+test_expect_success 'Do not show note on other ref by default' '
+ git log -1 > output &&
+ test_cmp expect-not-other output
+'
+
+test_expect_success 'Do show note when ref is given in GIT_NOTES_REF' '
+ GIT_NOTES_REF="refs/notes/other" git log -1 > output &&
+ test_cmp expect-other output
+'
+
+test_expect_success 'Do show note when ref is given in core.notesRef config' '
+ git config core.notesRef "refs/notes/other" &&
+ git log -1 > output &&
+ test_cmp expect-other output
+'
+
+test_expect_success 'Do not show note when core.notesRef is overridden' '
+ GIT_NOTES_REF="refs/notes/wrong" git log -1 > output &&
+ test_cmp expect-not-other output
+'
+
+cat > expect-both << EOF
+commit 387a89921c73d7ed72cd94d179c1c7048ca47756
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:18:13 2005 -0700
+
+ 6th
+
+Notes:
+ order test
+
+Notes (other):
+ other note
+
+commit bd1753200303d0a0344be813e504253b3d98e74d
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:17:13 2005 -0700
+
+ 5th
+
+Notes:
+ replacement for deleted note
+EOF
+
+test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '
+ GIT_NOTES_REF=refs/notes/commits git notes add \
+ -m"replacement for deleted note" HEAD^ &&
+ GIT_NOTES_REF=refs/notes/commits git notes add -m"order test" &&
+ git config --unset core.notesRef &&
+ git config notes.displayRef "refs/notes/*" &&
+ git log -2 > output &&
+ test_cmp expect-both output
+'
+
+test_expect_success 'core.notesRef is implicitly in notes.displayRef' '
+ git config core.notesRef refs/notes/commits &&
+ git config notes.displayRef refs/notes/other &&
+ git log -2 > output &&
+ test_cmp expect-both output
+'
+
+test_expect_success 'notes.displayRef can be given more than once' '
+ git config --unset core.notesRef &&
+ git config notes.displayRef refs/notes/commits &&
+ git config --add notes.displayRef refs/notes/other &&
+ git log -2 > output &&
+ test_cmp expect-both output
+'
+
+cat > expect-both-reversed << EOF
+commit 387a89921c73d7ed72cd94d179c1c7048ca47756
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:18:13 2005 -0700
+
+ 6th
+
+Notes (other):
+ other note
+
+Notes:
+ order test
+EOF
+
+test_expect_success 'notes.displayRef respects order' '
+ git config core.notesRef refs/notes/other &&
+ git config --unset-all notes.displayRef &&
+ git config notes.displayRef refs/notes/commits &&
+ git log -1 > output &&
+ test_cmp expect-both-reversed output
+'
+
+test_expect_success 'GIT_NOTES_DISPLAY_REF works' '
+ git config --unset-all core.notesRef &&
+ git config --unset-all notes.displayRef &&
+ GIT_NOTES_DISPLAY_REF=refs/notes/commits:refs/notes/other \
+ git log -2 > output &&
+ test_cmp expect-both output
+'
+
+cat > expect-none << EOF
+commit 387a89921c73d7ed72cd94d179c1c7048ca47756
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:18:13 2005 -0700
+
+ 6th
+
+commit bd1753200303d0a0344be813e504253b3d98e74d
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:17:13 2005 -0700
+
+ 5th
+EOF
+
+test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '
+ git config notes.displayRef "refs/notes/*" &&
+ GIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log -2 > output &&
+ test_cmp expect-none output
+'
+
+test_expect_success '--show-notes=* adds to GIT_NOTES_DISPLAY_REF' '
+ GIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log --show-notes=* -2 > output &&
+ test_cmp expect-both output
+'
+
+cat > expect-commits << EOF
+commit 387a89921c73d7ed72cd94d179c1c7048ca47756
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:18:13 2005 -0700
+
+ 6th
+
+Notes:
+ order test
+EOF
+
+test_expect_success '--no-standard-notes' '
+ git log --no-standard-notes --show-notes=commits -1 > output &&
+ test_cmp expect-commits output
+'
+
+test_expect_success '--standard-notes' '
+ git log --no-standard-notes --show-notes=commits \
+ --standard-notes -2 > output &&
+ test_cmp expect-both output
+'
+
+test_expect_success '--show-notes=ref accumulates' '
+ git log --show-notes=other --show-notes=commits \
+ --no-standard-notes -1 > output &&
+ test_cmp expect-both-reversed output
+'
+
+test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '
+ git config core.notesRef refs/notes/other &&
+ echo "Note on a tree" > expect
+ git notes add -m "Note on a tree" HEAD: &&
+ git notes show HEAD: > actual &&
+ test_cmp expect actual &&
+ echo "Note on a blob" > expect
+ filename=$(git ls-tree --name-only HEAD | head -n1) &&
+ git notes add -m "Note on a blob" HEAD:$filename &&
+ git notes show HEAD:$filename > actual &&
+ test_cmp expect actual &&
+ echo "Note on a tag" > expect
+ git tag -a -m "This is an annotated tag" foobar HEAD^ &&
+ git notes add -m "Note on a tag" foobar &&
+ git notes show foobar > actual &&
+ test_cmp expect actual
+'
+
+cat > expect << EOF
+commit 2ede89468182a62d0bde2583c736089bcf7d7e92
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:19:13 2005 -0700
+
+ 7th
+
+Notes (other):
+ other note
+EOF
+
+test_expect_success 'create note from other note with "git notes add -C"' '
+ : > a7 &&
+ git add a7 &&
+ test_tick &&
+ git commit -m 7th &&
+ git notes add -C $(git notes list HEAD^) &&
+ git log -1 > actual &&
+ test_cmp expect actual &&
+ test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
+'
+
+test_expect_success 'create note from non-existing note with "git notes add -C" fails' '
+ : > a8 &&
+ git add a8 &&
+ test_tick &&
+ git commit -m 8th &&
+ test_must_fail git notes add -C deadbeef &&
+ test_must_fail git notes list HEAD
+'
+
+cat > expect << EOF
+commit 016e982bad97eacdbda0fcbd7ce5b0ba87c81f1b
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:21:13 2005 -0700
+
+ 9th
+
+Notes (other):
+ yet another note
+EOF
+
+test_expect_success 'create note from other note with "git notes add -c"' '
+ : > a9 &&
+ git add a9 &&
+ test_tick &&
+ git commit -m 9th &&
+ MSG="yet another note" git notes add -c $(git notes list HEAD^^) &&
+ git log -1 > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'create note from non-existing note with "git notes add -c" fails' '
+ : > a10 &&
+ git add a10 &&
+ test_tick &&
+ git commit -m 10th &&
+ test_must_fail MSG="yet another note" git notes add -c deadbeef &&
+ test_must_fail git notes list HEAD
+'
+
+cat > expect << EOF
+commit 016e982bad97eacdbda0fcbd7ce5b0ba87c81f1b
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:21:13 2005 -0700
+
+ 9th
+
+Notes (other):
+ yet another note
+$whitespace
+ yet another note
+EOF
+
+test_expect_success 'append to note from other note with "git notes append -C"' '
+ git notes append -C $(git notes list HEAD^) HEAD^ &&
+ git log -1 HEAD^ > actual &&
+ test_cmp expect actual
+'
+
+cat > expect << EOF
+commit ffed603236bfa3891c49644257a83598afe8ae5a
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:22:13 2005 -0700
+
+ 10th
+
+Notes (other):
+ other note
+EOF
+
+test_expect_success 'create note from other note with "git notes append -c"' '
+ MSG="other note" git notes append -c $(git notes list HEAD^) &&
+ git log -1 > actual &&
+ test_cmp expect actual
+'
+
+cat > expect << EOF
+commit ffed603236bfa3891c49644257a83598afe8ae5a
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:22:13 2005 -0700
+
+ 10th
+
+Notes (other):
+ other note
+$whitespace
+ yet another note
+EOF
+
+test_expect_success 'append to note from other note with "git notes append -c"' '
+ MSG="yet another note" git notes append -c $(git notes list HEAD) &&
+ git log -1 > actual &&
+ test_cmp expect actual
+'
+
+cat > expect << EOF
+commit 6352c5e33dbcab725fe0579be16aa2ba8eb369be
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:23:13 2005 -0700
+
+ 11th
+
+Notes (other):
+ other note
+$whitespace
+ yet another note
+EOF
+
+test_expect_success 'copy note with "git notes copy"' '
+ : > a11 &&
+ git add a11 &&
+ test_tick &&
+ git commit -m 11th &&
+ git notes copy HEAD^ HEAD &&
+ git log -1 > actual &&
+ test_cmp expect actual &&
+ test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
+'
+
+test_expect_success 'prevent overwrite with "git notes copy"' '
+ test_must_fail git notes copy HEAD~2 HEAD &&
+ git log -1 > actual &&
+ test_cmp expect actual &&
+ test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
+'
+
+cat > expect << EOF
+commit 6352c5e33dbcab725fe0579be16aa2ba8eb369be
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:23:13 2005 -0700
+
+ 11th
+
+Notes (other):
+ yet another note
+$whitespace
+ yet another note
+EOF
+
+test_expect_success 'allow overwrite with "git notes copy -f"' '
+ git notes copy -f HEAD~2 HEAD &&
+ git log -1 > actual &&
+ test_cmp expect actual &&
+ test "$(git notes list HEAD)" = "$(git notes list HEAD~2)"
+'
+
+test_expect_success 'cannot copy note from object without notes' '
+ : > a12 &&
+ git add a12 &&
+ test_tick &&
+ git commit -m 12th &&
+ : > a13 &&
+ git add a13 &&
+ test_tick &&
+ git commit -m 13th &&
+ test_must_fail git notes copy HEAD^ HEAD
+'
+
+cat > expect << EOF
+commit e5d4fb5698d564ab8c73551538ecaf2b0c666185
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:25:13 2005 -0700
+
+ 13th
+
+Notes (other):
+ yet another note
+$whitespace
+ yet another note
+
+commit 7038787dfe22a14c3867ce816dbba39845359719
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:24:13 2005 -0700
+
+ 12th
+
+Notes (other):
+ other note
+$whitespace
+ yet another note
+EOF
+
+test_expect_success 'git notes copy --stdin' '
+ (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^); \
+ echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
+ git notes copy --stdin &&
+ git log -2 > output &&
+ test_cmp expect output &&
+ test "$(git notes list HEAD)" = "$(git notes list HEAD~2)" &&
+ test "$(git notes list HEAD^)" = "$(git notes list HEAD~3)"
+'
+
+cat > expect << EOF
+commit 37a0d4cba38afef96ba54a3ea567e6dac575700b
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:27:13 2005 -0700
+
+ 15th
+
+commit be28d8b4d9951ad940d229ee3b0b9ee3b1ec273d
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:26:13 2005 -0700
+
+ 14th
+EOF
+
+test_expect_success 'git notes copy --for-rewrite (unconfigured)' '
+ test_commit 14th &&
+ test_commit 15th &&
+ (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^); \
+ echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
+ git notes copy --for-rewrite=foo &&
+ git log -2 > output &&
+ test_cmp expect output
+'
+
+cat > expect << EOF
+commit 37a0d4cba38afef96ba54a3ea567e6dac575700b
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:27:13 2005 -0700
+
+ 15th
+
+Notes (other):
+ yet another note
+$whitespace
+ yet another note
+
+commit be28d8b4d9951ad940d229ee3b0b9ee3b1ec273d
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:26:13 2005 -0700
+
+ 14th
+
+Notes (other):
+ other note
+$whitespace
+ yet another note
+EOF
+
+test_expect_success 'git notes copy --for-rewrite (enabled)' '
+ git config notes.rewriteMode overwrite &&
+ git config notes.rewriteRef "refs/notes/*" &&
+ (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^); \
+ echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
+ git notes copy --for-rewrite=foo &&
+ git log -2 > output &&
+ test_cmp expect output
+'
+
+test_expect_success 'git notes copy --for-rewrite (disabled)' '
+ git config notes.rewrite.bar false &&
+ echo $(git rev-parse HEAD~3) $(git rev-parse HEAD) |
+ git notes copy --for-rewrite=bar &&
+ git log -2 > output &&
+ test_cmp expect output
+'
+
+cat > expect << EOF
+commit 37a0d4cba38afef96ba54a3ea567e6dac575700b
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:27:13 2005 -0700
+
+ 15th
+
+Notes (other):
+ a fresh note
+EOF
+
+test_expect_success 'git notes copy --for-rewrite (overwrite)' '
+ git notes add -f -m"a fresh note" HEAD^ &&
+ echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
+ git notes copy --for-rewrite=foo &&
+ git log -1 > output &&
+ test_cmp expect output
+'
+
+test_expect_success 'git notes copy --for-rewrite (ignore)' '
+ git config notes.rewriteMode ignore &&
+ echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
+ git notes copy --for-rewrite=foo &&
+ git log -1 > output &&
+ test_cmp expect output
+'
+
+cat > expect << EOF
+commit 37a0d4cba38afef96ba54a3ea567e6dac575700b
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:27:13 2005 -0700
+
+ 15th
+
+Notes (other):
+ a fresh note
+ another fresh note
+EOF
+
+test_expect_success 'git notes copy --for-rewrite (append)' '
+ git notes add -f -m"another fresh note" HEAD^ &&
+ git config notes.rewriteMode concatenate &&
+ echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
+ git notes copy --for-rewrite=foo &&
+ git log -1 > output &&
+ test_cmp expect output
+'
+
+cat > expect << EOF
+commit 37a0d4cba38afef96ba54a3ea567e6dac575700b
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:27:13 2005 -0700
+
+ 15th
+
+Notes (other):
+ a fresh note
+ another fresh note
+ append 1
+ append 2
+EOF
+
+test_expect_success 'git notes copy --for-rewrite (append two to one)' '
+ git notes add -f -m"append 1" HEAD^ &&
+ git notes add -f -m"append 2" HEAD^^ &&
+ (echo $(git rev-parse HEAD^) $(git rev-parse HEAD);
+ echo $(git rev-parse HEAD^^) $(git rev-parse HEAD)) |
+ git notes copy --for-rewrite=foo &&
+ git log -1 > output &&
+ test_cmp expect output
+'
+
+test_expect_success 'git notes copy --for-rewrite (append empty)' '
+ git notes remove HEAD^ &&
+ echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
+ git notes copy --for-rewrite=foo &&
+ git log -1 > output &&
+ test_cmp expect output
+'
+
+cat > expect << EOF
+commit 37a0d4cba38afef96ba54a3ea567e6dac575700b
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:27:13 2005 -0700
+
+ 15th
+
+Notes (other):
+ replacement note 1
+EOF
+
+test_expect_success 'GIT_NOTES_REWRITE_MODE works' '
+ git notes add -f -m"replacement note 1" HEAD^ &&
+ echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
+ GIT_NOTES_REWRITE_MODE=overwrite git notes copy --for-rewrite=foo &&
+ git log -1 > output &&
+ test_cmp expect output
+'
+
+cat > expect << EOF
+commit 37a0d4cba38afef96ba54a3ea567e6dac575700b
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:27:13 2005 -0700
+
+ 15th
+
+Notes (other):
+ replacement note 2
+EOF
+
+test_expect_success 'GIT_NOTES_REWRITE_REF works' '
+ git config notes.rewriteMode overwrite &&
+ git notes add -f -m"replacement note 2" HEAD^ &&
+ git config --unset-all notes.rewriteRef &&
+ echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
+ GIT_NOTES_REWRITE_REF=refs/notes/commits:refs/notes/other \
+ git notes copy --for-rewrite=foo &&
+ git log -1 > output &&
+ test_cmp expect output
+'
+
+test_expect_success 'GIT_NOTES_REWRITE_REF overrides config' '
+ git config notes.rewriteRef refs/notes/other &&
+ git notes add -f -m"replacement note 3" HEAD^ &&
+ echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
+ GIT_NOTES_REWRITE_REF= git notes copy --for-rewrite=foo &&
+ git log -1 > output &&
+ test_cmp expect output
+'
test_done
diff --git a/t/t3303-notes-subtrees.sh b/t/t3303-notes-subtrees.sh
index edc4bc8841..75ec18778e 100755
--- a/t/t3303-notes-subtrees.sh
+++ b/t/t3303-notes-subtrees.sh
@@ -95,12 +95,12 @@ INPUT_END
test_expect_success 'test notes in 2/38-fanout' 'test_sha1_based "s|^..|&/|"'
test_expect_success 'verify notes in 2/38-fanout' 'verify_notes'
-test_expect_success 'test notes in 4/36-fanout' 'test_sha1_based "s|^....|&/|"'
-test_expect_success 'verify notes in 4/36-fanout' 'verify_notes'
-
test_expect_success 'test notes in 2/2/36-fanout' 'test_sha1_based "s|^\(..\)\(..\)|\1/\2/|"'
test_expect_success 'verify notes in 2/2/36-fanout' 'verify_notes'
+test_expect_success 'test notes in 2/2/2/34-fanout' 'test_sha1_based "s|^\(..\)\(..\)\(..\)|\1/\2/\3/|"'
+test_expect_success 'verify notes in 2/2/2/34-fanout' 'verify_notes'
+
test_same_notes () {
(
start_note_commit &&
@@ -128,14 +128,17 @@ INPUT_END
git fast-import --quiet
}
-test_expect_success 'test same notes in 4/36-fanout and 2/38-fanout' 'test_same_notes "s|^..|&/|" "s|^....|&/|"'
-test_expect_success 'verify same notes in 4/36-fanout and 2/38-fanout' 'verify_notes'
+test_expect_success 'test same notes in no fanout and 2/38-fanout' 'test_same_notes "s|^..|&/|" ""'
+test_expect_success 'verify same notes in no fanout and 2/38-fanout' 'verify_notes'
+
+test_expect_success 'test same notes in no fanout and 2/2/36-fanout' 'test_same_notes "s|^\(..\)\(..\)|\1/\2/|" ""'
+test_expect_success 'verify same notes in no fanout and 2/2/36-fanout' 'verify_notes'
test_expect_success 'test same notes in 2/38-fanout and 2/2/36-fanout' 'test_same_notes "s|^\(..\)\(..\)|\1/\2/|" "s|^..|&/|"'
test_expect_success 'verify same notes in 2/38-fanout and 2/2/36-fanout' 'verify_notes'
-test_expect_success 'test same notes in 4/36-fanout and 2/2/36-fanout' 'test_same_notes "s|^\(..\)\(..\)|\1/\2/|" "s|^....|&/|"'
-test_expect_success 'verify same notes in 4/36-fanout and 2/2/36-fanout' 'verify_notes'
+test_expect_success 'test same notes in 2/2/2/34-fanout and 2/2/36-fanout' 'test_same_notes "s|^\(..\)\(..\)|\1/\2/|" "s|^\(..\)\(..\)\(..\)|\1/\2/\3/|"'
+test_expect_success 'verify same notes in 2/2/2/34-fanout and 2/2/36-fanout' 'verify_notes'
test_concatenated_notes () {
(
@@ -176,13 +179,16 @@ verify_concatenated_notes () {
test_cmp expect output
}
-test_expect_success 'test notes in 4/36-fanout concatenated with 2/38-fanout' 'test_concatenated_notes "s|^..|&/|" "s|^....|&/|"'
-test_expect_success 'verify notes in 4/36-fanout concatenated with 2/38-fanout' 'verify_concatenated_notes'
+test_expect_success 'test notes in no fanout concatenated with 2/38-fanout' 'test_concatenated_notes "s|^..|&/|" ""'
+test_expect_success 'verify notes in no fanout concatenated with 2/38-fanout' 'verify_concatenated_notes'
+
+test_expect_success 'test notes in no fanout concatenated with 2/2/36-fanout' 'test_concatenated_notes "s|^\(..\)\(..\)|\1/\2/|" ""'
+test_expect_success 'verify notes in no fanout concatenated with 2/2/36-fanout' 'verify_concatenated_notes'
test_expect_success 'test notes in 2/38-fanout concatenated with 2/2/36-fanout' 'test_concatenated_notes "s|^\(..\)\(..\)|\1/\2/|" "s|^..|&/|"'
test_expect_success 'verify notes in 2/38-fanout concatenated with 2/2/36-fanout' 'verify_concatenated_notes'
-test_expect_success 'test notes in 4/36-fanout concatenated with 2/2/36-fanout' 'test_concatenated_notes "s|^\(..\)\(..\)|\1/\2/|" "s|^....|&/|"'
-test_expect_success 'verify notes in 4/36-fanout concatenated with 2/2/36-fanout' 'verify_concatenated_notes'
+test_expect_success 'test notes in 2/2/36-fanout concatenated with 2/2/2/34-fanout' 'test_concatenated_notes "s|^\(..\)\(..\)\(..\)|\1/\2/\3/|" "s|^\(..\)\(..\)|\1/\2/|"'
+test_expect_success 'verify notes in 2/2/36-fanout concatenated with 2/2/2/34-fanout' 'verify_concatenated_notes'
test_done
diff --git a/t/t3304-notes-mixed.sh b/t/t3304-notes-mixed.sh
index 256687ffb5..1709e8c00b 100755
--- a/t/t3304-notes-mixed.sh
+++ b/t/t3304-notes-mixed.sh
@@ -131,6 +131,17 @@ data <<EOF
another non-note with SHA1-like name
EOF
+M 644 inline de/adbeefdeadbeefdeadbeefdeadbeefdeadbeef
+data <<EOF
+This is actually a valid note, albeit to a non-existing object.
+It is needed in order to trigger the "mishandling" of the dead/beef non-note.
+EOF
+
+M 644 inline dead/beef
+data <<EOF
+yet another non-note with SHA1-like name
+EOF
+
INPUT_END
git fast-import --quiet <input &&
git config core.notesRef refs/notes/commits
@@ -158,6 +169,9 @@ EXPECT_END
cat >expect_nn3 <<EXPECT_END
another non-note with SHA1-like name
EXPECT_END
+cat >expect_nn4 <<EXPECT_END
+yet another non-note with SHA1-like name
+EXPECT_END
test_expect_success "verify contents of non-notes" '
@@ -166,7 +180,27 @@ test_expect_success "verify contents of non-notes" '
git cat-file -p refs/notes/commits:deadbeef > actual_nn2 &&
test_cmp expect_nn2 actual_nn2 &&
git cat-file -p refs/notes/commits:de/adbeef > actual_nn3 &&
- test_cmp expect_nn3 actual_nn3
+ test_cmp expect_nn3 actual_nn3 &&
+ git cat-file -p refs/notes/commits:dead/beef > actual_nn4 &&
+ test_cmp expect_nn4 actual_nn4
+'
+
+test_expect_success "git-notes preserves non-notes" '
+
+ test_tick &&
+ git notes add -f -m "foo bar"
+'
+
+test_expect_success "verify contents of non-notes after git-notes" '
+
+ git cat-file -p refs/notes/commits:foobar/non-note.txt > actual_nn1 &&
+ test_cmp expect_nn1 actual_nn1 &&
+ git cat-file -p refs/notes/commits:deadbeef > actual_nn2 &&
+ test_cmp expect_nn2 actual_nn2 &&
+ git cat-file -p refs/notes/commits:de/adbeef > actual_nn3 &&
+ test_cmp expect_nn3 actual_nn3 &&
+ git cat-file -p refs/notes/commits:dead/beef > actual_nn4 &&
+ test_cmp expect_nn4 actual_nn4
'
test_done
diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh
new file mode 100755
index 0000000000..b1ea64b213
--- /dev/null
+++ b/t/t3305-notes-fanout.sh
@@ -0,0 +1,95 @@
+#!/bin/sh
+
+test_description='Test that adding/removing many notes triggers automatic fanout restructuring'
+
+. ./test-lib.sh
+
+test_expect_success 'creating many notes with git-notes' '
+ num_notes=300 &&
+ i=0 &&
+ while test $i -lt $num_notes
+ do
+ i=$(($i + 1)) &&
+ test_tick &&
+ echo "file for commit #$i" > file &&
+ git add file &&
+ git commit -q -m "commit #$i" &&
+ git notes add -m "note #$i" || return 1
+ done
+'
+
+test_expect_success 'many notes created correctly with git-notes' '
+ git log | grep "^ " > output &&
+ i=300 &&
+ while test $i -gt 0
+ do
+ echo " commit #$i" &&
+ echo " note #$i" &&
+ i=$(($i - 1));
+ done > expect &&
+ test_cmp expect output
+'
+
+test_expect_success 'many notes created with git-notes triggers fanout' '
+ # Expect entire notes tree to have a fanout == 1
+ git ls-tree -r --name-only refs/notes/commits |
+ while read path
+ do
+ case "$path" in
+ ??/??????????????????????????????????????)
+ : true
+ ;;
+ *)
+ echo "Invalid path \"$path\"" &&
+ return 1
+ ;;
+ esac
+ done
+'
+
+test_expect_success 'deleting most notes with git-notes' '
+ num_notes=250 &&
+ i=0 &&
+ git rev-list HEAD |
+ while read sha1
+ do
+ i=$(($i + 1)) &&
+ if test $i -gt $num_notes
+ then
+ break
+ fi &&
+ test_tick &&
+ git notes remove "$sha1"
+ done
+'
+
+test_expect_success 'most notes deleted correctly with git-notes' '
+ git log HEAD~250 | grep "^ " > output &&
+ i=50 &&
+ while test $i -gt 0
+ do
+ echo " commit #$i" &&
+ echo " note #$i" &&
+ i=$(($i - 1));
+ done > expect &&
+ test_cmp expect output
+'
+
+test_expect_success 'deleting most notes triggers fanout consolidation' '
+ # Expect entire notes tree to have a fanout == 0
+ git ls-tree -r --name-only refs/notes/commits |
+ while read path
+ do
+ case "$path" in
+ ????????????????????????????????????????)
+ : true
+ ;;
+ *)
+ echo "Invalid path \"$path\"" &&
+ return 1
+ ;;
+ esac
+ done
+'
+
+test_done
diff --git a/t/t3306-notes-prune.sh b/t/t3306-notes-prune.sh
new file mode 100755
index 0000000000..a0ed0353e6
--- /dev/null
+++ b/t/t3306-notes-prune.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+
+test_description='Test git notes prune'
+
+. ./test-lib.sh
+
+test_expect_success 'setup: create a few commits with notes' '
+
+ : > file1 &&
+ git add file1 &&
+ test_tick &&
+ git commit -m 1st &&
+ git notes add -m "Note #1" &&
+ : > file2 &&
+ git add file2 &&
+ test_tick &&
+ git commit -m 2nd &&
+ git notes add -m "Note #2" &&
+ : > file3 &&
+ git add file3 &&
+ test_tick &&
+ git commit -m 3rd &&
+ git notes add -m "Note #3"
+'
+
+cat > expect <<END_OF_LOG
+commit 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:15:13 2005 -0700
+
+ 3rd
+
+Notes:
+ Note #3
+
+commit 08341ad9e94faa089d60fd3f523affb25c6da189
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:14:13 2005 -0700
+
+ 2nd
+
+Notes:
+ Note #2
+
+commit ab5f302035f2e7aaf04265f08b42034c23256e1f
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:13:13 2005 -0700
+
+ 1st
+
+Notes:
+ Note #1
+END_OF_LOG
+
+test_expect_success 'verify commits and notes' '
+
+ git log > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'remove some commits' '
+
+ git reset --hard HEAD~2 &&
+ git reflog expire --expire=now HEAD &&
+ git gc --prune=now
+'
+
+test_expect_success 'verify that commits are gone' '
+
+ ! git cat-file -p 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
+ ! git cat-file -p 08341ad9e94faa089d60fd3f523affb25c6da189 &&
+ git cat-file -p ab5f302035f2e7aaf04265f08b42034c23256e1f
+'
+
+test_expect_success 'verify that notes are still present' '
+
+ git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
+ git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
+ git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+'
+
+test_expect_success 'prune notes' '
+
+ git notes prune
+'
+
+test_expect_success 'verify that notes are gone' '
+
+ ! git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
+ ! git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
+ git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+'
+
+test_done
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 4314ad2d66..dbf7dfba9b 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -151,4 +151,21 @@ test_expect_success 'Rebase a commit that sprinkles CRs in' '
git diff --exit-code file-with-cr:CR HEAD:CR
'
+test_expect_success 'rebase can copy notes' '
+ git config notes.rewrite.rebase true &&
+ git config notes.rewriteRef "refs/notes/*" &&
+ test_commit n1 &&
+ test_commit n2 &&
+ test_commit n3 &&
+ git notes add -m"a note" n3 &&
+ git rebase --onto n1 n2 &&
+ test "a note" = "$(git notes show HEAD)"
+'
+
+test_expect_success 'rebase -m can copy notes' '
+ git reset --hard n3 &&
+ git rebase -m --onto n1 n2 &&
+ test "a note" = "$(git notes show HEAD)"
+'
+
test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 4e3513709e..f20ea38411 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -22,12 +22,18 @@ set_fake_editor
# | \
# | F - G - H (branch1)
# | \
-# \ I (branch2)
-# \
-# J - K - L - M (no-conflict-branch)
+# |\ I (branch2)
+# | \
+# | J - K - L - M (no-conflict-branch)
+# \
+# N - O - P (no-ff-branch)
#
# where A, B, D and G all touch file1, and one, two, three, four all
# touch file "conflict".
+#
+# WARNING: Modifications to the initial repository can change the SHA ID used
+# in the expect2 file for the 'stop on conflicting pick' test.
+
test_expect_success 'setup' '
test_commit A file1 &&
@@ -50,6 +56,11 @@ test_expect_success 'setup' '
for n in J K L M
do
test_commit $n file$n
+ done &&
+ git checkout -b no-ff-branch A &&
+ for n in N O P
+ do
+ test_commit $n file$n
done
'
@@ -113,7 +124,7 @@ cat > expect2 << EOF
D
=======
G
->>>>>>> 51047de... G
+>>>>>>> 5d18e54... G
EOF
test_expect_success 'stop on conflicting pick' '
@@ -553,4 +564,54 @@ test_expect_success 'reword' '
git show HEAD~2 | grep "C changed"
'
+test_expect_success 'rebase -i can copy notes' '
+ git config notes.rewrite.rebase true &&
+ git config notes.rewriteRef "refs/notes/*" &&
+ test_commit n1 &&
+ test_commit n2 &&
+ test_commit n3 &&
+ git notes add -m"a note" n3 &&
+ git rebase --onto n1 n2 &&
+ test "a note" = "$(git notes show HEAD)"
+'
+
+cat >expect <<EOF
+an earlier note
+a note
+EOF
+
+test_expect_success 'rebase -i can copy notes over a fixup' '
+ git reset --hard n3 &&
+ git notes add -m"an earlier note" n2 &&
+ GIT_NOTES_REWRITE_MODE=concatenate FAKE_LINES="1 fixup 2" git rebase -i n1 &&
+ git notes show > output &&
+ test_cmp expect output
+'
+
+test_expect_success 'rebase while detaching HEAD' '
+ git symbolic-ref HEAD &&
+ grandparent=$(git rev-parse HEAD~2) &&
+ test_tick &&
+ FAKE_LINES="2 1" git rebase -i HEAD~2 HEAD^0 &&
+ test $grandparent = $(git rev-parse HEAD~2) &&
+ test_must_fail git symbolic-ref HEAD
+'
+
+test_tick # Ensure that the rebased commits get a different timestamp.
+test_expect_success 'always cherry-pick with --no-ff' '
+ git checkout no-ff-branch &&
+ git tag original-no-ff-branch &&
+ git rebase -i --no-ff A &&
+ touch empty &&
+ for p in 0 1 2
+ do
+ test ! $(git rev-parse HEAD~$p) = $(git rev-parse original-no-ff-branch~$p) &&
+ git diff HEAD~$p original-no-ff-branch~$p > out &&
+ test_cmp empty out
+ done &&
+ test $(git rev-parse HEAD~3) = $(git rev-parse original-no-ff-branch~3) &&
+ git diff HEAD~3 original-no-ff-branch~3 > out &&
+ test_cmp empty out
+'
+
test_done
diff --git a/t/t3506-cherry-pick-ff.sh b/t/t3506-cherry-pick-ff.sh
new file mode 100755
index 0000000000..e17ae712b1
--- /dev/null
+++ b/t/t3506-cherry-pick-ff.sh
@@ -0,0 +1,98 @@
+#!/bin/sh
+
+test_description='test cherry-picking with --ff option'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ echo first > file1 &&
+ git add file1 &&
+ test_tick &&
+ git commit -m "first" &&
+ git tag first &&
+
+ git checkout -b other &&
+ echo second >> file1 &&
+ git add file1 &&
+ test_tick &&
+ git commit -m "second" &&
+ git tag second
+'
+
+test_expect_success 'cherry-pick using --ff fast forwards' '
+ git checkout master &&
+ git reset --hard first &&
+ test_tick &&
+ git cherry-pick --ff second &&
+ test "$(git rev-parse --verify HEAD)" = "$(git rev-parse --verify second)"
+'
+
+test_expect_success 'cherry-pick not using --ff does not fast forwards' '
+ git checkout master &&
+ git reset --hard first &&
+ test_tick &&
+ git cherry-pick second &&
+ test "$(git rev-parse --verify HEAD)" != "$(git rev-parse --verify second)"
+'
+
+#
+# We setup the following graph:
+#
+# B---C
+# / /
+# first---A
+#
+# (This has been taken from t3502-cherry-pick-merge.sh)
+#
+test_expect_success 'merge setup' '
+ git checkout master &&
+ git reset --hard first &&
+ echo new line >A &&
+ git add A &&
+ test_tick &&
+ git commit -m "add line to A" A &&
+ git tag A &&
+ git checkout -b side first &&
+ echo new line >B &&
+ git add B &&
+ test_tick &&
+ git commit -m "add line to B" B &&
+ git tag B &&
+ git checkout master &&
+ git merge side &&
+ git tag C &&
+ git checkout -b new A
+'
+
+test_expect_success 'cherry-pick a non-merge with --ff and -m should fail' '
+ git reset --hard A -- &&
+ test_must_fail git cherry-pick --ff -m 1 B &&
+ git diff --exit-code A --
+'
+
+test_expect_success 'cherry pick a merge with --ff but without -m should fail' '
+ git reset --hard A -- &&
+ test_must_fail git cherry-pick --ff C &&
+ git diff --exit-code A --
+'
+
+test_expect_success 'cherry pick with --ff a merge (1)' '
+ git reset --hard A -- &&
+ git cherry-pick --ff -m 1 C &&
+ git diff --exit-code C &&
+ test "$(git rev-parse --verify HEAD)" = "$(git rev-parse --verify C)"
+'
+
+test_expect_success 'cherry pick with --ff a merge (2)' '
+ git reset --hard B -- &&
+ git cherry-pick --ff -m 2 C &&
+ git diff --exit-code C &&
+ test "$(git rev-parse --verify HEAD)" = "$(git rev-parse --verify C)"
+'
+
+test_expect_success 'cherry pick a merge relative to nonexistent parent with --ff should fail' '
+ git reset --hard B -- &&
+ test_must_fail git cherry-pick --ff -m 3 C
+'
+
+test_done
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
new file mode 100755
index 0000000000..e25cf8039a
--- /dev/null
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -0,0 +1,198 @@
+#!/bin/sh
+
+test_description='test cherry-pick and revert with conflicts
+
+ -
+ + picked: rewrites foo to c
+ + base: rewrites foo to b
+ + initial: writes foo as a, unrelated as unrelated
+
+'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+ echo unrelated >unrelated &&
+ git add unrelated &&
+ test_commit initial foo a &&
+ test_commit base foo b &&
+ test_commit picked foo c &&
+ git config advice.detachedhead false
+
+'
+
+test_expect_success 'failed cherry-pick does not advance HEAD' '
+
+ git checkout -f initial^0 &&
+ git read-tree -u --reset HEAD &&
+ git clean -d -f -f -q -x &&
+
+ git update-index --refresh &&
+ git diff-index --exit-code HEAD &&
+
+ head=$(git rev-parse HEAD) &&
+ test_must_fail git cherry-pick picked &&
+ newhead=$(git rev-parse HEAD) &&
+
+ test "$head" = "$newhead"
+'
+
+test_expect_success 'failed cherry-pick produces dirty index' '
+
+ git checkout -f initial^0 &&
+ git read-tree -u --reset HEAD &&
+ git clean -d -f -f -q -x &&
+
+ git update-index --refresh &&
+ git diff-index --exit-code HEAD &&
+
+ test_must_fail git cherry-pick picked &&
+
+ test_must_fail git update-index --refresh -q &&
+ test_must_fail git diff-index --exit-code HEAD
+'
+
+test_expect_success 'failed cherry-pick registers participants in index' '
+
+ git read-tree -u --reset HEAD &&
+ git clean -d -f -f -q -x &&
+ {
+ git checkout base -- foo &&
+ git ls-files --stage foo &&
+ git checkout initial -- foo &&
+ git ls-files --stage foo &&
+ git checkout picked -- foo &&
+ git ls-files --stage foo
+ } > stages &&
+ sed "
+ 1 s/ 0 / 1 /
+ 2 s/ 0 / 2 /
+ 3 s/ 0 / 3 /
+ " < stages > expected &&
+ git checkout -f initial^0 &&
+
+ git update-index --refresh &&
+ git diff-index --exit-code HEAD &&
+
+ test_must_fail git cherry-pick picked &&
+ git ls-files --stage --unmerged > actual &&
+
+ test_cmp expected actual
+'
+
+test_expect_success 'failed cherry-pick describes conflict in work tree' '
+
+ git checkout -f initial^0 &&
+ git read-tree -u --reset HEAD &&
+ git clean -d -f -f -q -x &&
+ cat <<-EOF > expected &&
+ <<<<<<< HEAD
+ a
+ =======
+ c
+ >>>>>>> objid picked
+ EOF
+
+ git update-index --refresh &&
+ git diff-index --exit-code HEAD &&
+
+ test_must_fail git cherry-pick picked &&
+
+ sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'diff3 -m style' '
+
+ git config merge.conflictstyle diff3 &&
+ git checkout -f initial^0 &&
+ git read-tree -u --reset HEAD &&
+ git clean -d -f -f -q -x &&
+ cat <<-EOF > expected &&
+ <<<<<<< HEAD
+ a
+ ||||||| parent of objid picked
+ b
+ =======
+ c
+ >>>>>>> objid picked
+ EOF
+
+ git update-index --refresh &&
+ git diff-index --exit-code HEAD &&
+
+ test_must_fail git cherry-pick picked &&
+
+ sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'revert also handles conflicts sanely' '
+
+ git config --unset merge.conflictstyle &&
+ git read-tree -u --reset HEAD &&
+ git clean -d -f -f -q -x &&
+ cat <<-EOF > expected &&
+ <<<<<<< HEAD
+ a
+ =======
+ b
+ >>>>>>> parent of objid picked
+ EOF
+ {
+ git checkout picked -- foo &&
+ git ls-files --stage foo &&
+ git checkout initial -- foo &&
+ git ls-files --stage foo &&
+ git checkout base -- foo &&
+ git ls-files --stage foo
+ } > stages &&
+ sed "
+ 1 s/ 0 / 1 /
+ 2 s/ 0 / 2 /
+ 3 s/ 0 / 3 /
+ " < stages > expected-stages &&
+ git checkout -f initial^0 &&
+
+ git update-index --refresh &&
+ git diff-index --exit-code HEAD &&
+
+ head=$(git rev-parse HEAD) &&
+ test_must_fail git revert picked &&
+ newhead=$(git rev-parse HEAD) &&
+ git ls-files --stage --unmerged > actual-stages &&
+
+ test "$head" = "$newhead" &&
+ test_must_fail git update-index --refresh -q &&
+ test_must_fail git diff-index --exit-code HEAD &&
+ test_cmp expected-stages actual-stages &&
+ sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'revert conflict, diff3 -m style' '
+ git config merge.conflictstyle diff3 &&
+ git checkout -f initial^0 &&
+ git read-tree -u --reset HEAD &&
+ git clean -d -f -f -q -x &&
+ cat <<-EOF > expected &&
+ <<<<<<< HEAD
+ a
+ ||||||| objid picked
+ c
+ =======
+ b
+ >>>>>>> parent of objid picked
+ EOF
+
+ git update-index --refresh &&
+ git diff-index --exit-code HEAD &&
+
+ test_must_fail git revert picked &&
+
+ sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
+ test_cmp expected actual
+'
+
+test_done
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 6fb027ba57..8eb47942e2 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -22,10 +22,12 @@ check_verify_failure () {
###########################################################
# first create a commit, so we have a valid object/type
# for the tag.
-echo Hello >A
-git update-index --add A
-git commit -m "Initial commit"
-head=$(git rev-parse --verify HEAD)
+test_expect_success 'setup' '
+ echo Hello >A &&
+ git update-index --add A &&
+ git commit -m "Initial commit" &&
+ head=$(git rev-parse --verify HEAD)
+'
############################################################
# 1. length check
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 8e3694ed5b..dae6358516 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -204,6 +204,9 @@ log --root --patch-with-stat --summary master
log --root -c --patch-with-stat --summary master
# improved by Timo's patch
log --root --cc --patch-with-stat --summary master
+log -p --first-parent master
+log -m -p --first-parent master
+log -m -p master
log -SF master
log -SF -p master
log --decorate --all
@@ -235,6 +238,9 @@ show initial
show --root initial
show side
show master
+show -c master
+show -m master
+show --first-parent master
show --stat side
show --stat --summary side
show --patch-with-stat side
diff --git a/t/t4013/diff.log_-m_-p_--first-parent_master b/t/t4013/diff.log_-m_-p_--first-parent_master
new file mode 100644
index 0000000000..7a0073f529
--- /dev/null
+++ b/t/t4013/diff.log_-m_-p_--first-parent_master
@@ -0,0 +1,100 @@
+$ git log -m -p --first-parent master
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
+Merge: 9a6d494 c7a2ab9
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:04:00 2006 +0000
+
+ Merge branch 'side'
+
+diff --git a/dir/sub b/dir/sub
+index cead32e..992913c 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -4,3 +4,5 @@ C
+ D
+ E
+ F
++1
++2
+diff --git a/file0 b/file0
+index b414108..10a8a9f 100644
+--- a/file0
++++ b/file0
+@@ -4,3 +4,6 @@
+ 4
+ 5
+ 6
++A
++B
++C
+
+commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:02:00 2006 +0000
+
+ Third
+
+diff --git a/dir/sub b/dir/sub
+index 8422d40..cead32e 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -2,3 +2,5 @@ A
+ B
+ C
+ D
++E
++F
+diff --git a/file1 b/file1
+new file mode 100644
+index 0000000..b1e6722
+--- /dev/null
++++ b/file1
+@@ -0,0 +1,3 @@
++A
++B
++C
+
+commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:01:00 2006 +0000
+
+ Second
+
+ This is the second commit.
+
+diff --git a/dir/sub b/dir/sub
+index 35d242b..8422d40 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -1,2 +1,4 @@
+ A
+ B
++C
++D
+diff --git a/file0 b/file0
+index 01e79c3..b414108 100644
+--- a/file0
++++ b/file0
+@@ -1,3 +1,6 @@
+ 1
+ 2
+ 3
++4
++5
++6
+diff --git a/file2 b/file2
+deleted file mode 100644
+index 01e79c3..0000000
+--- a/file2
++++ /dev/null
+@@ -1,3 +0,0 @@
+-1
+-2
+-3
+
+commit 444ac553ac7612cc88969031b02b3767fb8a353a
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:00:00 2006 +0000
+
+ Initial
+$
diff --git a/t/t4013/diff.log_-m_-p_master b/t/t4013/diff.log_-m_-p_master
new file mode 100644
index 0000000000..9ca62a01ed
--- /dev/null
+++ b/t/t4013/diff.log_-m_-p_master
@@ -0,0 +1,200 @@
+$ git log -m -p master
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (from 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0)
+Merge: 9a6d494 c7a2ab9
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:04:00 2006 +0000
+
+ Merge branch 'side'
+
+diff --git a/dir/sub b/dir/sub
+index cead32e..992913c 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -4,3 +4,5 @@ C
+ D
+ E
+ F
++1
++2
+diff --git a/file0 b/file0
+index b414108..10a8a9f 100644
+--- a/file0
++++ b/file0
+@@ -4,3 +4,6 @@
+ 4
+ 5
+ 6
++A
++B
++C
+
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (from c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a)
+Merge: 9a6d494 c7a2ab9
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:04:00 2006 +0000
+
+ Merge branch 'side'
+
+diff --git a/dir/sub b/dir/sub
+index 7289e35..992913c 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -1,4 +1,8 @@
+ A
+ B
++C
++D
++E
++F
+ 1
+ 2
+diff --git a/file0 b/file0
+index f4615da..10a8a9f 100644
+--- a/file0
++++ b/file0
+@@ -1,6 +1,9 @@
+ 1
+ 2
+ 3
++4
++5
++6
+ A
+ B
+ C
+diff --git a/file1 b/file1
+new file mode 100644
+index 0000000..b1e6722
+--- /dev/null
++++ b/file1
+@@ -0,0 +1,3 @@
++A
++B
++C
+diff --git a/file2 b/file2
+deleted file mode 100644
+index 01e79c3..0000000
+--- a/file2
++++ /dev/null
+@@ -1,3 +0,0 @@
+-1
+-2
+-3
+diff --git a/file3 b/file3
+deleted file mode 100644
+index 7289e35..0000000
+--- a/file3
++++ /dev/null
+@@ -1,4 +0,0 @@
+-A
+-B
+-1
+-2
+
+commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:03:00 2006 +0000
+
+ Side
+
+diff --git a/dir/sub b/dir/sub
+index 35d242b..7289e35 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -1,2 +1,4 @@
+ A
+ B
++1
++2
+diff --git a/file0 b/file0
+index 01e79c3..f4615da 100644
+--- a/file0
++++ b/file0
+@@ -1,3 +1,6 @@
+ 1
+ 2
+ 3
++A
++B
++C
+diff --git a/file3 b/file3
+new file mode 100644
+index 0000000..7289e35
+--- /dev/null
++++ b/file3
+@@ -0,0 +1,4 @@
++A
++B
++1
++2
+
+commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:02:00 2006 +0000
+
+ Third
+
+diff --git a/dir/sub b/dir/sub
+index 8422d40..cead32e 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -2,3 +2,5 @@ A
+ B
+ C
+ D
++E
++F
+diff --git a/file1 b/file1
+new file mode 100644
+index 0000000..b1e6722
+--- /dev/null
++++ b/file1
+@@ -0,0 +1,3 @@
++A
++B
++C
+
+commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:01:00 2006 +0000
+
+ Second
+
+ This is the second commit.
+
+diff --git a/dir/sub b/dir/sub
+index 35d242b..8422d40 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -1,2 +1,4 @@
+ A
+ B
++C
++D
+diff --git a/file0 b/file0
+index 01e79c3..b414108 100644
+--- a/file0
++++ b/file0
+@@ -1,3 +1,6 @@
+ 1
+ 2
+ 3
++4
++5
++6
+diff --git a/file2 b/file2
+deleted file mode 100644
+index 01e79c3..0000000
+--- a/file2
++++ /dev/null
+@@ -1,3 +0,0 @@
+-1
+-2
+-3
+
+commit 444ac553ac7612cc88969031b02b3767fb8a353a
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:00:00 2006 +0000
+
+ Initial
+$
diff --git a/t/t4013/diff.log_-p_--first-parent_master b/t/t4013/diff.log_-p_--first-parent_master
new file mode 100644
index 0000000000..3fc896d424
--- /dev/null
+++ b/t/t4013/diff.log_-p_--first-parent_master
@@ -0,0 +1,78 @@
+$ git log -p --first-parent master
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
+Merge: 9a6d494 c7a2ab9
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:04:00 2006 +0000
+
+ Merge branch 'side'
+
+commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:02:00 2006 +0000
+
+ Third
+
+diff --git a/dir/sub b/dir/sub
+index 8422d40..cead32e 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -2,3 +2,5 @@ A
+ B
+ C
+ D
++E
++F
+diff --git a/file1 b/file1
+new file mode 100644
+index 0000000..b1e6722
+--- /dev/null
++++ b/file1
+@@ -0,0 +1,3 @@
++A
++B
++C
+
+commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:01:00 2006 +0000
+
+ Second
+
+ This is the second commit.
+
+diff --git a/dir/sub b/dir/sub
+index 35d242b..8422d40 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -1,2 +1,4 @@
+ A
+ B
++C
++D
+diff --git a/file0 b/file0
+index 01e79c3..b414108 100644
+--- a/file0
++++ b/file0
+@@ -1,3 +1,6 @@
+ 1
+ 2
+ 3
++4
++5
++6
+diff --git a/file2 b/file2
+deleted file mode 100644
+index 01e79c3..0000000
+--- a/file2
++++ /dev/null
+@@ -1,3 +0,0 @@
+-1
+-2
+-3
+
+commit 444ac553ac7612cc88969031b02b3767fb8a353a
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:00:00 2006 +0000
+
+ Initial
+$
diff --git a/t/t4013/diff.show_--first-parent_master b/t/t4013/diff.show_--first-parent_master
new file mode 100644
index 0000000000..3dcbe473a0
--- /dev/null
+++ b/t/t4013/diff.show_--first-parent_master
@@ -0,0 +1,30 @@
+$ git show --first-parent master
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
+Merge: 9a6d494 c7a2ab9
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:04:00 2006 +0000
+
+ Merge branch 'side'
+
+diff --git a/dir/sub b/dir/sub
+index cead32e..992913c 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -4,3 +4,5 @@ C
+ D
+ E
+ F
++1
++2
+diff --git a/file0 b/file0
+index b414108..10a8a9f 100644
+--- a/file0
++++ b/file0
+@@ -4,3 +4,6 @@
+ 4
+ 5
+ 6
++A
++B
++C
+$
diff --git a/t/t4013/diff.show_-c_master b/t/t4013/diff.show_-c_master
new file mode 100644
index 0000000000..81aba8da96
--- /dev/null
+++ b/t/t4013/diff.show_-c_master
@@ -0,0 +1,36 @@
+$ git show -c master
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
+Merge: 9a6d494 c7a2ab9
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:04:00 2006 +0000
+
+ Merge branch 'side'
+
+diff --combined dir/sub
+index cead32e,7289e35..992913c
+--- a/dir/sub
++++ b/dir/sub
+@@@ -1,6 -1,4 +1,8 @@@
+ A
+ B
+ +C
+ +D
+ +E
+ +F
++ 1
++ 2
+diff --combined file0
+index b414108,f4615da..10a8a9f
+--- a/file0
++++ b/file0
+@@@ -1,6 -1,6 +1,9 @@@
+ 1
+ 2
+ 3
+ +4
+ +5
+ +6
++ A
++ B
++ C
+$
diff --git a/t/t4013/diff.show_-m_master b/t/t4013/diff.show_-m_master
new file mode 100644
index 0000000000..4ea2ee453d
--- /dev/null
+++ b/t/t4013/diff.show_-m_master
@@ -0,0 +1,93 @@
+$ git show -m master
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (from 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0)
+Merge: 9a6d494 c7a2ab9
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:04:00 2006 +0000
+
+ Merge branch 'side'
+
+diff --git a/dir/sub b/dir/sub
+index cead32e..992913c 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -4,3 +4,5 @@ C
+ D
+ E
+ F
++1
++2
+diff --git a/file0 b/file0
+index b414108..10a8a9f 100644
+--- a/file0
++++ b/file0
+@@ -4,3 +4,6 @@
+ 4
+ 5
+ 6
++A
++B
++C
+
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (from c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a)
+Merge: 9a6d494 c7a2ab9
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:04:00 2006 +0000
+
+ Merge branch 'side'
+
+diff --git a/dir/sub b/dir/sub
+index 7289e35..992913c 100644
+--- a/dir/sub
++++ b/dir/sub
+@@ -1,4 +1,8 @@
+ A
+ B
++C
++D
++E
++F
+ 1
+ 2
+diff --git a/file0 b/file0
+index f4615da..10a8a9f 100644
+--- a/file0
++++ b/file0
+@@ -1,6 +1,9 @@
+ 1
+ 2
+ 3
++4
++5
++6
+ A
+ B
+ C
+diff --git a/file1 b/file1
+new file mode 100644
+index 0000000..b1e6722
+--- /dev/null
++++ b/file1
+@@ -0,0 +1,3 @@
++A
++B
++C
+diff --git a/file2 b/file2
+deleted file mode 100644
+index 01e79c3..0000000
+--- a/file2
++++ /dev/null
+@@ -1,3 +0,0 @@
+-1
+-2
+-3
+diff --git a/file3 b/file3
+deleted file mode 100644
+index 7289e35..0000000
+--- a/file3
++++ /dev/null
+@@ -1,4 +0,0 @@
+-A
+-B
+-1
+-2
+$
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 843ef7f88c..d21c37f3a2 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -143,6 +143,58 @@ test_expect_success 'configuration headers and command line headers' '
grep "^ *S. E. Cipient <scipient@example.com>\$" patch7
'
+test_expect_success 'command line To: header' '
+
+ git config --unset-all format.headers &&
+ git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
+ grep "^To: R. E. Cipient <rcipient@example.com>\$" patch8
+'
+
+test_expect_success 'configuration To: header' '
+
+ git config format.to "R. E. Cipient <rcipient@example.com>" &&
+ git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
+ grep "^To: R. E. Cipient <rcipient@example.com>\$" patch9
+'
+
+test_expect_success '--no-to overrides config.to' '
+
+ git config --replace-all format.to \
+ "R. E. Cipient <rcipient@example.com>" &&
+ git format-patch --no-to --stdout master..side |
+ sed -e "/^\$/q" >patch10 &&
+ ! grep "^To: R. E. Cipient <rcipient@example.com>\$" patch10
+'
+
+test_expect_success '--no-to and --to replaces config.to' '
+
+ git config --replace-all format.to \
+ "Someone <someone@out.there>" &&
+ git format-patch --no-to --to="Someone Else <else@out.there>" \
+ --stdout master..side |
+ sed -e "/^\$/q" >patch11 &&
+ ! grep "^To: Someone <someone@out.there>\$" patch11 &&
+ grep "^To: Someone Else <else@out.there>\$" patch11
+'
+
+test_expect_success '--no-cc overrides config.cc' '
+
+ git config --replace-all format.cc \
+ "C. E. Cipient <rcipient@example.com>" &&
+ git format-patch --no-cc --stdout master..side |
+ sed -e "/^\$/q" >patch12 &&
+ ! grep "^Cc: C. E. Cipient <rcipient@example.com>\$" patch12
+'
+
+test_expect_success '--no-add-headers overrides config.headers' '
+
+ git config --replace-all format.headers \
+ "Header1: B. E. Cipient <rcipient@example.com>" &&
+ git format-patch --no-add-headers --stdout master..side |
+ sed -e "/^\$/q" >patch13 &&
+ ! grep "^Header1: B. E. Cipient <rcipient@example.com>\$" patch13
+'
+
test_expect_success 'multiple files' '
rm -rf patches/ &&
diff --git a/t/t4041-diff-submodule.sh b/t/t4041-diff-submodule.sh
index 464305405a..019acb926d 100755
--- a/t/t4041-diff-submodule.sh
+++ b/t/t4041-diff-submodule.sh
@@ -201,7 +201,7 @@ test_expect_success 'submodule contains untracked content' "
echo new > sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
diff actual - <<-EOF
-Submodule sm1 $head6..$head6-dirty:
+Submodule sm1 contains untracked content
EOF
"
@@ -209,7 +209,8 @@ test_expect_success 'submodule contains untracked and modifed content' "
echo new > sm1/foo6 &&
git diff-index -p --submodule=log HEAD >actual &&
diff actual - <<-EOF
-Submodule sm1 $head6..$head6-dirty:
+Submodule sm1 contains untracked content
+Submodule sm1 contains modified content
EOF
"
@@ -217,7 +218,7 @@ test_expect_success 'submodule contains modifed content' "
rm -f sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
diff actual - <<-EOF
-Submodule sm1 $head6..$head6-dirty:
+Submodule sm1 contains modified content
EOF
"
@@ -235,7 +236,8 @@ test_expect_success 'modified submodule contains untracked content' "
echo new > sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
diff actual - <<-EOF
-Submodule sm1 $head6..$head8-dirty:
+Submodule sm1 contains untracked content
+Submodule sm1 $head6..$head8:
> change
EOF
"
@@ -244,7 +246,9 @@ test_expect_success 'modified submodule contains untracked and modifed content'
echo modification >> sm1/foo6 &&
git diff-index -p --submodule=log HEAD >actual &&
diff actual - <<-EOF
-Submodule sm1 $head6..$head8-dirty:
+Submodule sm1 contains untracked content
+Submodule sm1 contains modified content
+Submodule sm1 $head6..$head8:
> change
EOF
"
@@ -253,7 +257,8 @@ test_expect_success 'modified submodule contains modifed content' "
rm -f sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
diff actual - <<-EOF
-Submodule sm1 $head6..$head8-dirty:
+Submodule sm1 contains modified content
+Submodule sm1 $head6..$head8:
> change
EOF
"
@@ -324,4 +329,19 @@ index 0000000..$head7
EOF
"
+test_expect_success 'setup .git file for sm2' '
+ (cd sm2 &&
+ REAL="$(pwd)/../.real" &&
+ mv .git "$REAL"
+ echo "gitdir: $REAL" >.git)
+'
+
+test_expect_success 'diff --submodule with .git file' '
+ git diff --submodule HEAD^ >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head6...0000000 (submodule deleted)
+Submodule sm2 0000000...$head7 (new submodule)
+EOF
+'
+
test_done
diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh
index ad4cc1a757..9692f16f35 100755
--- a/t/t4103-apply-binary.sh
+++ b/t/t4103-apply-binary.sh
@@ -20,23 +20,25 @@ EOF
cat file1 >file2
cat file1 >file4
-git update-index --add --remove file1 file2 file4
-git commit -m 'Initial Version' 2>/dev/null
-
-git checkout -b binary
-perl -pe 'y/x/\000/' <file1 >file3
-cat file3 >file4
-git add file2
-perl -pe 'y/\000/v/' <file3 >file1
-rm -f file2
-git update-index --add --remove file1 file2 file3 file4
-git commit -m 'Second Version'
-
-git diff-tree -p master binary >B.diff
-git diff-tree -p -C master binary >C.diff
-
-git diff-tree -p --binary master binary >BF.diff
-git diff-tree -p --binary -C master binary >CF.diff
+test_expect_success 'setup' "
+ git update-index --add --remove file1 file2 file4 &&
+ git commit -m 'Initial Version' 2>/dev/null &&
+
+ git checkout -b binary &&
+ perl -pe 'y/x/\000/' <file1 >file3 &&
+ cat file3 >file4 &&
+ git add file2 &&
+ perl -pe 'y/\000/v/' <file3 >file1 &&
+ rm -f file2 &&
+ git update-index --add --remove file1 file2 file3 file4 &&
+ git commit -m 'Second Version' &&
+
+ git diff-tree -p master binary >B.diff &&
+ git diff-tree -p -C master binary >C.diff &&
+
+ git diff-tree -p --binary master binary >BF.diff &&
+ git diff-tree -p --binary -C master binary >CF.diff
+"
test_expect_success 'stat binary diff -- should not fail.' \
'git checkout master
diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh
index bb402c3780..70856d07ed 100755
--- a/t/t4200-rerere.sh
+++ b/t/t4200-rerere.sh
@@ -8,40 +8,42 @@ test_description='git rerere
. ./test-lib.sh
-cat > a1 << EOF
-Some title
-==========
-Whether 'tis nobler in the mind to suffer
-The slings and arrows of outrageous fortune,
-Or to take arms against a sea of troubles,
-And by opposing end them? To die: to sleep;
-No more; and by a sleep to say we end
-The heart-ache and the thousand natural shocks
-That flesh is heir to, 'tis a consummation
-Devoutly to be wish'd.
-EOF
-
-git add a1
-git commit -q -a -m initial
-
-git checkout -b first
-cat >> a1 << EOF
-Some title
-==========
-To die, to sleep;
-To sleep: perchance to dream: ay, there's the rub;
-For in that sleep of death what dreams may come
-When we have shuffled off this mortal coil,
-Must give us pause: there's the respect
-That makes calamity of so long life;
-EOF
-git commit -q -a -m first
-
-git checkout -b second master
-git show first:a1 |
-sed -e 's/To die, t/To die! T/' -e 's/Some title/Some Title/' > a1
-echo "* END *" >>a1
-git commit -q -a -m second
+test_expect_success 'setup' "
+ cat > a1 <<- EOF &&
+ Some title
+ ==========
+ Whether 'tis nobler in the mind to suffer
+ The slings and arrows of outrageous fortune,
+ Or to take arms against a sea of troubles,
+ And by opposing end them? To die: to sleep;
+ No more; and by a sleep to say we end
+ The heart-ache and the thousand natural shocks
+ That flesh is heir to, 'tis a consummation
+ Devoutly to be wish'd.
+ EOF
+
+ git add a1 &&
+ git commit -q -a -m initial &&
+
+ git checkout -b first &&
+ cat >> a1 <<- EOF &&
+ Some title
+ ==========
+ To die, to sleep;
+ To sleep: perchance to dream: ay, there's the rub;
+ For in that sleep of death what dreams may come
+ When we have shuffled off this mortal coil,
+ Must give us pause: there's the respect
+ That makes calamity of so long life;
+ EOF
+ git commit -q -a -m first &&
+
+ git checkout -b second master &&
+ git show first:a1 |
+ sed -e 's/To die, t/To die! T/' -e 's/Some title/Some Title/' > a1 &&
+ echo '* END *' >>a1 &&
+ git commit -q -a -m second
+"
test_expect_success 'nothing recorded without rerere' '
(rm -rf .git/rr-cache; git config rerere.enabled false) &&
diff --git a/t/t4253-am-keep-cr-dos.sh b/t/t4253-am-keep-cr-dos.sh
new file mode 100755
index 0000000000..735e55d77c
--- /dev/null
+++ b/t/t4253-am-keep-cr-dos.sh
@@ -0,0 +1,96 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Stefan-W. Hahn
+#
+
+test_description='git-am mbox with dos line ending.
+
+'
+. ./test-lib.sh
+
+# Three patches which will be added as files with dos line ending.
+
+cat >file1 <<\EOF
+line 1
+EOF
+
+cat >file1a <<\EOF
+line 1
+line 4
+EOF
+
+cat >file2 <<\EOF
+line 1
+line 2
+EOF
+
+cat >file3 <<\EOF
+line 1
+line 2
+line 3
+EOF
+
+test_expect_success 'setup repository with dos files' '
+ append_cr <file1 >file &&
+ git add file &&
+ git commit -m Initial &&
+ git tag initial &&
+ append_cr <file2 >file &&
+ git commit -a -m Second &&
+ append_cr <file3 >file &&
+ git commit -a -m Third
+'
+
+test_expect_success 'am with dos files without --keep-cr' '
+ git checkout -b dosfiles initial &&
+ git format-patch -k initial..master &&
+ test_must_fail git am -k -3 000*.patch &&
+ git am --abort &&
+ rm -rf .git/rebase-apply 000*.patch
+'
+
+test_expect_success 'am with dos files with --keep-cr' '
+ git checkout -b dosfiles-keep-cr initial &&
+ git format-patch -k --stdout initial..master | git am --keep-cr -k -3 &&
+ git diff --exit-code master
+'
+
+test_expect_success 'am with dos files config am.keepcr' '
+ git config am.keepcr 1 &&
+ git checkout -b dosfiles-conf-keepcr initial &&
+ git format-patch -k --stdout initial..master | git am -k -3 &&
+ git diff --exit-code master
+'
+
+test_expect_success 'am with dos files config am.keepcr overriden by --no-keep-cr' '
+ git config am.keepcr 1 &&
+ git checkout -b dosfiles-conf-keepcr-override initial &&
+ git format-patch -k initial..master &&
+ test_must_fail git am -k -3 --no-keep-cr 000*.patch &&
+ git am --abort &&
+ rm -rf .git/rebase-apply 000*.patch
+'
+
+test_expect_success 'am with dos files with --keep-cr continue' '
+ git checkout -b dosfiles-keep-cr-continue initial &&
+ git format-patch -k initial..master &&
+ append_cr <file1a >file &&
+ git commit -m "different patch" file &&
+ test_must_fail git am --keep-cr -k -3 000*.patch &&
+ append_cr <file2 >file &&
+ git add file &&
+ git am -3 --resolved &&
+ git diff --exit-code master
+'
+
+test_expect_success 'am with unix files config am.keepcr overriden by --no-keep-cr' '
+ git config am.keepcr 1 &&
+ git checkout -b unixfiles-conf-keepcr-override initial &&
+ cp -f file1 file &&
+ git commit -m "line ending to unix" file &&
+ git format-patch -k initial..master &&
+ git am -k -3 --no-keep-cr 000*.patch &&
+ git diff --exit-code -w master
+'
+
+test_done
diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh
new file mode 100755
index 0000000000..552da65a61
--- /dev/null
+++ b/t/t5407-post-rewrite-hook.sh
@@ -0,0 +1,199 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Thomas Rast
+#
+
+test_description='Test the post-rewrite hook.'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit A foo A &&
+ test_commit B foo B &&
+ test_commit C foo C &&
+ test_commit D foo D
+'
+
+mkdir .git/hooks
+
+cat >.git/hooks/post-rewrite <<EOF
+#!/bin/sh
+echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args
+cat > "$TRASH_DIRECTORY"/post-rewrite.data
+EOF
+chmod u+x .git/hooks/post-rewrite
+
+clear_hook_input () {
+ rm -f post-rewrite.args post-rewrite.data
+}
+
+verify_hook_input () {
+ test_cmp "$TRASH_DIRECTORY"/post-rewrite.args expected.args &&
+ test_cmp "$TRASH_DIRECTORY"/post-rewrite.data expected.data
+}
+
+test_expect_success 'git commit --amend' '
+ clear_hook_input &&
+ echo "D new message" > newmsg &&
+ oldsha=$(git rev-parse HEAD^0) &&
+ git commit -Fnewmsg --amend &&
+ echo amend > expected.args &&
+ echo $oldsha $(git rev-parse HEAD^0) > expected.data &&
+ verify_hook_input
+'
+
+test_expect_success 'git commit --amend --no-post-rewrite' '
+ clear_hook_input &&
+ echo "D new message again" > newmsg &&
+ git commit --no-post-rewrite -Fnewmsg --amend &&
+ test ! -f post-rewrite.args &&
+ test ! -f post-rewrite.data
+'
+
+test_expect_success 'git rebase' '
+ git reset --hard D &&
+ clear_hook_input &&
+ test_must_fail git rebase --onto A B &&
+ echo C > foo &&
+ git add foo &&
+ git rebase --continue &&
+ echo rebase >expected.args &&
+ cat >expected.data <<EOF &&
+$(git rev-parse C) $(git rev-parse HEAD^)
+$(git rev-parse D) $(git rev-parse HEAD)
+EOF
+ verify_hook_input
+'
+
+test_expect_success 'git rebase --skip' '
+ git reset --hard D &&
+ clear_hook_input &&
+ test_must_fail git rebase --onto A B &&
+ test_must_fail git rebase --skip &&
+ echo D > foo &&
+ git add foo &&
+ git rebase --continue &&
+ echo rebase >expected.args &&
+ cat >expected.data <<EOF &&
+$(git rev-parse D) $(git rev-parse HEAD)
+EOF
+ verify_hook_input
+'
+
+test_expect_success 'git rebase -m' '
+ git reset --hard D &&
+ clear_hook_input &&
+ test_must_fail git rebase -m --onto A B &&
+ echo C > foo &&
+ git add foo &&
+ git rebase --continue &&
+ echo rebase >expected.args &&
+ cat >expected.data <<EOF &&
+$(git rev-parse C) $(git rev-parse HEAD^)
+$(git rev-parse D) $(git rev-parse HEAD)
+EOF
+ verify_hook_input
+'
+
+test_expect_success 'git rebase -m --skip' '
+ git reset --hard D &&
+ clear_hook_input &&
+ test_must_fail git rebase --onto A B &&
+ test_must_fail git rebase --skip &&
+ echo D > foo &&
+ git add foo &&
+ git rebase --continue &&
+ echo rebase >expected.args &&
+ cat >expected.data <<EOF &&
+$(git rev-parse D) $(git rev-parse HEAD)
+EOF
+ verify_hook_input
+'
+
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+set_fake_editor
+
+# Helper to work around the lack of one-shot exporting for
+# test_must_fail (as it is a shell function)
+test_fail_interactive_rebase () {
+ (
+ FAKE_LINES="$1" &&
+ shift &&
+ export FAKE_LINES &&
+ test_must_fail git rebase -i "$@"
+ )
+}
+
+test_expect_success 'git rebase -i (unchanged)' '
+ git reset --hard D &&
+ clear_hook_input &&
+ test_fail_interactive_rebase "1 2" --onto A B &&
+ echo C > foo &&
+ git add foo &&
+ git rebase --continue &&
+ echo rebase >expected.args &&
+ cat >expected.data <<EOF &&
+$(git rev-parse C) $(git rev-parse HEAD^)
+$(git rev-parse D) $(git rev-parse HEAD)
+EOF
+ verify_hook_input
+'
+
+test_expect_success 'git rebase -i (skip)' '
+ git reset --hard D &&
+ clear_hook_input &&
+ test_fail_interactive_rebase "2" --onto A B &&
+ echo D > foo &&
+ git add foo &&
+ git rebase --continue &&
+ echo rebase >expected.args &&
+ cat >expected.data <<EOF &&
+$(git rev-parse D) $(git rev-parse HEAD)
+EOF
+ verify_hook_input
+'
+
+test_expect_success 'git rebase -i (squash)' '
+ git reset --hard D &&
+ clear_hook_input &&
+ test_fail_interactive_rebase "1 squash 2" --onto A B &&
+ echo C > foo &&
+ git add foo &&
+ git rebase --continue &&
+ echo rebase >expected.args &&
+ cat >expected.data <<EOF &&
+$(git rev-parse C) $(git rev-parse HEAD)
+$(git rev-parse D) $(git rev-parse HEAD)
+EOF
+ verify_hook_input
+'
+
+test_expect_success 'git rebase -i (fixup without conflict)' '
+ git reset --hard D &&
+ clear_hook_input &&
+ FAKE_LINES="1 fixup 2" git rebase -i B &&
+ echo rebase >expected.args &&
+ cat >expected.data <<EOF &&
+$(git rev-parse C) $(git rev-parse HEAD)
+$(git rev-parse D) $(git rev-parse HEAD)
+EOF
+ verify_hook_input
+'
+
+test_expect_success 'git rebase -i (double edit)' '
+ git reset --hard D &&
+ clear_hook_input &&
+ FAKE_LINES="edit 1 edit 2" git rebase -i B &&
+ git rebase --continue &&
+ echo something > foo &&
+ git add foo &&
+ git rebase --continue &&
+ echo rebase >expected.args &&
+ cat >expected.data <<EOF &&
+$(git rev-parse C) $(git rev-parse HEAD^)
+$(git rev-parse D) $(git rev-parse HEAD)
+EOF
+ verify_hook_input
+'
+
+test_done
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 2692050209..230c0cd784 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -110,17 +110,18 @@ test_expect_success 'remove remote' '
test_expect_success 'remove remote protects non-remote branches' '
(
cd test &&
- (cat >expect1 <<EOF
+ { cat >expect1 <<EOF
Note: A non-remote branch was not removed; to delete it, use:
git branch -d master
EOF
- cat >expect2 <<EOF
+ } &&
+ { cat >expect2 <<EOF
Note: Non-remote branches were not removed; to delete them, use:
git branch -d foobranch
git branch -d master
EOF
-) &&
- git tag footag
+ } &&
+ git tag footag &&
git config --add remote.oops.fetch "+refs/*:refs/*" &&
git remote rm oops 2>actual1 &&
git branch foobranch &&
@@ -534,43 +535,34 @@ test_expect_success 'show empty remote' '
'
test_expect_success 'new remote' '
-(
git remote add someremote foo &&
echo foo >expect &&
git config --get-all remote.someremote.url >actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url bar' '
-(
git remote set-url someremote bar &&
echo bar >expect &&
git config --get-all remote.someremote.url >actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url baz bar' '
-(
git remote set-url someremote baz bar &&
echo baz >expect &&
git config --get-all remote.someremote.url >actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url zot bar' '
-(
test_must_fail git remote set-url someremote zot bar &&
echo baz >expect &&
git config --get-all remote.someremote.url >actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --push zot baz' '
-(
test_must_fail git remote set-url --push someremote zot baz &&
echo "YYY" >expect &&
echo baz >>expect &&
@@ -578,11 +570,9 @@ test_expect_success 'remote set-url --push zot baz' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --push zot' '
-(
git remote set-url --push someremote zot &&
echo zot >expect &&
echo "YYY" >>expect &&
@@ -591,11 +581,9 @@ test_expect_success 'remote set-url --push zot' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --push qux zot' '
-(
git remote set-url --push someremote qux zot &&
echo qux >expect &&
echo "YYY" >>expect &&
@@ -604,11 +592,9 @@ test_expect_success 'remote set-url --push qux zot' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --push foo qu+x' '
-(
git remote set-url --push someremote foo qu+x &&
echo foo >expect &&
echo "YYY" >>expect &&
@@ -617,11 +603,9 @@ test_expect_success 'remote set-url --push foo qu+x' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --push --add aaa' '
-(
git remote set-url --push --add someremote aaa &&
echo foo >expect &&
echo aaa >>expect &&
@@ -631,11 +615,9 @@ test_expect_success 'remote set-url --push --add aaa' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --push bar aaa' '
-(
git remote set-url --push someremote bar aaa &&
echo foo >expect &&
echo bar >>expect &&
@@ -645,11 +627,9 @@ test_expect_success 'remote set-url --push bar aaa' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --push --delete bar' '
-(
git remote set-url --push --delete someremote bar &&
echo foo >expect &&
echo "YYY" >>expect &&
@@ -658,11 +638,9 @@ test_expect_success 'remote set-url --push --delete bar' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --push --delete foo' '
-(
git remote set-url --push --delete someremote foo &&
echo "YYY" >expect &&
echo baz >>expect &&
@@ -670,11 +648,9 @@ test_expect_success 'remote set-url --push --delete foo' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --add bbb' '
-(
git remote set-url --add someremote bbb &&
echo "YYY" >expect &&
echo baz >>expect &&
@@ -683,12 +659,10 @@ test_expect_success 'remote set-url --add bbb' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --delete .*' '
-(
- test_must_fail git remote set-url --delete someremote .* &&
+ test_must_fail git remote set-url --delete someremote .\* &&
echo "YYY" >expect &&
echo baz >>expect &&
echo bbb >>expect &&
@@ -696,11 +670,9 @@ test_expect_success 'remote set-url --delete .*' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --delete bbb' '
-(
git remote set-url --delete someremote bbb &&
echo "YYY" >expect &&
echo baz >>expect &&
@@ -708,11 +680,9 @@ test_expect_success 'remote set-url --delete bbb' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --delete baz' '
-(
test_must_fail git remote set-url --delete someremote baz &&
echo "YYY" >expect &&
echo baz >>expect &&
@@ -720,11 +690,9 @@ test_expect_success 'remote set-url --delete baz' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --add ccc' '
-(
git remote set-url --add someremote ccc &&
echo "YYY" >expect &&
echo baz >>expect &&
@@ -733,11 +701,9 @@ test_expect_success 'remote set-url --add ccc' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_expect_success 'remote set-url --delete baz' '
-(
git remote set-url --delete someremote baz &&
echo "YYY" >expect &&
echo ccc >>expect &&
@@ -745,7 +711,6 @@ test_expect_success 'remote set-url --delete baz' '
echo "YYY" >>actual &&
git config --get-all remote.someremote.url >>actual &&
cmp expect actual
-)
'
test_done
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 169af1edde..721821ec92 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -341,6 +341,13 @@ test_expect_success 'fetch into the current branch with --update-head-ok' '
'
+test_expect_success 'fetch --dry-run' '
+
+ rm -f .git/FETCH_HEAD &&
+ git fetch --dry-run . &&
+ ! test -f .git/FETCH_HEAD
+'
+
test_expect_success "should be able to fetch with duplicate refspecs" '
mkdir dups &&
cd dups &&
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 0f04b2e894..2de98e6561 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -660,4 +660,54 @@ test_expect_success 'push with branches containing #' '
git checkout master
'
+test_expect_success 'push --porcelain' '
+ mk_empty &&
+ echo >.git/foo "To testrepo" &&
+ echo >>.git/foo "* refs/heads/master:refs/remotes/origin/master [new branch]" &&
+ echo >>.git/foo "Done" &&
+ git push >.git/bar --porcelain testrepo refs/heads/master:refs/remotes/origin/master &&
+ (
+ cd testrepo &&
+ r=$(git show-ref -s --verify refs/remotes/origin/master) &&
+ test "z$r" = "z$the_commit" &&
+ test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
+ ) &&
+ test_cmp .git/foo .git/bar
+'
+
+test_expect_success 'push --porcelain bad url' '
+ mk_empty &&
+ test_must_fail git push >.git/bar --porcelain asdfasdfasd refs/heads/master:refs/remotes/origin/master &&
+ test_must_fail grep -q Done .git/bar
+'
+
+test_expect_success 'push --porcelain rejected' '
+ mk_empty &&
+ git push testrepo refs/heads/master:refs/remotes/origin/master &&
+ (cd testrepo &&
+ git reset --hard origin/master^
+ git config receive.denyCurrentBranch true) &&
+
+ echo >.git/foo "To testrepo" &&
+ echo >>.git/foo "! refs/heads/master:refs/heads/master [remote rejected] (branch is currently checked out)" &&
+
+ test_must_fail git push >.git/bar --porcelain testrepo refs/heads/master:refs/heads/master &&
+ test_cmp .git/foo .git/bar
+'
+
+test_expect_success 'push --porcelain --dry-run rejected' '
+ mk_empty &&
+ git push testrepo refs/heads/master:refs/remotes/origin/master &&
+ (cd testrepo &&
+ git reset --hard origin/master
+ git config receive.denyCurrentBranch true) &&
+
+ echo >.git/foo "To testrepo" &&
+ echo >>.git/foo "! refs/heads/master^:refs/heads/master [rejected] (non-fast-forward)" &&
+ echo >>.git/foo "Done" &&
+
+ test_must_fail git push >.git/bar --porcelain --dry-run testrepo refs/heads/master^:refs/heads/master &&
+ test_cmp .git/foo .git/bar
+'
+
test_done
diff --git a/t/t5540-http-push.sh b/t/t5540-http-push.sh
index bb18f8bfc4..37fe875411 100755
--- a/t/t5540-http-push.sh
+++ b/t/t5540-http-push.sh
@@ -137,6 +137,9 @@ test_expect_success 'PUT and MOVE sends object to URLs with SHA-1 hash suffix' '
'
+test_http_push_nonff "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \
+ "$ROOT_PATH"/test_repo_clone master
+
stop_httpd
test_done
diff --git a/t/t5541-http-push.sh b/t/t5541-http-push.sh
index 53f54a2789..795dc2bcdf 100755
--- a/t/t5541-http-push.sh
+++ b/t/t5541-http-push.sh
@@ -88,26 +88,8 @@ test_expect_success 'used receive-pack service' '
test_cmp exp act
'
-test_expect_success 'non-fast-forward push fails' '
- cd "$ROOT_PATH"/test_repo_clone &&
- git checkout master &&
- echo "changed" > path2 &&
- git commit -a -m path2 --amend &&
-
- HEAD=$(git rev-parse --verify HEAD) &&
- !(git push -v origin >output 2>&1) &&
- (cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
- test $HEAD != $(git rev-parse --verify HEAD))
-'
-
-test_expect_success 'non-fast-forward push show ref status' '
- grep "^ ! \[rejected\][ ]*master -> master (non-fast-forward)$" output
-'
-
-test_expect_success 'non-fast-forward push shows help message' '
- grep "To prevent you from losing history, non-fast-forward updates were rejected" \
- output
-'
+test_http_push_nonff "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \
+ "$ROOT_PATH"/test_repo_clone master
test_expect_success 'push fails for non-fast-forward refs unmatched by remote helper' '
# create a dissimilarly-named remote ref so that git is unable to match the
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 214756731b..678cee502d 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -34,7 +34,7 @@ test_expect_success 'clone with excess parameters (2)' '
test_expect_success 'output from clone' '
rm -fr dst &&
git clone -n "file://$(pwd)/src" dst >output &&
- test $(grep Initialized output | wc -l) = 1
+ test $(grep Clon output | wc -l) = 1
'
test_expect_success 'clone does not keep pack' '
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index d24ca5c077..a49b7c5722 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -213,7 +213,7 @@ test_expect_success 'oneline with empty message' '
git commit -m "dummy" --allow-empty &&
git commit -m "dummy" --allow-empty &&
git filter-branch --msg-filter "sed -e s/dummy//" HEAD^^.. &&
- git rev-list --oneline HEAD > /tmp/test.txt &&
+ git rev-list --oneline HEAD >test.txt &&
test $(git rev-list --oneline HEAD | wc -l) -eq 5 &&
test $(git rev-list --oneline --graph HEAD | wc -l) -eq 5
'
diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh
index 6291307cd0..d486d73994 100755
--- a/t/t6023-merge-file.sh
+++ b/t/t6023-merge-file.sh
@@ -64,6 +64,10 @@ cp new1.txt test.txt
test_expect_success "merge without conflict" \
"git merge-file test.txt orig.txt new2.txt"
+cp new1.txt test.txt
+test_expect_success "merge without conflict (--quiet)" \
+ "git merge-file --quiet test.txt orig.txt new2.txt"
+
cp new1.txt test2.txt
test_expect_success "merge without conflict (missing LF at EOF)" \
"git merge-file test2.txt orig.txt new2.txt"
@@ -177,7 +181,7 @@ et nihil mihi deerit;
In loco pascuae ibi me collocavit;
super aquam refectionis educavit me.
-|||||||
+||||||| new5.txt
et nihil mihi deerit.
In loco pascuae ibi me collocavit,
super aquam refectionis educavit me;
@@ -211,4 +215,41 @@ test_expect_success '"diff3 -m" style output (2)' '
test_cmp expect actual
'
+cat >expect <<\EOF
+Dominus regit me,
+<<<<<<<<<< new8.txt
+et nihil mihi deerit;
+
+
+
+
+In loco pascuae ibi me collocavit;
+super aquam refectionis educavit me.
+|||||||||| new5.txt
+et nihil mihi deerit.
+In loco pascuae ibi me collocavit,
+super aquam refectionis educavit me;
+==========
+et nihil mihi deerit,
+
+
+
+
+In loco pascuae ibi me collocavit --
+super aquam refectionis educavit me,
+>>>>>>>>>> new9.txt
+animam meam convertit,
+deduxit me super semitas jusitiae,
+propter nomen suum.
+Nam et si ambulavero in medio umbrae mortis,
+non timebo mala, quoniam TU mecum es:
+virga tua et baculus tuus ipsa me consolata sunt.
+EOF
+
+test_expect_success 'marker size' '
+ test_must_fail git merge-file -p --marker-size=10 \
+ new8.txt new5.txt new9.txt >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
index 42f6fff373..42f8ece097 100755
--- a/t/t6200-fmt-merge-msg.sh
+++ b/t/t6200-fmt-merge-msg.sh
@@ -7,65 +7,69 @@ test_description='fmt-merge-msg test'
. ./test-lib.sh
-datestamp=1151939923
-setdate () {
- GIT_COMMITTER_DATE="$datestamp +0200"
- GIT_AUTHOR_DATE="$datestamp +0200"
- datestamp=`expr "$datestamp" + 1`
- export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
-}
-
test_expect_success setup '
echo one >one &&
git add one &&
- setdate &&
+ test_tick &&
git commit -m "Initial" &&
+ git clone . remote &&
+
echo uno >one &&
echo dos >two &&
git add two &&
- setdate &&
+ test_tick &&
git commit -a -m "Second" &&
git checkout -b left &&
- echo $datestamp >one &&
- setdate &&
+ echo "c1" >one &&
+ test_tick &&
git commit -a -m "Common #1" &&
- echo $datestamp >one &&
- setdate &&
+ echo "c2" >one &&
+ test_tick &&
git commit -a -m "Common #2" &&
git branch right &&
- echo $datestamp >two &&
- setdate &&
+ echo "l3" >two &&
+ test_tick &&
git commit -a -m "Left #3" &&
- echo $datestamp >two &&
- setdate &&
+ echo "l4" >two &&
+ test_tick &&
git commit -a -m "Left #4" &&
- echo $datestamp >two &&
- setdate &&
+ echo "l5" >two &&
+ test_tick &&
git commit -a -m "Left #5" &&
+ git tag tag-l5 &&
git checkout right &&
- echo $datestamp >three &&
+ echo "r3" >three &&
git add three &&
- setdate &&
+ test_tick &&
git commit -a -m "Right #3" &&
+ git tag tag-r3 &&
- echo $datestamp >three &&
- setdate &&
+ echo "r4" >three &&
+ test_tick &&
git commit -a -m "Right #4" &&
- echo $datestamp >three &&
- setdate &&
+ echo "r5" >three &&
+ test_tick &&
git commit -a -m "Right #5" &&
+ git checkout -b long &&
+ i=0 &&
+ while test $i -lt 30
+ do
+ test_commit $i one &&
+ i=$(($i+1))
+ done &&
+
git show-branch
'
@@ -113,7 +117,7 @@ test_expect_success 'merge-msg test #3-1' '
git config merge.log true &&
git checkout master &&
- setdate &&
+ test_tick &&
git fetch . left &&
git fmt-merge-msg <.git/FETCH_HEAD >actual &&
@@ -127,7 +131,7 @@ test_expect_success 'merge-msg test #3-2' '
git config merge.summary true &&
git checkout master &&
- setdate &&
+ test_tick &&
git fetch . left &&
git fmt-merge-msg <.git/FETCH_HEAD >actual &&
@@ -159,7 +163,7 @@ test_expect_success 'merge-msg test #4-1' '
git config merge.log true &&
git checkout master &&
- setdate &&
+ test_tick &&
git fetch . left right &&
git fmt-merge-msg <.git/FETCH_HEAD >actual &&
@@ -173,7 +177,7 @@ test_expect_success 'merge-msg test #4-2' '
git config merge.summary true &&
git checkout master &&
- setdate &&
+ test_tick &&
git fetch . left right &&
git fmt-merge-msg <.git/FETCH_HEAD >actual &&
@@ -187,7 +191,7 @@ test_expect_success 'merge-msg test #5-1' '
git config merge.log yes &&
git checkout master &&
- setdate &&
+ test_tick &&
git fetch . left right &&
git fmt-merge-msg <.git/FETCH_HEAD >actual &&
@@ -201,7 +205,7 @@ test_expect_success 'merge-msg test #5-2' '
git config merge.summary yes &&
git checkout master &&
- setdate &&
+ test_tick &&
git fetch . left right &&
git fmt-merge-msg <.git/FETCH_HEAD >actual &&
@@ -215,7 +219,7 @@ test_expect_success 'merge-msg -F' '
git config merge.summary yes &&
git checkout master &&
- setdate &&
+ test_tick &&
git fetch . left right &&
git fmt-merge-msg -F .git/FETCH_HEAD >actual &&
@@ -229,7 +233,7 @@ test_expect_success 'merge-msg -F in subdirectory' '
git config merge.summary yes &&
git checkout master &&
- setdate &&
+ test_tick &&
git fetch . left right &&
mkdir sub &&
cp .git/FETCH_HEAD sub/FETCH_HEAD &&
@@ -240,4 +244,128 @@ test_expect_success 'merge-msg -F in subdirectory' '
test_cmp expected actual
'
+test_expect_success 'merge-msg with nothing to merge' '
+
+ git config --unset-all merge.log
+ git config --unset-all merge.summary
+ git config merge.summary yes &&
+
+ (
+ cd remote &&
+ git checkout -b unrelated &&
+ test_tick &&
+ git fetch origin &&
+ git fmt-merge-msg <.git/FETCH_HEAD >../actual
+ ) &&
+
+ test_cmp /dev/null actual
+'
+
+cat >expected <<\EOF
+Merge tag 'tag-r3'
+
+* tag 'tag-r3':
+ Right #3
+ Common #2
+ Common #1
+EOF
+
+test_expect_success 'merge-msg tag' '
+
+ git config --unset-all merge.log
+ git config --unset-all merge.summary
+ git config merge.summary yes &&
+
+ git checkout master &&
+ test_tick &&
+ git fetch . tag tag-r3 &&
+
+ git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+Merge tags 'tag-r3' and 'tag-l5'
+
+* tag 'tag-r3':
+ Right #3
+ Common #2
+ Common #1
+
+* tag 'tag-l5':
+ Left #5
+ Left #4
+ Left #3
+ Common #2
+ Common #1
+EOF
+
+test_expect_success 'merge-msg two tags' '
+
+ git config --unset-all merge.log
+ git config --unset-all merge.summary
+ git config merge.summary yes &&
+
+ git checkout master &&
+ test_tick &&
+ git fetch . tag tag-r3 tag tag-l5 &&
+
+ git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+Merge branch 'left', tag 'tag-r3'
+
+* tag 'tag-r3':
+ Right #3
+ Common #2
+ Common #1
+
+* left:
+ Left #5
+ Left #4
+ Left #3
+ Common #2
+ Common #1
+EOF
+
+test_expect_success 'merge-msg tag and branch' '
+
+ git config --unset-all merge.log
+ git config --unset-all merge.summary
+ git config merge.summary yes &&
+
+ git checkout master &&
+ test_tick &&
+ git fetch . tag tag-r3 left &&
+
+ git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+Merge branch 'long'
+
+* long: (35 commits)
+EOF
+
+test_expect_success 'merge-msg lots of commits' '
+
+ git checkout master &&
+ test_tick &&
+ git fetch . long &&
+
+ i=29 &&
+ while test $i -gt 9
+ do
+ echo " $i" &&
+ i=$(($i-1))
+ done >>expected &&
+ echo " ..." >>expected
+
+ git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/t/t7002-grep.sh b/t/t7002-grep.sh
index af63d6ec6d..e249c3ed41 100755
--- a/t/t7002-grep.sh
+++ b/t/t7002-grep.sh
@@ -442,6 +442,58 @@ test_expect_success 'grep -Fi' '
test_cmp expected actual
'
+test_expect_success 'outside of git repository' '
+ rm -fr non &&
+ mkdir -p non/git/sub &&
+ echo hello >non/git/file1 &&
+ echo world >non/git/sub/file2 &&
+ echo ".*o*" >non/git/.gitignore &&
+ {
+ echo file1:hello &&
+ echo sub/file2:world
+ } >non/expect.full &&
+ echo file2:world >non/expect.sub
+ (
+ GIT_CEILING_DIRECTORIES="$(pwd)/non/git" &&
+ export GIT_CEILING_DIRECTORIES &&
+ cd non/git &&
+ test_must_fail git grep o &&
+ git grep --no-index o >../actual.full &&
+ test_cmp ../expect.full ../actual.full
+ cd sub &&
+ test_must_fail git grep o &&
+ git grep --no-index o >../../actual.sub &&
+ test_cmp ../../expect.sub ../../actual.sub
+ )
+'
+
+test_expect_success 'inside git repository but with --no-index' '
+ rm -fr is &&
+ mkdir -p is/git/sub &&
+ echo hello >is/git/file1 &&
+ echo world >is/git/sub/file2 &&
+ echo ".*o*" >is/git/.gitignore &&
+ {
+ echo file1:hello &&
+ echo sub/file2:world
+ } >is/expect.full &&
+ : >is/expect.empty &&
+ echo file2:world >is/expect.sub
+ (
+ cd is/git &&
+ git init &&
+ test_must_fail git grep o >../actual.full &&
+ test_cmp ../expect.empty ../actual.full &&
+ git grep --no-index o >../actual.full &&
+ test_cmp ../expect.full ../actual.full &&
+ cd sub &&
+ test_must_fail git grep o >../../actual.sub &&
+ test_cmp ../../expect.empty ../../actual.sub &&
+ git grep --no-index o >../../actual.sub &&
+ test_cmp ../../expect.sub ../../actual.sub
+ )
+'
+
test_expect_success 'setup double-dash tests' '
cat >double-dash <<EOF &&
--
diff --git a/t/t7103-reset-bare.sh b/t/t7103-reset-bare.sh
index afb55b3a46..1eef93c2b2 100755
--- a/t/t7103-reset-bare.sh
+++ b/t/t7103-reset-bare.sh
@@ -11,21 +11,26 @@ test_expect_success 'setup non-bare' '
git commit -a -m two
'
-test_expect_success 'hard reset requires a worktree' '
+test_expect_success '"hard" reset requires a worktree' '
(cd .git &&
test_must_fail git reset --hard)
'
-test_expect_success 'merge reset requires a worktree' '
+test_expect_success '"merge" reset requires a worktree' '
(cd .git &&
test_must_fail git reset --merge)
'
-test_expect_success 'mixed reset is ok' '
+test_expect_success '"keep" reset requires a worktree' '
+ (cd .git &&
+ test_must_fail git reset --keep)
+'
+
+test_expect_success '"mixed" reset is ok' '
(cd .git && git reset)
'
-test_expect_success 'soft reset is ok' '
+test_expect_success '"soft" reset is ok' '
(cd .git && git reset --soft)
'
@@ -40,19 +45,23 @@ test_expect_success 'setup bare' '
cd bare.git
'
-test_expect_success 'hard reset is not allowed in bare' '
+test_expect_success '"hard" reset is not allowed in bare' '
test_must_fail git reset --hard HEAD^
'
-test_expect_success 'merge reset is not allowed in bare' '
+test_expect_success '"merge" reset is not allowed in bare' '
test_must_fail git reset --merge HEAD^
'
-test_expect_success 'mixed reset is not allowed in bare' '
+test_expect_success '"keep" reset is not allowed in bare' '
+ test_must_fail git reset --keep HEAD^
+'
+
+test_expect_success '"mixed" reset is not allowed in bare' '
test_must_fail git reset --mixed HEAD^
'
-test_expect_success 'soft reset is allowed in bare' '
+test_expect_success '"soft" reset is allowed in bare' '
git reset --soft HEAD^ &&
test "`git show --pretty=format:%s | head -n 1`" = "one"
'
diff --git a/t/t7110-reset-merge.sh b/t/t7110-reset-merge.sh
index 8704d00196..70cdd8e618 100755
--- a/t/t7110-reset-merge.sh
+++ b/t/t7110-reset-merge.sh
@@ -3,7 +3,7 @@
# Copyright (c) 2009 Christian Couder
#
-test_description='Tests for "git reset --merge"'
+test_description='Tests for "git reset" with "--merge" and "--keep" options'
. ./test-lib.sh
@@ -47,6 +47,30 @@ test_expect_success 'reset --merge is ok when switching back' '
#
# working index HEAD target working index HEAD
# ----------------------------------------------------
+# file1: C C C D --keep D D D
+# file2: C D D D --keep C D D
+test_expect_success 'reset --keep is ok with changes in file it does not touch' '
+ git reset --hard second &&
+ cat file1 >file2 &&
+ git reset --keep HEAD^ &&
+ ! grep 4 file1 &&
+ grep 4 file2 &&
+ test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" &&
+ test -z "$(git diff --cached)"
+'
+
+test_expect_success 'reset --keep is ok when switching back' '
+ git reset --keep second &&
+ grep 4 file1 &&
+ grep 4 file2 &&
+ test "$(git rev-parse HEAD)" = "$(git rev-parse second)" &&
+ test -z "$(git diff --cached)"
+'
+
+# The next test will test the following:
+#
+# working index HEAD target working index HEAD
+# ----------------------------------------------------
# file1: B B C D --merge D D D
# file2: C D D D --merge C D D
test_expect_success 'reset --merge discards changes added to index (1)' '
@@ -78,6 +102,18 @@ test_expect_success 'reset --merge is ok again when switching back (1)' '
#
# working index HEAD target working index HEAD
# ----------------------------------------------------
+# file1: B B C D --keep (disallowed)
+test_expect_success 'reset --keep fails with changes in index in files it touches' '
+ git reset --hard second &&
+ echo "line 5" >> file1 &&
+ git add file1 &&
+ test_must_fail git reset --keep HEAD^
+'
+
+# The next test will test the following:
+#
+# working index HEAD target working index HEAD
+# ----------------------------------------------------
# file1: C C C D --merge D D D
# file2: C C D D --merge D D D
test_expect_success 'reset --merge discards changes added to index (2)' '
@@ -104,6 +140,30 @@ test_expect_success 'reset --merge is ok again when switching back (2)' '
#
# working index HEAD target working index HEAD
# ----------------------------------------------------
+# file1: C C C D --keep D D D
+# file2: C C D D --keep C D D
+test_expect_success 'reset --keep keeps changes it does not touch' '
+ git reset --hard second &&
+ echo "line 4" >> file2 &&
+ git add file2 &&
+ git reset --keep HEAD^ &&
+ grep 4 file2 &&
+ test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" &&
+ test -z "$(git diff --cached)"
+'
+
+test_expect_success 'reset --keep keeps changes when switching back' '
+ git reset --keep second &&
+ grep 4 file2 &&
+ grep 4 file1 &&
+ test "$(git rev-parse HEAD)" = "$(git rev-parse second)" &&
+ test -z "$(git diff --cached)"
+'
+
+# The next test will test the following:
+#
+# working index HEAD target working index HEAD
+# ----------------------------------------------------
# file1: A B B C --merge (disallowed)
test_expect_success 'reset --merge fails with changes in file it touches' '
git reset --hard second &&
@@ -116,6 +176,22 @@ test_expect_success 'reset --merge fails with changes in file it touches' '
grep file1 err.log | grep "not uptodate"
'
+# The next test will test the following:
+#
+# working index HEAD target working index HEAD
+# ----------------------------------------------------
+# file1: A B B C --keep (disallowed)
+test_expect_success 'reset --keep fails with changes in file it touches' '
+ git reset --hard second &&
+ echo "line 5" >> file1 &&
+ test_tick &&
+ git commit -m "add line 5" file1 &&
+ sed -e "s/line 1/changed line 1/" <file1 >file3 &&
+ mv file3 file1 &&
+ test_must_fail git reset --keep HEAD^ 2>err.log &&
+ grep file1 err.log | grep "not uptodate"
+'
+
test_expect_success 'setup 3 different branches' '
git reset --hard second &&
git branch branch1 &&
@@ -156,6 +232,18 @@ test_expect_success '"reset --merge HEAD^" is ok with pending merge' '
#
# working index HEAD target working index HEAD
# ----------------------------------------------------
+# file1: X U B C --keep (disallowed)
+test_expect_success '"reset --keep HEAD^" fails with pending merge' '
+ git reset --hard third &&
+ test_must_fail git merge branch1 &&
+ test_must_fail git reset --keep HEAD^ 2>err.log &&
+ grep "middle of a merge" err.log
+'
+
+# The next test will test the following:
+#
+# working index HEAD target working index HEAD
+# ----------------------------------------------------
# file1: X U B B --merge B B B
test_expect_success '"reset --merge HEAD" is ok with pending merge' '
git reset --hard third &&
@@ -166,7 +254,19 @@ test_expect_success '"reset --merge HEAD" is ok with pending merge' '
test -z "$(git diff)"
'
-test_expect_success '--merge with added/deleted' '
+# The next test will test the following:
+#
+# working index HEAD target working index HEAD
+# ----------------------------------------------------
+# file1: X U B B --keep (disallowed)
+test_expect_success '"reset --keep HEAD" fails with pending merge' '
+ git reset --hard third &&
+ test_must_fail git merge branch1 &&
+ test_must_fail git reset --keep HEAD 2>err.log &&
+ grep "middle of a merge" err.log
+'
+
+test_expect_success '--merge is ok with added/deleted merge' '
git reset --hard third &&
rm -f file2 &&
test_must_fail git merge branch3 &&
@@ -180,4 +280,16 @@ test_expect_success '--merge with added/deleted' '
git diff --exit-code --cached
'
+test_expect_success '--keep fails with added/deleted merge' '
+ git reset --hard third &&
+ rm -f file2 &&
+ test_must_fail git merge branch3 &&
+ ! test -f file2 &&
+ test -f file3 &&
+ git diff --exit-code file3 &&
+ git diff --exit-code branch3 file3 &&
+ test_must_fail git reset --keep HEAD 2>err.log &&
+ grep "middle of a merge" err.log
+'
+
test_done
diff --git a/t/t7111-reset-table.sh b/t/t7111-reset-table.sh
index de896c948d..ce421ad5ac 100755
--- a/t/t7111-reset-table.sh
+++ b/t/t7111-reset-table.sh
@@ -44,26 +44,32 @@ A B C D soft A B D
A B C D mixed A D D
A B C D hard D D D
A B C D merge XXXXX
+A B C D keep XXXXX
A B C C soft A B C
A B C C mixed A C C
A B C C hard C C C
A B C C merge XXXXX
+A B C C keep A C C
B B C D soft B B D
B B C D mixed B D D
B B C D hard D D D
B B C D merge D D D
+B B C D keep XXXXX
B B C C soft B B C
B B C C mixed B C C
B B C C hard C C C
B B C C merge C C C
+B B C C keep B C C
B C C D soft B C D
B C C D mixed B D D
B C C D hard D D D
B C C D merge XXXXX
+B C C D keep XXXXX
B C C C soft B C C
B C C C mixed B C C
B C C C hard C C C
B C C C merge B C C
+B C C C keep B C C
EOF
test_expect_success 'setting up branches to test with unmerged entries' '
@@ -104,10 +110,12 @@ X U B C soft XXXXX
X U B C mixed X C C
X U B C hard C C C
X U B C merge C C C
+X U B C keep XXXXX
X U B B soft XXXXX
X U B B mixed X B B
X U B B hard B B B
X U B B merge B B B
+X U B B keep XXXXX
EOF
test_done
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index d20ed61b48..1337fa5a22 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -11,10 +11,12 @@ Test switching across them.
! [master] Initial A one, A two
* [renamer] Renamer R one->uno, M two
! [side] Side M one, D two, A three
- ---
- + [side] Side M one, D two, A three
- * [renamer] Renamer R one->uno, M two
- +*+ [master] Initial A one, A two
+ ! [simple] Simple D one, M two
+ ----
+ + [simple] Simple D one, M two
+ + [side] Side M one, D two, A three
+ * [renamer] Renamer R one->uno, M two
+ +*++ [master] Initial A one, A two
'
@@ -52,6 +54,11 @@ test_expect_success setup '
git update-index --add --remove one two three &&
git commit -m "Side M one, D two, A three" &&
+ git checkout -b simple master &&
+ rm -f one &&
+ fill a c e > two &&
+ git commit -a -m "Simple D one, M two" &&
+
git checkout master
'
@@ -166,6 +173,56 @@ test_expect_success 'checkout -m with merge conflict' '
! test -s current
'
+test_expect_success 'format of merge conflict from checkout -m' '
+
+ git checkout -f master && git clean -f &&
+
+ fill b d > two &&
+ git checkout -m simple &&
+
+ git ls-files >current &&
+ fill same two two two >expect &&
+ test_cmp current expect &&
+
+ cat <<-EOF >expect &&
+ <<<<<<< simple
+ a
+ c
+ e
+ =======
+ b
+ d
+ >>>>>>> local
+ EOF
+ test_cmp two expect
+'
+
+test_expect_success 'checkout --merge --conflict=diff3 <branch>' '
+
+ git checkout -f master && git reset --hard && git clean -f &&
+
+ fill b d > two &&
+ git checkout --merge --conflict=diff3 simple &&
+
+ cat <<-EOF >expect &&
+ <<<<<<< simple
+ a
+ c
+ e
+ ||||||| master
+ a
+ b
+ c
+ d
+ e
+ =======
+ b
+ d
+ >>>>>>> local
+ EOF
+ test_cmp two expect
+'
+
test_expect_success 'checkout to detach HEAD (with advice declined)' '
git config advice.detachedHead false &&
@@ -481,7 +538,7 @@ test_expect_success 'checkout with --merge, in diff3 -m style' '
(
echo "<<<<<<< ours"
echo ourside
- echo "|||||||"
+ echo "||||||| base"
echo original
echo "======="
echo theirside
@@ -525,7 +582,7 @@ test_expect_success 'checkout --conflict=diff3' '
(
echo "<<<<<<< ours"
echo ourside
- echo "|||||||"
+ echo "||||||| base"
echo original
echo "======="
echo theirside
diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh
index d3c039f724..cee319da0a 100755
--- a/t/t7401-submodule-summary.sh
+++ b/t/t7401-submodule-summary.sh
@@ -227,4 +227,11 @@ test_expect_success 'fail when using --files together with --cached' "
test_must_fail git submodule summary --files --cached
"
+test_expect_success 'should not fail in an empty repo' "
+ git init xyzzy &&
+ cd xyzzy &&
+ git submodule summary >output 2>&1 &&
+ test_cmp output /dev/null
+"
+
test_done
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index 7940901d47..8297cb4f1e 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -425,4 +425,16 @@ test_expect_success 'amend using the message from a commit named with tag' '
'
+test_expect_success 'amend can copy notes' '
+
+ git config notes.rewrite.amend true &&
+ git config notes.rewriteRef "refs/notes/*" &&
+ test_commit foo &&
+ git notes add -m"a note" &&
+ test_tick &&
+ git commit --amend -m"new foo" &&
+ test "$(git notes show)" = "a note"
+
+'
+
test_done
diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh
index 253c334319..3d4f85d74f 100755
--- a/t/t7506-status-submodule.sh
+++ b/t/t7506-status-submodule.sh
@@ -34,7 +34,7 @@ test_expect_success 'status with modified file in submodule' '
(cd sub && git reset --hard) &&
echo "changed" >sub/foo &&
git status >output &&
- grep "modified: sub" output
+ grep "modified: sub (modified content)" output
'
test_expect_success 'status with modified file in submodule (porcelain)' '
@@ -49,7 +49,7 @@ test_expect_success 'status with modified file in submodule (porcelain)' '
test_expect_success 'status with added file in submodule' '
(cd sub && git reset --hard && echo >foo && git add foo) &&
git status >output &&
- grep "modified: sub" output
+ grep "modified: sub (modified content)" output
'
test_expect_success 'status with added file in submodule (porcelain)' '
@@ -64,7 +64,12 @@ test_expect_success 'status with untracked file in submodule' '
(cd sub && git reset --hard) &&
echo "content" >sub/new-file &&
git status >output &&
- grep "modified: sub" output
+ grep "modified: sub (untracked content)" output
+'
+
+test_expect_success 'status -uno with untracked file in submodule' '
+ git status -uno >output &&
+ grep "^nothing to commit" output
'
test_expect_success 'status with untracked file in submodule (porcelain)' '
@@ -74,6 +79,100 @@ test_expect_success 'status with untracked file in submodule (porcelain)' '
EOF
'
+test_expect_success 'status with added and untracked file in submodule' '
+ (cd sub && git reset --hard && echo >foo && git add foo) &&
+ echo "content" >sub/new-file &&
+ git status >output &&
+ grep "modified: sub (modified content, untracked content)" output
+'
+
+test_expect_success 'status with added and untracked file in submodule (porcelain)' '
+ (cd sub && git reset --hard && echo >foo && git add foo) &&
+ echo "content" >sub/new-file &&
+ git status --porcelain >output &&
+ diff output - <<-\EOF
+ M sub
+ EOF
+'
+
+test_expect_success 'status with modified file in modified submodule' '
+ (cd sub && git reset --hard) &&
+ rm sub/new-file &&
+ (cd sub && echo "next change" >foo && git commit -m "next change" foo) &&
+ echo "changed" >sub/foo &&
+ git status >output &&
+ grep "modified: sub (new commits, modified content)" output
+'
+
+test_expect_success 'status with modified file in modified submodule (porcelain)' '
+ (cd sub && git reset --hard) &&
+ echo "changed" >sub/foo &&
+ git status --porcelain >output &&
+ diff output - <<-\EOF
+ M sub
+ EOF
+'
+
+test_expect_success 'status with added file in modified submodule' '
+ (cd sub && git reset --hard && echo >foo && git add foo) &&
+ git status >output &&
+ grep "modified: sub (new commits, modified content)" output
+'
+
+test_expect_success 'status with added file in modified submodule (porcelain)' '
+ (cd sub && git reset --hard && echo >foo && git add foo) &&
+ git status --porcelain >output &&
+ diff output - <<-\EOF
+ M sub
+ EOF
+'
+
+test_expect_success 'status with untracked file in modified submodule' '
+ (cd sub && git reset --hard) &&
+ echo "content" >sub/new-file &&
+ git status >output &&
+ grep "modified: sub (new commits, untracked content)" output
+'
+
+test_expect_success 'status with untracked file in modified submodule (porcelain)' '
+ git status --porcelain >output &&
+ diff output - <<-\EOF
+ M sub
+ EOF
+'
+
+test_expect_success 'status with added and untracked file in modified submodule' '
+ (cd sub && git reset --hard && echo >foo && git add foo) &&
+ echo "content" >sub/new-file &&
+ git status >output &&
+ grep "modified: sub (new commits, modified content, untracked content)" output
+'
+
+test_expect_success 'status with added and untracked file in modified submodule (porcelain)' '
+ (cd sub && git reset --hard && echo >foo && git add foo) &&
+ echo "content" >sub/new-file &&
+ git status --porcelain >output &&
+ diff output - <<-\EOF
+ M sub
+ EOF
+'
+
+test_expect_success 'setup .git file for sub' '
+ (cd sub &&
+ rm -f new-file
+ REAL="$(pwd)/../.real" &&
+ mv .git "$REAL"
+ echo "gitdir: $REAL" >.git) &&
+ echo .real >>.gitignore &&
+ git commit -m "added .real to .gitignore" .gitignore
+'
+
+test_expect_success 'status with added file in modified submodule with .git file' '
+ (cd sub && git reset --hard && echo >foo && git add foo) &&
+ git status >output &&
+ grep "modified: sub (new commits, modified content)" output
+'
+
test_expect_success 'rm submodule contents' '
rm -rf sub/* sub/.git
'
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index c09f375288..640b3d2bb4 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -852,4 +852,70 @@ test_expect_success 'no warning with sendemail.chainreplyto = true' '
! grep "no-chain-reply-to" errors
'
+test_expect_success 'sendemail.to works' '
+ git config --replace-all sendemail.to "Somebody <somebody@ex.com>" &&
+ git send-email \
+ --dry-run \
+ --from="Example <nobody@example.com>" \
+ $patches $patches >stdout &&
+ grep "To: Somebody <somebody@ex.com>" stdout
+'
+
+test_expect_success '--no-to overrides sendemail.to' '
+ git send-email \
+ --dry-run \
+ --from="Example <nobody@example.com>" \
+ --no-to \
+ --to=nobody@example.com \
+ $patches $patches >stdout &&
+ grep "To: nobody@example.com" stdout &&
+ ! grep "To: Somebody <somebody@ex.com>" stdout
+'
+
+test_expect_success 'sendemail.cc works' '
+ git config --replace-all sendemail.cc "Somebody <somebody@ex.com>" &&
+ git send-email \
+ --dry-run \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ $patches $patches >stdout &&
+ grep "Cc: Somebody <somebody@ex.com>" stdout
+'
+
+test_expect_success '--no-cc overrides sendemail.cc' '
+ git send-email \
+ --dry-run \
+ --from="Example <nobody@example.com>" \
+ --no-cc \
+ --cc=bodies@example.com \
+ --to=nobody@example.com \
+ $patches $patches >stdout &&
+ grep "Cc: bodies@example.com" stdout &&
+ ! grep "Cc: Somebody <somebody@ex.com>" stdout
+'
+
+test_expect_success 'sendemail.bcc works' '
+ git config --replace-all sendemail.bcc "Other <other@ex.com>" &&
+ git send-email \
+ --dry-run \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server relay.example.com \
+ $patches $patches >stdout &&
+ grep "RCPT TO:<other@ex.com>" stdout
+'
+
+test_expect_success '--no-bcc overrides sendemail.bcc' '
+ git send-email \
+ --dry-run \
+ --from="Example <nobody@example.com>" \
+ --no-bcc \
+ --bcc=bodies@example.com \
+ --to=nobody@example.com \
+ --smtp-server relay.example.com \
+ $patches $patches >stdout &&
+ grep "RCPT TO:<bodies@example.com>" stdout &&
+ ! grep "RCPT TO:<other@ex.com>" stdout
+'
+
test_done
diff --git a/t/t9119-git-svn-info.sh b/t/t9119-git-svn-info.sh
index 95741cbbac..a9a558d292 100755
--- a/t/t9119-git-svn-info.sh
+++ b/t/t9119-git-svn-info.sh
@@ -7,9 +7,10 @@ test_description='git svn info'
. ./lib-git-svn.sh
# Tested with: svn, version 1.4.4 (r25188)
+# Tested with: svn, version 1.6.[12345689]
v=`svn_cmd --version | sed -n -e 's/^svn, version \(1\.[0-9]*\.[0-9]*\).*$/\1/p'`
case $v in
-1.[45].*)
+1.[456].*)
;;
*)
say "skipping svn-info test (SVN version: $v not supported)"
diff --git a/t/t9150-svk-mergetickets.sh b/t/t9150-svk-mergetickets.sh
index 53581425c4..24c2421bfc 100755
--- a/t/t9150-svk-mergetickets.sh
+++ b/t/t9150-svk-mergetickets.sh
@@ -11,6 +11,7 @@ test_expect_success 'load svk depot' "
svnadmin load -q '$rawsvnrepo' \
< '$TEST_DIRECTORY/t9150/svk-merge.dump' &&
git svn init --minimize-url -R svkmerge \
+ --rewrite-root=http://svn.example.org \
-T trunk -b branches '$svnrepo' &&
git svn fetch --all
"
diff --git a/t/t9151-svn-mergeinfo.sh b/t/t9151-svn-mergeinfo.sh
index 3569c62096..250c651eae 100755
--- a/t/t9151-svn-mergeinfo.sh
+++ b/t/t9151-svn-mergeinfo.sh
@@ -11,6 +11,7 @@ test_expect_success 'load svn dump' "
svnadmin load -q '$rawsvnrepo' \
< '$TEST_DIRECTORY/t9151/svn-mergeinfo.dump' &&
git svn init --minimize-url -R svnmerge \
+ --rewrite-root=http://svn.example.org \
-T trunk -b branches '$svnrepo' &&
git svn fetch --all
"
@@ -33,6 +34,21 @@ test_expect_success 'svn non-merge merge commits did not become git merge commit
[ -z "$bad_non_merges" ]
'
+test_expect_success 'commit made to merged branch is reachable from the merge' '
+ before_commit=$(git rev-list --all --grep="trunk commit before merging trunk to b2")
+ merge_commit=$(git rev-list --all --grep="Merge trunk to b2")
+ not_reachable=$(git rev-list -1 $before_commit --not $merge_commit)
+ [ -z "$not_reachable" ]
+ '
+
+test_expect_success 'merging two branches in one commit is detected correctly' '
+ f1_commit=$(git rev-list --all --grep="make f1 branch from trunk")
+ f2_commit=$(git rev-list --all --grep="make f2 branch from trunk")
+ merge_commit=$(git rev-list --all --grep="Merge f1 and f2 to trunk")
+ not_reachable=$(git rev-list -1 $f1_commit $f2_commit --not $merge_commit)
+ [ -z "$not_reachable" ]
+ '
+
test_expect_failure 'everything got merged in the end' '
unmerged=$(git rev-list --all --not master)
[ -z "$unmerged" ]
diff --git a/t/t9151/make-svnmerge-dump b/t/t9151/make-svnmerge-dump
index 3d73f140f8..e1e138cb1a 100644
--- a/t/t9151/make-svnmerge-dump
+++ b/t/t9151/make-svnmerge-dump
@@ -156,6 +156,89 @@ svn merge ../branches/right --accept postpone
i=$(commit $i "non-merge right to trunk 2")
cd ..
+say "Branching b1 from trunk"
+svn update
+svn cp trunk branches/b1
+i=$(commit $i "make b1 branch from trunk")
+
+say "Branching b2 from trunk"
+svn update
+svn cp trunk branches/b2
+i=$(commit $i "make b2 branch from trunk")
+
+say "Make a commit to b2"
+svn update
+cd branches/b2
+echo "b2" > b2file
+svn add b2file
+i=$(commit $i "b2 update 1")
+cd ../..
+
+say "Make a commit to b1"
+svn update
+cd branches/b1
+echo "b1" > b1file
+svn add b1file
+i=$(commit $i "b1 update 1")
+cd ../..
+
+say "Merge b1 to trunk"
+svn update
+cd trunk
+svn merge ../branches/b1/ --accept postpone
+i=$(commit $i "Merge b1 to trunk")
+cd ..
+
+say "Make a commit to trunk before merging trunk to b2"
+svn update
+cd trunk
+echo "trunk" > trunkfile
+svn add trunkfile
+i=$(commit $i "trunk commit before merging trunk to b2")
+cd ..
+
+say "Merge trunk to b2"
+svn update
+cd branches/b2
+svn merge ../../trunk/ --accept postpone
+i=$(commit $i "Merge trunk to b2")
+cd ../..
+
+say "Merge b2 to trunk"
+svn update
+cd trunk
+svn merge ../branches/b2/ --accept postpone
+svn resolved b1file
+svn resolved trunkfile
+i=$(commit $i "Merge b2 to trunk")
+cd ..
+
+say "Creating f1 from trunk with a new file"
+svn update
+svn cp trunk branches/f1
+cd branches/f1
+echo "f1" > f1file
+svn add f1file
+cd ../..
+i=$(commit $i "make f1 branch from trunk with a new file")
+
+say "Creating f2 from trunk with a new file"
+svn update
+svn cp trunk branches/f2
+cd branches/f2
+echo "f2" > f2file
+svn add f2file
+cd ../..
+i=$(commit $i "make f2 branch from trunk with a new file")
+
+say "Merge f1 and f2 to trunk in one go"
+svn update
+cd trunk
+svn merge ../branches/f1/ --accept postpone
+svn merge ../branches/f2/ --accept postpone
+i=$(commit $i "Merge f1 and f2 to trunk")
+cd ..
+
say "Adding subdirectory to LEFT"
svn update
cd branches/left
@@ -174,8 +257,8 @@ cd ..
say "Make PARTIAL branch"
svn update
-i=$(commit $i "make partial branch")
svn cp trunk/subdir branches/partial
+i=$(commit $i "make partial branch")
say "Make a commit to PARTIAL"
svn update
@@ -194,13 +277,13 @@ cd ../../
say "Tagging trunk"
svn update
-i=$(commit $i "tagging v1.0")
svn cp trunk tags/v1.0
+i=$(commit $i "tagging v1.0")
say "Branching BUGFIX from v1.0"
svn update
-i=$(commit $i "make bugfix branch from tag")
svn cp tags/v1.0 branches/bugfix
+i=$(commit $i "make bugfix branch from tag")
say "Make a commit to BUGFIX"
svn update
diff --git a/t/t9151/svn-mergeinfo.dump b/t/t9151/svn-mergeinfo.dump
index ebf386ebd5..47cafcf528 100644
--- a/t/t9151/svn-mergeinfo.dump
+++ b/t/t9151/svn-mergeinfo.dump
@@ -1633,13 +1633,427 @@ PROPS-END
Revision-number: 25
+Prop-content-length: 129
+Content-length: 129
+
+K 7
+svn:log
+V 31
+(r25) make b1 branch from trunk
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:18:56.084589Z
+PROPS-END
+
+Node-path: branches/b1
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 24
+Node-copyfrom-path: trunk
+
+
+Revision-number: 26
+Prop-content-length: 129
+Content-length: 129
+
+K 7
+svn:log
+V 31
+(r26) make b2 branch from trunk
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:18:59.076940Z
+PROPS-END
+
+Node-path: branches/b2
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 25
+Node-copyfrom-path: trunk
+
+
+Revision-number: 27
+Prop-content-length: 115
+Content-length: 115
+
+K 7
+svn:log
+V 17
+(r27) b2 update 1
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:19:01.095762Z
+PROPS-END
+
+Node-path: branches/b2/b2file
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 3
+Text-content-md5: 5edbdd57cba621eb3c6e601bf563b4dc
+Text-content-sha1: 9d4b38049776bd0a2074d67cad23f8eaed35a3b3
+Content-length: 13
+
+PROPS-END
+b2
+
+
+Revision-number: 28
+Prop-content-length: 115
+Content-length: 115
+
+K 7
+svn:log
+V 17
+(r28) b1 update 1
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:19:03.097465Z
+PROPS-END
+
+Node-path: branches/b1/b1file
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 3
+Text-content-md5: 08778dfd9ac4f603231896aba7aad523
+Text-content-sha1: b551771aa4ad5b14123fc3bd98d89db2bc0edd4f
+Content-length: 13
+
+PROPS-END
+b1
+
+
+Revision-number: 29
+Prop-content-length: 121
+Content-length: 121
+
+K 7
+svn:log
+V 23
+(r29) Merge b1 to trunk
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:19:06.073175Z
+PROPS-END
+
+Node-path: trunk
+Node-kind: dir
+Node-action: change
+Prop-content-length: 118
+Content-length: 118
+
+K 13
+svn:mergeinfo
+V 83
+/branches/b1:25-28
+/branches/left:2-22
+/branches/left-sub:4-19
+/branches/right:2-22
+PROPS-END
+
+
+Node-path: trunk/b1file
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 28
+Node-copyfrom-path: branches/b1/b1file
+Text-copy-source-md5: 08778dfd9ac4f603231896aba7aad523
+Text-copy-source-sha1: b551771aa4ad5b14123fc3bd98d89db2bc0edd4f
+
+
+Revision-number: 30
+Prop-content-length: 143
+Content-length: 143
+
+K 7
+svn:log
+V 45
+(r30) trunk commit before merging trunk to b2
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:19:08.096353Z
+PROPS-END
+
+Node-path: trunk/trunkfile
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 6
+Text-content-md5: edf45fe5c98c5367733b39bbb2bb20d9
+Text-content-sha1: 7361d1685e5c86dfc523620cfaf598f196f86239
+Content-length: 16
+
+PROPS-END
+trunk
+
+
+Revision-number: 31
+Prop-content-length: 121
+Content-length: 121
+
+K 7
+svn:log
+V 23
+(r31) Merge trunk to b2
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:19:11.081541Z
+PROPS-END
+
+Node-path: branches/b2
+Node-kind: dir
+Node-action: change
+Prop-content-length: 131
+Content-length: 131
+
+K 13
+svn:mergeinfo
+V 96
+/branches/b1:25-28
+/branches/left:2-22
+/branches/left-sub:4-19
+/branches/right:2-22
+/trunk:26-30
+PROPS-END
+
+
+Node-path: branches/b2/b1file
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 30
+Node-copyfrom-path: trunk/b1file
+Text-copy-source-md5: 08778dfd9ac4f603231896aba7aad523
+Text-copy-source-sha1: b551771aa4ad5b14123fc3bd98d89db2bc0edd4f
+
+
+Node-path: branches/b2/trunkfile
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 30
+Node-copyfrom-path: trunk/trunkfile
+Text-copy-source-md5: edf45fe5c98c5367733b39bbb2bb20d9
+Text-copy-source-sha1: 7361d1685e5c86dfc523620cfaf598f196f86239
+
+
+Revision-number: 32
+Prop-content-length: 121
+Content-length: 121
+
+K 7
+svn:log
+V 23
+(r32) Merge b2 to trunk
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:19:14.117939Z
+PROPS-END
+
+Node-path: trunk
+Node-kind: dir
+Node-action: change
+Prop-content-length: 138
+Content-length: 138
+
+K 13
+svn:mergeinfo
+V 102
+/branches/b1:25-28
+/branches/b2:26-31
+/branches/left:2-22
+/branches/left-sub:4-19
+/branches/right:2-22
+PROPS-END
+
+
+Node-path: trunk/b2file
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 31
+Node-copyfrom-path: branches/b2/b2file
+Text-copy-source-md5: 5edbdd57cba621eb3c6e601bf563b4dc
+Text-copy-source-sha1: 9d4b38049776bd0a2074d67cad23f8eaed35a3b3
+
+
+Revision-number: 33
+Prop-content-length: 145
+Content-length: 145
+
+K 7
+svn:log
+V 47
+(r33) make f1 branch from trunk with a new file
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:19:17.105832Z
+PROPS-END
+
+Node-path: branches/f1
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 32
+Node-copyfrom-path: trunk
+
+
+Node-path: branches/f1/f1file
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 3
+Text-content-md5: 2b1abc6b6c5c0018851f9f8e6475563b
+Text-content-sha1: aece6dfba588900e00d95601d22b4408d49580af
+Content-length: 13
+
+PROPS-END
+f1
+
+
+Revision-number: 34
+Prop-content-length: 145
+Content-length: 145
+
+K 7
+svn:log
+V 47
+(r34) make f2 branch from trunk with a new file
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:19:20.110057Z
+PROPS-END
+
+Node-path: branches/f2
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 33
+Node-copyfrom-path: trunk
+
+
+Node-path: branches/f2/f2file
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 3
+Text-content-md5: 575c5638d60271457e54ab7d07309502
+Text-content-sha1: 1c49a440c352f3473efa9512255033b94dc7def0
+Content-length: 13
+
+PROPS-END
+f2
+
+
+Revision-number: 35
+Prop-content-length: 128
+Content-length: 128
+
+K 7
+svn:log
+V 30
+(r35) Merge f1 and f2 to trunk
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:19:24.081490Z
+PROPS-END
+
+Node-path: trunk
+Node-kind: dir
+Node-action: change
+Prop-content-length: 173
+Content-length: 173
+
+K 13
+svn:mergeinfo
+V 137
+/branches/b1:25-28
+/branches/b2:26-31
+/branches/f1:33-34
+/branches/f2:34
+/branches/left:2-22
+/branches/left-sub:4-19
+/branches/right:2-22
+PROPS-END
+
+
+Node-path: trunk/f1file
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 34
+Node-copyfrom-path: branches/f1/f1file
+Text-copy-source-md5: 2b1abc6b6c5c0018851f9f8e6475563b
+Text-copy-source-sha1: aece6dfba588900e00d95601d22b4408d49580af
+
+
+Node-path: trunk/f2file
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 34
+Node-copyfrom-path: branches/f2/f2file
+Text-copy-source-md5: 575c5638d60271457e54ab7d07309502
+Text-copy-source-sha1: 1c49a440c352f3473efa9512255033b94dc7def0
+
+
+Revision-number: 36
Prop-content-length: 135
Content-length: 135
K 7
svn:log
V 37
-(r25) add subdirectory to left branch
+(r36) add subdirectory to left branch
K 10
svn:author
V 3
@@ -1647,7 +2061,7 @@ adm
K 8
svn:date
V 27
-2010-01-19T04:14:46.052649Z
+2010-02-22T06:19:26.113516Z
PROPS-END
Node-path: branches/left/subdir
@@ -1672,14 +2086,14 @@ PROPS-END
Yeehaw
-Revision-number: 26
+Revision-number: 37
Prop-content-length: 123
Content-length: 123
K 7
svn:log
V 25
-(r26) merge left to trunk
+(r37) merge left to trunk
K 10
svn:author
V 3
@@ -1687,19 +2101,23 @@ adm
K 8
svn:date
V 27
-2010-01-19T04:14:49.040783Z
+2010-02-22T06:19:29.073699Z
PROPS-END
Node-path: trunk
Node-kind: dir
Node-action: change
-Prop-content-length: 99
-Content-length: 99
+Prop-content-length: 173
+Content-length: 173
K 13
svn:mergeinfo
-V 64
-/branches/left:2-25
+V 137
+/branches/b1:25-28
+/branches/b2:26-31
+/branches/f1:33-34
+/branches/f2:34
+/branches/left:2-36
/branches/left-sub:4-19
/branches/right:2-22
PROPS-END
@@ -1708,18 +2126,18 @@ PROPS-END
Node-path: trunk/subdir
Node-kind: dir
Node-action: add
-Node-copyfrom-rev: 25
+Node-copyfrom-rev: 36
Node-copyfrom-path: branches/left/subdir
-Revision-number: 27
-Prop-content-length: 118
-Content-length: 118
+Revision-number: 38
+Prop-content-length: 123
+Content-length: 123
K 7
svn:log
-V 20
-(r28) partial update
+V 25
+(r38) make partial branch
K 10
svn:author
V 3
@@ -1727,16 +2145,34 @@ adm
K 8
svn:date
V 27
-2010-01-19T04:14:53.049037Z
+2010-02-22T06:19:32.072243Z
PROPS-END
Node-path: branches/partial
Node-kind: dir
Node-action: add
-Node-copyfrom-rev: 26
+Node-copyfrom-rev: 37
Node-copyfrom-path: trunk/subdir
+Revision-number: 39
+Prop-content-length: 118
+Content-length: 118
+
+K 7
+svn:log
+V 20
+(r39) partial update
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:19:34.097961Z
+PROPS-END
+
Node-path: branches/partial/palindromes
Node-kind: file
Node-action: add
@@ -1750,14 +2186,14 @@ PROPS-END
racecar
-Revision-number: 28
+Revision-number: 40
Prop-content-length: 126
Content-length: 126
K 7
svn:log
V 28
-(r29) merge partial to trunk
+(r40) merge partial to trunk
K 10
svn:author
V 3
@@ -1765,21 +2201,25 @@ adm
K 8
svn:date
V 27
-2010-01-19T04:14:56.041526Z
+2010-02-22T06:19:37.080211Z
PROPS-END
Node-path: trunk/subdir
Node-kind: dir
Node-action: change
-Prop-content-length: 142
-Content-length: 142
+Prop-content-length: 246
+Content-length: 246
K 13
svn:mergeinfo
-V 106
-/branches/left/subdir:2-25
+V 210
+/branches/b1/subdir:25-28
+/branches/b2/subdir:26-31
+/branches/f1/subdir:33-34
+/branches/f2/subdir:34
+/branches/left/subdir:2-36
/branches/left-sub/subdir:4-19
-/branches/partial:27
+/branches/partial:38-39
/branches/right/subdir:2-22
PROPS-END
@@ -1787,20 +2227,20 @@ PROPS-END
Node-path: trunk/subdir/palindromes
Node-kind: file
Node-action: add
-Node-copyfrom-rev: 27
+Node-copyfrom-rev: 39
Node-copyfrom-path: branches/partial/palindromes
Text-copy-source-md5: 5d1c2024fb5efc4eef812856df1b080c
Text-copy-source-sha1: 5f8509ddd14c91a52864dd1447344e706f9bbc69
-Revision-number: 29
-Prop-content-length: 131
-Content-length: 131
+Revision-number: 41
+Prop-content-length: 116
+Content-length: 116
K 7
svn:log
-V 33
-(r31) make bugfix branch from tag
+V 18
+(r41) tagging v1.0
K 10
svn:author
V 3
@@ -1808,24 +2248,24 @@ adm
K 8
svn:date
V 27
-2010-01-19T04:15:00.039761Z
+2010-02-22T06:19:40.083460Z
PROPS-END
Node-path: tags/v1.0
Node-kind: dir
Node-action: add
-Node-copyfrom-rev: 28
+Node-copyfrom-rev: 40
Node-copyfrom-path: trunk
-Revision-number: 30
-Prop-content-length: 120
-Content-length: 120
+Revision-number: 42
+Prop-content-length: 131
+Content-length: 131
K 7
svn:log
-V 22
-(r32) commit to bugfix
+V 33
+(r42) make bugfix branch from tag
K 10
svn:author
V 3
@@ -1833,16 +2273,34 @@ adm
K 8
svn:date
V 27
-2010-01-19T04:15:03.043218Z
+2010-02-22T06:19:43.118075Z
PROPS-END
Node-path: branches/bugfix
Node-kind: dir
Node-action: add
-Node-copyfrom-rev: 29
+Node-copyfrom-rev: 41
Node-copyfrom-path: tags/v1.0
+Revision-number: 43
+Prop-content-length: 120
+Content-length: 120
+
+K 7
+svn:log
+V 22
+(r43) commit to bugfix
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-02-22T06:19:45.079536Z
+PROPS-END
+
Node-path: branches/bugfix/subdir/palindromes
Node-kind: file
Node-action: change
@@ -1855,14 +2313,14 @@ racecar
kayak
-Revision-number: 31
+Revision-number: 44
Prop-content-length: 125
Content-length: 125
K 7
svn:log
V 27
-(r33) Merge BUGFIX to TRUNK
+(r44) Merge BUGFIX to TRUNK
K 10
svn:author
V 3
@@ -1870,41 +2328,49 @@ adm
K 8
svn:date
V 27
-2010-01-19T04:15:06.043723Z
+2010-02-22T06:19:48.078914Z
PROPS-END
Node-path: trunk
Node-kind: dir
Node-action: change
-Prop-content-length: 133
-Content-length: 133
+Prop-content-length: 210
+Content-length: 210
K 13
svn:mergeinfo
-V 98
-/branches/bugfix:30
-/branches/left:2-25
+V 174
+/branches/b1:25-28
+/branches/b2:26-31
+/branches/bugfix:42-43
+/branches/f1:33-34
+/branches/f2:34
+/branches/left:2-36
/branches/left-sub:4-19
/branches/right:2-22
-/tags/v1.0:29
+/tags/v1.0:41
PROPS-END
Node-path: trunk/subdir
Node-kind: dir
Node-action: change
-Prop-content-length: 190
-Content-length: 190
+Prop-content-length: 297
+Content-length: 297
K 13
svn:mergeinfo
-V 154
-/branches/bugfix/subdir:30
-/branches/left/subdir:2-25
+V 261
+/branches/b1/subdir:25-28
+/branches/b2/subdir:26-31
+/branches/bugfix/subdir:42-43
+/branches/f1/subdir:33-34
+/branches/f2/subdir:34
+/branches/left/subdir:2-36
/branches/left-sub/subdir:4-19
-/branches/partial:27
+/branches/partial:38-39
/branches/right/subdir:2-22
-/tags/v1.0/subdir:29
+/tags/v1.0/subdir:41
PROPS-END
diff --git a/t/t9501-gitweb-standalone-http-status.sh b/t/t9501-gitweb-standalone-http-status.sh
index d196cc5ca9..2487da1296 100755
--- a/t/t9501-gitweb-standalone-http-status.sh
+++ b/t/t9501-gitweb-standalone-http-status.sh
@@ -15,9 +15,10 @@ code and message.'
# ----------------------------------------------------------------------
# snapshot settings
-test_commit \
- 'SnapshotTests' \
- 'i can has snapshot?'
+test_expect_success 'setup' "
+ test_commit 'SnapshotTests' 'i can has snapshot?'
+"
+
cat >>gitweb_config.perl <<\EOF
$feature{'snapshot'}{'override'} = 0;
diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh
index 363345faef..b572ce3ab7 100755
--- a/t/t9600-cvsimport.sh
+++ b/t/t9600-cvsimport.sh
@@ -47,13 +47,20 @@ EOF
test_expect_success 'import a trivial module' '
- git cvsimport -a -z 0 -C module-git module &&
+ git cvsimport -a -R -z 0 -C module-git module &&
test_cmp module-cvs/o_fortuna module-git/o_fortuna
'
test_expect_success 'pack refs' 'cd module-git && git gc && cd ..'
+test_expect_success 'initial import has correct .git/cvs-revisions' '
+
+ (cd module-git &&
+ git log --format="o_fortuna 1.1 %H" -1) > expected &&
+ test_cmp expected module-git/.git/cvs-revisions
+'
+
test_expect_success 'update cvs module' '
cd module-cvs &&
@@ -86,13 +93,21 @@ EOF
test_expect_success 'update git module' '
cd module-git &&
- git cvsimport -a -z 0 module &&
+ git cvsimport -a -R -z 0 module &&
git merge origin &&
cd .. &&
test_cmp module-cvs/o_fortuna module-git/o_fortuna
'
+test_expect_success 'update has correct .git/cvs-revisions' '
+
+ (cd module-git &&
+ git log --format="o_fortuna 1.1 %H" -1 HEAD^ &&
+ git log --format="o_fortuna 1.2 %H" -1 HEAD) > expected &&
+ test_cmp expected module-git/.git/cvs-revisions
+'
+
test_expect_success 'update cvs module' '
cd module-cvs &&
@@ -107,13 +122,22 @@ test_expect_success 'cvsimport.module config works' '
cd module-git &&
git config cvsimport.module module &&
- git cvsimport -a -z0 &&
+ git cvsimport -a -R -z0 &&
git merge origin &&
cd .. &&
test_cmp module-cvs/tick module-git/tick
'
+test_expect_success 'second update has correct .git/cvs-revisions' '
+
+ (cd module-git &&
+ git log --format="o_fortuna 1.1 %H" -1 HEAD^^ &&
+ git log --format="o_fortuna 1.2 %H" -1 HEAD^
+ git log --format="tick 1.1 %H" -1 HEAD) > expected &&
+ test_cmp expected module-git/.git/cvs-revisions
+'
+
test_expect_success 'import from a CVS working tree' '
$CVS co -d import-from-wt module &&
@@ -126,6 +150,12 @@ test_expect_success 'import from a CVS working tree' '
'
+test_expect_success 'no .git/cvs-revisions created by default' '
+
+ ! test -e import-from-wt/.git/cvs-revisions
+
+'
+
test_expect_success 'test entire HEAD' 'test_cmp_branch_tree master'
test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh
index a0e396a952..9234eb7561 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -2,6 +2,18 @@
#
# Copyright (c) 2005 Junio C Hamano
#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
# if --tee was passed, write the output not only to the terminal, but
# additionally to the file test-results/$BASENAME.out, too.
@@ -54,6 +66,10 @@ unset GIT_OBJECT_DIRECTORY
unset GIT_CEILING_DIRECTORIES
unset SHA1_FILE_DIRECTORIES
unset SHA1_FILE_DIRECTORY
+unset GIT_NOTES_REF
+unset GIT_NOTES_DISPLAY_REF
+unset GIT_NOTES_REWRITE_REF
+unset GIT_NOTES_REWRITE_MODE
GIT_MERGE_VERBOSITY=5
export GIT_MERGE_VERBOSITY
export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME