aboutsummaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rwxr-xr-xt/t1009-read-tree-new-index.sh25
-rwxr-xr-xt/t2000-checkout-cache-clash.sh9
-rwxr-xr-xt/t2015-checkout-unborn.sh40
-rwxr-xr-xt/t3400-rebase.sh26
-rwxr-xr-xt/t4013-diff-various.sh1
-rw-r--r--t/t4013/diff.log_--decorate=full_--all34
-rwxr-xr-xt/t4039-diff-assume-unchanged.sh31
-rwxr-xr-xt/t4107-apply-ignore-whitespace.sh185
-rwxr-xr-xt/t5500-fetch-pack.sh47
-rw-r--r--t/t5531-deep-submodule-push.sh35
-rwxr-xr-xt/t6015-rev-list-show-all-parents.sh31
-rwxr-xr-xt/t6016-rev-list-graph-simplify-history.sh276
-rwxr-xr-xt/t6030-bisect-porcelain.sh18
-rwxr-xr-xt/t6050-replace.sh200
-rwxr-xr-xt/t7060-wtstatus.sh58
-rwxr-xr-xt/t7401-submodule-summary.sh22
-rwxr-xr-xt/t7407-submodule-foreach.sh237
-rwxr-xr-xt/t7408-submodule-reference.sh (renamed from t/t7406-submodule-reference.sh)0
-rw-r--r--t/test-lib.sh15
19 files changed, 1279 insertions, 11 deletions
diff --git a/t/t1009-read-tree-new-index.sh b/t/t1009-read-tree-new-index.sh
new file mode 100755
index 000000000..59b3aa4bc
--- /dev/null
+++ b/t/t1009-read-tree-new-index.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+test_description='test read-tree into a fresh index file'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ echo one >a &&
+ git add a &&
+ git commit -m initial
+'
+
+test_expect_success 'non-existent index file' '
+ rm -f new-index &&
+ GIT_INDEX_FILE=new-index git read-tree master
+'
+
+test_expect_success 'empty index file' '
+ rm -f new-index &&
+ > new-index &&
+ GIT_INDEX_FILE=new-index git read-tree master
+'
+
+test_done
+
diff --git a/t/t2000-checkout-cache-clash.sh b/t/t2000-checkout-cache-clash.sh
index f7e1a735e..de3edb5d5 100755
--- a/t/t2000-checkout-cache-clash.sh
+++ b/t/t2000-checkout-cache-clash.sh
@@ -48,4 +48,13 @@ test_expect_success \
'git checkout-index conflicting paths.' \
'test -f path0 && test -d path1 && test -f path1/file1'
+test_expect_success SYMLINKS 'checkout-index -f twice with --prefix' '
+ mkdir -p tar/get &&
+ ln -s tar/get there &&
+ echo first &&
+ git checkout-index -a -f --prefix=there/ &&
+ echo second &&
+ git checkout-index -a -f --prefix=there/
+'
+
test_done
diff --git a/t/t2015-checkout-unborn.sh b/t/t2015-checkout-unborn.sh
new file mode 100755
index 000000000..c551d39a6
--- /dev/null
+++ b/t/t2015-checkout-unborn.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+test_description='checkout from unborn branch protects contents'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ mkdir parent &&
+ (cd parent &&
+ git init &&
+ echo content >file &&
+ git add file &&
+ git commit -m base
+ ) &&
+ git fetch parent master:origin
+'
+
+test_expect_success 'checkout from unborn preserves untracked files' '
+ echo precious >expect &&
+ echo precious >file &&
+ test_must_fail git checkout -b new origin &&
+ test_cmp expect file
+'
+
+test_expect_success 'checkout from unborn preserves index contents' '
+ echo precious >expect &&
+ echo precious >file &&
+ git add file &&
+ test_must_fail git checkout -b new origin &&
+ test_cmp expect file &&
+ git show :file >file &&
+ test_cmp expect file
+'
+
+test_expect_success 'checkout from unborn merges identical index contents' '
+ echo content >file &&
+ git add file &&
+ git checkout -b new origin
+'
+
+test_done
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index c5c29ccc4..4e6a44b62 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -3,9 +3,10 @@
# Copyright (c) 2005 Amos Waterland
#
-test_description='git rebase should not destroy author information
+test_description='git rebase assorted tests
-This test runs git rebase and checks that the author information is not lost.
+This test runs git rebase and checks that the author information is not lost
+among other things.
'
. ./test-lib.sh
@@ -133,4 +134,25 @@ test_expect_success 'rebase -q is quiet' '
test ! -s output.out
'
+q_to_cr () {
+ tr Q '\015'
+}
+
+test_expect_success 'Rebase a commit that sprinkles CRs in' '
+ (
+ echo "One"
+ echo "TwoQ"
+ echo "Three"
+ echo "FQur"
+ echo "Five"
+ ) | q_to_cr >CR &&
+ git add CR &&
+ test_tick &&
+ git commit -a -m "A file with a line with CR" &&
+ git tag file-with-cr &&
+ git checkout HEAD^0 &&
+ git rebase --onto HEAD^^ HEAD^ &&
+ git diff --exit-code file-with-cr:CR HEAD:CR
+'
+
test_done
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 8b33321f8..8e3694ed5 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -207,6 +207,7 @@ log --root --cc --patch-with-stat --summary master
log -SF master
log -SF -p master
log --decorate --all
+log --decorate=full --all
rev-list --parents HEAD
rev-list --children HEAD
diff --git a/t/t4013/diff.log_--decorate=full_--all b/t/t4013/diff.log_--decorate=full_--all
new file mode 100644
index 000000000..903d9d965
--- /dev/null
+++ b/t/t4013/diff.log_--decorate=full_--all
@@ -0,0 +1,34 @@
+$ git log --decorate=full --all
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (refs/heads/master)
+Merge: 9a6d494 c7a2ab9
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:04:00 2006 +0000
+
+ Merge branch 'side'
+
+commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (refs/heads/side)
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:03:00 2006 +0000
+
+ Side
+
+commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:02:00 2006 +0000
+
+ Third
+
+commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:01:00 2006 +0000
+
+ Second
+
+ This is the second commit.
+
+commit 444ac553ac7612cc88969031b02b3767fb8a353a (refs/heads/initial)
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:00:00 2006 +0000
+
+ Initial
+$
diff --git a/t/t4039-diff-assume-unchanged.sh b/t/t4039-diff-assume-unchanged.sh
new file mode 100755
index 000000000..9d9498bd9
--- /dev/null
+++ b/t/t4039-diff-assume-unchanged.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+test_description='diff with assume-unchanged entries'
+
+. ./test-lib.sh
+
+# external diff has been tested in t4020-diff-external.sh
+
+test_expect_success 'setup' '
+ echo zero > zero &&
+ git add zero &&
+ git commit -m zero &&
+ echo one > one &&
+ echo two > two &&
+ git add one two &&
+ git commit -m onetwo &&
+ git update-index --assume-unchanged one &&
+ echo borked >> one &&
+ test "$(git ls-files -v one)" = "h one"
+'
+
+test_expect_success 'diff-index does not examine assume-unchanged entries' '
+ git diff-index HEAD^ -- one | grep -q 5626abf0f72e58d7a153368ba57db4c673c0e171
+'
+
+test_expect_success 'diff-files does not examine assume-unchanged entries' '
+ rm one &&
+ test -z "$(git diff-files -- one)"
+'
+
+test_done
diff --git a/t/t4107-apply-ignore-whitespace.sh b/t/t4107-apply-ignore-whitespace.sh
new file mode 100755
index 000000000..484654d6e
--- /dev/null
+++ b/t/t4107-apply-ignore-whitespace.sh
@@ -0,0 +1,185 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Giuseppe Bilotta
+#
+
+test_description='git-apply --ignore-whitespace.
+
+'
+. ./test-lib.sh
+
+# This primes main.c file that indents without using HT at all.
+# Various patches with HT and other spaces are attempted in the test.
+
+cat > patch1.patch <<\EOF
+diff --git a/main.c b/main.c
+new file mode 100644
+--- /dev/null
++++ b/main.c
+@@ -0,0 +1,22 @@
++#include <stdio.h>
++
++void print_int(int num);
++int func(int num);
++
++int main() {
++ int i;
++
++ for (i = 0; i < 10; i++) {
++ print_int(func(i)); /* stuff */
++ }
++
++ return 0;
++}
++
++int func(int num) {
++ return num * num;
++}
++
++void print_int(int num) {
++ printf("%d", num);
++}
+EOF
+
+# Since whitespace is very significant and we want to prevent whitespace
+# mangling when creating this test from a patch, we protect 'fixable'
+# whitespace by replacing spaces with Z and replacing them at patch
+# creation time, hence the sed trick.
+
+# This patch will fail unless whitespace differences are being ignored
+
+sed -e 's/Z/ /g' > patch2.patch <<\EOF
+diff --git a/main.c b/main.c
+--- a/main.c
++++ b/main.c
+@@ -10,6 +10,8 @@
+Z print_int(func(i)); /* stuff */
+Z }
+Z
++ printf("\n");
++
+Z return 0;
+Z}
+Z
+EOF
+
+# This patch will fail even if whitespace differences are being ignored,
+# because of the missing string at EOL. TODO: this testcase should be
+# improved by creating a line that has the same hash with and without
+# the final string.
+
+sed -e 's/Z/ /g' > patch3.patch <<\EOF
+diff --git a/main.c b/main.c
+--- a/main.c
++++ b/main.c
+@@ -10,3 +10,4 @@
+Z for (i = 0; i < 10; i++) {
+Z print_int(func(i));Z
++ /* stuff */
+Z }
+EOF
+
+# This patch will fail even if whitespace differences are being ignored,
+# because of the missing EOL at EOF.
+
+sed -e 's/Z/ /g' > patch4.patch <<\EOF
+diff --git a/main.c b/main.c
+--- a/main.c
++++ b/main.c
+@@ -21,1 +21,1 @@
+- };Z
+\ No newline at end of file
++ };
+EOF
+
+# This patch will fail unless whitespace differences are being ignored.
+
+sed -e 's/Z/ /g' > patch5.patch <<\EOF
+diff --git a/main.c b/main.c
+--- a/main.c
++++ b/main.c
+@@ -2,2 +2,3 @@
+Z void print_int(int num);
++ /* a comment */
+Z int func(int num);
+EOF
+
+# And this is how the final output should be. Patches introduce
+# HTs but the original SP indents are mostly kept.
+
+sed -e 's/T/ /g' > main.c.final <<\EOF
+#include <stdio.h>
+
+void print_int(int num);
+T/* a comment */
+int func(int num);
+
+int main() {
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ print_int(func(i)); /* stuff */
+ }
+
+Tprintf("\n");
+
+ return 0;
+}
+
+int func(int num) {
+ return num * num;
+}
+
+void print_int(int num) {
+ printf("%d", num);
+}
+EOF
+
+test_expect_success 'file creation' '
+ git-apply patch1.patch
+'
+
+test_expect_success 'patch2 fails (retab)' '
+ test_must_fail git-apply patch2.patch
+'
+
+test_expect_success 'patch2 applies with --ignore-whitespace' '
+ git-apply --ignore-whitespace patch2.patch
+'
+
+test_expect_success 'patch2 reverse applies with --ignore-space-change' '
+ git-apply -R --ignore-space-change patch2.patch
+'
+
+git config apply.ignorewhitespace change
+
+test_expect_success 'patch2 applies (apply.ignorewhitespace = change)' '
+ git-apply patch2.patch
+'
+
+test_expect_success 'patch3 fails (missing string at EOL)' '
+ test_must_fail git-apply patch3.patch
+'
+
+test_expect_success 'patch4 fails (missing EOL at EOF)' '
+ test_must_fail git-apply patch4.patch
+'
+
+test_expect_success 'patch5 applies (leading whitespace)' '
+ git-apply patch5.patch
+'
+
+test_expect_success 'patches do not mangle whitespace' '
+ test_cmp main.c main.c.final
+'
+
+test_expect_success 're-create file (with --ignore-whitespace)' '
+ rm -f main.c &&
+ git-apply patch1.patch
+'
+
+test_expect_success 'patch5 fails (--no-ignore-whitespace)' '
+ test_must_fail git-apply --no-ignore-whitespace patch5.patch
+'
+
+test_done
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index a8c2ca2a7..18376d660 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -139,6 +139,36 @@ test_expect_success 'fsck in shallow repo' '
)
'
+test_expect_success 'simple fetch in shallow repo' '
+ (
+ cd shallow &&
+ git fetch
+ )
+'
+
+test_expect_success 'no changes expected' '
+ (
+ cd shallow &&
+ git count-objects -v
+ ) > count.shallow.2 &&
+ cmp count.shallow count.shallow.2
+'
+
+test_expect_success 'fetch same depth in shallow repo' '
+ (
+ cd shallow &&
+ git fetch --depth=2
+ )
+'
+
+test_expect_success 'no changes expected' '
+ (
+ cd shallow &&
+ git count-objects -v
+ ) > count.shallow.3 &&
+ cmp count.shallow count.shallow.3
+'
+
test_expect_success 'add two more' '
add B66 $B65 &&
add B67 $B66
@@ -201,4 +231,21 @@ test_expect_success 'pull in shallow repo with missing merge base' '
)
'
+test_expect_success 'additional simple shallow deepenings' '
+ (
+ cd shallow &&
+ git fetch --depth=8 &&
+ git fetch --depth=10 &&
+ git fetch --depth=11
+ )
+'
+
+test_expect_success 'clone shallow object count' '
+ (
+ cd shallow &&
+ git count-objects -v
+ ) > count.shallow &&
+ grep "^count: 52" count.shallow
+'
+
test_done
diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh
new file mode 100644
index 000000000..65d8d474b
--- /dev/null
+++ b/t/t5531-deep-submodule-push.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+test_description='unpack-objects'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ mkdir pub.git &&
+ GIT_DIR=pub.git git init --bare
+ GIT_DIR=pub.git git config receive.fsckobjects true &&
+ mkdir work &&
+ (
+ cd work &&
+ git init &&
+ mkdir -p gar/bage &&
+ (
+ cd gar/bage &&
+ git init &&
+ >junk &&
+ git add junk &&
+ git commit -m "Initial junk"
+ ) &&
+ git add gar/bage &&
+ git commit -m "Initial superproject"
+ )
+'
+
+test_expect_success push '
+ (
+ cd work &&
+ git push ../pub.git master
+ )
+'
+
+test_done
diff --git a/t/t6015-rev-list-show-all-parents.sh b/t/t6015-rev-list-show-all-parents.sh
new file mode 100755
index 000000000..8b146fb43
--- /dev/null
+++ b/t/t6015-rev-list-show-all-parents.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+test_description='--show-all --parents does not rewrite TREESAME commits'
+
+. ./test-lib.sh
+
+test_expect_success 'set up --show-all --parents test' '
+ test_commit one foo.txt &&
+ commit1=`git rev-list -1 HEAD` &&
+ test_commit two bar.txt &&
+ commit2=`git rev-list -1 HEAD` &&
+ test_commit three foo.txt &&
+ commit3=`git rev-list -1 HEAD`
+ '
+
+test_expect_success '--parents rewrites TREESAME parents correctly' '
+ echo $commit3 $commit1 > expected &&
+ echo $commit1 >> expected &&
+ git rev-list --parents HEAD -- foo.txt > actual &&
+ test_cmp expected actual
+ '
+
+test_expect_success '--parents --show-all does not rewrites TREESAME parents' '
+ echo $commit3 $commit2 > expected &&
+ echo $commit2 $commit1 >> expected &&
+ echo $commit1 >> expected &&
+ git rev-list --parents --show-all HEAD -- foo.txt > actual &&
+ test_cmp expected actual
+ '
+
+test_done
diff --git a/t/t6016-rev-list-graph-simplify-history.sh b/t/t6016-rev-list-graph-simplify-history.sh
new file mode 100755
index 000000000..27fd52b7b
--- /dev/null
+++ b/t/t6016-rev-list-graph-simplify-history.sh
@@ -0,0 +1,276 @@
+#!/bin/sh
+
+# There's more than one "correct" way to represent the history graphically.
+# These tests depend on the current behavior of the graphing code. If the
+# graphing code is ever changed to draw the output differently, these tests
+# cases will need to be updated to know about the new layout.
+
+test_description='--graph and simplified history'
+
+. ./test-lib.sh
+
+test_expect_success 'set up rev-list --graph test' '
+ # 3 commits on branch A
+ test_commit A1 foo.txt &&
+ test_commit A2 bar.txt &&
+ test_commit A3 bar.txt &&
+ git branch -m master A &&
+
+ # 2 commits on branch B, started from A1
+ git checkout -b B A1 &&
+ test_commit B1 foo.txt &&
+ test_commit B2 abc.txt &&
+
+ # 2 commits on branch C, started from A2
+ git checkout -b C A2 &&
+ test_commit C1 xyz.txt &&
+ test_commit C2 xyz.txt &&
+
+ # Octopus merge B and C into branch A
+ git checkout A &&
+ git merge B C &&
+ git tag A4
+
+ test_commit A5 bar.txt &&
+
+ # More commits on C, then merge C into A
+ git checkout C &&
+ test_commit C3 foo.txt &&
+ test_commit C4 bar.txt &&
+ git checkout A &&
+ git merge -s ours C &&
+ git tag A6
+
+ test_commit A7 bar.txt &&
+
+ # Store commit names in variables for later use
+ A1=$(git rev-parse --verify A1) &&
+ A2=$(git rev-parse --verify A2) &&
+ A3=$(git rev-parse --verify A3) &&
+ A4=$(git rev-parse --verify A4) &&
+ A5=$(git rev-parse --verify A5) &&
+ A6=$(git rev-parse --verify A6) &&
+ A7=$(git rev-parse --verify A7) &&
+ B1=$(git rev-parse --verify B1) &&
+ B2=$(git rev-parse --verify B2) &&
+ C1=$(git rev-parse --verify C1) &&
+ C2=$(git rev-parse --verify C2) &&
+ C3=$(git rev-parse --verify C3) &&
+ C4=$(git rev-parse --verify C4)
+ '
+
+test_expect_success '--graph --all' '
+ rm -f expected &&
+ echo "* $A7" >> expected &&
+ echo "* $A6" >> expected &&
+ echo "|\\ " >> expected &&
+ echo "| * $C4" >> expected &&
+ echo "| * $C3" >> expected &&
+ echo "* | $A5" >> expected &&
+ echo "| | " >> expected &&
+ echo "| \\ " >> expected &&
+ echo "*-. \\ $A4" >> expected &&
+ echo "|\\ \\ \\ " >> expected &&
+ echo "| | |/ " >> expected &&
+ echo "| | * $C2" >> expected &&
+ echo "| | * $C1" >> expected &&
+ echo "| * | $B2" >> expected &&
+ echo "| * | $B1" >> expected &&
+ echo "* | | $A3" >> expected &&
+ echo "| |/ " >> expected &&
+ echo "|/| " >> expected &&
+ echo "* | $A2" >> expected &&
+ echo "|/ " >> expected &&
+ echo "* $A1" >> expected &&
+ git rev-list --graph --all > actual &&
+ test_cmp expected actual
+ '
+
+# Make sure the graph_is_interesting() code still realizes
+# that undecorated merges are interesting, even with --simplify-by-decoration
+test_expect_success '--graph --simplify-by-decoration' '
+ rm -f expected &&
+ git tag -d A4
+ echo "* $A7" >> expected &&
+ echo "* $A6" >> expected &&
+ echo "|\\ " >> expected &&
+ echo "| * $C4" >> expected &&
+ echo "| * $C3" >> expected &&
+ echo "* | $A5" >> expected &&
+ echo "| | " >> expected &&
+ echo "| \\ " >> expected &&
+ echo "*-. \\ $A4" >> expected &&
+ echo "|\\ \\ \\ " >> expected &&
+ echo "| | |/ " >> expected &&
+ echo "| | * $C2" >> expected &&
+ echo "| | * $C1" >> expected &&
+ echo "| * | $B2" >> expected &&
+ echo "| * | $B1" >> expected &&
+ echo "* | | $A3" >> expected &&
+ echo "| |/ " >> expected &&
+ echo "|/| " >> expected &&
+ echo "* | $A2" >> expected &&
+ echo "|/ " >> expected &&
+ echo "* $A1" >> expected &&
+ git rev-list --graph --all --simplify-by-decoration > actual &&
+ test_cmp expected actual
+ '
+
+# Get rid of all decorations on branch B, and graph with it simplified away
+test_expect_success '--graph --simplify-by-decoration prune branch B' '
+ rm -f expected &&
+ git tag -d B2
+ git tag -d B1
+ git branch -d B
+ echo "* $A7" >> expected &&
+ echo "* $A6" >> expected &&
+ echo "|\\ " >> expected &&
+ echo "| * $C4" >> expected &&
+ echo "| * $C3" >> expected &&
+ echo "* | $A5" >> expected &&
+ echo "* | $A4" >> expected &&
+ echo "|\\ \\ " >> expected &&
+ echo "| |/ " >> expected &&
+ echo "| * $C2" >> expected &&
+ echo "| * $C1" >> expected &&
+ echo "* | $A3" >> expected &&
+ echo "|/ " >> expected &&
+ echo "* $A2" >> expected &&
+ echo "* $A1" >> expected &&
+ git rev-list --graph --simplify-by-decoration --all > actual &&
+ test_cmp expected actual
+ '
+
+test_expect_success '--graph --full-history -- bar.txt' '
+ rm -f expected &&
+ git tag -d B2
+ git tag -d B1
+ git branch -d B
+ echo "* $A7" >> expected &&
+ echo "* $A6" >> expected &&
+ echo "|\\ " >> expected &&
+ echo "| * $C4" >> expected &&
+ echo "* | $A5" >> expected &&
+ echo "* | $A4" >> expected &&
+ echo "|\\ \\ " >> expected &&
+ echo "| |/ " >> expected &&
+ echo "* | $A3" >> expected &&
+ echo "|/ " >> expected &&
+ echo "* $A2" >> expected &&
+ git rev-list --graph --full-history --all -- bar.txt > actual &&
+ test_cmp expected actual
+ '
+
+test_expect_success '--graph --full-history --simplify-merges -- bar.txt' '
+ rm -f expected &&
+ git tag -d B2
+ git tag -d B1
+ git branch -d B
+ echo "* $A7" >> expected &&
+ echo "* $A6" >> expected &&
+ echo "|\\ " >> expected &&
+ echo "| * $C4" >> expected &&
+ echo "* | $A5" >> expected &&
+ echo "* | $A3" >> expected &&
+ echo "|/ " >> expected &&
+ echo "* $A2" >> expected &&
+ git rev-list --graph --full-history --simplify-merges --all \
+ -- bar.txt > actual &&
+ test_cmp expected actual
+ '
+
+test_expect_success '--graph -- bar.txt' '
+ rm -f expected &&
+ git tag -d B2
+ git tag -d B1
+ git branch -d B
+ echo "* $A7" >> expected &&
+ echo "* $A5" >> expected &&
+ echo "* $A3" >> expected &&
+ echo "| * $C4" >> expected &&
+ echo "|/ " >> expected &&
+ echo "* $A2" >> expected &&
+ git rev-list --graph --all -- bar.txt > actual &&
+ test_cmp expected actual
+ '
+
+test_expect_success '--graph --sparse -- bar.txt' '
+ rm -f expected &&
+ git tag -d B2
+ git tag -d B1
+ git branch -d B
+ echo "* $A7" >> expected &&
+ echo "* $A6" >> expected &&
+ echo "* $A5" >> expected &&
+ echo "* $A4" >> expected &&
+ echo "* $A3" >> expected &&
+ echo "| * $C4" >> expected &&
+ echo "| * $C3" >> expected &&
+ echo "| * $C2" >> expected &&
+ echo "| * $C1" >> expected &&
+ echo "|/ " >> expected &&
+ echo "* $A2" >> expected &&
+ echo "* $A1" >> expected &&
+ git rev-list --graph --sparse --all -- bar.txt > actual &&
+ test_cmp expected actual
+ '
+
+test_expect_success '--graph ^C4' '
+ rm -f expected &&
+ echo "* $A7" >> expected &&
+ echo "* $A6" >> expected &&
+ echo "* $A5" >> expected &&
+ echo "* $A4" >> expected &&
+ echo "|\\ " >> expected &&
+ echo "| * $B2" >> expected &&
+ echo "| * $B1" >> expected &&
+ echo "* $A3" >> expected &&
+ git rev-list --graph --all ^C4 > actual &&
+ test_cmp expected actual
+ '
+
+test_expect_success '--graph ^C3' '
+ rm -f expected &&
+ echo "* $A7" >> expected &&
+ echo "* $A6" >> expected &&
+ echo "|\\ " >> expected &&
+ echo "| * $C4" >> expected &&
+ echo "* $A5" >> expected &&
+ echo "* $A4" >> expected &&
+ echo "|\\ " >> expected &&
+ echo "| * $B2" >> expected &&
+ echo "| * $B1" >> expected &&
+ echo "* $A3" >> expected &&
+ git rev-list --graph --all ^C3 > actual &&
+ test_cmp expected actual
+ '
+
+# I don't think the ordering of the boundary commits is really
+# that important, but this test depends on it. If the ordering ever changes
+# in the code, we'll need to update this test.
+test_expect_success '--graph --boundary ^C3' '
+ rm -f expected &&
+ echo "* $A7" >> expected &&
+ echo "* $A6" >> expected &&
+ echo "|\\ " >> expected &&
+ echo "| * $C4" >> expected &&
+ echo "* | $A5" >> expected &&
+ echo "| | " >> expected &&
+ echo "| \\ " >> expected &&
+ echo "*-. \\ $A4" >> expected &&
+ echo "|\\ \\ \\ " >> expected &&
+ echo "| * | | $B2" >> expected &&
+ echo "| * | | $B1" >> expected &&
+ echo "* | | | $A3" >> expected &&
+ echo "o | | | $A2" >> expected &&
+ echo "|/ / / " >> expected &&
+ echo "o | | $A1" >> expected &&
+ echo " / / " >> expected &&
+ echo "| o $C3" >> expected &&
+ echo "|/ " >> expected &&
+ echo "o $C2" >> expected &&
+ git rev-list --graph --boundary --all ^C3 > actual &&
+ test_cmp expected actual
+ '
+
+test_done
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 1315bab59..def397c53 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -175,7 +175,7 @@ test_expect_success 'bisect skip: successfull result' '
git bisect start $HASH4 $HASH1 &&
git bisect skip &&
git bisect bad > my_bisect_log.txt &&
- grep "$HASH2 is first bad commit" my_bisect_log.txt &&
+ grep "$HASH2 is the first bad commit" my_bisect_log.txt &&
git bisect reset
'
@@ -261,7 +261,7 @@ test_expect_success \
git bisect good $HASH1 &&
git bisect bad $HASH4 &&
git bisect run ./test_script.sh > my_bisect_log.txt &&
- grep "$HASH3 is first bad commit" my_bisect_log.txt &&
+ grep "$HASH3 is the first bad commit" my_bisect_log.txt &&
git bisect reset'
# We want to automatically find the commit that
@@ -274,7 +274,7 @@ test_expect_success \
chmod +x test_script.sh &&
git bisect start $HASH4 $HASH1 &&
git bisect run ./test_script.sh > my_bisect_log.txt &&
- grep "$HASH4 is first bad commit" my_bisect_log.txt &&
+ grep "$HASH4 is the first bad commit" my_bisect_log.txt &&
git bisect reset'
# $HASH1 is good, $HASH5 is bad, we skip $HASH3
@@ -287,14 +287,14 @@ test_expect_success 'bisect skip: add line and then a new test' '
git bisect start $HASH5 $HASH1 &&
git bisect skip &&
git bisect good > my_bisect_log.txt &&
- grep "$HASH5 is first bad commit" my_bisect_log.txt &&
+ grep "$HASH5 is the first bad commit" my_bisect_log.txt &&
git bisect log > log_to_replay.txt &&
git bisect reset
'
test_expect_success 'bisect skip and bisect replay' '
git bisect replay log_to_replay.txt > my_bisect_log.txt &&
- grep "$HASH5 is first bad commit" my_bisect_log.txt &&
+ grep "$HASH5 is the first bad commit" my_bisect_log.txt &&
git bisect reset
'
@@ -335,7 +335,7 @@ test_expect_success 'bisect run & skip: find first bad' '
chmod +x test_script.sh &&
git bisect start $HASH7 $HASH1 &&
git bisect run ./test_script.sh > my_bisect_log.txt &&
- grep "$HASH6 is first bad commit" my_bisect_log.txt
+ grep "$HASH6 is the first bad commit" my_bisect_log.txt
'
test_expect_success 'bisect skip only one range' '
@@ -385,7 +385,7 @@ test_expect_success 'bisect does not create a "bisect" branch' '
rev_hash6=$(git rev-parse --verify HEAD) &&
test "$rev_hash6" = "$HASH6" &&
git bisect good > my_bisect_log.txt &&
- grep "$HASH7 is first bad commit" my_bisect_log.txt &&
+ grep "$HASH7 is the first bad commit" my_bisect_log.txt &&
git bisect reset &&
rev_hash6=$(git rev-parse --verify bisect) &&
test "$rev_hash6" = "$HASH6" &&
@@ -534,7 +534,7 @@ test_expect_success 'restricting bisection on one dir' '
para1=$(git rev-parse --verify HEAD) &&
test "$para1" = "$PARA_HASH1" &&
git bisect bad > my_bisect_log.txt &&
- grep "$PARA_HASH1 is first bad commit" my_bisect_log.txt
+ grep "$PARA_HASH1 is the first bad commit" my_bisect_log.txt
'
test_expect_success 'restricting bisection on one dir and a file' '
@@ -552,7 +552,7 @@ test_expect_success 'restricting bisection on one dir and a file' '
para1=$(git rev-parse --verify HEAD) &&
test "$para1" = "$PARA_HASH1" &&
git bisect good > my_bisect_log.txt &&
- grep "$PARA_HASH4 is first bad commit" my_bisect_log.txt
+ grep "$PARA_HASH4 is the first bad commit" my_bisect_log.txt
'
test_expect_success 'skipping away from skipped commit' '
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
new file mode 100755
index 000000000..8b8bd81c0
--- /dev/null
+++ b/t/t6050-replace.sh
@@ -0,0 +1,200 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 Christian Couder
+#
+test_description='Tests replace refs functionality'
+
+exec </dev/null
+
+. ./test-lib.sh
+
+add_and_commit_file()
+{
+ _file="$1"
+ _msg="$2"
+
+ git add $_file || return $?
+ test_tick || return $?
+ git commit --quiet -m "$_file: $_msg"
+}
+
+HASH1=
+HASH2=
+HASH3=
+HASH4=
+HASH5=
+HASH6=
+HASH7=
+
+test_expect_success 'set up buggy branch' '
+ echo "line 1" >> hello &&
+ echo "line 2" >> hello &&
+ echo "line 3" >> hello &&
+ echo "line 4" >> hello &&
+ add_and_commit_file hello "4 lines" &&
+ HASH1=$(git rev-parse --verify HEAD) &&
+ echo "line BUG" >> hello &&
+ echo "line 6" >> hello &&
+ echo "line 7" >> hello &&
+ echo "line 8" >> hello &&
+ add_and_commit_file hello "4 more lines with a BUG" &&
+ HASH2=$(git rev-parse --verify HEAD) &&
+ echo "line 9" >> hello &&
+ echo "line 10" >> hello &&
+ add_and_commit_file hello "2 more lines" &&
+ HASH3=$(git rev-parse --verify HEAD) &&
+ echo "line 11" >> hello &&
+ add_and_commit_file hello "1 more line" &&
+ HASH4=$(git rev-parse --verify HEAD) &&
+ sed -e "s/BUG/5/" hello > hello.new &&
+ mv hello.new hello &&
+ add_and_commit_file hello "BUG fixed" &&
+ HASH5=$(git rev-parse --verify HEAD) &&
+ echo "line 12" >> hello &&
+ echo "line 13" >> hello &&
+ add_and_commit_file hello "2 more lines" &&
+ HASH6=$(git rev-parse --verify HEAD)
+ echo "line 14" >> hello &&
+ echo "line 15" >> hello &&
+ echo "line 16" >> hello &&
+ add_and_commit_file hello "again 3 more lines" &&
+ HASH7=$(git rev-parse --verify HEAD)
+'
+
+test_expect_success 'replace the author' '
+ git cat-file commit $HASH2 | grep "author A U Thor" &&
+ R=$(git cat-file commit $HASH2 | sed -e "s/A U/O/" | git hash-object -t commit --stdin -w) &&
+ git cat-file commit $R | grep "author O Thor" &&
+ git update-ref refs/replace/$HASH2 $R &&
+ git show HEAD~5 | grep "O Thor" &&
+ git show $HASH2 | grep "O Thor"
+'
+
+cat >tag.sig <<EOF
+object $HASH2
+type commit
+tag mytag
+tagger T A Gger <> 0 +0000
+
+EOF
+
+test_expect_success 'tag replaced commit' '
+ git mktag <tag.sig >.git/refs/tags/mytag 2>message
+'
+
+test_expect_success '"git fsck" works' '
+ git fsck master > fsck_master.out &&
+ grep "dangling commit $R" fsck_master.out &&
+ grep "dangling tag $(cat .git/refs/tags/mytag)" fsck_master.out &&
+ test -z "$(git fsck)"
+'
+
+test_expect_success 'repack, clone and fetch work' '
+ git repack -a -d &&
+ git clone --no-hardlinks . clone_dir &&
+ cd clone_dir &&
+ git show HEAD~5 | grep "A U Thor" &&
+ git show $HASH2 | grep "A U Thor" &&
+ git cat-file commit $R &&
+ git repack -a -d &&
+ test_must_fail git cat-file commit $R &&
+ git fetch ../ "refs/replace/*:refs/replace/*" &&
+ git show HEAD~5 | grep "O Thor" &&
+ git show $HASH2 | grep "O Thor" &&
+ git cat-file commit $R &&
+ cd ..
+'
+
+test_expect_success '"git replace" listing and deleting' '
+ test "$HASH2" = "$(git replace -l)" &&
+ test "$HASH2" = "$(git replace)" &&
+ aa=${HASH2%??????????????????????????????????????} &&
+ test "$HASH2" = "$(git replace -l "$aa*")" &&
+ test_must_fail git replace -d $R &&
+ test_must_fail git replace -d &&
+ test_must_fail git replace -l -d $HASH2 &&
+ git replace -d $HASH2 &&
+ git show $HASH2 | grep "A U Thor" &&
+ test -z "$(git replace -l)"
+'
+
+test_expect_success '"git replace" replacing' '
+ git replace $HASH2 $R &&
+ git show $HASH2 | grep "O Thor" &&
+ test_must_fail git replace $HASH2 $R &&
+ git replace -f $HASH2 $R &&
+ test_must_fail git replace -f &&
+ test "$HASH2" = "$(git replace)"
+'
+
+# This creates a side branch where the bug in H2
+# does not appear because P2 is created by applying
+# H2 and squashing H5 into it.
+# P3, P4 and P6 are created by cherry-picking H3, H4
+# and H6 respectively.
+#
+# At this point, we should have the following:
+#
+# P2--P3--P4--P6
+# /
+# H1-H2-H3-H4-H5-H6-H7
+#
+# Then we replace H6 with P6.
+#
+test_expect_success 'create parallel branch without the bug' '
+ git replace -d $HASH2 &&
+ git show $HASH2 | grep "A U Thor" &&
+ git checkout $HASH1 &&
+ git cherry-pick $HASH2 &&
+ git show $HASH5 | git apply &&
+ git commit --amend -m "hello: 4 more lines WITHOUT the bug" hello &&
+ PARA2=$(git rev-parse --verify HEAD) &&
+ git cherry-pick $HASH3 &&
+ PARA3=$(git rev-parse --verify HEAD) &&
+ git cherry-pick $HASH4 &&
+ PARA4=$(git rev-parse --verify HEAD) &&
+ git cherry-pick $HASH6 &&
+ PARA6=$(git rev-parse --verify HEAD) &&
+ git replace $HASH6 $PARA6 &&
+ git checkout master &&
+ cur=$(git rev-parse --verify HEAD) &&
+ test "$cur" = "$HASH7" &&
+ git log --pretty=oneline | grep $PARA2 &&
+ git remote add cloned ./clone_dir
+'
+
+test_expect_success 'push to cloned repo' '
+ git push cloned $HASH6^:refs/heads/parallel &&
+ cd clone_dir &&
+ git checkout parallel &&
+ git log --pretty=oneline | grep $PARA2 &&
+ cd ..
+'
+
+test_expect_success 'push branch with replacement' '
+ git cat-file commit $PARA3 | grep "author A U Thor" &&
+ S=$(git cat-file commit $PARA3 | sed -e "s/A U/O/" | git hash-object -t commit --stdin -w) &&
+ git cat-file commit $S | grep "author O Thor" &&
+ git replace $PARA3 $S &&
+ git show $HASH6~2 | grep "O Thor" &&
+ git show $PARA3 | grep "O Thor" &&
+ git push cloned $HASH6^:refs/heads/parallel2 &&
+ cd clone_dir &&
+ git checkout parallel2 &&
+ git log --pretty=oneline | grep $PARA3 &&
+ git show $PARA3 | grep "A U Thor" &&
+ cd ..
+'
+
+test_expect_success 'fetch branch with replacement' '
+ git branch tofetch $HASH6 &&
+ cd clone_dir &&
+ git fetch origin refs/heads/tofetch:refs/heads/parallel3
+ git log --pretty=oneline parallel3 | grep $PARA3
+ git show $PARA3 | grep "A U Thor"
+ cd ..
+'
+
+#
+#
+test_done
diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh
new file mode 100755
index 000000000..1044aa654
--- /dev/null
+++ b/t/t7060-wtstatus.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+test_description='basic work tree status reporting'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ test_commit A &&
+ test_commit B oneside added &&
+ git checkout A^0 &&
+ test_commit C oneside created
+'
+
+test_expect_success 'A/A conflict' '
+ git checkout B^0 &&
+ test_must_fail git merge C
+'
+
+test_expect_success 'Report path with conflict' '
+ git diff --cached --name-status >actual &&
+ echo "U oneside" >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'Report new path with conflict' '
+ git diff --cached --name-status HEAD^ >actual &&
+ echo "U oneside" >expect &&
+ test_cmp expect actual
+'
+
+cat >expect <<EOF
+# On branch side
+# Unmerged paths:
+# (use "git reset HEAD <file>..." to unstage)
+# (use "git add <file>..." to mark resolution)
+#
+# deleted by us: foo
+#
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
+
+test_expect_success 'M/D conflict does not segfault' '
+ mkdir mdconflict &&
+ (
+ cd mdconflict &&
+ git init &&
+ test_commit initial foo "" &&
+ test_commit modify foo foo &&
+ git checkout -b side HEAD^ &&
+ git rm foo &&
+ git commit -m delete &&
+ test_must_fail git merge master &&
+ test_must_fail git status > ../actual
+ ) &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh
index 61498293b..6cc16c39f 100755
--- a/t/t7401-submodule-summary.sh
+++ b/t/t7401-submodule-summary.sh
@@ -56,6 +56,15 @@ test_expect_success 'modified submodule(forward)' "
EOF
"
+test_expect_success 'modified submodule(forward), --files' "
+ git submodule summary --files >actual &&
+ diff actual - <<-EOF
+* sm1 $head1...$head2 (1):
+ > Add foo3
+
+EOF
+"
+
commit_file sm1 &&
cd sm1 &&
git reset --hard HEAD~2 >/dev/null &&
@@ -114,6 +123,15 @@ test_expect_success 'typechanged submodule(submodule->blob), --cached' "
EOF
"
+test_expect_success 'typechanged submodule(submodule->blob), --files' "
+ git submodule summary --files >actual &&
+ diff actual - <<-EOF
+* sm1 $head5(blob)->$head4(submodule) (3):
+ > Add foo5
+
+EOF
+"
+
rm -rf sm1 &&
git checkout-index sm1
test_expect_success 'typechanged submodule(submodule->blob)' "
@@ -205,4 +223,8 @@ test_expect_success '--for-status' "
EOF
"
+test_expect_success 'fail when using --files together with --cached' "
+ test_must_fail git submodule summary --files --cached
+"
+
test_done
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
new file mode 100755
index 000000000..2a527750c
--- /dev/null
+++ b/t/t7407-submodule-foreach.sh
@@ -0,0 +1,237 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Johan Herland
+#
+
+test_description='Test "git submodule foreach"
+
+This test verifies that "git submodule foreach" correctly visits all submodules
+that are currently checked out.
+'
+
+. ./test-lib.sh
+
+
+test_expect_success 'setup a submodule tree' '
+ echo file > file &&
+ git add file &&
+ test_tick &&
+ git commit -m upstream
+ git clone . super &&
+ git clone super submodule &&
+ (
+ cd super &&
+ git submodule add ../submodule sub1 &&
+ git submodule add ../submodule sub2 &&
+ git submodule add ../submodule sub3 &&
+ git config -f .gitmodules --rename-section \
+ submodule.sub1 submodule.foo1 &&
+ git config -f .gitmodules --rename-section \
+ submodule.sub2 submodule.foo2 &&
+ git config -f .gitmodules --rename-section \
+ submodule.sub3 submodule.foo3 &&
+ git add .gitmodules
+ test_tick &&
+ git commit -m "submodules" &&
+ git submodule init sub1 &&
+ git submodule init sub2 &&
+ git submodule init sub3
+ ) &&
+ (
+ cd submodule &&
+ echo different > file &&
+ git add file &&
+ test_tick &&
+ git commit -m "different"
+ ) &&
+ (
+ cd super &&
+ (
+ cd sub3 &&
+ git pull
+ ) &&
+ git add sub3 &&
+ test_tick &&
+ git commit -m "update sub3"
+ )
+'
+
+sub1sha1=$(cd super/sub1 && git rev-parse HEAD)
+sub3sha1=$(cd super/sub3 && git rev-parse HEAD)
+
+cat > expect <<EOF
+Entering 'sub1'
+foo1-sub1-$sub1sha1
+Entering 'sub3'
+foo3-sub3-$sub3sha1
+EOF
+
+test_expect_success 'test basic "submodule foreach" usage' '
+ git clone super clone &&
+ (
+ cd clone &&
+ git submodule update --init -- sub1 sub3 &&
+ git submodule foreach "echo \$name-\$path-\$sha1" > ../actual
+ ) &&
+ test_cmp expect actual
+'
+
+test_expect_success 'setup nested submodules' '
+ git clone submodule nested1 &&
+ git clone submodule nested2 &&
+ git clone submodule nested3 &&
+ (
+ cd nested3 &&
+ git submodule add ../submodule submodule &&
+ test_tick &&
+ git commit -m "submodule" &&
+ git submodule init submodule
+ ) &&
+ (
+ cd nested2 &&
+ git submodule add ../nested3 nested3 &&
+ test_tick &&
+ git commit -m "nested3" &&
+ git submodule init nested3
+ ) &&
+ (
+ cd nested1 &&
+ git submodule add ../nested2 nested2 &&
+ test_tick &&
+ git commit -m "nested2" &&
+ git submodule init nested2
+ ) &&
+ (
+ cd super &&
+ git submodule add ../nested1 nested1 &&
+ test_tick &&
+ git commit -m "nested1" &&
+ git submodule init nested1
+ )
+'
+
+test_expect_success 'use "submodule foreach" to checkout 2nd level submodule' '
+ git clone super clone2 &&
+ (
+ cd clone2 &&
+ test ! -d sub1/.git &&
+ test ! -d sub2/.git &&
+ test ! -d sub3/.git &&
+ test ! -d nested1/.git &&
+ git submodule update --init &&
+ test -d sub1/.git &&
+ test -d sub2/.git &&
+ test -d sub3/.git &&
+ test -d nested1/.git &&
+ test ! -d nested1/nested2/.git &&
+ git submodule foreach "git submodule update --init" &&
+ test -d nested1/nested2/.git &&
+ test ! -d nested1/nested2/nested3/.git
+ )
+'
+
+test_expect_success 'use "foreach --recursive" to checkout all submodules' '
+ (
+ cd clone2 &&
+ git submodule foreach --recursive "git submodule update --init" &&
+ test -d nested1/nested2/nested3/.git &&
+ test -d nested1/nested2/nested3/submodule/.git
+ )
+'
+
+cat > expect <<EOF
+Entering 'nested1'
+Entering 'nested1/nested2'
+Entering 'nested1/nested2/nested3'
+Entering 'nested1/nested2/nested3/submodule'
+Entering 'sub1'
+Entering 'sub2'
+Entering 'sub3'
+EOF
+
+test_expect_success 'test messages from "foreach --recursive"' '
+ (
+ cd clone2 &&
+ git submodule foreach --recursive "true" > ../actual
+ ) &&
+ test_cmp expect actual
+'
+
+cat > expect <<EOF
+nested1-nested1
+nested2-nested2
+nested3-nested3
+submodule-submodule
+foo1-sub1
+foo2-sub2
+foo3-sub3
+EOF
+
+test_expect_success 'test "foreach --quiet --recursive"' '
+ (
+ cd clone2 &&
+ git submodule foreach -q --recursive "echo \$name-\$path" > ../actual
+ ) &&
+ test_cmp expect actual
+'
+
+test_expect_success 'use "update --recursive" to checkout all submodules' '
+ git clone super clone3 &&
+ (
+ cd clone3 &&
+ test ! -d sub1/.git &&
+ test ! -d sub2/.git &&
+ test ! -d sub3/.git &&
+ test ! -d nested1/.git &&
+ git submodule update --init --recursive &&
+ test -d sub1/.git &&
+ test -d sub2/.git &&
+ test -d sub3/.git &&
+ test -d nested1/.git &&
+ test -d nested1/nested2/.git &&
+ test -d nested1/nested2/nested3/.git &&
+ test -d nested1/nested2/nested3/submodule/.git
+ )
+'
+
+nested1sha1=$(cd clone3/nested1 && git rev-parse HEAD)
+nested2sha1=$(cd clone3/nested1/nested2 && git rev-parse HEAD)
+nested3sha1=$(cd clone3/nested1/nested2/nested3 && git rev-parse HEAD)
+submodulesha1=$(cd clone3/nested1/nested2/nested3/submodule && git rev-parse HEAD)
+sub1sha1=$(cd clone3/sub1 && git rev-parse HEAD)
+sub2sha1=$(cd clone3/sub2 && git rev-parse HEAD)
+sub3sha1=$(cd clone3/sub3 && git rev-parse HEAD)
+sub1sha1_short=$(cd clone3/sub1 && git rev-parse --short HEAD)
+sub2sha1_short=$(cd clone3/sub2 && git rev-parse --short HEAD)
+
+cat > expect <<EOF
+ $nested1sha1 nested1 (heads/master)
+ $nested2sha1 nested1/nested2 (heads/master)
+ $nested3sha1 nested1/nested2/nested3 (heads/master)
+ $submodulesha1 nested1/nested2/nested3/submodule (heads/master)
+ $sub1sha1 sub1 ($sub1sha1_short)
+ $sub2sha1 sub2 ($sub2sha1_short)
+ $sub3sha1 sub3 (heads/master)
+EOF
+
+test_expect_success 'test "status --recursive"' '
+ (
+ cd clone3 &&
+ git submodule status --recursive > ../actual
+ ) &&
+ test_cmp expect actual
+'
+
+test_expect_success 'use "git clone --recursive" to checkout all submodules' '
+ git clone --recursive super clone4 &&
+ test -d clone4/.git &&
+ test -d clone4/sub1/.git &&
+ test -d clone4/sub2/.git &&
+ test -d clone4/sub3/.git &&
+ test -d clone4/nested1/.git &&
+ test -d clone4/nested1/nested2/.git &&
+ test -d clone4/nested1/nested2/nested3/.git &&
+ test -d clone4/nested1/nested2/nested3/submodule/.git
+'
+
+test_done
diff --git a/t/t7406-submodule-reference.sh b/t/t7408-submodule-reference.sh
index cc16d3f05..cc16d3f05 100755
--- a/t/t7406-submodule-reference.sh
+++ b/t/t7408-submodule-reference.sh
diff --git a/t/test-lib.sh b/t/test-lib.sh
index a5b8d03db..f2ca53647 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -685,6 +685,21 @@ do
esac
done
+# Provide an implementation of the 'yes' utility
+yes () {
+ if test $# = 0
+ then
+ y=y
+ else
+ y="$*"
+ fi
+
+ while echo "$y"
+ do
+ :
+ done
+}
+
# Fix some commands on Windows
case $(uname -s) in
*MINGW*)