diff options
Diffstat (limited to 't')
653 files changed, 53770 insertions, 0 deletions
diff --git a/t/.gitattributes b/t/.gitattributes new file mode 100644 index 0000000000..1b97c5465b --- /dev/null +++ b/t/.gitattributes @@ -0,0 +1 @@ +t[0-9][0-9][0-9][0-9]/* -whitespace diff --git a/t/.gitignore b/t/.gitignore new file mode 100644 index 0000000000..b27e280083 --- /dev/null +++ b/t/.gitignore @@ -0,0 +1,2 @@ +/trash directory +/test-results diff --git a/t/Makefile b/t/Makefile new file mode 100644 index 0000000000..0d65cedaa6 --- /dev/null +++ b/t/Makefile @@ -0,0 +1,37 @@ +# Run tests +# +# Copyright (c) 2005 Junio C Hamano +# + +#GIT_TEST_OPTS=--verbose --debug +SHELL_PATH ?= $(SHELL) +TAR ?= $(TAR) +RM ?= rm -f + +# Shell quote; +SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) + +T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh) +TSVN = $(wildcard t91[0-9][0-9]-*.sh) + +all: pre-clean $(T) aggregate-results clean + +$(T): + @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS) + +pre-clean: + $(RM) -r test-results + +clean: + $(RM) -r 'trash directory' test-results + +aggregate-results: + '$(SHELL_PATH_SQ)' ./aggregate-results.sh test-results/t*-* + +# we can test NO_OPTIMIZE_COMMITS independently of LC_ALL +full-svn-test: + $(MAKE) $(TSVN) GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C + $(MAKE) $(TSVN) GIT_SVN_NO_OPTIMIZE_COMMITS=0 LC_ALL=en_US.UTF-8 + +.PHONY: pre-clean $(T) aggregate-results clean +.NOTPARALLEL: diff --git a/t/README b/t/README new file mode 100644 index 0000000000..8f12d48fe8 --- /dev/null +++ b/t/README @@ -0,0 +1,241 @@ +Core GIT Tests +============== + +This directory holds many test scripts for core GIT tools. The +first part of this short document describes how to run the tests +and read their output. + +When fixing the tools or adding enhancements, you are strongly +encouraged to add tests in this directory to cover what you are +trying to fix or enhance. The later part of this short document +describes how your test scripts should be organized. + + +Running Tests +------------- + +The easiest way to run tests is to say "make". This runs all +the tests. + + *** t0000-basic.sh *** + * ok 1: .git/objects should be empty after git-init in an empty repo. + * ok 2: .git/objects should have 256 subdirectories. + * ok 3: git-update-index without --add should fail adding. + ... + * ok 23: no diff after checkout and git-update-index --refresh. + * passed all 23 test(s) + *** t0100-environment-names.sh *** + * ok 1: using old names should issue warnings. + * ok 2: using old names but having new names should not issue warnings. + ... + +Or you can run each test individually from command line, like +this: + + $ sh ./t3001-ls-files-killed.sh + * ok 1: git-update-index --add to add various paths. + * ok 2: git-ls-files -k to show killed files. + * ok 3: validate git-ls-files -k output. + * passed all 3 test(s) + +You can pass --verbose (or -v), --debug (or -d), and --immediate +(or -i) command line argument to the test. + +--verbose:: + This makes the test more verbose. Specifically, the + command being run and their output if any are also + output. + +--debug:: + This may help the person who is developing a new test. + It causes the command defined with test_debug to run. + +--immediate:: + This causes the test to immediately exit upon the first + failed test. + +--long-tests:: + This causes additional long-running tests to be run (where + available), for more exhaustive testing. + + +Skipping Tests +-------------- + +In some environments, certain tests have no way of succeeding +due to platform limitation, such as lack of 'unzip' program, or +filesystem that do not allow arbitrary sequence of non-NUL bytes +as pathnames. + +You should be able to say something like + + $ GIT_SKIP_TESTS=t9200.8 sh ./t9200-git-cvsexport-commit.sh + +and even: + + $ GIT_SKIP_TESTS='t[0-4]??? t91?? t9200.8' make + +to omit such tests. The value of the environment variable is a +SP separated list of patterns that tells which tests to skip, +and either can match the "t[0-9]{4}" part to skip the whole +test, or t[0-9]{4} followed by ".$number" to say which +particular test to skip. + +Note that some tests in the existing test suite rely on previous +test item, so you cannot arbitrarily disable one and expect the +remainder of test to check what the test originally was intended +to check. + + +Naming Tests +------------ + +The test files are named as: + + tNNNN-commandname-details.sh + +where N is a decimal digit. + +First digit tells the family: + + 0 - the absolute basics and global stuff + 1 - the basic commands concerning database + 2 - the basic commands concerning the working tree + 3 - the other basic commands (e.g. ls-files) + 4 - the diff commands + 5 - the pull and exporting commands + 6 - the revision tree commands (even e.g. merge-base) + 7 - the porcelainish commands concerning the working tree + 8 - the porcelainish commands concerning forensics + 9 - the git tools + +Second digit tells the particular command we are testing. + +Third digit (optionally) tells the particular switch or group of switches +we are testing. + +If you create files under t/ directory (i.e. here) that is not +the top-level test script, never name the file to match the above +pattern. The Makefile here considers all such files as the +top-level test script and tries to run all of them. A care is +especially needed if you are creating a common test library +file, similar to test-lib.sh, because such a library file may +not be suitable for standalone execution. + + +Writing Tests +------------- + +The test script is written as a shell script. It should start +with the standard "#!/bin/sh" with copyright notices, and an +assignment to variable 'test_description', like this: + + #!/bin/sh + # + # Copyright (c) 2005 Junio C Hamano + # + + test_description='xxx test (option --frotz) + + This test registers the following structure in the cache + and tries to run git-ls-files with option --frotz.' + + +Source 'test-lib.sh' +-------------------- + +After assigning test_description, the test script should source +test-lib.sh like this: + + . ./test-lib.sh + +This test harness library does the following things: + + - If the script is invoked with command line argument --help + (or -h), it shows the test_description and exits. + + - Creates an empty test directory with an empty .git/objects + database and chdir(2) into it. This directory is 't/trash directory' + if you must know, but I do not think you care. + + - Defines standard test helper functions for your scripts to + use. These functions are designed to make all scripts behave + consistently when command line arguments --verbose (or -v), + --debug (or -d), and --immediate (or -i) is given. + + +End with test_done +------------------ + +Your script will be a sequence of tests, using helper functions +from the test harness library. At the end of the script, call +'test_done'. + + +Test harness library +-------------------- + +There are a handful helper functions defined in the test harness +library for your script to use. + + - test_expect_success <message> <script> + + This takes two strings as parameter, and evaluates the + <script>. If it yields success, test is considered + successful. <message> should state what it is testing. + + Example: + + test_expect_success \ + 'git-write-tree should be able to write an empty tree.' \ + 'tree=$(git-write-tree)' + + - test_expect_failure <message> <script> + + This is NOT the opposite of test_expect_success, but is used + to mark a test that demonstrates a known breakage. Unlike + the usual test_expect_success tests, which say "ok" on + success and "FAIL" on failure, this will say "FIXED" on + success and "still broken" on failure. Failures from these + tests won't cause -i (immediate) to stop. + + - test_debug <script> + + This takes a single argument, <script>, and evaluates it only + when the test script is started with --debug command line + argument. This is primarily meant for use during the + development of a new test script. + + - test_done + + Your test script must have test_done at the end. Its purpose + is to summarize successes and failures in the test script and + exit with an appropriate error code. + + +Tips for Writing Tests +---------------------- + +As with any programming projects, existing programs are the best +source of the information. However, do _not_ emulate +t0000-basic.sh when writing your tests. The test is special in +that it tries to validate the very core of GIT. For example, it +knows that there will be 256 subdirectories under .git/objects/, +and it knows that the object ID of an empty tree is a certain +40-byte string. This is deliberately done so in t0000-basic.sh +because the things the very basic core test tries to achieve is +to serve as a basis for people who are changing the GIT internal +drastically. For these people, after making certain changes, +not seeing failures from the basic test _is_ a failure. And +such drastic changes to the core GIT that even changes these +otherwise supposedly stable object IDs should be accompanied by +an update to t0000-basic.sh. + +However, other tests that simply rely on basic parts of the core +GIT working properly should not have that level of intimate +knowledge of the core GIT internals. If all the test scripts +hardcoded the object IDs like t0000-basic.sh does, that defeats +the purpose of t0000-basic.sh, which is to isolate that level of +validation in one place. Your test also ends up needing +updating when such a change to the internal happens, so do _not_ +do it and leave the low level of validation to t0000-basic.sh. diff --git a/t/aggregate-results.sh b/t/aggregate-results.sh new file mode 100755 index 0000000000..d5bab75d7d --- /dev/null +++ b/t/aggregate-results.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +fixed=0 +success=0 +failed=0 +broken=0 +total=0 + +for file +do + while read type value + do + case $type in + '') + continue ;; + fixed) + fixed=$(($fixed + $value)) ;; + success) + success=$(($success + $value)) ;; + failed) + failed=$(($failed + $value)) ;; + broken) + broken=$(($broken + $value)) ;; + total) + total=$(($total + $value)) ;; + esac + done <"$file" +done + +printf "%-8s%d\n" fixed $fixed +printf "%-8s%d\n" success $success +printf "%-8s%d\n" failed $failed +printf "%-8s%d\n" broken $broken +printf "%-8s%d\n" total $total diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh new file mode 100644 index 0000000000..cacb273aff --- /dev/null +++ b/t/annotate-tests.sh @@ -0,0 +1,123 @@ +# This file isn't used as a test script directly, instead it is +# sourced from t8001-annotate.sh and t8001-blame.sh. + +check_count () { + head= + case "$1" in -h) head="$2"; shift; shift ;; esac + echo "$PROG file $head" >&4 + $PROG file $head >.result || return 1 + cat .result | perl -e ' + my %expect = (@ARGV); + my %count = (); + while (<STDIN>) { + if (/^[0-9a-f]+\t\(([^\t]+)\t/) { + my $author = $1; + for ($author) { s/^\s*//; s/\s*$//; } + if (exists $expect{$author}) { + $count{$author}++; + } + } + } + my $bad = 0; + while (my ($author, $count) = each %count) { + my $ok; + if ($expect{$author} != $count) { + $bad = 1; + $ok = "bad"; + } + else { + $ok = "good"; + } + print STDERR "Author $author (expected $expect{$author}, attributed $count) $ok\n"; + } + exit($bad); + ' "$@" +} + +test_expect_success \ + 'prepare reference tree' \ + 'echo "1A quick brown fox jumps over the" >file && + echo "lazy dog" >>file && + git add file + GIT_AUTHOR_NAME="A" git commit -a -m "Initial."' + +test_expect_success \ + 'check all lines blamed on A' \ + 'check_count A 2' + +test_expect_success \ + 'Setup new lines blamed on B' \ + 'echo "2A quick brown fox jumps over the" >>file && + echo "lazy dog" >> file && + GIT_AUTHOR_NAME="B" git commit -a -m "Second."' + +test_expect_success \ + 'Two lines blamed on A, two on B' \ + 'check_count A 2 B 2' + +test_expect_success \ + 'merge-setup part 1' \ + 'git checkout -b branch1 master && + echo "3A slow green fox jumps into the" >> file && + echo "well." >> file && + GIT_AUTHOR_NAME="B1" git commit -a -m "Branch1-1"' + +test_expect_success \ + 'Two lines blamed on A, two on B, two on B1' \ + 'check_count A 2 B 2 B1 2' + +test_expect_success \ + 'merge-setup part 2' \ + 'git checkout -b branch2 master && + sed -e "s/2A quick brown/4A quick brown lazy dog/" < file > file.new && + mv file.new file && + GIT_AUTHOR_NAME="B2" git commit -a -m "Branch2-1"' + +test_expect_success \ + 'Two lines blamed on A, one on B, one on B2' \ + 'check_count A 2 B 1 B2 1' + +test_expect_success \ + 'merge-setup part 3' \ + 'git pull . branch1' + +test_expect_success \ + 'Two lines blamed on A, one on B, two on B1, one on B2' \ + 'check_count A 2 B 1 B1 2 B2 1' + +test_expect_success \ + 'Annotating an old revision works' \ + 'check_count -h master A 2 B 2' + +test_expect_success \ + 'Annotating an old revision works' \ + 'check_count -h master^ A 2' + +test_expect_success \ + 'merge-setup part 4' \ + 'echo "evil merge." >>file && + git commit -a --amend' + +test_expect_success \ + 'Two lines blamed on A, one on B, two on B1, one on B2, one on A U Thor' \ + 'check_count A 2 B 1 B1 2 B2 1 "A U Thor" 1' + +test_expect_success \ + 'an incomplete line added' \ + 'echo "incomplete" | tr -d "\\012" >>file && + GIT_AUTHOR_NAME="C" git commit -a -m "Incomplete"' + +test_expect_success \ + 'With incomplete lines.' \ + 'check_count A 2 B 1 B1 2 B2 1 "A U Thor" 1 C 1' + +test_expect_success \ + 'some edit' \ + 'mv file file.orig && + sed -e "s/^3A/99/" -e "/^1A/d" -e "/^incomplete/d" < file.orig > file && + echo "incomplete" | tr -d "\\012" >>file && + GIT_AUTHOR_NAME="D" git commit -a -m "edit"' + +test_expect_success \ + 'some edit' \ + 'check_count A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1' diff --git a/t/diff-lib.sh b/t/diff-lib.sh new file mode 100644 index 0000000000..4bddeb591e --- /dev/null +++ b/t/diff-lib.sh @@ -0,0 +1,41 @@ +: + +_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' +_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" +sanitize_diff_raw='/^:/s/ '"$_x40"' '"$_x40"' \([A-Z]\)[0-9]* / X X \1# /' +compare_diff_raw () { + # When heuristics are improved, the score numbers would change. + # Ignore them while comparing. + # Also we do not check SHA1 hash generation in this test, which + # is a job for t0000-basic.sh + + sed -e "$sanitize_diff_raw" <"$1" >.tmp-1 + sed -e "$sanitize_diff_raw" <"$2" >.tmp-2 + test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2 +} + +sanitize_diff_raw_z='/^:/s/ '"$_x40"' '"$_x40"' \([A-Z]\)[0-9]*$/ X X \1#/' +compare_diff_raw_z () { + # When heuristics are improved, the score numbers would change. + # Ignore them while comparing. + # Also we do not check SHA1 hash generation in this test, which + # is a job for t0000-basic.sh + + perl -pe 'y/\000/\012/' <"$1" | sed -e "$sanitize_diff_raw_z" >.tmp-1 + perl -pe 'y/\000/\012/' <"$2" | sed -e "$sanitize_diff_raw_z" >.tmp-2 + test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2 +} + +compare_diff_patch () { + # When heuristics are improved, the score numbers would change. + # Ignore them while comparing. + sed -e ' + /^[dis]*imilarity index [0-9]*%$/d + /^index [0-9a-f]*\.\.[0-9a-f]/d + ' <"$1" >.tmp-1 + sed -e ' + /^[dis]*imilarity index [0-9]*%$/d + /^index [0-9a-f]*\.\.[0-9a-f]/d + ' <"$2" >.tmp-2 + test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2 +} diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh new file mode 100644 index 0000000000..a841df2a9e --- /dev/null +++ b/t/lib-git-svn.sh @@ -0,0 +1,137 @@ +. ./test-lib.sh + +if test -n "$NO_SVN_TESTS" +then + test_expect_success 'skipping git-svn tests, NO_SVN_TESTS defined' : + test_done + exit +fi + +GIT_DIR=$PWD/.git +GIT_SVN_DIR=$GIT_DIR/svn/git-svn +SVN_TREE=$GIT_SVN_DIR/svn-tree + +svn >/dev/null 2>&1 +if test $? -ne 1 +then + test_expect_success 'skipping git-svn tests, svn not found' : + test_done + exit +fi + +svnrepo=$PWD/svnrepo +export svnrepo + +perl -w -e " +use SVN::Core; +use SVN::Repos; +\$SVN::Core::VERSION gt '1.1.0' or exit(42); +system(qw/svnadmin create --fs-type fsfs/, \$ENV{svnrepo}) == 0 or exit(41); +" >&3 2>&4 +x=$? +if test $x -ne 0 +then + if test $x -eq 42; then + err='Perl SVN libraries must be >= 1.1.0' + elif test $x -eq 41; then + err='svnadmin failed to create fsfs repository' + else + err='Perl SVN libraries not found or unusable, skipping test' + fi + test_expect_success "$err" : + test_done + exit +fi + +rawsvnrepo="$svnrepo" +svnrepo="file://$svnrepo" + +poke() { + test-chmtime +1 "$1" +} + +for d in \ + "$SVN_HTTPD_PATH" \ + /usr/sbin/apache2 \ + /usr/sbin/httpd \ +; do + if test -f "$d" + then + SVN_HTTPD_PATH="$d" + break + fi +done +for d in \ + "$SVN_HTTPD_MODULE_PATH" \ + /usr/lib/apache2/modules \ + /usr/libexec/apache2 \ +; do + if test -d "$d" + then + SVN_HTTPD_MODULE_PATH="$d" + break + fi +done + +start_httpd () { + repo_base_path="$1" + if test -z "$SVN_HTTPD_PORT" + then + echo >&2 'SVN_HTTPD_PORT is not defined!' + return + fi + if test -z "$repo_base_path" + then + repo_base_path=svn + fi + + mkdir "$GIT_DIR"/logs + + cat > "$GIT_DIR/httpd.conf" <<EOF +ServerName "git-svn test" +ServerRoot "$GIT_DIR" +DocumentRoot "$GIT_DIR" +PidFile "$GIT_DIR/httpd.pid" +LockFile logs/accept.lock +Listen 127.0.0.1:$SVN_HTTPD_PORT +LoadModule dav_module $SVN_HTTPD_MODULE_PATH/mod_dav.so +LoadModule dav_svn_module $SVN_HTTPD_MODULE_PATH/mod_dav_svn.so +<Location /$repo_base_path> + DAV svn + SVNPath "$rawsvnrepo" +</Location> +EOF + "$SVN_HTTPD_PATH" -f "$GIT_DIR"/httpd.conf -k start + svnrepo="http://127.0.0.1:$SVN_HTTPD_PORT/$repo_base_path" +} + +stop_httpd () { + test -z "$SVN_HTTPD_PORT" && return + "$SVN_HTTPD_PATH" -f "$GIT_DIR"/httpd.conf -k stop +} + +convert_to_rev_db () { + perl -w -- - "$@" <<\EOF +use strict; +@ARGV == 2 or die "Usage: convert_to_rev_db <input> <output>"; +open my $wr, '+>', $ARGV[1] or die "$!: couldn't open: $ARGV[1]"; +open my $rd, '<', $ARGV[0] or die "$!: couldn't open: $ARGV[0]"; +my $size = (stat($rd))[7]; +($size % 24) == 0 or die "Inconsistent size: $size"; +while (sysread($rd, my $buf, 24) == 24) { + my ($r, $c) = unpack('NH40', $buf); + my $offset = $r * 41; + seek $wr, 0, 2 or die $!; + my $pos = tell $wr; + if ($pos < $offset) { + for (1 .. (($offset - $pos) / 41)) { + print $wr (('0' x 40),"\n") or die $!; + } + } + seek $wr, $offset, 0 or die $!; + print $wr $c,"\n" or die $!; +} +close $wr or die $!; +close $rd or die $!; +EOF +} diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh new file mode 100644 index 0000000000..dc473dfb53 --- /dev/null +++ b/t/lib-httpd.sh @@ -0,0 +1,99 @@ +#!/bin/sh +# +# Copyright (c) 2008 Clemens Buchacher <drizzd@aon.at> +# + +if test -z "$GIT_TEST_HTTPD" +then + say "skipping test, network testing disabled by default" + say "(define GIT_TEST_HTTPD to enable)" + test_done + exit +fi + +LIB_HTTPD_PATH=${LIB_HTTPD_PATH-'/usr/sbin/apache2'} +LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'8111'} + +TEST_PATH="$PWD"/../lib-httpd +HTTPD_ROOT_PATH="$PWD"/httpd +HTTPD_DOCUMENT_ROOT_PATH=$HTTPD_ROOT_PATH/www + +if ! test -x "$LIB_HTTPD_PATH" +then + say "skipping test, no web server found at '$LIB_HTTPD_PATH'" + test_done + exit +fi + +HTTPD_VERSION=`$LIB_HTTPD_PATH -v | \ + sed -n 's/^Server version: Apache\/\([0-9]*\)\..*$/\1/p; q'` + +if test -n "$HTTPD_VERSION" +then + if test -z "$LIB_HTTPD_MODULE_PATH" + then + if ! test $HTTPD_VERSION -ge 2 + then + say "skipping test, at least Apache version 2 is required" + test_done + exit + fi + + LIB_HTTPD_MODULE_PATH='/usr/lib/apache2/modules' + fi +else + error "Could not identify web server at '$LIB_HTTPD_PATH'" +fi + +HTTPD_PARA="" + +prepare_httpd() { + mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH" + + ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules" + + if test -n "$LIB_HTTPD_SSL" + then + HTTPD_URL=https://127.0.0.1:$LIB_HTTPD_PORT + + RANDFILE_PATH="$HTTPD_ROOT_PATH"/.rnd openssl req \ + -config "$TEST_PATH/ssl.cnf" \ + -new -x509 -nodes \ + -out "$HTTPD_ROOT_PATH/httpd.pem" \ + -keyout "$HTTPD_ROOT_PATH/httpd.pem" + GIT_SSL_NO_VERIFY=t + export GIT_SSL_NO_VERIFY + HTTPD_PARA="$HTTPD_PARA -DSSL" + else + HTTPD_URL=http://127.0.0.1:$LIB_HTTPD_PORT + fi + + if test -n "$LIB_HTTPD_DAV" -o -n "$LIB_HTTPD_SVN" + then + HTTPD_PARA="$HTTPD_PARA -DDAV" + + if test -n "$LIB_HTTPD_SVN" + then + HTTPD_PARA="$HTTPD_PARA -DSVN" + rawsvnrepo="$HTTPD_ROOT_PATH/svnrepo" + svnrepo="http://127.0.0.1:$LIB_HTTPD_PORT/svn" + fi + fi +} + +start_httpd() { + prepare_httpd + + trap 'stop_httpd; die' exit + + "$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \ + -f "$TEST_PATH/apache.conf" $HTTPD_PARA \ + -c "Listen 127.0.0.1:$LIB_HTTPD_PORT" -k start +} + +stop_httpd() { + trap 'die' exit + + "$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \ + -f "$TEST_PATH/apache.conf" -k stop +} diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf new file mode 100644 index 0000000000..4717c2d33b --- /dev/null +++ b/t/lib-httpd/apache.conf @@ -0,0 +1,35 @@ +ServerName dummy +PidFile httpd.pid +DocumentRoot www +ErrorLog error.log + +<IfDefine SSL> +LoadModule ssl_module modules/mod_ssl.so + +SSLCertificateFile httpd.pem +SSLCertificateKeyFile httpd.pem +SSLRandomSeed startup file:/dev/urandom 512 +SSLRandomSeed connect file:/dev/urandom 512 +SSLSessionCache none +SSLMutex file:ssl_mutex +SSLEngine On +</IfDefine> + +<IfDefine DAV> + LoadModule dav_module modules/mod_dav.so + LoadModule dav_fs_module modules/mod_dav_fs.so + + DAVLockDB DAVLock + <Location /> + Dav on + </Location> +</IfDefine> + +<IfDefine SVN> + LoadModule dav_svn_module modules/mod_dav_svn.so + + <Location /svn> + DAV svn + SVNPath svnrepo + </Location> +</IfDefine> diff --git a/t/lib-httpd/ssl.cnf b/t/lib-httpd/ssl.cnf new file mode 100644 index 0000000000..6dab2579cb --- /dev/null +++ b/t/lib-httpd/ssl.cnf @@ -0,0 +1,8 @@ +RANDFILE = $ENV::RANDFILE_PATH + +[ req ] +default_bits = 1024 +distinguished_name = req_distinguished_name +prompt = no +[ req_distinguished_name ] +commonName = 127.0.0.1 diff --git a/t/lib-read-tree-m-3way.sh b/t/lib-read-tree-m-3way.sh new file mode 100644 index 0000000000..168329adbc --- /dev/null +++ b/t/lib-read-tree-m-3way.sh @@ -0,0 +1,158 @@ +: Included from t1000-read-tree-m-3way.sh and others +# Original tree. +mkdir Z +for a in N D M +do + for b in N D M + do + p=$a$b + echo This is $p from the original tree. >$p + echo This is Z/$p from the original tree. >Z/$p + test_expect_success \ + "adding test file $p and Z/$p" \ + 'git update-index --add $p && + git update-index --add Z/$p' + done +done +echo This is SS from the original tree. >SS +test_expect_success \ + 'adding test file SS' \ + 'git update-index --add SS' +cat >TT <<\EOF +This is a trivial merge sample text. +Branch A is expected to upcase this word, here. +There are some filler lines to avoid diff context +conflicts here, +like this one, +and this one, +and this one is yet another one of them. +At the very end, here comes another line, that is +the word, expected to be upcased by Branch B. +This concludes the trivial merge sample file. +EOF +test_expect_success \ + 'adding test file TT' \ + 'git update-index --add TT' +test_expect_success \ + 'prepare initial tree' \ + 'tree_O=$(git write-tree)' + +################################################################ +# Branch A and B makes the changes according to the above matrix. + +################################################################ +# Branch A + +to_remove=$(echo D? Z/D?) +rm -f $to_remove +test_expect_success \ + 'change in branch A (removal)' \ + 'git update-index --remove $to_remove' + +for p in M? Z/M? +do + echo This is modified $p in the branch A. >$p + test_expect_success \ + 'change in branch A (modification)' \ + "git update-index $p" +done + +for p in AN AA Z/AN Z/AA +do + echo This is added $p in the branch A. >$p + test_expect_success \ + 'change in branch A (addition)' \ + "git update-index --add $p" +done + +echo This is SS from the modified tree. >SS +echo This is LL from the modified tree. >LL +test_expect_success \ + 'change in branch A (addition)' \ + 'git update-index --add LL && + git update-index SS' +mv TT TT- +sed -e '/Branch A/s/word/WORD/g' <TT- >TT +rm -f TT- +test_expect_success \ + 'change in branch A (edit)' \ + 'git update-index TT' + +mkdir DF +echo Branch A makes a file at DF/DF, creating a directory DF. >DF/DF +test_expect_success \ + 'change in branch A (change file to directory)' \ + 'git update-index --add DF/DF' + +test_expect_success \ + 'recording branch A tree' \ + 'tree_A=$(git write-tree)' + +################################################################ +# Branch B +# Start from O + +rm -rf [NDMASLT][NDMASLT] Z DF +mkdir Z +test_expect_success \ + 'reading original tree and checking out' \ + 'git read-tree $tree_O && + git checkout-index -a' + +to_remove=$(echo ?D Z/?D) +rm -f $to_remove +test_expect_success \ + 'change in branch B (removal)' \ + "git update-index --remove $to_remove" + +for p in ?M Z/?M +do + echo This is modified $p in the branch B. >$p + test_expect_success \ + 'change in branch B (modification)' \ + "git update-index $p" +done + +for p in NA AA Z/NA Z/AA +do + echo This is added $p in the branch B. >$p + test_expect_success \ + 'change in branch B (addition)' \ + "git update-index --add $p" +done +echo This is SS from the modified tree. >SS +echo This is LL from the modified tree. >LL +test_expect_success \ + 'change in branch B (addition and modification)' \ + 'git update-index --add LL && + git update-index SS' +mv TT TT- +sed -e '/Branch B/s/word/WORD/g' <TT- >TT +rm -f TT- +test_expect_success \ + 'change in branch B (modification)' \ + 'git update-index TT' + +echo Branch B makes a file at DF. >DF +test_expect_success \ + 'change in branch B (addition of a file to conflict with directory)' \ + 'git update-index --add DF' + +test_expect_success \ + 'recording branch B tree' \ + 'tree_B=$(git write-tree)' + +test_expect_success \ + 'keep contents of 3 trees for easy access' \ + 'rm -f .git/index && + git read-tree $tree_O && + mkdir .orig-O && + git checkout-index --prefix=.orig-O/ -f -q -a && + rm -f .git/index && + git read-tree $tree_A && + mkdir .orig-A && + git checkout-index --prefix=.orig-A/ -f -q -a && + rm -f .git/index && + git read-tree $tree_B && + mkdir .orig-B && + git checkout-index --prefix=.orig-B/ -f -q -a' diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh new file mode 100755 index 0000000000..70df15cbd8 --- /dev/null +++ b/t/t0000-basic.sh @@ -0,0 +1,334 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Test the very basics part #1. + +The rest of the test suite does not check the basic operation of git +plumbing commands to work very carefully. Their job is to concentrate +on tricky features that caused bugs in the past to detect regression. + +This test runs very basic features, like registering things in cache, +writing tree, etc. + +Note that this test *deliberately* hard-codes many expected object +IDs. When object ID computation changes, like in the previous case of +swapping compression and hashing order, the person who is making the +modification *should* take notice and update the test vectors here. +' + +################################################################ +# It appears that people try to run tests without building... + +../git >/dev/null +if test $? != 1 +then + echo >&2 'You do not seem to have built git yet.' + exit 1 +fi + +. ./test-lib.sh + +################################################################ +# git init has been done in an empty repository. +# make sure it is empty. + +find .git/objects -type f -print >should-be-empty +test_expect_success \ + '.git/objects should be empty after git init in an empty repo.' \ + 'cmp -s /dev/null should-be-empty' + +# also it should have 2 subdirectories; no fan-out anymore, pack, and info. +# 3 is counting "objects" itself +find .git/objects -type d -print >full-of-directories +test_expect_success \ + '.git/objects should have 3 subdirectories.' \ + 'test $(wc -l < full-of-directories) = 3' + +################################################################ +# Test harness +test_expect_success 'success is reported like this' ' + : +' +test_expect_failure 'pretend we have a known breakage' ' + false +' +test_expect_failure 'pretend we have fixed a known breakage' ' + : +' + +################################################################ +# Basics of the basics + +# updating a new file without --add should fail. +test_expect_success 'git update-index without --add should fail adding.' ' + test_must_fail git update-index should-be-empty +' + +# and with --add it should succeed, even if it is empty (it used to fail). +test_expect_success \ + 'git update-index with --add should succeed.' \ + 'git update-index --add should-be-empty' + +test_expect_success \ + 'writing tree out with git write-tree' \ + 'tree=$(git write-tree)' + +# we know the shape and contents of the tree and know the object ID for it. +test_expect_success \ + 'validate object ID of a known tree.' \ + 'test "$tree" = 7bb943559a305bdd6bdee2cef6e5df2413c3d30a' + +# Removing paths. +rm -f should-be-empty full-of-directories +test_expect_success 'git update-index without --remove should fail removing.' ' + test_must_fail git update-index should-be-empty +' + +test_expect_success \ + 'git update-index with --remove should be able to remove.' \ + 'git update-index --remove should-be-empty' + +# Empty tree can be written with recent write-tree. +test_expect_success \ + 'git write-tree should be able to write an empty tree.' \ + 'tree=$(git write-tree)' + +test_expect_success \ + 'validate object ID of a known tree.' \ + 'test "$tree" = 4b825dc642cb6eb9a060e54bf8d69288fbee4904' + +# Various types of objects +mkdir path2 path3 path3/subp3 +for p in path0 path2/file2 path3/file3 path3/subp3/file3 +do + echo "hello $p" >$p + ln -s "hello $p" ${p}sym +done +test_expect_success \ + 'adding various types of objects with git update-index --add.' \ + 'find path* ! -type d -print | xargs git update-index --add' + +# Show them and see that matches what we expect. +test_expect_success \ + 'showing stage with git ls-files --stage' \ + 'git ls-files --stage >current' + +cat >expected <<\EOF +100644 f87290f8eb2cbbea7857214459a0739927eab154 0 path0 +120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0 path0sym +100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0 path2/file2 +120000 d8ce161addc5173867a3c3c730924388daedbc38 0 path2/file2sym +100644 0aa34cae68d0878578ad119c86ca2b5ed5b28376 0 path3/file3 +120000 8599103969b43aff7e430efea79ca4636466794f 0 path3/file3sym +100644 00fb5908cb97c2564a9783c0c64087333b3b464f 0 path3/subp3/file3 +120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0 path3/subp3/file3sym +EOF +test_expect_success \ + 'validate git ls-files output for a known tree.' \ + 'diff current expected' + +test_expect_success \ + 'writing tree out with git write-tree.' \ + 'tree=$(git write-tree)' +test_expect_success \ + 'validate object ID for a known tree.' \ + 'test "$tree" = 087704a96baf1c2d1c869a8b084481e121c88b5b' + +test_expect_success \ + 'showing tree with git ls-tree' \ + 'git ls-tree $tree >current' +cat >expected <<\EOF +100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0 +120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym +040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe path2 +040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3 path3 +EOF +test_expect_success \ + 'git ls-tree output for a known tree.' \ + 'diff current expected' + +# This changed in ls-tree pathspec change -- recursive does +# not show tree nodes anymore. +test_expect_success \ + 'showing tree with git ls-tree -r' \ + 'git ls-tree -r $tree >current' +cat >expected <<\EOF +100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0 +120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym +100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 path2/file2 +120000 blob d8ce161addc5173867a3c3c730924388daedbc38 path2/file2sym +100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376 path3/file3 +120000 blob 8599103969b43aff7e430efea79ca4636466794f path3/file3sym +100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f path3/subp3/file3 +120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c path3/subp3/file3sym +EOF +test_expect_success \ + 'git ls-tree -r output for a known tree.' \ + 'diff current expected' + +# But with -r -t we can have both. +test_expect_success \ + 'showing tree with git ls-tree -r -t' \ + 'git ls-tree -r -t $tree >current' +cat >expected <<\EOF +100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0 +120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym +040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe path2 +100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 path2/file2 +120000 blob d8ce161addc5173867a3c3c730924388daedbc38 path2/file2sym +040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3 path3 +100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376 path3/file3 +120000 blob 8599103969b43aff7e430efea79ca4636466794f path3/file3sym +040000 tree 3c5e5399f3a333eddecce7a9b9465b63f65f51e2 path3/subp3 +100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f path3/subp3/file3 +120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c path3/subp3/file3sym +EOF +test_expect_success \ + 'git ls-tree -r output for a known tree.' \ + 'diff current expected' + +test_expect_success \ + 'writing partial tree out with git write-tree --prefix.' \ + 'ptree=$(git write-tree --prefix=path3)' +test_expect_success \ + 'validate object ID for a known tree.' \ + 'test "$ptree" = 21ae8269cacbe57ae09138dcc3a2887f904d02b3' + +test_expect_success \ + 'writing partial tree out with git write-tree --prefix.' \ + 'ptree=$(git write-tree --prefix=path3/subp3)' +test_expect_success \ + 'validate object ID for a known tree.' \ + 'test "$ptree" = 3c5e5399f3a333eddecce7a9b9465b63f65f51e2' + +cat >badobjects <<EOF +100644 blob 1000000000000000000000000000000000000000 dir/file1 +100644 blob 2000000000000000000000000000000000000000 dir/file2 +100644 blob 3000000000000000000000000000000000000000 dir/file3 +100644 blob 4000000000000000000000000000000000000000 dir/file4 +100644 blob 5000000000000000000000000000000000000000 dir/file5 +EOF + +rm .git/index +test_expect_success \ + 'put invalid objects into the index.' \ + 'git update-index --index-info < badobjects' + +test_expect_success 'writing this tree without --missing-ok.' ' + test_must_fail git write-tree +' + +test_expect_success \ + 'writing this tree with --missing-ok.' \ + 'git write-tree --missing-ok' + + +################################################################ +rm .git/index +test_expect_success \ + 'git read-tree followed by write-tree should be idempotent.' \ + 'git read-tree $tree && + test -f .git/index && + newtree=$(git write-tree) && + test "$newtree" = "$tree"' + +cat >expected <<\EOF +:100644 100644 f87290f8eb2cbbea7857214459a0739927eab154 0000000000000000000000000000000000000000 M path0 +:120000 120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0000000000000000000000000000000000000000 M path0sym +:100644 100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0000000000000000000000000000000000000000 M path2/file2 +:120000 120000 d8ce161addc5173867a3c3c730924388daedbc38 0000000000000000000000000000000000000000 M path2/file2sym +:100644 100644 0aa34cae68d0878578ad119c86ca2b5ed5b28376 0000000000000000000000000000000000000000 M path3/file3 +:120000 120000 8599103969b43aff7e430efea79ca4636466794f 0000000000000000000000000000000000000000 M path3/file3sym +:100644 100644 00fb5908cb97c2564a9783c0c64087333b3b464f 0000000000000000000000000000000000000000 M path3/subp3/file3 +:120000 120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0000000000000000000000000000000000000000 M path3/subp3/file3sym +EOF +test_expect_success \ + 'validate git diff-files output for a know cache/work tree state.' \ + 'git diff-files >current && diff >/dev/null -b current expected' + +test_expect_success \ + 'git update-index --refresh should succeed.' \ + 'git update-index --refresh' + +test_expect_success \ + 'no diff after checkout and git update-index --refresh.' \ + 'git diff-files >current && cmp -s current /dev/null' + +################################################################ +P=087704a96baf1c2d1c869a8b084481e121c88b5b +test_expect_success \ + 'git commit-tree records the correct tree in a commit.' \ + 'commit0=$(echo NO | git commit-tree $P) && + tree=$(git show --pretty=raw $commit0 | + sed -n -e "s/^tree //p" -e "/^author /q") && + test "z$tree" = "z$P"' + +test_expect_success \ + 'git commit-tree records the correct parent in a commit.' \ + 'commit1=$(echo NO | git commit-tree $P -p $commit0) && + parent=$(git show --pretty=raw $commit1 | + sed -n -e "s/^parent //p" -e "/^author /q") && + test "z$commit0" = "z$parent"' + +test_expect_success \ + 'git commit-tree omits duplicated parent in a commit.' \ + 'commit2=$(echo NO | git commit-tree $P -p $commit0 -p $commit0) && + parent=$(git show --pretty=raw $commit2 | + sed -n -e "s/^parent //p" -e "/^author /q" | + sort -u) && + test "z$commit0" = "z$parent" && + numparent=$(git show --pretty=raw $commit2 | + sed -n -e "s/^parent //p" -e "/^author /q" | + wc -l) && + test $numparent = 1' + +test_expect_success 'update-index D/F conflict' ' + mv path0 tmp && + mv path2 path0 && + mv tmp path2 && + git update-index --add --replace path2 path0/file2 && + numpath0=$(git ls-files path0 | wc -l) && + test $numpath0 = 1 +' + +test_expect_success 'absolute path works as expected' ' + mkdir first && + ln -s ../.git first/.git && + mkdir second && + ln -s ../first second/other && + mkdir third && + dir="$(cd .git; pwd -P)" && + dir2=third/../second/other/.git && + test "$dir" = "$(test-path-utils make_absolute_path $dir2)" && + file="$dir"/index && + test "$file" = "$(test-path-utils make_absolute_path $dir2/index)" && + basename=blub && + test "$dir/$basename" = "$(cd .git && test-path-utils make_absolute_path "$basename")" && + ln -s ../first/file .git/syml && + sym="$(cd first; pwd -P)"/file && + test "$sym" = "$(test-path-utils make_absolute_path "$dir2/syml")" +' + +test_expect_success 'very long name in the index handled sanely' ' + + a=a && # 1 + a=$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a && # 16 + a=$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a && # 256 + a=$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a && # 4096 + a=${a}q && + + >path4 && + git update-index --add path4 && + ( + git ls-files -s path4 | + sed -e "s/ .*/ /" | + tr -d "\012" + echo "$a" + ) | git update-index --index-info && + len=$(git ls-files "a*" | wc -c) && + test $len = 4098 +' + +test_done diff --git a/t/t0001-init.sh b/t/t0001-init.sh new file mode 100755 index 0000000000..620da5b320 --- /dev/null +++ b/t/t0001-init.sh @@ -0,0 +1,170 @@ +#!/bin/sh + +test_description='git init' + +. ./test-lib.sh + +check_config () { + if test -d "$1" && test -f "$1/config" && test -d "$1/refs" + then + : happy + else + echo "expected a directory $1, a file $1/config and $1/refs" + return 1 + fi + bare=$(GIT_CONFIG="$1/config" git config --bool core.bare) + worktree=$(GIT_CONFIG="$1/config" git config core.worktree) || + worktree=unset + + test "$bare" = "$2" && test "$worktree" = "$3" || { + echo "expected bare=$2 worktree=$3" + echo " got bare=$bare worktree=$worktree" + return 1 + } +} + +test_expect_success 'plain' ' + ( + unset GIT_DIR GIT_WORK_TREE + mkdir plain && + cd plain && + git init + ) && + check_config plain/.git false unset +' + +test_expect_success 'plain with GIT_WORK_TREE' ' + if ( + unset GIT_DIR + mkdir plain-wt && + cd plain-wt && + GIT_WORK_TREE=$(pwd) git init + ) + then + echo Should have failed -- GIT_WORK_TREE should not be used + false + fi +' + +test_expect_success 'plain bare' ' + ( + unset GIT_DIR GIT_WORK_TREE GIT_CONFIG + mkdir plain-bare-1 && + cd plain-bare-1 && + git --bare init + ) && + check_config plain-bare-1 true unset +' + +test_expect_success 'plain bare with GIT_WORK_TREE' ' + if ( + unset GIT_DIR GIT_CONFIG + mkdir plain-bare-2 && + cd plain-bare-2 && + GIT_WORK_TREE=$(pwd) git --bare init + ) + then + echo Should have failed -- GIT_WORK_TREE should not be used + false + fi +' + +test_expect_success 'GIT_DIR bare' ' + + ( + unset GIT_CONFIG + mkdir git-dir-bare.git && + GIT_DIR=git-dir-bare.git git init + ) && + check_config git-dir-bare.git true unset +' + +test_expect_success 'init --bare' ' + + ( + unset GIT_DIR GIT_WORK_TREE GIT_CONFIG + mkdir init-bare.git && + cd init-bare.git && + git init --bare + ) && + check_config init-bare.git true unset +' + +test_expect_success 'GIT_DIR non-bare' ' + + ( + unset GIT_CONFIG + mkdir non-bare && + cd non-bare && + GIT_DIR=.git git init + ) && + check_config non-bare/.git false unset +' + +test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' ' + + ( + unset GIT_CONFIG + mkdir git-dir-wt-1.git && + GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-1.git git init + ) && + check_config git-dir-wt-1.git false "$(pwd)" +' + +test_expect_success 'GIT_DIR & GIT_WORK_TREE (2)' ' + + if ( + unset GIT_CONFIG + mkdir git-dir-wt-2.git && + GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-2.git git --bare init + ) + then + echo Should have failed -- --bare should not be used + false + fi +' + +test_expect_success 'reinit' ' + + ( + unset GIT_CONFIG GIT_WORK_TREE GIT_CONFIG + + mkdir again && + cd again && + git init >out1 2>err1 && + git init >out2 2>err2 + ) && + grep "Initialized empty" again/out1 && + grep "Reinitialized existing" again/out2 && + >again/empty && + test_cmp again/empty again/err1 && + test_cmp again/empty again/err2 +' + +test_expect_success 'init with --template' ' + mkdir template-source && + echo content >template-source/file && + ( + mkdir template-custom && + cd template-custom && + git init --template=../template-source + ) && + test_cmp template-source/file template-custom/.git/file +' + +test_expect_success 'init with --template (blank)' ' + ( + mkdir template-plain && + cd template-plain && + git init + ) && + test -f template-plain/.git/info/exclude && + ( + mkdir template-blank && + cd template-blank && + git init --template= + ) && + ! test -f template-blank/.git/info/exclude +' + +test_done diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh new file mode 100755 index 0000000000..4db4ac44c9 --- /dev/null +++ b/t/t0002-gitfile.sh @@ -0,0 +1,103 @@ +#!/bin/sh + +test_description='.git file + +Verify that plumbing commands work when .git is a file +' +. ./test-lib.sh + +objpath() { + echo "$1" | sed -e 's|\(..\)|\1/|' +} + +objck() { + p=$(objpath "$1") + if test ! -f "$REAL/objects/$p" + then + echo "Object not found: $REAL/objects/$p" + false + fi +} + + +test_expect_success 'initial setup' ' + REAL="$(pwd)/.real" && + mv .git "$REAL" +' + +test_expect_success 'bad setup: invalid .git file format' ' + echo "gitdir $REAL" >.git && + if git rev-parse 2>.err + then + echo "git rev-parse accepted an invalid .git file" + false + fi && + if ! grep -qe "Invalid gitfile format" .err + then + echo "git rev-parse returned wrong error" + false + fi +' + +test_expect_success 'bad setup: invalid .git file path' ' + echo "gitdir: $REAL.not" >.git && + if git rev-parse 2>.err + then + echo "git rev-parse accepted an invalid .git file path" + false + fi && + if ! grep -qe "Not a git repository" .err + then + echo "git rev-parse returned wrong error" + false + fi +' + +test_expect_success 'final setup + check rev-parse --git-dir' ' + echo "gitdir: $REAL" >.git && + test "$REAL" = "$(git rev-parse --git-dir)" +' + +test_expect_success 'check hash-object' ' + echo "foo" >bar && + SHA=$(cat bar | git hash-object -w --stdin) && + objck $SHA +' + +test_expect_success 'check cat-file' ' + git cat-file blob $SHA >actual && + test_cmp bar actual +' + +test_expect_success 'check update-index' ' + if test -f "$REAL/index" + then + echo "Hmm, $REAL/index exists?" + false + fi && + rm -f "$REAL/objects/$(objpath $SHA)" && + git update-index --add bar && + if ! test -f "$REAL/index" + then + echo "$REAL/index not found" + false + fi && + objck $SHA +' + +test_expect_success 'check write-tree' ' + SHA=$(git write-tree) && + objck $SHA +' + +test_expect_success 'check commit-tree' ' + SHA=$(echo "commit bar" | git commit-tree $SHA) && + objck $SHA +' + +test_expect_success 'check rev-list' ' + echo $SHA >"$REAL/HEAD" && + test "$SHA" = "$(git rev-list HEAD)" +' + +test_done diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh new file mode 100755 index 0000000000..3d8e06a20f --- /dev/null +++ b/t/t0003-attributes.sh @@ -0,0 +1,92 @@ +#!/bin/sh + +test_description=gitattributes + +. ./test-lib.sh + +attr_check () { + + path="$1" + expect="$2" + + git check-attr test -- "$path" >actual && + echo "$path: test: $2" >expect && + test_cmp expect actual + +} + + +test_expect_success 'setup' ' + + mkdir -p a/b/d a/c && + ( + echo "f test=f" + echo "a/i test=a/i" + ) >.gitattributes && + ( + echo "g test=a/g" && + echo "b/g test=a/b/g" + ) >a/.gitattributes && + ( + echo "h test=a/b/h" && + echo "d/* test=a/b/d/*" + ) >a/b/.gitattributes + +' + +test_expect_success 'attribute test' ' + + attr_check f f && + attr_check a/f f && + attr_check a/c/f f && + attr_check a/g a/g && + attr_check a/b/g a/b/g && + attr_check b/g unspecified && + attr_check a/b/h a/b/h && + attr_check a/b/d/g "a/b/d/*" + +' + +test_expect_success 'root subdir attribute test' ' + + attr_check a/i a/i && + attr_check subdir/a/i unspecified + +' + +test_expect_success 'setup bare' ' + + git clone --bare . bare.git && + cd bare.git + +' + +test_expect_success 'bare repository: check that .gitattribute is ignored' ' + + ( + echo "f test=f" + echo "a/i test=a/i" + ) >.gitattributes && + attr_check f unspecified && + attr_check a/f unspecified && + attr_check a/c/f unspecified && + attr_check a/i unspecified && + attr_check subdir/a/i unspecified + +' + +test_expect_success 'bare repository: test info/attributes' ' + + ( + echo "f test=f" + echo "a/i test=a/i" + ) >info/attributes && + attr_check f f && + attr_check a/f f && + attr_check a/c/f f && + attr_check a/i a/i && + attr_check subdir/a/i unspecified + +' + +test_done diff --git a/t/t0004-unwritable.sh b/t/t0004-unwritable.sh new file mode 100755 index 0000000000..63e1217e71 --- /dev/null +++ b/t/t0004-unwritable.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +test_description='detect unwritable repository and fail correctly' + +. ./test-lib.sh + +test_expect_success setup ' + + >file && + git add file && + test_tick && + git commit -m initial && + echo >file && + git add file + +' + +test_expect_success 'write-tree should notice unwritable repository' ' + + ( + chmod a-w .git/objects .git/objects/?? && + test_must_fail git write-tree + ) + status=$? + chmod 775 .git/objects .git/objects/?? + (exit $status) + +' + +test_expect_success 'commit should notice unwritable repository' ' + + ( + chmod a-w .git/objects .git/objects/?? && + test_must_fail git commit -m second + ) + status=$? + chmod 775 .git/objects .git/objects/?? + (exit $status) + +' + +test_expect_success 'update-index should notice unwritable repository' ' + + ( + echo 6O >file && + chmod a-w .git/objects .git/objects/?? && + test_must_fail git update-index file + ) + status=$? + chmod 775 .git/objects .git/objects/?? + (exit $status) + +' + +test_expect_success 'add should notice unwritable repository' ' + + ( + echo b >file && + chmod a-w .git/objects .git/objects/?? && + test_must_fail git add file + ) + status=$? + chmod 775 .git/objects .git/objects/?? + (exit $status) + +' + +test_done diff --git a/t/t0010-racy-git.sh b/t/t0010-racy-git.sh new file mode 100755 index 0000000000..e45a9e40e4 --- /dev/null +++ b/t/t0010-racy-git.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +test_description='racy GIT' + +. ./test-lib.sh + +# This test can give false success if your machine is sufficiently +# slow or your trial happened to happen on second boundary. + +for trial in 0 1 2 3 4 +do + rm -f .git/index + echo frotz >infocom + git update-index --add infocom + echo xyzzy >infocom + + files=`git diff-files -p` + test_expect_success \ + "Racy GIT trial #$trial part A" \ + 'test "" != "$files"' + + sleep 1 + echo xyzzy >cornerstone + git update-index --add cornerstone + + files=`git diff-files -p` + test_expect_success \ + "Racy GIT trial #$trial part B" \ + 'test "" != "$files"' + +done + +test_done diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh new file mode 100755 index 0000000000..1be7446d8d --- /dev/null +++ b/t/t0020-crlf.sh @@ -0,0 +1,439 @@ +#!/bin/sh + +test_description='CRLF conversion' + +. ./test-lib.sh + +q_to_nul () { + perl -pe 'y/Q/\000/' +} + +q_to_cr () { + tr Q '\015' +} + +append_cr () { + sed -e 's/$/Q/' | tr Q '\015' +} + +remove_cr () { + tr '\015' Q <"$1" | grep Q >/dev/null && + tr '\015' Q <"$1" | sed -ne 's/Q$//p' +} + +test_expect_success setup ' + + git config core.autocrlf false && + + for w in Hello world how are you; do echo $w; done >one && + mkdir dir && + for w in I am very very fine thank you; do echo $w; done >dir/two && + for w in Oh here is NULQin text here; do echo $w; done | q_to_nul >three && + git add . && + + git commit -m initial && + + one=`git rev-parse HEAD:one` && + dir=`git rev-parse HEAD:dir` && + two=`git rev-parse HEAD:dir/two` && + three=`git rev-parse HEAD:three` && + + for w in Some extra lines here; do echo $w; done >>one && + git diff >patch.file && + patched=`git hash-object --stdin <one` && + git read-tree --reset -u HEAD && + + echo happy. +' + +test_expect_success 'safecrlf: autocrlf=input, all CRLF' ' + + git config core.autocrlf input && + git config core.safecrlf true && + + for w in I am all CRLF; do echo $w; done | append_cr >allcrlf && + test_must_fail git add allcrlf +' + +test_expect_success 'safecrlf: autocrlf=input, mixed LF/CRLF' ' + + git config core.autocrlf input && + git config core.safecrlf true && + + for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed && + test_must_fail git add mixed +' + +test_expect_success 'safecrlf: autocrlf=true, all LF' ' + + git config core.autocrlf true && + git config core.safecrlf true && + + for w in I am all LF; do echo $w; done >alllf && + test_must_fail git add alllf +' + +test_expect_success 'safecrlf: autocrlf=true mixed LF/CRLF' ' + + git config core.autocrlf true && + git config core.safecrlf true && + + for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed && + test_must_fail git add mixed +' + +test_expect_success 'safecrlf: print warning only once' ' + + git config core.autocrlf input && + git config core.safecrlf warn && + + for w in I am all LF; do echo $w; done >doublewarn && + git add doublewarn && + git commit -m "nowarn" && + for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >doublewarn && + test $(git add doublewarn 2>&1 | grep "CRLF will be replaced by LF" | wc -l) = 1 +' + +test_expect_success 'switch off autocrlf, safecrlf, reset HEAD' ' + git config core.autocrlf false && + git config core.safecrlf false && + git reset --hard HEAD^ +' + +test_expect_success 'update with autocrlf=input' ' + + rm -f tmp one dir/two three && + git read-tree --reset -u HEAD && + git config core.autocrlf input && + + for f in one dir/two + do + append_cr <$f >tmp && mv -f tmp $f && + git update-index -- $f || { + echo Oops + false + break + } + done && + + differs=`git diff-index --cached HEAD` && + test -z "$differs" || { + echo Oops "$differs" + false + } + +' + +test_expect_success 'update with autocrlf=true' ' + + rm -f tmp one dir/two three && + git read-tree --reset -u HEAD && + git config core.autocrlf true && + + for f in one dir/two + do + append_cr <$f >tmp && mv -f tmp $f && + git update-index -- $f || { + echo "Oops $f" + false + break + } + done && + + differs=`git diff-index --cached HEAD` && + test -z "$differs" || { + echo Oops "$differs" + false + } + +' + +test_expect_success 'checkout with autocrlf=true' ' + + rm -f tmp one dir/two three && + git config core.autocrlf true && + git read-tree --reset -u HEAD && + + for f in one dir/two + do + remove_cr "$f" >tmp && mv -f tmp $f && + git update-index -- $f || { + echo "Eh? $f" + false + break + } + done && + test "$one" = `git hash-object --stdin <one` && + test "$two" = `git hash-object --stdin <dir/two` && + differs=`git diff-index --cached HEAD` && + test -z "$differs" || { + echo Oops "$differs" + false + } +' + +test_expect_success 'checkout with autocrlf=input' ' + + rm -f tmp one dir/two three && + git config core.autocrlf input && + git read-tree --reset -u HEAD && + + for f in one dir/two + do + if remove_cr "$f" >/dev/null + then + echo "Eh? $f" + false + break + else + git update-index -- $f + fi + done && + test "$one" = `git hash-object --stdin <one` && + test "$two" = `git hash-object --stdin <dir/two` && + differs=`git diff-index --cached HEAD` && + test -z "$differs" || { + echo Oops "$differs" + false + } +' + +test_expect_success 'apply patch (autocrlf=input)' ' + + rm -f tmp one dir/two three && + git config core.autocrlf input && + git read-tree --reset -u HEAD && + + git apply patch.file && + test "$patched" = "`git hash-object --stdin <one`" || { + echo "Eh? apply without index" + false + } +' + +test_expect_success 'apply patch --cached (autocrlf=input)' ' + + rm -f tmp one dir/two three && + git config core.autocrlf input && + git read-tree --reset -u HEAD && + + git apply --cached patch.file && + test "$patched" = `git rev-parse :one` || { + echo "Eh? apply with --cached" + false + } +' + +test_expect_success 'apply patch --index (autocrlf=input)' ' + + rm -f tmp one dir/two three && + git config core.autocrlf input && + git read-tree --reset -u HEAD && + + git apply --index patch.file && + test "$patched" = `git rev-parse :one` && + test "$patched" = `git hash-object --stdin <one` || { + echo "Eh? apply with --index" + false + } +' + +test_expect_success 'apply patch (autocrlf=true)' ' + + rm -f tmp one dir/two three && + git config core.autocrlf true && + git read-tree --reset -u HEAD && + + git apply patch.file && + test "$patched" = "`remove_cr one | git hash-object --stdin`" || { + echo "Eh? apply without index" + false + } +' + +test_expect_success 'apply patch --cached (autocrlf=true)' ' + + rm -f tmp one dir/two three && + git config core.autocrlf true && + git read-tree --reset -u HEAD && + + git apply --cached patch.file && + test "$patched" = `git rev-parse :one` || { + echo "Eh? apply without index" + false + } +' + +test_expect_success 'apply patch --index (autocrlf=true)' ' + + rm -f tmp one dir/two three && + git config core.autocrlf true && + git read-tree --reset -u HEAD && + + git apply --index patch.file && + test "$patched" = `git rev-parse :one` && + test "$patched" = "`remove_cr one | git hash-object --stdin`" || { + echo "Eh? apply with --index" + false + } +' + +test_expect_success '.gitattributes says two is binary' ' + + rm -f tmp one dir/two three && + echo "two -crlf" >.gitattributes && + git config core.autocrlf true && + git read-tree --reset -u HEAD && + + if remove_cr dir/two >/dev/null + then + echo "Huh?" + false + else + : happy + fi && + + if remove_cr one >/dev/null + then + : happy + else + echo "Huh?" + false + fi && + + if remove_cr three >/dev/null + then + echo "Huh?" + false + else + : happy + fi +' + +test_expect_success '.gitattributes says two is input' ' + + rm -f tmp one dir/two three && + echo "two crlf=input" >.gitattributes && + git read-tree --reset -u HEAD && + + if remove_cr dir/two >/dev/null + then + echo "Huh?" + false + else + : happy + fi +' + +test_expect_success '.gitattributes says two and three are text' ' + + rm -f tmp one dir/two three && + echo "t* crlf" >.gitattributes && + git read-tree --reset -u HEAD && + + if remove_cr dir/two >/dev/null + then + : happy + else + echo "Huh?" + false + fi && + + if remove_cr three >/dev/null + then + : happy + else + echo "Huh?" + false + fi +' + +test_expect_success 'in-tree .gitattributes (1)' ' + + echo "one -crlf" >>.gitattributes && + git add .gitattributes && + git commit -m "Add .gitattributes" && + + rm -rf tmp one dir .gitattributes patch.file three && + git read-tree --reset -u HEAD && + + if remove_cr one >/dev/null + then + echo "Eh? one should not have CRLF" + false + else + : happy + fi && + remove_cr three >/dev/null || { + echo "Eh? three should still have CRLF" + false + } +' + +test_expect_success 'in-tree .gitattributes (2)' ' + + rm -rf tmp one dir .gitattributes patch.file three && + git read-tree --reset HEAD && + git checkout-index -f -q -u -a && + + if remove_cr one >/dev/null + then + echo "Eh? one should not have CRLF" + false + else + : happy + fi && + remove_cr three >/dev/null || { + echo "Eh? three should still have CRLF" + false + } +' + +test_expect_success 'in-tree .gitattributes (3)' ' + + rm -rf tmp one dir .gitattributes patch.file three && + git read-tree --reset HEAD && + git checkout-index -u .gitattributes && + git checkout-index -u one dir/two three && + + if remove_cr one >/dev/null + then + echo "Eh? one should not have CRLF" + false + else + : happy + fi && + remove_cr three >/dev/null || { + echo "Eh? three should still have CRLF" + false + } +' + +test_expect_success 'in-tree .gitattributes (4)' ' + + rm -rf tmp one dir .gitattributes patch.file three && + git read-tree --reset HEAD && + git checkout-index -u one dir/two three && + git checkout-index -u .gitattributes && + + if remove_cr one >/dev/null + then + echo "Eh? one should not have CRLF" + false + else + : happy + fi && + remove_cr three >/dev/null || { + echo "Eh? three should still have CRLF" + false + } +' + +test_expect_success 'invalid .gitattributes (must not crash)' ' + + echo "three +crlf" >>.gitattributes && + git diff + +' + +test_done diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh new file mode 100755 index 0000000000..8fc39d77ce --- /dev/null +++ b/t/t0021-conversion.sh @@ -0,0 +1,91 @@ +#!/bin/sh + +test_description='blob conversion via gitattributes' + +. ./test-lib.sh + +cat <<\EOF >rot13.sh +tr \ + 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' \ + 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM' +EOF +chmod +x rot13.sh + +test_expect_success setup ' + git config filter.rot13.smudge ./rot13.sh && + git config filter.rot13.clean ./rot13.sh && + + { + echo "*.t filter=rot13" + echo "*.i ident" + } >.gitattributes && + + { + echo a b c d e f g h i j k l m + echo n o p q r s t u v w x y z + echo '\''$Id$'\'' + } >test && + cat test >test.t && + cat test >test.o && + cat test >test.i && + git add test test.t test.i && + rm -f test test.t test.i && + git checkout -- test test.t test.i +' + +script='s/^\$Id: \([0-9a-f]*\) \$/\1/p' + +test_expect_success check ' + + cmp test.o test && + cmp test.o test.t && + + # ident should be stripped in the repository + git diff --raw --exit-code :test :test.i && + id=$(git rev-parse --verify :test) && + embedded=$(sed -ne "$script" test.i) && + test "z$id" = "z$embedded" && + + git cat-file blob :test.t > test.r && + + ./rot13.sh < test.o > test.t && + cmp test.r test.t +' + +# If an expanded ident ever gets into the repository, we want to make sure that +# it is collapsed before being expanded again on checkout +test_expect_success expanded_in_repo ' + { + echo "File with expanded keywords" + echo "\$Id\$" + echo "\$Id:\$" + echo "\$Id: 0000000000000000000000000000000000000000 \$" + echo "\$Id: NoSpaceAtEnd\$" + echo "\$Id:NoSpaceAtFront \$" + echo "\$Id:NoSpaceAtEitherEnd\$" + echo "\$Id: NoTerminatingSymbol" + } > expanded-keywords && + + { + echo "File with expanded keywords" + echo "\$Id: 4f21723e7b15065df7de95bd46c8ba6fb1818f4c \$" + echo "\$Id: 4f21723e7b15065df7de95bd46c8ba6fb1818f4c \$" + echo "\$Id: 4f21723e7b15065df7de95bd46c8ba6fb1818f4c \$" + echo "\$Id: 4f21723e7b15065df7de95bd46c8ba6fb1818f4c \$" + echo "\$Id: 4f21723e7b15065df7de95bd46c8ba6fb1818f4c \$" + echo "\$Id: 4f21723e7b15065df7de95bd46c8ba6fb1818f4c \$" + echo "\$Id: NoTerminatingSymbol" + } > expected-output && + + git add expanded-keywords && + git commit -m "File with keywords expanded" && + + echo "expanded-keywords ident" >> .gitattributes && + + rm -f expanded-keywords && + git checkout -- expanded-keywords && + cat expanded-keywords && + cmp expanded-keywords expected-output +' + +test_done diff --git a/t/t0022-crlf-rename.sh b/t/t0022-crlf-rename.sh new file mode 100755 index 0000000000..7d1ce2d056 --- /dev/null +++ b/t/t0022-crlf-rename.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +test_description='ignore CR in CRLF sequence while computing similiarity' + +. ./test-lib.sh + +test_expect_success setup ' + + cat ../t0022-crlf-rename.sh >sample && + git add sample && + + test_tick && + git commit -m Initial && + + sed -e "s/\$/
/" ../t0022-crlf-rename.sh >elpmas && + git add elpmas && + rm -f sample && + + test_tick && + git commit -a -m Second + +' + +test_expect_success 'diff -M' ' + + git diff-tree -M -r --name-status HEAD^ HEAD | + sed -e "s/R[0-9]*/RNUM/" >actual && + echo "RNUM sample elpmas" >expect && + test_cmp expect actual + +' + +test_done diff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh new file mode 100755 index 0000000000..aaed725402 --- /dev/null +++ b/t/t0023-crlf-am.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +test_description='Test am with auto.crlf' + +. ./test-lib.sh + +cat >patchfile <<\EOF +From 38be10072e45dd6b08ce40851e3fca60a31a340b Mon Sep 17 00:00:00 2001 +From: Marius Storm-Olsen <x@y.com> +Date: Thu, 23 Aug 2007 13:00:00 +0200 +Subject: test1 + +--- + foo | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + create mode 100644 foo + +diff --git a/foo b/foo +new file mode 100644 +index 0000000000000000000000000000000000000000..5716ca5987cbf97d6bb54920bea6adde242d87e6 +--- /dev/null ++++ b/foo +@@ -0,0 +1 @@ ++bar +EOF + +test_expect_success 'setup' ' + + git config core.autocrlf true && + echo foo >bar && + git add bar && + test_tick && + git commit -m initial + +' + +test_expect_success 'am' ' + + git am -3 <patchfile && + git diff-files --name-status --exit-code + +' + +test_done diff --git a/t/t0030-stripspace.sh b/t/t0030-stripspace.sh new file mode 100755 index 0000000000..ccb0a3cb61 --- /dev/null +++ b/t/t0030-stripspace.sh @@ -0,0 +1,400 @@ +#!/bin/sh +# +# Copyright (c) 2007 Carlos Rica +# + +test_description='git stripspace' + +. ./test-lib.sh + +t40='A quick brown fox jumps over the lazy do' +s40=' ' +sss="$s40$s40$s40$s40$s40$s40$s40$s40$s40$s40" # 400 +ttt="$t40$t40$t40$t40$t40$t40$t40$t40$t40$t40" # 400 + +test_expect_success \ + 'long lines without spaces should be unchanged' ' + echo "$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual && + + echo "$ttt$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual && + + echo "$ttt$ttt$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual && + + echo "$ttt$ttt$ttt$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual +' + +test_expect_success \ + 'lines with spaces at the beginning should be unchanged' ' + echo "$sss$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual && + + echo "$sss$sss$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual && + + echo "$sss$sss$sss$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual +' + +test_expect_success \ + 'lines with intermediate spaces should be unchanged' ' + echo "$ttt$sss$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual && + + echo "$ttt$sss$sss$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual +' + +test_expect_success \ + 'consecutive blank lines should be unified' ' + printf "$ttt\n\n$ttt\n" > expect && + printf "$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt\n\n$ttt\n" > expect && + printf "$ttt$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt$ttt\n\n$ttt\n" > expect && + printf "$ttt$ttt$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n\n$ttt\n" > expect && + printf "$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n\n$ttt$ttt\n" > expect && + printf "$ttt\n\n\n\n\n$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n\n$ttt$ttt$ttt\n" > expect && + printf "$ttt\n\n\n\n\n$ttt$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n\n$ttt\n" > expect && + printf "$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt\n\n$ttt\n" > expect && + printf "$ttt$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt$ttt\n\n$ttt\n" > expect && + printf "$ttt$ttt$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n\n$ttt\n" > expect && + printf "$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n\n$ttt$ttt\n" > expect && + printf "$ttt\n\t\n \n\n \t\t\n$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n\n$ttt$ttt$ttt\n" > expect && + printf "$ttt\n\t\n \n\n \t\t\n$ttt$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual +' + +test_expect_success \ + 'only consecutive blank lines should be completely removed' ' + > expect && + + printf "\n" | git stripspace >actual && + test_cmp expect actual && + + printf "\n\n\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$sss\n$sss\n$sss\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$sss$sss\n$sss\n\n" | git stripspace >actual && + test_cmp expect actual && + + printf "\n$sss\n$sss$sss\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$sss$sss$sss$sss\n\n\n" | git stripspace >actual && + test_cmp expect actual && + + printf "\n$sss$sss$sss$sss\n\n" | git stripspace >actual && + test_cmp expect actual && + + printf "\n\n$sss$sss$sss$sss\n" | git stripspace >actual && + test_cmp expect actual +' + +test_expect_success \ + 'consecutive blank lines at the beginning should be removed' ' + printf "$ttt\n" > expect && + printf "\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n" > expect && + printf "\n\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt\n" > expect && + printf "\n\n\n$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt$ttt\n" > expect && + printf "\n\n\n$ttt$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt$ttt$ttt\n" > expect && + printf "\n\n\n$ttt$ttt$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n" > expect && + + printf "$sss\n$sss\n$sss\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "\n$sss\n$sss$sss\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$sss$sss\n$sss\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$sss$sss$sss\n\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "\n$sss$sss$sss\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "\n\n$sss$sss$sss\n$ttt\n" | git stripspace >actual && + test_cmp expect actual +' + +test_expect_success \ + 'consecutive blank lines at the end should be removed' ' + printf "$ttt\n" > expect && + printf "$ttt\n\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n" > expect && + printf "$ttt\n\n\n\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt\n" > expect && + printf "$ttt$ttt\n\n\n\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt$ttt\n" > expect && + printf "$ttt$ttt$ttt\n\n\n\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt$ttt$ttt\n" > expect && + printf "$ttt$ttt$ttt$ttt\n\n\n\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n" > expect && + + printf "$ttt\n$sss\n$sss\n$sss\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n\n$sss\n$sss$sss\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n$sss$sss\n$sss\n\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n$sss$sss$sss\n\n\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n\n$sss$sss$sss\n\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n\n\n$sss$sss$sss\n" | git stripspace >actual && + test_cmp expect actual +' + +test_expect_success \ + 'text without newline at end should end with newline' ' + test `printf "$ttt" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$ttt" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$ttt$ttt" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$ttt$ttt$ttt" | git stripspace | wc -l` -gt 0 +' + +# text plus spaces at the end: + +test_expect_success \ + 'text plus spaces without newline at end should end with newline' ' + test `printf "$ttt$sss" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$ttt$sss" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$ttt$ttt$sss" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$sss$sss" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$ttt$sss$sss" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$sss$sss$sss" | git stripspace | wc -l` -gt 0 +' + +test_expect_success \ + 'text plus spaces without newline at end should not show spaces' ' + ! (printf "$ttt$sss" | git stripspace | grep " " >/dev/null) && + ! (printf "$ttt$ttt$sss" | git stripspace | grep " " >/dev/null) && + ! (printf "$ttt$ttt$ttt$sss" | git stripspace | grep " " >/dev/null) && + ! (printf "$ttt$sss$sss" | git stripspace | grep " " >/dev/null) && + ! (printf "$ttt$ttt$sss$sss" | git stripspace | grep " " >/dev/null) && + ! (printf "$ttt$sss$sss$sss" | git stripspace | grep " " >/dev/null) +' + +test_expect_success \ + 'text plus spaces without newline should show the correct lines' ' + printf "$ttt\n" >expect && + printf "$ttt$sss" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n" >expect && + printf "$ttt$sss$sss" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n" >expect && + printf "$ttt$sss$sss$sss" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt\n" >expect && + printf "$ttt$ttt$sss" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt\n" >expect && + printf "$ttt$ttt$sss$sss" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt$ttt\n" >expect && + printf "$ttt$ttt$ttt$sss" | git stripspace >actual && + test_cmp expect actual +' + +test_expect_success \ + 'text plus spaces at end should not show spaces' ' + ! (echo "$ttt$sss" | git stripspace | grep " " >/dev/null) && + ! (echo "$ttt$ttt$sss" | git stripspace | grep " " >/dev/null) && + ! (echo "$ttt$ttt$ttt$sss" | git stripspace | grep " " >/dev/null) && + ! (echo "$ttt$sss$sss" | git stripspace | grep " " >/dev/null) && + ! (echo "$ttt$ttt$sss$sss" | git stripspace | grep " " >/dev/null) && + ! (echo "$ttt$sss$sss$sss" | git stripspace | grep " " >/dev/null) +' + +test_expect_success \ + 'text plus spaces at end should be cleaned and newline must remain' ' + echo "$ttt" >expect && + echo "$ttt$sss" | git stripspace >actual && + test_cmp expect actual && + + echo "$ttt" >expect && + echo "$ttt$sss$sss" | git stripspace >actual && + test_cmp expect actual && + + echo "$ttt" >expect && + echo "$ttt$sss$sss$sss" | git stripspace >actual && + test_cmp expect actual && + + echo "$ttt$ttt" >expect && + echo "$ttt$ttt$sss" | git stripspace >actual && + test_cmp expect actual && + + echo "$ttt$ttt" >expect && + echo "$ttt$ttt$sss$sss" | git stripspace >actual && + test_cmp expect actual && + + echo "$ttt$ttt$ttt" >expect && + echo "$ttt$ttt$ttt$sss" | git stripspace >actual && + test_cmp expect actual +' + +# spaces only: + +test_expect_success \ + 'spaces with newline at end should be replaced with empty string' ' + printf "" >expect && + + echo | git stripspace >actual && + test_cmp expect actual && + + echo "$sss" | git stripspace >actual && + test_cmp expect actual && + + echo "$sss$sss" | git stripspace >actual && + test_cmp expect actual && + + echo "$sss$sss$sss" | git stripspace >actual && + test_cmp expect actual && + + echo "$sss$sss$sss$sss" | git stripspace >actual && + test_cmp expect actual +' + +test_expect_success \ + 'spaces without newline at end should not show spaces' ' + ! (printf "" | git stripspace | grep " " >/dev/null) && + ! (printf "$sss" | git stripspace | grep " " >/dev/null) && + ! (printf "$sss$sss" | git stripspace | grep " " >/dev/null) && + ! (printf "$sss$sss$sss" | git stripspace | grep " " >/dev/null) && + ! (printf "$sss$sss$sss$sss" | git stripspace | grep " " >/dev/null) +' + +test_expect_success \ + 'spaces without newline at end should be replaced with empty string' ' + printf "" >expect && + + printf "" | git stripspace >actual && + test_cmp expect actual && + + printf "$sss$sss" | git stripspace >actual && + test_cmp expect actual && + + printf "$sss$sss$sss" | git stripspace >actual && + test_cmp expect actual && + + printf "$sss$sss$sss$sss" | git stripspace >actual && + test_cmp expect actual +' + +test_expect_success \ + 'consecutive text lines should be unchanged' ' + printf "$ttt$ttt\n$ttt\n" >expect && + printf "$ttt$ttt\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n$ttt$ttt\n$ttt\n" >expect && + printf "$ttt\n$ttt$ttt\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n$ttt\n$ttt\n$ttt$ttt\n" >expect && + printf "$ttt\n$ttt\n$ttt\n$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n$ttt\n\n$ttt$ttt\n$ttt\n" >expect && + printf "$ttt\n$ttt\n\n$ttt$ttt\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt$ttt\n\n$ttt\n$ttt$ttt\n" >expect && + printf "$ttt$ttt\n\n$ttt\n$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && + + printf "$ttt\n$ttt$ttt\n\n$ttt\n" >expect && + printf "$ttt\n$ttt$ttt\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual +' + +test_expect_success 'strip comments, too' ' + test ! -z "$(echo "# comment" | git stripspace)" && + test -z "$(echo "# comment" | git stripspace -s)" +' + +test_done diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh new file mode 100755 index 0000000000..e38241c80a --- /dev/null +++ b/t/t0040-parse-options.sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes Schindelin +# + +test_description='our own option parser' + +. ./test-lib.sh + +cat > expect.err << EOF +usage: test-parse-options <options> + + -b, --boolean get a boolean + -4, --or4 bitwise-or boolean with ...0100 + + -i, --integer <n> get a integer + -j <n> get a integer, too + --set23 set integer to 23 + -t <time> get timestamp of <time> + -L, --length <str> get length of <str> + +String options + -s, --string <string> + get a string + --string2 <str> get another string + --st <st> get another string (pervert ordering) + -o <str> get another string + --default-string set string to default + +Magic arguments + --quux means --quux + +Standard options + --abbrev[=<n>] use <n> digits to display SHA-1s + -v, --verbose be verbose + -n, --dry-run dry run + -q, --quiet be quiet + +EOF + +test_expect_success 'test help' ' + test_must_fail test-parse-options -h > output 2> output.err && + test ! -s output && + test_cmp expect.err output.err +' + +cat > expect << EOF +boolean: 2 +integer: 1729 +timestamp: 0 +string: 123 +abbrev: 7 +verbose: 2 +quiet: no +dry run: yes +EOF + +test_expect_success 'short options' ' + test-parse-options -s123 -b -i 1729 -b -vv -n > output 2> output.err && + test_cmp expect output && + test ! -s output.err +' + +cat > expect << EOF +boolean: 2 +integer: 1729 +timestamp: 0 +string: 321 +abbrev: 10 +verbose: 2 +quiet: no +dry run: no +EOF + +test_expect_success 'long options' ' + test-parse-options --boolean --integer 1729 --boolean --string2=321 \ + --verbose --verbose --no-dry-run --abbrev=10 \ + > output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +test_expect_success 'missing required value' ' + test-parse-options -s; + test $? = 129 && + test-parse-options --string; + test $? = 129 +' + +cat > expect << EOF +boolean: 1 +integer: 13 +timestamp: 0 +string: 123 +abbrev: 7 +verbose: 0 +quiet: no +dry run: no +arg 00: a1 +arg 01: b1 +arg 02: --boolean +EOF + +test_expect_success 'intermingled arguments' ' + test-parse-options a1 --string 123 b1 --boolean -j 13 -- --boolean \ + > output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +cat > expect << EOF +boolean: 0 +integer: 2 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: 0 +quiet: no +dry run: no +EOF + +test_expect_success 'unambiguously abbreviated option' ' + test-parse-options --int 2 --boolean --no-bo > output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +test_expect_success 'unambiguously abbreviated option with "="' ' + test-parse-options --int=2 > output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +test_expect_success 'ambiguously abbreviated option' ' + test-parse-options --strin 123; + test $? = 129 +' + +cat > expect << EOF +boolean: 0 +integer: 0 +timestamp: 0 +string: 123 +abbrev: 7 +verbose: 0 +quiet: no +dry run: no +EOF + +test_expect_success 'non ambiguous option (after two options it abbreviates)' ' + test-parse-options --st 123 > output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +cat > typo.err << EOF +error: did you mean \`--boolean\` (with two dashes ?) +EOF + +test_expect_success 'detect possible typos' ' + test_must_fail test-parse-options -boolean > output 2> output.err && + test ! -s output && + test_cmp typo.err output.err +' + +cat > expect <<EOF +boolean: 0 +integer: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: 0 +quiet: no +dry run: no +arg 00: --quux +EOF + +test_expect_success 'keep some options as arguments' ' + test-parse-options --quux > output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +cat > expect <<EOF +boolean: 0 +integer: 0 +timestamp: 1 +string: default +abbrev: 7 +verbose: 0 +quiet: yes +dry run: no +arg 00: foo +EOF + +test_expect_success 'OPT_DATE() and OPT_SET_PTR() work' ' + test-parse-options -t "1970-01-01 00:00:01 +0000" --default-string \ + foo -q > output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +cat > expect <<EOF +Callback: "four", 0 +boolean: 5 +integer: 4 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: 0 +quiet: no +dry run: no +EOF + +test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' ' + test-parse-options --length=four -b -4 > output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +cat > expect <<EOF +Callback: "not set", 1 +EOF + +test_expect_success 'OPT_CALLBACK() and callback errors work' ' + test_must_fail test-parse-options --no-length > output 2> output.err && + test_cmp expect output && + test_cmp expect.err output.err +' + +cat > expect <<EOF +boolean: 1 +integer: 23 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: 0 +quiet: no +dry run: no +EOF + +test_expect_success 'OPT_BIT() and OPT_SET_INT() work' ' + test-parse-options --set23 -bbbbb --no-or4 > output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +# --or4 +# --no-or4 + +test_done diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh new file mode 100755 index 0000000000..b177174ef5 --- /dev/null +++ b/t/t0050-filesystem.sh @@ -0,0 +1,122 @@ +#!/bin/sh + +test_description='Various filesystem issues' + +. ./test-lib.sh + +auml=`printf '\xc3\xa4'` +aumlcdiar=`printf '\x61\xcc\x88'` + +case_insensitive= +test_expect_success 'see if we expect ' ' + + test_case=test_expect_success + test_unicode=test_expect_success + mkdir junk && + echo good >junk/CamelCase && + echo bad >junk/camelcase && + if test "$(cat junk/CamelCase)" != good + then + test_case=test_expect_failure + case_insensitive=t + say "will test on a case insensitive filesystem" + fi && + rm -fr junk && + mkdir junk && + >junk/"$auml" && + case "$(cd junk && echo *)" in + "$aumlcdiar") + test_unicode=test_expect_failure + say "will test on a unicode corrupting filesystem" + ;; + *) ;; + esac && + rm -fr junk +' + +if test "$case_insensitive" +then +test_expect_success "detection of case insensitive filesystem during repo init" ' + + test $(git config --bool core.ignorecase) = true +' +else +test_expect_success "detection of case insensitive filesystem during repo init" ' + + test_must_fail git config --bool core.ignorecase >/dev/null || + test $(git config --bool core.ignorecase) = false +' +fi + +test_expect_success "setup case tests" ' + + git config core.ignorecase true && + touch camelcase && + git add camelcase && + git commit -m "initial" && + git tag initial && + git checkout -b topic && + git mv camelcase tmp && + git mv tmp CamelCase && + git commit -m "rename" && + git checkout -f master + +' + +$test_case 'rename (case change)' ' + + git mv camelcase CamelCase && + git commit -m "rename" + +' + +$test_case 'merge (case change)' ' + + rm -f CamelCase && + rm -f camelcase && + git reset --hard initial && + git merge topic + +' + +$test_case 'add (with different case)' ' + + git reset --hard initial && + rm camelcase && + echo 1 >CamelCase && + git add CamelCase && + test $(git-ls-files | grep -i camelcase | wc -l) = 1 + +' + +test_expect_success "setup unicode normalization tests" ' + + test_create_repo unicode && + cd unicode && + touch "$aumlcdiar" && + git add "$aumlcdiar" && + git commit -m initial + git tag initial && + git checkout -b topic && + git mv $aumlcdiar tmp && + git mv tmp "$auml" && + git commit -m rename && + git checkout -f master + +' + +$test_unicode 'rename (silent unicode normalization)' ' + + git mv "$aumlcdiar" "$auml" && + git commit -m rename + +' + +$test_unicode 'merge (silent unicode normalization)' ' + + git reset --hard initial && + git merge topic + +' + +test_done diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh new file mode 100755 index 0000000000..6e7501f352 --- /dev/null +++ b/t/t0060-path-utils.sh @@ -0,0 +1,87 @@ +#!/bin/sh +# +# Copyright (c) 2008 David Reiss +# + +test_description='Test various path utilities' + +. ./test-lib.sh + +norm_abs() { + test_expect_success "normalize absolute" \ + "test \$(test-path-utils normalize_absolute_path '$1') = '$2'" +} + +ancestor() { + test_expect_success "longest ancestor" \ + "test \$(test-path-utils longest_ancestor_length '$1' '$2') = '$3'" +} + +norm_abs "" / +norm_abs / / +norm_abs // / +norm_abs /// / +norm_abs /. / +norm_abs /./ / +norm_abs /./.. / +norm_abs /../. / +norm_abs /./../.// / +norm_abs /dir/.. / +norm_abs /dir/sub/../.. / +norm_abs /dir /dir +norm_abs /dir// /dir +norm_abs /./dir /dir +norm_abs /dir/. /dir +norm_abs /dir///./ /dir +norm_abs /dir//sub/.. /dir +norm_abs /dir/sub/../ /dir +norm_abs //dir/sub/../. /dir +norm_abs /dir/s1/../s2/ /dir/s2 +norm_abs /d1/s1///s2/..//../s3/ /d1/s3 +norm_abs /d1/s1//../s2/../../d2 /d2 +norm_abs /d1/.../d2 /d1/.../d2 +norm_abs /d1/..././../d2 /d1/d2 + +ancestor / "" -1 +ancestor / / -1 +ancestor /foo "" -1 +ancestor /foo : -1 +ancestor /foo ::. -1 +ancestor /foo ::..:: -1 +ancestor /foo / 0 +ancestor /foo /fo -1 +ancestor /foo /foo -1 +ancestor /foo /foo/ -1 +ancestor /foo /bar -1 +ancestor /foo /bar/ -1 +ancestor /foo /foo/bar -1 +ancestor /foo /foo:/bar/ -1 +ancestor /foo /foo/:/bar/ -1 +ancestor /foo /foo::/bar/ -1 +ancestor /foo /:/foo:/bar/ 0 +ancestor /foo /foo:/:/bar/ 0 +ancestor /foo /:/bar/:/foo 0 +ancestor /foo/bar "" -1 +ancestor /foo/bar / 0 +ancestor /foo/bar /fo -1 +ancestor /foo/bar foo -1 +ancestor /foo/bar /foo 4 +ancestor /foo/bar /foo/ 4 +ancestor /foo/bar /foo/ba -1 +ancestor /foo/bar /:/fo 0 +ancestor /foo/bar /foo:/foo/ba 4 +ancestor /foo/bar /bar -1 +ancestor /foo/bar /bar/ -1 +ancestor /foo/bar /fo: -1 +ancestor /foo/bar :/fo -1 +ancestor /foo/bar /foo:/bar/ 4 +ancestor /foo/bar /:/foo:/bar/ 4 +ancestor /foo/bar /foo:/:/bar/ 4 +ancestor /foo/bar /:/bar/:/fo 0 +ancestor /foo/bar /:/bar/ 0 +ancestor /foo/bar :://foo/. 4 +ancestor /foo/bar :://foo/.:: 4 +ancestor /foo/bar //foo/./::/bar 4 +ancestor /foo/bar ::/bar -1 + +test_done diff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh new file mode 100755 index 0000000000..807fb83af8 --- /dev/null +++ b/t/t1000-read-tree-m-3way.sh @@ -0,0 +1,531 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Three way merge with read-tree -m + +This test tries three-way merge with read-tree -m + +There is one ancestor (called O for Original) and two branches A +and B derived from it. We want to do a 3-way merge between A and +B, using O as the common ancestor. + + merge A O B + +Decisions are made by comparing contents of O, A and B pathname +by pathname. The result is determined by the following guiding +principle: + + - If only A does something to it and B does not touch it, take + whatever A does. + + - If only B does something to it and A does not touch it, take + whatever B does. + + - If both A and B does something but in the same way, take + whatever they do. + + - If A and B does something but different things, we need a + 3-way merge: + + - We cannot do anything about the following cases: + + * O does not have it. A and B both must be adding to the + same path independently. + + * A deletes it. B must be modifying. + + - Otherwise, A and B are modifying. Run 3-way merge. + +First, the case matrix. + + - Vertical axis is for A'\''s actions. + - Horizontal axis is for B'\''s actions. + +.----------------------------------------------------------------. +| A B | No Action | Delete | Modify | Add | +|------------+------------+------------+------------+------------| +| No Action | | | | | +| | select O | delete | select B | select B | +| | | | | | +|------------+------------+------------+------------+------------| +| Delete | | | ********** | can | +| | delete | delete | merge | not | +| | | | | happen | +|------------+------------+------------+------------+------------| +| Modify | | ********** | ?????????? | can | +| | select A | merge | select A=B | not | +| | | | merge | happen | +|------------+------------+------------+------------+------------| +| Add | | can | can | ?????????? | +| | select A | not | not | select A=B | +| | | happen | happen | merge | +.----------------------------------------------------------------. + +In addition: + + SS: a special case of MM, where A and B makes the same modification. + LL: a special case of AA, where A and B creates the same file. + TT: a special case of MM, where A and B makes mergeable changes. + DF: a special case, where A makes a directory and B makes a file. + +' +. ./test-lib.sh +. ../lib-read-tree-m-3way.sh + +################################################################ +# Trivial "majority when 3 stages exist" merge plus #2ALT, #3ALT +# and #5ALT trivial merges. + +cat >expected <<\EOF +100644 X 2 AA +100644 X 3 AA +100644 X 0 AN +100644 X 1 DD +100644 X 3 DF +100644 X 2 DF/DF +100644 X 1 DM +100644 X 3 DM +100644 X 1 DN +100644 X 3 DN +100644 X 0 LL +100644 X 1 MD +100644 X 2 MD +100644 X 1 MM +100644 X 2 MM +100644 X 3 MM +100644 X 0 MN +100644 X 0 NA +100644 X 1 ND +100644 X 2 ND +100644 X 0 NM +100644 X 0 NN +100644 X 0 SS +100644 X 1 TT +100644 X 2 TT +100644 X 3 TT +100644 X 2 Z/AA +100644 X 3 Z/AA +100644 X 0 Z/AN +100644 X 1 Z/DD +100644 X 1 Z/DM +100644 X 3 Z/DM +100644 X 1 Z/DN +100644 X 3 Z/DN +100644 X 1 Z/MD +100644 X 2 Z/MD +100644 X 1 Z/MM +100644 X 2 Z/MM +100644 X 3 Z/MM +100644 X 0 Z/MN +100644 X 0 Z/NA +100644 X 1 Z/ND +100644 X 2 Z/ND +100644 X 0 Z/NM +100644 X 0 Z/NN +EOF + +_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' +_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" + +check_result () { + git ls-files --stage | sed -e 's/ '"$_x40"' / X /' >current && + test_cmp expected current +} + +# This is done on an empty work directory, which is the normal +# merge person behaviour. +test_expect_success \ + '3-way merge with git read-tree -m, empty cache' \ + "rm -fr [NDMALTS][NDMALTSF] Z && + rm .git/index && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +# This starts out with the first head, which is the normal +# patch submitter behaviour. +test_expect_success \ + '3-way merge with git read-tree -m, match H' \ + "rm -fr [NDMALTS][NDMALTSF] Z && + rm .git/index && + git read-tree $tree_A && + git checkout-index -f -u -a && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +: <<\END_OF_CASE_TABLE + +We have so far tested only empty index and clean-and-matching-A index +case which are trivial. Make sure index requirements are also +checked. + +"git read-tree -m O A B" + + O A B result index requirements +------------------------------------------------------------------- + 1 missing missing missing - must not exist. + ------------------------------------------------------------------ + 2 missing missing exists take B* must match B, if exists. + ------------------------------------------------------------------ + 3 missing exists missing take A* must match A, if exists. + ------------------------------------------------------------------ + 4 missing exists A!=B no merge must match A and be + up-to-date, if exists. + ------------------------------------------------------------------ + 5 missing exists A==B take A must match A, if exists. + ------------------------------------------------------------------ + 6 exists missing missing remove must not exist. + ------------------------------------------------------------------ + 7 exists missing O!=B no merge must not exist. + ------------------------------------------------------------------ + 8 exists missing O==B remove must not exist. + ------------------------------------------------------------------ + 9 exists O!=A missing no merge must match A and be + up-to-date, if exists. + ------------------------------------------------------------------ + 10 exists O==A missing no merge must match A + ------------------------------------------------------------------ + 11 exists O!=A O!=B no merge must match A and be + A!=B up-to-date, if exists. + ------------------------------------------------------------------ + 12 exists O!=A O!=B take A must match A, if exists. + A==B + ------------------------------------------------------------------ + 13 exists O!=A O==B take A must match A, if exists. + ------------------------------------------------------------------ + 14 exists O==A O!=B take B if exists, must either (1) + match A and be up-to-date, + or (2) match B. + ------------------------------------------------------------------ + 15 exists O==A O==B take B must match A if exists. + ------------------------------------------------------------------ + 16 exists O==A O==B barf must match A if exists. + *multi* in one in another +------------------------------------------------------------------- + +Note: we need to be careful in case 2 and 3. The tree A may contain +DF (file) when tree B require DF to be a directory by having DF/DF +(file). + +END_OF_CASE_TABLE + +test_expect_success '1 - must not have an entry not in A.' " + rm -f .git/index XX && + echo XX >XX && + git update-index --add XX && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '2 - must match B in !O && !A && B case.' \ + "rm -f .git/index NA && + cp .orig-B/NA NA && + git update-index --add NA && + git read-tree -m $tree_O $tree_A $tree_B" + +test_expect_success \ + '2 - matching B alone is OK in !O && !A && B case.' \ + "rm -f .git/index NA && + cp .orig-B/NA NA && + git update-index --add NA && + echo extra >>NA && + git read-tree -m $tree_O $tree_A $tree_B" + +test_expect_success \ + '3 - must match A in !O && A && !B case.' \ + "rm -f .git/index AN && + cp .orig-A/AN AN && + git update-index --add AN && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '3 - matching A alone is OK in !O && A && !B case.' \ + "rm -f .git/index AN && + cp .orig-A/AN AN && + git update-index --add AN && + echo extra >>AN && + git read-tree -m $tree_O $tree_A $tree_B" + +test_expect_success \ + '3 (fail) - must match A in !O && A && !B case.' " + rm -f .git/index AN && + cp .orig-A/AN AN && + echo extra >>AN && + git update-index --add AN && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '4 - must match and be up-to-date in !O && A && B && A!=B case.' \ + "rm -f .git/index AA && + cp .orig-A/AA AA && + git update-index --add AA && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' " + rm -f .git/index AA && + cp .orig-A/AA AA && + git update-index --add AA && + echo extra >>AA && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' " + rm -f .git/index AA && + cp .orig-A/AA AA && + echo extra >>AA && + git update-index --add AA && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '5 - must match in !O && A && B && A==B case.' \ + "rm -f .git/index LL && + cp .orig-A/LL LL && + git update-index --add LL && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '5 - must match in !O && A && B && A==B case.' \ + "rm -f .git/index LL && + cp .orig-A/LL LL && + git update-index --add LL && + echo extra >>LL && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '5 (fail) - must match A in !O && A && B && A==B case.' " + rm -f .git/index LL && + cp .orig-A/LL LL && + echo extra >>LL && + git update-index --add LL && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '6 - must not exist in O && !A && !B case' " + rm -f .git/index DD && + echo DD >DD + git update-index --add DD && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '7 - must not exist in O && !A && B && O!=B case' " + rm -f .git/index DM && + cp .orig-B/DM DM && + git update-index --add DM && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '8 - must not exist in O && !A && B && O==B case' " + rm -f .git/index DN && + cp .orig-B/DN DN && + git update-index --add DN && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '9 - must match and be up-to-date in O && A && !B && O!=A case' \ + "rm -f .git/index MD && + cp .orig-A/MD MD && + git update-index --add MD && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' " + rm -f .git/index MD && + cp .orig-A/MD MD && + git update-index --add MD && + echo extra >>MD && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' " + rm -f .git/index MD && + cp .orig-A/MD MD && + echo extra >>MD && + git update-index --add MD && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '10 - must match and be up-to-date in O && A && !B && O==A case' \ + "rm -f .git/index ND && + cp .orig-A/ND ND && + git update-index --add ND && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' " + rm -f .git/index ND && + cp .orig-A/ND ND && + git update-index --add ND && + echo extra >>ND && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' " + rm -f .git/index ND && + cp .orig-A/ND ND && + echo extra >>ND && + git update-index --add ND && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '11 - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \ + "rm -f .git/index MM && + cp .orig-A/MM MM && + git update-index --add MM && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' " + rm -f .git/index MM && + cp .orig-A/MM MM && + git update-index --add MM && + echo extra >>MM && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' " + rm -f .git/index MM && + cp .orig-A/MM MM && + echo extra >>MM && + git update-index --add MM && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '12 - must match A in O && A && B && O!=A && A==B case' \ + "rm -f .git/index SS && + cp .orig-A/SS SS && + git update-index --add SS && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '12 - must match A in O && A && B && O!=A && A==B case' \ + "rm -f .git/index SS && + cp .orig-A/SS SS && + git update-index --add SS && + echo extra >>SS && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '12 (fail) - must match A in O && A && B && O!=A && A==B case' " + rm -f .git/index SS && + cp .orig-A/SS SS && + echo extra >>SS && + git update-index --add SS && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '13 - must match A in O && A && B && O!=A && O==B case' \ + "rm -f .git/index MN && + cp .orig-A/MN MN && + git update-index --add MN && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '13 - must match A in O && A && B && O!=A && O==B case' \ + "rm -f .git/index MN && + cp .orig-A/MN MN && + git update-index --add MN && + echo extra >>MN && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '14 - must match and be up-to-date in O && A && B && O==A && O!=B case' \ + "rm -f .git/index NM && + cp .orig-A/NM NM && + git update-index --add NM && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '14 - may match B in O && A && B && O==A && O!=B case' \ + "rm -f .git/index NM && + cp .orig-B/NM NM && + git update-index --add NM && + echo extra >>NM && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' " + rm -f .git/index NM && + cp .orig-A/NM NM && + git update-index --add NM && + echo extra >>NM && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' " + rm -f .git/index NM && + cp .orig-A/NM NM && + echo extra >>NM && + git update-index --add NM && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +test_expect_success \ + '15 - must match A in O && A && B && O==A && O==B case' \ + "rm -f .git/index NN && + cp .orig-A/NN NN && + git update-index --add NN && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '15 - must match A in O && A && B && O==A && O==B case' \ + "rm -f .git/index NN && + cp .orig-A/NN NN && + git update-index --add NN && + echo extra >>NN && + git read-tree -m $tree_O $tree_A $tree_B && + check_result" + +test_expect_success \ + '15 (fail) - must match A in O && A && B && O==A && O==B case' " + rm -f .git/index NN && + cp .orig-A/NN NN && + echo extra >>NN && + git update-index --add NN && + test_must_fail git read-tree -m $tree_O $tree_A $tree_B +" + +# #16 +test_expect_success \ + '16 - A matches in one and B matches in another.' \ + 'rm -f .git/index F16 && + echo F16 >F16 && + git update-index --add F16 && + tree0=`git write-tree` && + echo E16 >F16 && + git update-index F16 && + tree1=`git write-tree` && + git read-tree -m $tree0 $tree1 $tree1 $tree0 && + git ls-files --stage' + +test_done diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh new file mode 100755 index 0000000000..4b44e131b2 --- /dev/null +++ b/t/t1001-read-tree-m-2way.sh @@ -0,0 +1,344 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Two way merge with read-tree -m $H $M + +This test tries two-way merge (aka fast forward with carry forward). + +There is the head (called H) and another commit (called M), which is +simply ahead of H. The index and the work tree contains a state that +is derived from H, but may also have local changes. This test checks +all the combinations described in the two-tree merge "carry forward" +rules, found in <Documentation/git read-tree.txt>. + +In the test, these paths are used: + bozbar - in H, stays in M, modified from bozbar to gnusto + frotz - not in H added in M + nitfol - in H, stays in M unmodified + rezrov - in H, deleted in M + yomin - not in H nor M +' +. ./test-lib.sh + +read_tree_twoway () { + git read-tree -m "$1" "$2" && git ls-files --stage +} + +_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' +_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" +compare_change () { + sed -n >current \ + -e '/^--- /d; /^+++ /d; /^@@ /d;' \ + -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$_x40"' /\1 X /p' \ + "$1" + test_cmp expected current +} + +check_cache_at () { + clean_if_empty=`git diff-files -- "$1"` + case "$clean_if_empty" in + '') echo "$1: clean" ;; + ?*) echo "$1: dirty" ;; + esac + case "$2,$clean_if_empty" in + clean,) : ;; + clean,?*) false ;; + dirty,) false ;; + dirty,?*) : ;; + esac +} + +cat >bozbar-old <<\EOF +This is a sample file used in two-way fast forward merge +tests. Its second line ends with a magic word bozbar +which will be modified by the merged head to gnusto. +It has some extra lines so that external tools can +successfully merge independent changes made to later +lines (such as this one), avoiding line conflicts. +EOF + +sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old >bozbar-new + +test_expect_success \ + setup \ + 'echo frotz >frotz && + echo nitfol >nitfol && + cat bozbar-old >bozbar && + echo rezrov >rezrov && + echo yomin >yomin && + git update-index --add nitfol bozbar rezrov && + treeH=`git write-tree` && + echo treeH $treeH && + git ls-tree $treeH && + + cat bozbar-new >bozbar && + git update-index --add frotz bozbar --force-remove rezrov && + git ls-files --stage >M.out && + treeM=`git write-tree` && + echo treeM $treeM && + git ls-tree $treeM && + git diff-tree $treeH $treeM' + +test_expect_success \ + '1, 2, 3 - no carry forward' \ + 'rm -f .git/index && + read_tree_twoway $treeH $treeM && + git ls-files --stage >1-3.out && + test_cmp M.out 1-3.out && + check_cache_at bozbar dirty && + check_cache_at frotz dirty && + check_cache_at nitfol dirty' + +echo '+100644 X 0 yomin' >expected + +test_expect_success \ + '4 - carry forward local addition.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + git update-index --add yomin && + read_tree_twoway $treeH $treeM && + git ls-files --stage >4.out || return 1 + git diff --no-index M.out 4.out >4diff.out + compare_change 4diff.out expected && + check_cache_at yomin clean' + +test_expect_success \ + '5 - carry forward local addition.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + echo yomin >yomin && + git update-index --add yomin && + echo yomin yomin >yomin && + read_tree_twoway $treeH $treeM && + git ls-files --stage >5.out || return 1 + git diff --no-index M.out 5.out >5diff.out + compare_change 5diff.out expected && + check_cache_at yomin dirty' + +test_expect_success \ + '6 - local addition already has the same.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + git update-index --add frotz && + read_tree_twoway $treeH $treeM && + git ls-files --stage >6.out && + test_cmp M.out 6.out && + check_cache_at frotz clean' + +test_expect_success \ + '7 - local addition already has the same.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + echo frotz >frotz && + git update-index --add frotz && + echo frotz frotz >frotz && + read_tree_twoway $treeH $treeM && + git ls-files --stage >7.out && + test_cmp M.out 7.out && + check_cache_at frotz dirty' + +test_expect_success \ + '8 - conflicting addition.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + echo frotz frotz >frotz && + git update-index --add frotz && + if read_tree_twoway $treeH $treeM; then false; else :; fi' + +test_expect_success \ + '9 - conflicting addition.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + echo frotz frotz >frotz && + git update-index --add frotz && + echo frotz >frotz && + if read_tree_twoway $treeH $treeM; then false; else :; fi' + +test_expect_success \ + '10 - path removed.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + echo rezrov >rezrov && + git update-index --add rezrov && + read_tree_twoway $treeH $treeM && + git ls-files --stage >10.out && + test_cmp M.out 10.out' + +test_expect_success \ + '11 - dirty path removed.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + echo rezrov >rezrov && + git update-index --add rezrov && + echo rezrov rezrov >rezrov && + if read_tree_twoway $treeH $treeM; then false; else :; fi' + +test_expect_success \ + '12 - unmatching local changes being removed.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + echo rezrov rezrov >rezrov && + git update-index --add rezrov && + if read_tree_twoway $treeH $treeM; then false; else :; fi' + +test_expect_success \ + '13 - unmatching local changes being removed.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + echo rezrov rezrov >rezrov && + git update-index --add rezrov && + echo rezrov >rezrov && + if read_tree_twoway $treeH $treeM; then false; else :; fi' + +cat >expected <<EOF +-100644 X 0 nitfol ++100644 X 0 nitfol +EOF + +test_expect_success \ + '14 - unchanged in two heads.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + echo nitfol nitfol >nitfol && + git update-index --add nitfol && + read_tree_twoway $treeH $treeM && + git ls-files --stage >14.out || return 1 + git diff --no-index M.out 14.out >14diff.out + compare_change 14diff.out expected && + check_cache_at nitfol clean' + +test_expect_success \ + '15 - unchanged in two heads.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + echo nitfol nitfol >nitfol && + git update-index --add nitfol && + echo nitfol nitfol nitfol >nitfol && + read_tree_twoway $treeH $treeM && + git ls-files --stage >15.out || return 1 + git diff --no-index M.out 15.out >15diff.out + compare_change 15diff.out expected && + check_cache_at nitfol dirty' + +test_expect_success \ + '16 - conflicting local change.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + echo bozbar bozbar >bozbar && + git update-index --add bozbar && + if read_tree_twoway $treeH $treeM; then false; else :; fi' + +test_expect_success \ + '17 - conflicting local change.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + echo bozbar bozbar >bozbar && + git update-index --add bozbar && + echo bozbar bozbar bozbar >bozbar && + if read_tree_twoway $treeH $treeM; then false; else :; fi' + +test_expect_success \ + '18 - local change already having a good result.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + cat bozbar-new >bozbar && + git update-index --add bozbar && + read_tree_twoway $treeH $treeM && + git ls-files --stage >18.out && + test_cmp M.out 18.out && + check_cache_at bozbar clean' + +test_expect_success \ + '19 - local change already having a good result, further modified.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + cat bozbar-new >bozbar && + git update-index --add bozbar && + echo gnusto gnusto >bozbar && + read_tree_twoway $treeH $treeM && + git ls-files --stage >19.out && + test_cmp M.out 19.out && + check_cache_at bozbar dirty' + +test_expect_success \ + '20 - no local change, use new tree.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + cat bozbar-old >bozbar && + git update-index --add bozbar && + read_tree_twoway $treeH $treeM && + git ls-files --stage >20.out && + test_cmp M.out 20.out && + check_cache_at bozbar dirty' + +test_expect_success \ + '21 - no local change, dirty cache.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + cat bozbar-old >bozbar && + git update-index --add bozbar && + echo gnusto gnusto >bozbar && + if read_tree_twoway $treeH $treeM; then false; else :; fi' + +# This fails with straight two-way fast forward. +test_expect_success \ + '22 - local change cache updated.' \ + 'rm -f .git/index && + git read-tree $treeH && + git checkout-index -u -f -q -a && + sed -e "s/such as/SUCH AS/" bozbar-old >bozbar && + git update-index --add bozbar && + if read_tree_twoway $treeH $treeM; then false; else :; fi' + +# Also make sure we did not break DF vs DF/DF case. +test_expect_success \ + 'DF vs DF/DF case setup.' \ + 'rm -f .git/index && + echo DF >DF && + git update-index --add DF && + treeDF=`git write-tree` && + echo treeDF $treeDF && + git ls-tree $treeDF && + + rm -f DF && + mkdir DF && + echo DF/DF >DF/DF && + git update-index --add --remove DF DF/DF && + treeDFDF=`git write-tree` && + echo treeDFDF $treeDFDF && + git ls-tree $treeDFDF && + git ls-files --stage >DFDF.out' + +test_expect_success \ + 'DF vs DF/DF case test.' \ + 'rm -f .git/index && + rm -fr DF && + echo DF >DF && + git update-index --add DF && + read_tree_twoway $treeDF $treeDFDF && + git ls-files --stage >DFDFcheck.out && + test_cmp DFDF.out DFDFcheck.out && + check_cache_at DF/DF dirty && + :' + +test_done diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh new file mode 100755 index 0000000000..aa9dd580a6 --- /dev/null +++ b/t/t1002-read-tree-m-u-2way.sh @@ -0,0 +1,344 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Two way merge with read-tree -m -u $H $M + +This is identical to t1001, but uses -u to update the work tree as well. + +' +. ./test-lib.sh + +_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' +_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" +compare_change () { + sed >current \ + -e '/^--- /d; /^+++ /d; /^@@ /d;' \ + -e 's/^\(.[0-7][0-7][0-7][0-7][0-7][0-7]\) '"$_x40"' /\1 X /' "$1" + test_cmp expected current +} + +check_cache_at () { + clean_if_empty=`git diff-files -- "$1"` + case "$clean_if_empty" in + '') echo "$1: clean" ;; + ?*) echo "$1: dirty" ;; + esac + case "$2,$clean_if_empty" in + clean,) : ;; + clean,?*) false ;; + dirty,) false ;; + dirty,?*) : ;; + esac +} + +test_expect_success \ + setup \ + 'echo frotz >frotz && + echo nitfol >nitfol && + echo bozbar >bozbar && + echo rezrov >rezrov && + git update-index --add nitfol bozbar rezrov && + treeH=`git write-tree` && + echo treeH $treeH && + git ls-tree $treeH && + + echo gnusto >bozbar && + git update-index --add frotz bozbar --force-remove rezrov && + git ls-files --stage >M.out && + treeM=`git write-tree` && + echo treeM $treeM && + git ls-tree $treeM && + sum bozbar frotz nitfol >M.sum && + git diff-tree $treeH $treeM' + +test_expect_success \ + '1, 2, 3 - no carry forward' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >1-3.out && + cmp M.out 1-3.out && + sum bozbar frotz nitfol >actual3.sum && + cmp M.sum actual3.sum && + check_cache_at bozbar clean && + check_cache_at frotz clean && + check_cache_at nitfol clean' + +test_expect_success \ + '4 - carry forward local addition.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo "+100644 X 0 yomin" >expected && + echo yomin >yomin && + git update-index --add yomin && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >4.out || return 1 + diff -U0 M.out 4.out >4diff.out + compare_change 4diff.out expected && + check_cache_at yomin clean && + sum bozbar frotz nitfol >actual4.sum && + cmp M.sum actual4.sum && + echo yomin >yomin1 && + diff yomin yomin1 && + rm -f yomin1' + +test_expect_success \ + '5 - carry forward local addition.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + git read-tree -m -u $treeH && + echo yomin >yomin && + git update-index --add yomin && + echo yomin yomin >yomin && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >5.out || return 1 + diff -U0 M.out 5.out >5diff.out + compare_change 5diff.out expected && + check_cache_at yomin dirty && + sum bozbar frotz nitfol >actual5.sum && + cmp M.sum actual5.sum && + : dirty index should have prevented -u from checking it out. && + echo yomin yomin >yomin1 && + diff yomin yomin1 && + rm -f yomin1' + +test_expect_success \ + '6 - local addition already has the same.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo frotz >frotz && + git update-index --add frotz && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >6.out && + test_cmp M.out 6.out && + check_cache_at frotz clean && + sum bozbar frotz nitfol >actual3.sum && + cmp M.sum actual3.sum && + echo frotz >frotz1 && + diff frotz frotz1 && + rm -f frotz1' + +test_expect_success \ + '7 - local addition already has the same.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo frotz >frotz && + git update-index --add frotz && + echo frotz frotz >frotz && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >7.out && + test_cmp M.out 7.out && + check_cache_at frotz dirty && + sum bozbar frotz nitfol >actual7.sum && + if cmp M.sum actual7.sum; then false; else :; fi && + : dirty index should have prevented -u from checking it out. && + echo frotz frotz >frotz1 && + diff frotz frotz1 && + rm -f frotz1' + +test_expect_success \ + '8 - conflicting addition.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo frotz frotz >frotz && + git update-index --add frotz && + if git read-tree -m -u $treeH $treeM; then false; else :; fi' + +test_expect_success \ + '9 - conflicting addition.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo frotz frotz >frotz && + git update-index --add frotz && + echo frotz >frotz && + if git read-tree -m -u $treeH $treeM; then false; else :; fi' + +test_expect_success \ + '10 - path removed.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo rezrov >rezrov && + git update-index --add rezrov && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >10.out && + cmp M.out 10.out && + sum bozbar frotz nitfol >actual10.sum && + cmp M.sum actual10.sum' + +test_expect_success \ + '11 - dirty path removed.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo rezrov >rezrov && + git update-index --add rezrov && + echo rezrov rezrov >rezrov && + if git read-tree -m -u $treeH $treeM; then false; else :; fi' + +test_expect_success \ + '12 - unmatching local changes being removed.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo rezrov rezrov >rezrov && + git update-index --add rezrov && + if git read-tree -m -u $treeH $treeM; then false; else :; fi' + +test_expect_success \ + '13 - unmatching local changes being removed.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo rezrov rezrov >rezrov && + git update-index --add rezrov && + echo rezrov >rezrov && + if git read-tree -m -u $treeH $treeM; then false; else :; fi' + +cat >expected <<EOF +-100644 X 0 nitfol ++100644 X 0 nitfol +EOF + +test_expect_success \ + '14 - unchanged in two heads.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo nitfol nitfol >nitfol && + git update-index --add nitfol && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >14.out || return 1 + diff -U0 M.out 14.out >14diff.out + compare_change 14diff.out expected && + sum bozbar frotz >actual14.sum && + grep -v nitfol M.sum > expected14.sum && + cmp expected14.sum actual14.sum && + sum bozbar frotz nitfol >actual14a.sum && + if cmp M.sum actual14a.sum; then false; else :; fi && + check_cache_at nitfol clean && + echo nitfol nitfol >nitfol1 && + diff nitfol nitfol1 && + rm -f nitfol1' + +test_expect_success \ + '15 - unchanged in two heads.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo nitfol nitfol >nitfol && + git update-index --add nitfol && + echo nitfol nitfol nitfol >nitfol && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >15.out || return 1 + diff -U0 M.out 15.out >15diff.out + compare_change 15diff.out expected && + check_cache_at nitfol dirty && + sum bozbar frotz >actual15.sum && + grep -v nitfol M.sum > expected15.sum && + cmp expected15.sum actual15.sum && + sum bozbar frotz nitfol >actual15a.sum && + if cmp M.sum actual15a.sum; then false; else :; fi && + echo nitfol nitfol nitfol >nitfol1 && + diff nitfol nitfol1 && + rm -f nitfol1' + +test_expect_success \ + '16 - conflicting local change.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo bozbar bozbar >bozbar && + git update-index --add bozbar && + if git read-tree -m -u $treeH $treeM; then false; else :; fi' + +test_expect_success \ + '17 - conflicting local change.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo bozbar bozbar >bozbar && + git update-index --add bozbar && + echo bozbar bozbar bozbar >bozbar && + if git read-tree -m -u $treeH $treeM; then false; else :; fi' + +test_expect_success \ + '18 - local change already having a good result.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo gnusto >bozbar && + git update-index --add bozbar && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >18.out && + test_cmp M.out 18.out && + check_cache_at bozbar clean && + sum bozbar frotz nitfol >actual18.sum && + cmp M.sum actual18.sum' + +test_expect_success \ + '19 - local change already having a good result, further modified.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo gnusto >bozbar && + git update-index --add bozbar && + echo gnusto gnusto >bozbar && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >19.out && + test_cmp M.out 19.out && + check_cache_at bozbar dirty && + sum frotz nitfol >actual19.sum && + grep -v bozbar M.sum > expected19.sum && + cmp expected19.sum actual19.sum && + sum bozbar frotz nitfol >actual19a.sum && + if cmp M.sum actual19a.sum; then false; else :; fi && + echo gnusto gnusto >bozbar1 && + diff bozbar bozbar1 && + rm -f bozbar1' + +test_expect_success \ + '20 - no local change, use new tree.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo bozbar >bozbar && + git update-index --add bozbar && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >20.out && + test_cmp M.out 20.out && + check_cache_at bozbar clean && + sum bozbar frotz nitfol >actual20.sum && + cmp M.sum actual20.sum' + +test_expect_success \ + '21 - no local change, dirty cache.' \ + 'rm -f .git/index nitfol bozbar rezrov frotz && + git read-tree --reset -u $treeH && + echo bozbar >bozbar && + git update-index --add bozbar && + echo gnusto gnusto >bozbar && + if git read-tree -m -u $treeH $treeM; then false; else :; fi' + +# Also make sure we did not break DF vs DF/DF case. +test_expect_success \ + 'DF vs DF/DF case setup.' \ + 'rm -f .git/index + echo DF >DF && + git update-index --add DF && + treeDF=`git write-tree` && + echo treeDF $treeDF && + git ls-tree $treeDF && + + rm -f DF && + mkdir DF && + echo DF/DF >DF/DF && + git update-index --add --remove DF DF/DF && + treeDFDF=`git write-tree` && + echo treeDFDF $treeDFDF && + git ls-tree $treeDFDF && + git ls-files --stage >DFDF.out' + +test_expect_success \ + 'DF vs DF/DF case test.' \ + 'rm -f .git/index && + rm -fr DF && + echo DF >DF && + git update-index --add DF && + git read-tree -m -u $treeDF $treeDFDF && + git ls-files --stage >DFDFcheck.out && + test_cmp DFDF.out DFDFcheck.out && + check_cache_at DF/DF clean' + +test_done diff --git a/t/t1003-read-tree-prefix.sh b/t/t1003-read-tree-prefix.sh new file mode 100755 index 0000000000..8c6d67edda --- /dev/null +++ b/t/t1003-read-tree-prefix.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='git read-tree --prefix test. +' + +. ./test-lib.sh + +test_expect_success setup ' + echo hello >one && + git update-index --add one && + tree=`git write-tree` && + echo tree is $tree +' + +echo 'one +two/one' >expect + +test_expect_success 'read-tree --prefix' ' + git read-tree --prefix=two/ $tree && + git ls-files >actual && + cmp expect actual +' + +test_done diff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh new file mode 100755 index 0000000000..570d3729bd --- /dev/null +++ b/t/t1004-read-tree-m-u-wf.sh @@ -0,0 +1,241 @@ +#!/bin/sh + +test_description='read-tree -m -u checks working tree files' + +. ./test-lib.sh + +# two-tree test + +test_expect_success 'two-way setup' ' + + mkdir subdir && + echo >file1 file one && + echo >file2 file two && + echo >subdir/file1 file one in subdirectory && + echo >subdir/file2 file two in subdirectory && + git update-index --add file1 file2 subdir/file1 subdir/file2 && + git commit -m initial && + + git branch side && + git tag -f branch-point && + + echo file2 is not tracked on the master anymore && + rm -f file2 subdir/file2 && + git update-index --remove file2 subdir/file2 && + git commit -a -m "master removes file2 and subdir/file2" +' + +test_expect_success 'two-way not clobbering' ' + + echo >file2 master creates untracked file2 && + echo >subdir/file2 master creates untracked subdir/file2 && + if err=`git read-tree -m -u master side 2>&1` + then + echo should have complained + false + else + echo "happy to see $err" + fi +' + +echo file2 >.gitignore + +test_expect_success 'two-way with incorrect --exclude-per-directory (1)' ' + + if err=`git read-tree -m --exclude-per-directory=.gitignore master side 2>&1` + then + echo should have complained + false + else + echo "happy to see $err" + fi +' + +test_expect_success 'two-way with incorrect --exclude-per-directory (2)' ' + + if err=`git read-tree -m -u --exclude-per-directory=foo --exclude-per-directory=.gitignore master side 2>&1` + then + echo should have complained + false + else + echo "happy to see $err" + fi +' + +test_expect_success 'two-way clobbering a ignored file' ' + + git read-tree -m -u --exclude-per-directory=.gitignore master side +' + +rm -f .gitignore + +# three-tree test + +test_expect_success 'three-way not complaining on an untracked path in both' ' + + rm -f file2 subdir/file2 && + git checkout side && + echo >file3 file three && + echo >subdir/file3 file three && + git update-index --add file3 subdir/file3 && + git commit -a -m "side adds file3 and removes file2" && + + git checkout master && + echo >file2 file two is untracked on the master side && + echo >subdir/file2 file two is untracked on the master side && + + git read-tree -m -u branch-point master side +' + +test_expect_success 'three-way not clobbering a working tree file' ' + + git reset --hard && + rm -f file2 subdir/file2 file3 subdir/file3 && + git checkout master && + echo >file3 file three created in master, untracked && + echo >subdir/file3 file three created in master, untracked && + if err=`git read-tree -m -u branch-point master side 2>&1` + then + echo should have complained + false + else + echo "happy to see $err" + fi +' + +echo >.gitignore file3 + +test_expect_success 'three-way not complaining on an untracked file' ' + + git reset --hard && + rm -f file2 subdir/file2 file3 subdir/file3 && + git checkout master && + echo >file3 file three created in master, untracked && + echo >subdir/file3 file three created in master, untracked && + + git read-tree -m -u --exclude-per-directory=.gitignore branch-point master side +' + +test_expect_success '3-way not overwriting local changes (setup)' ' + + git reset --hard && + git checkout -b side-a branch-point && + echo >>file1 "new line to be kept in the merge result" && + git commit -a -m "side-a changes file1" && + git checkout -b side-b branch-point && + echo >>file2 "new line to be kept in the merge result" && + git commit -a -m "side-b changes file2" && + git checkout side-a + +' + +test_expect_success '3-way not overwriting local changes (our side)' ' + + # At this point, file1 from side-a should be kept as side-b + # did not touch it. + + git reset --hard && + + echo >>file1 "local changes" && + git read-tree -m -u branch-point side-a side-b && + grep "new line to be kept" file1 && + grep "local changes" file1 + +' + +test_expect_success '3-way not overwriting local changes (their side)' ' + + # At this point, file2 from side-b should be taken as side-a + # did not touch it. + + git reset --hard && + + echo >>file2 "local changes" && + test_must_fail git read-tree -m -u branch-point side-a side-b && + ! grep "new line to be kept" file2 && + grep "local changes" file2 + +' + +test_expect_success 'funny symlink in work tree' ' + + git reset --hard && + git checkout -b sym-b side-b && + mkdir -p a && + >a/b && + git add a/b && + git commit -m "side adds a/b" && + + rm -fr a && + git checkout -b sym-a side-a && + mkdir -p a && + ln -s ../b a/b && + git add a/b && + git commit -m "we add a/b" && + + git read-tree -m -u sym-a sym-a sym-b + +' + +test_expect_success 'funny symlink in work tree, un-unlink-able' ' + + rm -fr a b && + git reset --hard && + + git checkout sym-a && + chmod a-w a && + test_must_fail git read-tree -m -u sym-a sym-a sym-b + +' + +# clean-up from the above test +chmod a+w a +rm -fr a b + +test_expect_success 'D/F setup' ' + + git reset --hard && + + git checkout side-a && + rm -f subdir/file2 && + mkdir subdir/file2 && + echo qfwfq >subdir/file2/another && + git add subdir/file2/another && + test_tick && + git commit -m "side-a changes file2 to directory" + +' + +test_expect_success 'D/F' ' + + git checkout side-b && + git read-tree -m -u branch-point side-b side-a && + git ls-files -u >actual && + ( + a=$(git rev-parse branch-point:subdir/file2) + b=$(git rev-parse side-a:subdir/file2/another) + echo "100644 $a 1 subdir/file2" + echo "100644 $a 2 subdir/file2" + echo "100644 $b 3 subdir/file2/another" + ) >expect && + test_cmp actual expect + +' + +test_expect_success 'D/F resolve' ' + + git reset --hard && + git checkout side-b && + git merge-resolve branch-point -- side-b side-a + +' + +test_expect_success 'D/F recursive' ' + + git reset --hard && + git checkout side-b && + git merge-recursive branch-point -- side-b side-a + +' + +test_done diff --git a/t/t1005-read-tree-reset.sh b/t/t1005-read-tree-reset.sh new file mode 100755 index 0000000000..b0d31f5a9b --- /dev/null +++ b/t/t1005-read-tree-reset.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +test_description='read-tree -u --reset' + +. ./test-lib.sh + +# two-tree test + +test_expect_success 'setup' ' + git init && + mkdir df && + echo content >df/file && + git add df/file && + git commit -m one && + git ls-files >expect && + rm -rf df && + echo content >df && + git add df && + echo content >new && + git add new && + git commit -m two +' + +test_expect_success 'reset should work' ' + git read-tree -u --reset HEAD^ && + git ls-files >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh new file mode 100755 index 0000000000..d8b7f2ffbc --- /dev/null +++ b/t/t1006-cat-file.sh @@ -0,0 +1,244 @@ +#!/bin/sh + +test_description='git cat-file' + +. ./test-lib.sh + +echo_without_newline () { + printf '%s' "$*" +} + +strlen () { + echo_without_newline "$1" | wc -c | sed -e 's/^ *//' +} + +maybe_remove_timestamp () { + if test -z "$2"; then + echo_without_newline "$1" + else + echo_without_newline "$(printf '%s\n' "$1" | sed -e 's/ [0-9][0-9]* [-+][0-9][0-9][0-9][0-9]$//')" + fi +} + +run_tests () { + type=$1 + sha1=$2 + size=$3 + content=$4 + pretty_content=$5 + no_ts=$6 + + batch_output="$sha1 $type $size +$content" + + test_expect_success "$type exists" ' + git cat-file -e $sha1 + ' + + test_expect_success "Type of $type is correct" ' + test $type = "$(git cat-file -t $sha1)" + ' + + test_expect_success "Size of $type is correct" ' + test $size = "$(git cat-file -s $sha1)" + ' + + test -z "$content" || + test_expect_success "Content of $type is correct" ' + expect="$(maybe_remove_timestamp "$content" $no_ts)" + actual="$(maybe_remove_timestamp "$(git cat-file $type $sha1)" $no_ts)" + + if test "z$expect" = "z$actual" + then + : happy + else + echo "Oops: expected $expect" + echo "but got $actual" + false + fi + ' + + test_expect_success "Pretty content of $type is correct" ' + expect="$(maybe_remove_timestamp "$pretty_content" $no_ts)" + actual="$(maybe_remove_timestamp "$(git cat-file -p $sha1)" $no_ts)" + if test "z$expect" = "z$actual" + then + : happy + else + echo "Oops: expected $expect" + echo "but got $actual" + false + fi + ' + + test -z "$content" || + test_expect_success "--batch output of $type is correct" ' + expect="$(maybe_remove_timestamp "$batch_output" $no_ts)" + actual="$(maybe_remove_timestamp "$(echo $sha1 | git cat-file --batch)" $no_ts)" + if test "z$expect" = "z$actual" + then + : happy + else + echo "Oops: expected $expect" + echo "but got $actual" + false + fi + ' + + test_expect_success "--batch-check output of $type is correct" ' + expect="$sha1 $type $size" + actual="$(echo_without_newline $sha1 | git cat-file --batch-check)" + if test "z$expect" = "z$actual" + then + : happy + else + echo "Oops: expected $expect" + echo "but got $actual" + false + fi + ' +} + +hello_content="Hello World" +hello_size=$(strlen "$hello_content") +hello_sha1=$(echo_without_newline "$hello_content" | git hash-object --stdin) + +test_expect_success "setup" ' + echo_without_newline "$hello_content" > hello && + git update-index --add hello +' + +run_tests 'blob' $hello_sha1 $hello_size "$hello_content" "$hello_content" + +tree_sha1=$(git write-tree) +tree_size=33 +tree_pretty_content="100644 blob $hello_sha1 hello" + +run_tests 'tree' $tree_sha1 $tree_size "" "$tree_pretty_content" + +commit_message="Intial commit" +commit_sha1=$(echo_without_newline "$commit_message" | git commit-tree $tree_sha1) +commit_size=176 +commit_content="tree $tree_sha1 +author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 0000000000 +0000 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 0000000000 +0000 + +$commit_message" + +run_tests 'commit' $commit_sha1 $commit_size "$commit_content" "$commit_content" 1 + +tag_header_without_timestamp="object $hello_sha1 +type blob +tag hellotag +tagger $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" +tag_description="This is a tag" +tag_content="$tag_header_without_timestamp 0000000000 +0000 + +$tag_description" +tag_pretty_content="$tag_header_without_timestamp Thu Jan 1 00:00:00 1970 +0000 + +$tag_description" + +tag_sha1=$(echo_without_newline "$tag_content" | git mktag) +tag_size=$(strlen "$tag_content") + +run_tests 'tag' $tag_sha1 $tag_size "$tag_content" "$tag_pretty_content" 1 + +test_expect_success \ + "Reach a blob from a tag pointing to it" \ + "test '$hello_content' = \"\$(git cat-file blob $tag_sha1)\"" + +for batch in batch batch-check +do + for opt in t s e p + do + test_expect_success "Passing -$opt with --$batch fails" ' + test_must_fail git cat-file --$batch -$opt $hello_sha1 + ' + + test_expect_success "Passing --$batch with -$opt fails" ' + test_must_fail git cat-file -$opt --$batch $hello_sha1 + ' + done + + test_expect_success "Passing <type> with --$batch fails" ' + test_must_fail git cat-file --$batch blob $hello_sha1 + ' + + test_expect_success "Passing --$batch with <type> fails" ' + test_must_fail git cat-file blob --$batch $hello_sha1 + ' + + test_expect_success "Passing sha1 with --$batch fails" ' + test_must_fail git cat-file --$batch $hello_sha1 + ' +done + +test_expect_success "--batch-check for a non-existent named object" ' + test "foobar42 missing +foobar84 missing" = \ + "$( ( echo foobar42; echo_without_newline foobar84; ) | git cat-file --batch-check)" +' + +test_expect_success "--batch-check for a non-existent hash" ' + test "0000000000000000000000000000000000000042 missing +0000000000000000000000000000000000000084 missing" = \ + "$( ( echo 0000000000000000000000000000000000000042; + echo_without_newline 0000000000000000000000000000000000000084; ) \ + | git cat-file --batch-check)" +' + +test_expect_success "--batch for an existent and a non-existent hash" ' + test "$tag_sha1 tag $tag_size +$tag_content +0000000000000000000000000000000000000000 missing" = \ + "$( ( echo $tag_sha1; + echo_without_newline 0000000000000000000000000000000000000000; ) \ + | git cat-file --batch)" +' + +test_expect_success "--batch-check for an emtpy line" ' + test " missing" = "$(echo | git cat-file --batch-check)" +' + +batch_input="$hello_sha1 +$commit_sha1 +$tag_sha1 +deadbeef + +" + +batch_output="$hello_sha1 blob $hello_size +$hello_content +$commit_sha1 commit $commit_size +$commit_content +$tag_sha1 tag $tag_size +$tag_content +deadbeef missing + missing" + +test_expect_success '--batch with multiple sha1s gives correct format' ' + test "$(maybe_remove_timestamp "$batch_output" 1)" = "$(maybe_remove_timestamp "$(echo_without_newline "$batch_input" | git cat-file --batch)" 1)" +' + +batch_check_input="$hello_sha1 +$tree_sha1 +$commit_sha1 +$tag_sha1 +deadbeef + +" + +batch_check_output="$hello_sha1 blob $hello_size +$tree_sha1 tree $tree_size +$commit_sha1 commit $commit_size +$tag_sha1 tag $tag_size +deadbeef missing + missing" + +test_expect_success "--batch-check with multiple sha1s gives correct format" ' + test "$batch_check_output" = \ + "$(echo_without_newline "$batch_check_input" | git cat-file --batch-check)" +' + +test_done diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh new file mode 100755 index 0000000000..1ec0535138 --- /dev/null +++ b/t/t1007-hash-object.sh @@ -0,0 +1,133 @@ +#!/bin/sh + +test_description="git-hash-object" + +. ./test-lib.sh + +echo_without_newline() { + printf '%s' "$*" +} + +test_blob_does_not_exist() { + test_expect_success 'blob does not exist in database' " + test_must_fail git cat-file blob $1 + " +} + +test_blob_exists() { + test_expect_success 'blob exists in database' " + git cat-file blob $1 + " +} + +hello_content="Hello World" +hello_sha1=5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689 + +example_content="This is an example" +example_sha1=ddd3f836d3e3fbb7ae289aa9ae83536f76956399 + +setup_repo() { + echo_without_newline "$hello_content" > hello + echo_without_newline "$example_content" > example +} + +test_repo=test +push_repo() { + test_create_repo $test_repo + cd $test_repo + + setup_repo +} + +pop_repo() { + cd .. + rm -rf $test_repo +} + +setup_repo + +# Argument checking + +test_expect_success "multiple '--stdin's are rejected" ' + test_must_fail git hash-object --stdin --stdin < example +' + +test_expect_success "Can't use --stdin and --stdin-paths together" ' + test_must_fail git hash-object --stdin --stdin-paths && + test_must_fail git hash-object --stdin-paths --stdin +' + +test_expect_success "Can't pass filenames as arguments with --stdin-paths" ' + test_must_fail git hash-object --stdin-paths hello < example +' + +# Behavior + +push_repo + +test_expect_success 'hash a file' ' + test $hello_sha1 = $(git hash-object hello) +' + +test_blob_does_not_exist $hello_sha1 + +test_expect_success 'hash from stdin' ' + test $example_sha1 = $(git hash-object --stdin < example) +' + +test_blob_does_not_exist $example_sha1 + +test_expect_success 'hash a file and write to database' ' + test $hello_sha1 = $(git hash-object -w hello) +' + +test_blob_exists $hello_sha1 + +test_expect_success 'git hash-object --stdin file1 <file0 first operates on file0, then file1' ' + echo foo > file1 && + obname0=$(echo bar | git hash-object --stdin) && + obname1=$(git hash-object file1) && + obname0new=$(echo bar | git hash-object --stdin file1 | sed -n -e 1p) && + obname1new=$(echo bar | git hash-object --stdin file1 | sed -n -e 2p) && + test "$obname0" = "$obname0new" && + test "$obname1" = "$obname1new" +' + +pop_repo + +for args in "-w --stdin" "--stdin -w"; do + push_repo + + test_expect_success "hash from stdin and write to database ($args)" ' + test $example_sha1 = $(git hash-object $args < example) + ' + + test_blob_exists $example_sha1 + + pop_repo +done + +filenames="hello +example" + +sha1s="$hello_sha1 +$example_sha1" + +test_expect_success "hash two files with names on stdin" ' + test "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object --stdin-paths)" +' + +for args in "-w --stdin-paths" "--stdin-paths -w"; do + push_repo + + test_expect_success "hash two files with names on stdin and write to database ($args)" ' + test "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object $args)" + ' + + test_blob_exists $hello_sha1 + test_blob_exists $example_sha1 + + pop_repo +done + +test_done diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh new file mode 100755 index 0000000000..fc386ba033 --- /dev/null +++ b/t/t1020-subdirectory.sh @@ -0,0 +1,138 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='Try various core-level commands in subdirectory. +' + +. ./test-lib.sh + +test_expect_success setup ' + long="a b c d e f g h i j k l m n o p q r s t u v w x y z" && + for c in $long; do echo $c; done >one && + mkdir dir && + for c in x y z $long a b c; do echo $c; done >dir/two && + cp one original.one && + cp dir/two original.two +' +HERE=`pwd` +LF=' +' + +test_expect_success 'update-index and ls-files' ' + cd "$HERE" && + git update-index --add one && + case "`git ls-files`" in + one) echo ok one ;; + *) echo bad one; exit 1 ;; + esac && + cd dir && + git update-index --add two && + case "`git ls-files`" in + two) echo ok two ;; + *) echo bad two; exit 1 ;; + esac && + cd .. && + case "`git ls-files`" in + dir/two"$LF"one) echo ok both ;; + *) echo bad; exit 1 ;; + esac +' + +test_expect_success 'cat-file' ' + cd "$HERE" && + two=`git ls-files -s dir/two` && + two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` && + echo "$two" && + git cat-file -p "$two" >actual && + cmp dir/two actual && + cd dir && + git cat-file -p "$two" >actual && + cmp two actual +' +rm -f actual dir/actual + +test_expect_success 'diff-files' ' + cd "$HERE" && + echo a >>one && + echo d >>dir/two && + case "`git diff-files --name-only`" in + dir/two"$LF"one) echo ok top ;; + *) echo bad top; exit 1 ;; + esac && + # diff should not omit leading paths + cd dir && + case "`git diff-files --name-only`" in + dir/two"$LF"one) echo ok subdir ;; + *) echo bad subdir; exit 1 ;; + esac && + case "`git diff-files --name-only .`" in + dir/two) echo ok subdir limited ;; + *) echo bad subdir limited; exit 1 ;; + esac +' + +test_expect_success 'write-tree' ' + cd "$HERE" && + top=`git write-tree` && + echo $top && + cd dir && + sub=`git write-tree` && + echo $sub && + test "z$top" = "z$sub" +' + +test_expect_success 'checkout-index' ' + cd "$HERE" && + git checkout-index -f -u one && + cmp one original.one && + cd dir && + git checkout-index -f -u two && + cmp two ../original.two +' + +test_expect_success 'read-tree' ' + cd "$HERE" && + rm -f one dir/two && + tree=`git write-tree` && + git read-tree --reset -u "$tree" && + cmp one original.one && + cmp dir/two original.two && + cd dir && + rm -f two && + git read-tree --reset -u "$tree" && + cmp two ../original.two && + cmp ../one ../original.one +' + +test_expect_success 'no file/rev ambiguity check inside .git' ' + cd "$HERE" && + git commit -a -m 1 && + cd "$HERE"/.git && + git show -s HEAD +' + +test_expect_success 'no file/rev ambiguity check inside a bare repo' ' + cd "$HERE" && + git clone -s --bare .git foo.git && + cd foo.git && GIT_DIR=. git show -s HEAD +' + +# This still does not work as it should... +: test_expect_success 'no file/rev ambiguity check inside a bare repo' ' + cd "$HERE" && + git clone -s --bare .git foo.git && + cd foo.git && git show -s HEAD +' + +test_expect_success 'detection should not be fooled by a symlink' ' + cd "$HERE" && + rm -fr foo.git && + git clone -s .git another && + ln -s another yetanother && + cd yetanother/.git && + git show -s HEAD +' + +test_done diff --git a/t/t1100-commit-tree-options.sh b/t/t1100-commit-tree-options.sh new file mode 100755 index 0000000000..7f7fc36734 --- /dev/null +++ b/t/t1100-commit-tree-options.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# +# Copyright (C) 2005 Rene Scharfe +# + +test_description='git commit-tree options test + +This test checks that git commit-tree can create a specific commit +object by defining all environment variables that it understands. +' + +. ./test-lib.sh + +cat >expected <<EOF +tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 +author Author Name <author@email> 1117148400 +0000 +committer Committer Name <committer@email> 1117150200 +0000 + +comment text +EOF + +test_expect_success \ + 'test preparation: write empty tree' \ + 'git write-tree >treeid' + +test_expect_success \ + 'construct commit' \ + 'echo comment text | + GIT_AUTHOR_NAME="Author Name" \ + GIT_AUTHOR_EMAIL="author@email" \ + GIT_AUTHOR_DATE="2005-05-26 23:00" \ + GIT_COMMITTER_NAME="Committer Name" \ + GIT_COMMITTER_EMAIL="committer@email" \ + GIT_COMMITTER_DATE="2005-05-26 23:30" \ + TZ=GMT git commit-tree `cat treeid` >commitid 2>/dev/null' + +test_expect_success \ + 'read commit' \ + 'git cat-file commit `cat commitid` >commit' + +test_expect_success \ + 'compare commit' \ + 'diff expected commit' + +test_done diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh new file mode 100755 index 0000000000..09a8199335 --- /dev/null +++ b/t/t1200-tutorial.sh @@ -0,0 +1,163 @@ +#!/bin/sh +# +# Copyright (c) 2005 Johannes Schindelin +# + +test_description='A simple turial in the form of a test case' + +. ./test-lib.sh + +echo "Hello World" > hello +echo "Silly example" > example + +git update-index --add hello example + +test_expect_success 'blob' "test blob = \"$(git cat-file -t 557db03)\"" + +test_expect_success 'blob 557db03' "test \"Hello World\" = \"$(git cat-file blob 557db03)\"" + +echo "It's a new day for git" >>hello +cat > diff.expect << EOF +diff --git a/hello b/hello +index 557db03..263414f 100644 +--- a/hello ++++ b/hello +@@ -1 +1,2 @@ + Hello World ++It's a new day for git +EOF +git diff-files -p > diff.output +test_expect_success 'git diff-files -p' 'cmp diff.expect diff.output' +git diff > diff.output +test_expect_success 'git diff' 'cmp diff.expect diff.output' + +tree=$(git write-tree 2>/dev/null) + +test_expect_success 'tree' "test 8988da15d077d4829fc51d8544c097def6644dbb = $tree" + +output="$(echo "Initial commit" | git commit-tree $(git write-tree) 2>&1 > .git/refs/heads/master)" + +git diff-index -p HEAD > diff.output +test_expect_success 'git diff-index -p HEAD' 'cmp diff.expect diff.output' + +git diff HEAD > diff.output +test_expect_success 'git diff HEAD' 'cmp diff.expect diff.output' + +#rm hello +#test_expect_success 'git read-tree --reset HEAD' "git read-tree --reset HEAD ; test \"hello: needs update\" = \"$(git update-index --refresh)\"" + +cat > whatchanged.expect << EOF +commit VARIABLE +Author: VARIABLE +Date: VARIABLE + + Initial commit + +diff --git a/example b/example +new file mode 100644 +index 0000000..f24c74a +--- /dev/null ++++ b/example +@@ -0,0 +1 @@ ++Silly example +diff --git a/hello b/hello +new file mode 100644 +index 0000000..557db03 +--- /dev/null ++++ b/hello +@@ -0,0 +1 @@ ++Hello World +EOF + +git whatchanged -p --root | \ + sed -e "1s/^\(.\{7\}\).\{40\}/\1VARIABLE/" \ + -e "2,3s/^\(.\{8\}\).*$/\1VARIABLE/" \ +> whatchanged.output +test_expect_success 'git whatchanged -p --root' 'cmp whatchanged.expect whatchanged.output' + +git tag my-first-tag +test_expect_success 'git tag my-first-tag' 'cmp .git/refs/heads/master .git/refs/tags/my-first-tag' + +# TODO: test git-clone + +git checkout -b mybranch +test_expect_success 'git checkout -b mybranch' 'cmp .git/refs/heads/master .git/refs/heads/mybranch' + +cat > branch.expect <<EOF + master +* mybranch +EOF + +git branch > branch.output +test_expect_success 'git branch' 'cmp branch.expect branch.output' + +git checkout mybranch +echo "Work, work, work" >>hello +git commit -m 'Some work.' -i hello + +git checkout master + +echo "Play, play, play" >>hello +echo "Lots of fun" >>example +git commit -m 'Some fun.' -i hello example + +test_expect_success 'git resolve now fails' ' + test_must_fail git merge -m "Merge work in mybranch" mybranch +' + +cat > hello << EOF +Hello World +It's a new day for git +Play, play, play +Work, work, work +EOF + +git commit -m 'Merged "mybranch" changes.' -i hello + +test_done + +cat > show-branch.expect << EOF +* [master] Merged "mybranch" changes. + ! [mybranch] Some work. +-- +- [master] Merged "mybranch" changes. +*+ [mybranch] Some work. +EOF + +git show-branch --topo-order master mybranch > show-branch.output +test_expect_success 'git show-branch' 'cmp show-branch.expect show-branch.output' + +git checkout mybranch + +cat > resolve.expect << EOF +Updating from VARIABLE to VARIABLE + example | 1 + + hello | 1 + + 2 files changed, 2 insertions(+), 0 deletions(-) +EOF + +git merge -s "Merge upstream changes." master | \ + sed -e "1s/[0-9a-f]\{40\}/VARIABLE/g" >resolve.output +test_expect_success 'git resolve' 'cmp resolve.expect resolve.output' + +cat > show-branch2.expect << EOF +! [master] Merged "mybranch" changes. + * [mybranch] Merged "mybranch" changes. +-- +-- [master] Merged "mybranch" changes. +EOF + +git show-branch --topo-order master mybranch > show-branch2.output +test_expect_success 'git show-branch' 'cmp show-branch2.expect show-branch2.output' + +# TODO: test git fetch + +# TODO: test git push + +test_expect_success 'git repack' 'git repack' +test_expect_success 'git prune-packed' 'git prune-packed' +test_expect_success '-> only packed objects' ' + ! find -type f .git/objects/[0-9a-f][0-9a-f] +' + +test_done diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh new file mode 100755 index 0000000000..64567fb94d --- /dev/null +++ b/t/t1300-repo-config.sh @@ -0,0 +1,744 @@ +#!/bin/sh +# +# Copyright (c) 2005 Johannes Schindelin +# + +test_description='Test git config in different settings' + +. ./test-lib.sh + +test -f .git/config && rm .git/config + +git config core.penguin "little blue" + +cat > expect << EOF +[core] + penguin = little blue +EOF + +test_expect_success 'initial' 'cmp .git/config expect' + +git config Core.Movie BadPhysics + +cat > expect << EOF +[core] + penguin = little blue + Movie = BadPhysics +EOF + +test_expect_success 'mixed case' 'cmp .git/config expect' + +git config Cores.WhatEver Second + +cat > expect << EOF +[core] + penguin = little blue + Movie = BadPhysics +[Cores] + WhatEver = Second +EOF + +test_expect_success 'similar section' 'cmp .git/config expect' + +git config CORE.UPPERCASE true + +cat > expect << EOF +[core] + penguin = little blue + Movie = BadPhysics + UPPERCASE = true +[Cores] + WhatEver = Second +EOF + +test_expect_success 'similar section' 'cmp .git/config expect' + +test_expect_success 'replace with non-match' \ + 'git config core.penguin kingpin !blue' + +test_expect_success 'replace with non-match (actually matching)' \ + 'git config core.penguin "very blue" !kingpin' + +cat > expect << EOF +[core] + penguin = very blue + Movie = BadPhysics + UPPERCASE = true + penguin = kingpin +[Cores] + WhatEver = Second +EOF + +test_expect_success 'non-match result' 'cmp .git/config expect' + +cat > .git/config <<\EOF +[alpha] +bar = foo +[beta] +baz = multiple \ +lines +EOF + +test_expect_success 'unset with cont. lines' \ + 'git config --unset beta.baz' + +cat > expect <<\EOF +[alpha] +bar = foo +[beta] +EOF + +test_expect_success 'unset with cont. lines is correct' 'cmp .git/config expect' + +cat > .git/config << EOF +[beta] ; silly comment # another comment +noIndent= sillyValue ; 'nother silly comment + +# empty line + ; comment + haha ="beta" # last silly comment +haha = hello + haha = bello +[nextSection] noNewline = ouch +EOF + +cp .git/config .git/config2 + +test_expect_success 'multiple unset' \ + 'git config --unset-all beta.haha' + +cat > expect << EOF +[beta] ; silly comment # another comment +noIndent= sillyValue ; 'nother silly comment + +# empty line + ; comment +[nextSection] noNewline = ouch +EOF + +test_expect_success 'multiple unset is correct' 'cmp .git/config expect' + +mv .git/config2 .git/config + +test_expect_success '--replace-all' \ + 'git config --replace-all beta.haha gamma' + +cat > expect << EOF +[beta] ; silly comment # another comment +noIndent= sillyValue ; 'nother silly comment + +# empty line + ; comment + haha = gamma +[nextSection] noNewline = ouch +EOF + +test_expect_success 'all replaced' 'cmp .git/config expect' + +git config beta.haha alpha + +cat > expect << EOF +[beta] ; silly comment # another comment +noIndent= sillyValue ; 'nother silly comment + +# empty line + ; comment + haha = alpha +[nextSection] noNewline = ouch +EOF + +test_expect_success 'really mean test' 'cmp .git/config expect' + +git config nextsection.nonewline wow + +cat > expect << EOF +[beta] ; silly comment # another comment +noIndent= sillyValue ; 'nother silly comment + +# empty line + ; comment + haha = alpha +[nextSection] + nonewline = wow +EOF + +test_expect_success 'really really mean test' 'cmp .git/config expect' + +test_expect_success 'get value' 'test alpha = $(git config beta.haha)' +git config --unset beta.haha + +cat > expect << EOF +[beta] ; silly comment # another comment +noIndent= sillyValue ; 'nother silly comment + +# empty line + ; comment +[nextSection] + nonewline = wow +EOF + +test_expect_success 'unset' 'cmp .git/config expect' + +git config nextsection.NoNewLine "wow2 for me" "for me$" + +cat > expect << EOF +[beta] ; silly comment # another comment +noIndent= sillyValue ; 'nother silly comment + +# empty line + ; comment +[nextSection] + nonewline = wow + NoNewLine = wow2 for me +EOF + +test_expect_success 'multivar' 'cmp .git/config expect' + +test_expect_success 'non-match' \ + 'git config --get nextsection.nonewline !for' + +test_expect_success 'non-match value' \ + 'test wow = $(git config --get nextsection.nonewline !for)' + +test_expect_success 'ambiguous get' ' + test_must_fail git config --get nextsection.nonewline +' + +test_expect_success 'get multivar' \ + 'git config --get-all nextsection.nonewline' + +git config nextsection.nonewline "wow3" "wow$" + +cat > expect << EOF +[beta] ; silly comment # another comment +noIndent= sillyValue ; 'nother silly comment + +# empty line + ; comment +[nextSection] + nonewline = wow3 + NoNewLine = wow2 for me +EOF + +test_expect_success 'multivar replace' 'cmp .git/config expect' + +test_expect_success 'ambiguous value' ' + test_must_fail git config nextsection.nonewline +' + +test_expect_success 'ambiguous unset' ' + test_must_fail git config --unset nextsection.nonewline +' + +test_expect_success 'invalid unset' ' + test_must_fail git config --unset somesection.nonewline +' + +git config --unset nextsection.nonewline "wow3$" + +cat > expect << EOF +[beta] ; silly comment # another comment +noIndent= sillyValue ; 'nother silly comment + +# empty line + ; comment +[nextSection] + NoNewLine = wow2 for me +EOF + +test_expect_success 'multivar unset' 'cmp .git/config expect' + +test_expect_success 'invalid key' 'test_must_fail git config inval.2key blabla' + +test_expect_success 'correct key' 'git config 123456.a123 987' + +test_expect_success 'hierarchical section' \ + 'git config Version.1.2.3eX.Alpha beta' + +cat > expect << EOF +[beta] ; silly comment # another comment +noIndent= sillyValue ; 'nother silly comment + +# empty line + ; comment +[nextSection] + NoNewLine = wow2 for me +[123456] + a123 = 987 +[Version "1.2.3eX"] + Alpha = beta +EOF + +test_expect_success 'hierarchical section value' 'cmp .git/config expect' + +cat > expect << EOF +beta.noindent=sillyValue +nextsection.nonewline=wow2 for me +123456.a123=987 +version.1.2.3eX.alpha=beta +EOF + +test_expect_success 'working --list' \ + 'git config --list > output && cmp output expect' + +cat > expect << EOF +beta.noindent sillyValue +nextsection.nonewline wow2 for me +EOF + +test_expect_success '--get-regexp' \ + 'git config --get-regexp in > output && cmp output expect' + +git config --add nextsection.nonewline "wow4 for you" + +cat > expect << EOF +wow2 for me +wow4 for you +EOF + +test_expect_success '--add' \ + 'git config --get-all nextsection.nonewline > output && cmp output expect' + +cat > .git/config << EOF +[novalue] + variable +[emptyvalue] + variable = +EOF + +test_expect_success 'get variable with no value' \ + 'git config --get novalue.variable ^$' + +test_expect_success 'get variable with empty value' \ + 'git config --get emptyvalue.variable ^$' + +echo novalue.variable > expect + +test_expect_success 'get-regexp variable with no value' \ + 'git config --get-regexp novalue > output && + cmp output expect' + +echo 'emptyvalue.variable ' > expect + +test_expect_success 'get-regexp variable with empty value' \ + 'git config --get-regexp emptyvalue > output && + cmp output expect' + +echo true > expect + +test_expect_success 'get bool variable with no value' \ + 'git config --bool novalue.variable > output && + cmp output expect' + +echo false > expect + +test_expect_success 'get bool variable with empty value' \ + 'git config --bool emptyvalue.variable > output && + cmp output expect' + +git config > output 2>&1 + +test_expect_success 'no arguments, but no crash' \ + "test $? = 129 && grep usage output" + +cat > .git/config << EOF +[a.b] + c = d +EOF + +git config a.x y + +cat > expect << EOF +[a.b] + c = d +[a] + x = y +EOF + +test_expect_success 'new section is partial match of another' 'cmp .git/config expect' + +git config b.x y +git config a.b c + +cat > expect << EOF +[a.b] + c = d +[a] + x = y + b = c +[b] + x = y +EOF + +test_expect_success 'new variable inserts into proper section' 'cmp .git/config expect' + +test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' \ + 'git config --file non-existing-config -l; test $? != 0' + +cat > other-config << EOF +[ein] + bahn = strasse +EOF + +cat > expect << EOF +ein.bahn=strasse +EOF + +GIT_CONFIG=other-config git config -l > output + +test_expect_success 'alternative GIT_CONFIG' 'cmp output expect' + +test_expect_success 'alternative GIT_CONFIG (--file)' \ + 'git config --file other-config -l > output && cmp output expect' + +GIT_CONFIG=other-config git config anwohner.park ausweis + +cat > expect << EOF +[ein] + bahn = strasse +[anwohner] + park = ausweis +EOF + +test_expect_success '--set in alternative GIT_CONFIG' 'cmp other-config expect' + +cat > .git/config << EOF +# Hallo + #Bello +[branch "eins"] + x = 1 +[branch.eins] + y = 1 + [branch "1 234 blabl/a"] +weird +EOF + +test_expect_success "rename section" \ + "git config --rename-section branch.eins branch.zwei" + +cat > expect << EOF +# Hallo + #Bello +[branch "zwei"] + x = 1 +[branch "zwei"] + y = 1 + [branch "1 234 blabl/a"] +weird +EOF + +test_expect_success "rename succeeded" "test_cmp expect .git/config" + +test_expect_success "rename non-existing section" ' + test_must_fail git config --rename-section \ + branch."world domination" branch.drei +' + +test_expect_success "rename succeeded" "test_cmp expect .git/config" + +test_expect_success "rename another section" \ + 'git config --rename-section branch."1 234 blabl/a" branch.drei' + +cat > expect << EOF +# Hallo + #Bello +[branch "zwei"] + x = 1 +[branch "zwei"] + y = 1 +[branch "drei"] +weird +EOF + +test_expect_success "rename succeeded" "test_cmp expect .git/config" + +cat >> .git/config << EOF + [branch "zwei"] a = 1 [branch "vier"] +EOF + +test_expect_success "remove section" "git config --remove-section branch.zwei" + +cat > expect << EOF +# Hallo + #Bello +[branch "drei"] +weird +EOF + +test_expect_success "section was removed properly" \ + "test_cmp expect .git/config" + +rm .git/config + +cat > expect << EOF +[gitcvs] + enabled = true + dbname = %Ggitcvs2.%a.%m.sqlite +[gitcvs "ext"] + dbname = %Ggitcvs1.%a.%m.sqlite +EOF + +test_expect_success 'section ending' ' + + git config gitcvs.enabled true && + git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite && + git config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite && + cmp .git/config expect + +' + +test_expect_success numbers ' + + git config kilo.gram 1k && + git config mega.ton 1m && + k=$(git config --int --get kilo.gram) && + test z1024 = "z$k" && + m=$(git config --int --get mega.ton) && + test z1048576 = "z$m" +' + +cat > expect <<EOF +fatal: bad config value for 'aninvalid.unit' in .git/config +EOF + +test_expect_success 'invalid unit' ' + + git config aninvalid.unit "1auto" && + s=$(git config aninvalid.unit) && + test "z1auto" = "z$s" && + if git config --int --get aninvalid.unit 2>actual + then + echo config should have failed + false + fi && + cmp actual expect +' + +cat > expect << EOF +true +false +true +false +true +false +true +false +EOF + +test_expect_success bool ' + + git config bool.true1 01 && + git config bool.true2 -1 && + git config bool.true3 YeS && + git config bool.true4 true && + git config bool.false1 000 && + git config bool.false2 "" && + git config bool.false3 nO && + git config bool.false4 FALSE && + rm -f result && + for i in 1 2 3 4 + do + git config --bool --get bool.true$i >>result + git config --bool --get bool.false$i >>result + done && + cmp expect result' + +test_expect_success 'invalid bool (--get)' ' + + git config bool.nobool foobar && + test_must_fail git config --bool --get bool.nobool' + +test_expect_success 'invalid bool (set)' ' + + test_must_fail git config --bool bool.nobool foobar' + +rm .git/config + +cat > expect <<\EOF +[bool] + true1 = true + true2 = true + true3 = true + true4 = true + false1 = false + false2 = false + false3 = false + false4 = false +EOF + +test_expect_success 'set --bool' ' + + git config --bool bool.true1 01 && + git config --bool bool.true2 -1 && + git config --bool bool.true3 YeS && + git config --bool bool.true4 true && + git config --bool bool.false1 000 && + git config --bool bool.false2 "" && + git config --bool bool.false3 nO && + git config --bool bool.false4 FALSE && + cmp expect .git/config' + +rm .git/config + +cat > expect <<\EOF +[int] + val1 = 1 + val2 = -1 + val3 = 5242880 +EOF + +test_expect_success 'set --int' ' + + git config --int int.val1 01 && + git config --int int.val2 -1 && + git config --int int.val3 5m && + cmp expect .git/config' + +rm .git/config + +cat >expect <<\EOF +[bool] + true1 = true + true2 = true + false1 = false + false2 = false +[int] + int1 = 0 + int2 = 1 + int3 = -1 +EOF + +test_expect_success 'get --bool-or-int' ' + ( + echo "[bool]" + echo true1 + echo true2 = true + echo false = false + echo "[int]" + echo int1 = 0 + echo int2 = 1 + echo int3 = -1 + ) >>.git/config && + test $(git config --bool-or-int bool.true1) = true && + test $(git config --bool-or-int bool.true2) = true && + test $(git config --bool-or-int bool.false) = false && + test $(git config --bool-or-int int.int1) = 0 && + test $(git config --bool-or-int int.int2) = 1 && + test $(git config --bool-or-int int.int3) = -1 + +' + +rm .git/config +cat >expect <<\EOF +[bool] + true1 = true + false1 = false + true2 = true + false2 = false +[int] + int1 = 0 + int2 = 1 + int3 = -1 +EOF + +test_expect_success 'set --bool-or-int' ' + git config --bool-or-int bool.true1 true && + git config --bool-or-int bool.false1 false && + git config --bool-or-int bool.true2 yes && + git config --bool-or-int bool.false2 no && + git config --bool-or-int int.int1 0 && + git config --bool-or-int int.int2 1 && + git config --bool-or-int int.int3 -1 && + test_cmp expect .git/config +' + +rm .git/config + +git config quote.leading " test" +git config quote.ending "test " +git config quote.semicolon "test;test" +git config quote.hash "test#test" + +cat > expect << EOF +[quote] + leading = " test" + ending = "test " + semicolon = "test;test" + hash = "test#test" +EOF + +test_expect_success 'quoting' 'cmp .git/config expect' + +test_expect_success 'key with newline' ' + test_must_fail git config "key.with +newline" 123' + +test_expect_success 'value with newline' 'git config key.sub value.with\\\ +newline' + +cat > .git/config <<\EOF +[section] + ; comment \ + continued = cont\ +inued + noncont = not continued ; \ + quotecont = "cont;\ +inued" +EOF + +cat > expect <<\EOF +section.continued=continued +section.noncont=not continued +section.quotecont=cont;inued +EOF + +git config --list > result + +test_expect_success 'value continued on next line' 'cmp result expect' + +cat > .git/config <<\EOF +[section "sub=section"] + val1 = foo=bar + val2 = foo\nbar + val3 = \n\n + val4 = + val5 +EOF + +cat > expect <<\EOF +section.sub=section.val1 +foo=barQsection.sub=section.val2 +foo +barQsection.sub=section.val3 + + +Qsection.sub=section.val4 +Qsection.sub=section.val5Q +EOF + +git config --null --list | perl -pe 'y/\000/Q/' > result +echo >>result + +test_expect_success '--null --list' 'cmp result expect' + +git config --null --get-regexp 'val[0-9]' | perl -pe 'y/\000/Q/' > result +echo >>result + +test_expect_success '--null --get-regexp' 'cmp result expect' + +test_expect_success 'symlinked configuration' ' + + ln -s notyet myconfig && + GIT_CONFIG=myconfig git config test.frotz nitfol && + test -h myconfig && + test -f notyet && + test "z$(GIT_CONFIG=notyet git config test.frotz)" = znitfol && + GIT_CONFIG=myconfig git config test.xyzzy rezrov && + test -h myconfig && + test -f notyet && + test "z$(GIT_CONFIG=notyet git config test.frotz)" = znitfol && + test "z$(GIT_CONFIG=notyet git config test.xyzzy)" = zrezrov + +' + +test_done diff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh new file mode 100755 index 0000000000..dc85e8b60a --- /dev/null +++ b/t/t1301-shared-repo.sh @@ -0,0 +1,124 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes Schindelin +# + +test_description='Test shared repository initialization' + +. ./test-lib.sh + +# User must have read permissions to the repo -> failure on --shared=0400 +test_expect_success 'shared = 0400 (faulty permission u-w)' ' + mkdir sub && ( + cd sub && git init --shared=0400 + ) + ret="$?" + rm -rf sub + test $ret != "0" +' + +for u in 002 022 +do + test_expect_success "shared=1 does not clear bits preset by umask $u" ' + mkdir sub && ( + cd sub && + umask $u && + git init --shared=1 && + test 1 = "$(git config core.sharedrepository)" + ) && + actual=$(ls -l sub/.git/HEAD) + case "$actual" in + -rw-rw-r--*) + : happy + ;; + *) + echo Oops, .git/HEAD is not 0664 but $actual + false + ;; + esac + ' + rm -rf sub +done + +test_expect_success 'shared=all' ' + mkdir sub && + cd sub && + git init --shared=all && + test 2 = $(git config core.sharedrepository) +' + +test_expect_success 'update-server-info honors core.sharedRepository' ' + : > a1 && + git add a1 && + test_tick && + git commit -m a1 && + umask 0277 && + git update-server-info && + actual="$(ls -l .git/info/refs)" && + case "$actual" in + -r--r--r--*) + : happy + ;; + *) + echo Oops, .git/info/refs is not 0444 + false + ;; + esac +' + +for u in 0660:rw-rw---- \ + 0640:rw-r----- \ + 0600:rw------- \ + 0666:rw-rw-rw- \ + 0664:rw-rw-r-- +do + x=$(expr "$u" : ".*:\([rw-]*\)") && + y=$(echo "$x" | sed -e "s/w/-/g") && + u=$(expr "$u" : "\([0-7]*\)") && + git config core.sharedrepository "$u" && + umask 0277 && + + test_expect_success "shared = $u ($y) ro" ' + + rm -f .git/info/refs && + git update-server-info && + actual="$(ls -l .git/info/refs)" && + actual=${actual%% *} && + test "x$actual" = "x-$y" || { + ls -lt .git/info + false + } + ' + + umask 077 && + test_expect_success "shared = $u ($x) rw" ' + + rm -f .git/info/refs && + git update-server-info && + actual="$(ls -l .git/info/refs)" && + actual=${actual%% *} && + test "x$actual" = "x-$x" || { + ls -lt .git/info + false + } + + ' + +done + +test_expect_success 'git reflog expire honors core.sharedRepository' ' + git config core.sharedRepository group && + git reflog expire --all && + actual="$(ls -l .git/logs/refs/heads/master)" && + case "$actual" in + -rw-rw-*) + : happy + ;; + *) + echo Ooops, .git/logs/refs/heads/master is not 0662 [$actual] + false + ;; + esac +' + +test_done diff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh new file mode 100755 index 0000000000..8d305b4372 --- /dev/null +++ b/t/t1302-repo-version.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# +# Copyright (c) 2007 Nguyá»…n Thái Ngá»c Duy +# + +test_description='Test repository version check' + +. ./test-lib.sh + +cat >test.patch <<EOF +diff --git a/test.txt b/test.txt +new file mode 100644 +--- /dev/null ++++ b/test.txt +@@ -0,0 +1 @@ ++123 +EOF + +test_create_repo "test" +test_create_repo "test2" + +GIT_CONFIG=test2/.git/config git config core.repositoryformatversion 99 || exit 1 + +test_expect_success 'gitdir selection on normal repos' ' + (test "$(git config core.repositoryformatversion)" = 0 && + cd test && + test "$(git config core.repositoryformatversion)" = 0)' + +# Make sure it would stop at test2, not trash +test_expect_success 'gitdir selection on unsupported repo' ' + (cd test2 && + test "$(git config core.repositoryformatversion)" = 99)' + +test_expect_success 'gitdir not required mode' ' + (git apply --stat test.patch && + cd test && git apply --stat ../test.patch && + cd ../test2 && git apply --stat ../test.patch)' + +test_expect_success 'gitdir required mode on normal repos' ' + (git apply --check --index test.patch && + cd test && git apply --check --index ../test.patch)' + +test_expect_success 'gitdir required mode on unsupported repo' ' + (cd test2 && test_must_fail git apply --check --index ../test.patch) +' + +test_done diff --git a/t/t1303-wacky-config.sh b/t/t1303-wacky-config.sh new file mode 100755 index 0000000000..f98f4c5179 --- /dev/null +++ b/t/t1303-wacky-config.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +test_description='Test wacky input to git config' +. ./test-lib.sh + +setup() { + (printf "[section]\n" && + printf " key = foo") >.git/config +} + +check() { + echo "$2" >expected + git config --get "$1" >actual + test_cmp actual expected +} + +test_expect_success 'modify same key' ' + setup && + git config section.key bar && + check section.key bar +' + +test_expect_success 'add key in same section' ' + setup && + git config section.other bar && + check section.key foo && + check section.other bar +' + +test_expect_success 'add key in different section' ' + setup && + git config section2.key bar && + check section.key foo && + check section2.key bar +' + +SECTION="test.q\"s\\sq'sp e.key" +test_expect_success 'make sure git-config escapes section names properly' ' + git config "$SECTION" bar && + check "$SECTION" bar +' + +test_done diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh new file mode 100755 index 0000000000..b31e4b1ac6 --- /dev/null +++ b/t/t1400-update-ref.sh @@ -0,0 +1,270 @@ +#!/bin/sh +# +# Copyright (c) 2006 Shawn Pearce +# + +test_description='Test git update-ref and basic ref logging' +. ./test-lib.sh + +Z=0000000000000000000000000000000000000000 + +test_expect_success setup ' + + for name in A B C D E F + do + test_tick && + T=$(git write-tree) && + sha1=$(echo $name | git commit-tree $T) && + eval $name=$sha1 + done + +' + +m=refs/heads/master +n_dir=refs/heads/gu +n=$n_dir/fixes + +test_expect_success \ + "create $m" \ + "git update-ref $m $A && + test $A"' = $(cat .git/'"$m"')' +test_expect_success \ + "create $m" \ + "git update-ref $m $B $A && + test $B"' = $(cat .git/'"$m"')' +test_expect_success "fail to delete $m with stale ref" ' + test_must_fail git update-ref -d $m $A && + test $B = "$(cat .git/$m)" +' +test_expect_success "delete $m" ' + git update-ref -d $m $B && + ! test -f .git/$m +' +rm -f .git/$m + +test_expect_success "delete $m without oldvalue verification" " + git update-ref $m $A && + test $A = \$(cat .git/$m) && + git update-ref -d $m && + ! test -f .git/$m +" +rm -f .git/$m + +test_expect_success \ + "fail to create $n" \ + "touch .git/$n_dir + git update-ref $n $A >out 2>err"' + test $? != 0' +rm -f .git/$n_dir out err + +test_expect_success \ + "create $m (by HEAD)" \ + "git update-ref HEAD $A && + test $A"' = $(cat .git/'"$m"')' +test_expect_success \ + "create $m (by HEAD)" \ + "git update-ref HEAD $B $A && + test $B"' = $(cat .git/'"$m"')' +test_expect_success "fail to delete $m (by HEAD) with stale ref" ' + test_must_fail git update-ref -d HEAD $A && + test $B = $(cat .git/$m) +' +test_expect_success "delete $m (by HEAD)" ' + git update-ref -d HEAD $B && + ! test -f .git/$m +' +rm -f .git/$m + +test_expect_success '(not) create HEAD with old sha1' " + test_must_fail git update-ref HEAD $A $B +" +test_expect_success "(not) prior created .git/$m" " + ! test -f .git/$m +" +rm -f .git/$m + +test_expect_success \ + "create HEAD" \ + "git update-ref HEAD $A" +test_expect_success '(not) change HEAD with wrong SHA1' " + test_must_fail git update-ref HEAD $B $Z +" +test_expect_success "(not) changed .git/$m" " + ! test $B"' = $(cat .git/'"$m"') +' +rm -f .git/$m + +: a repository with working tree always has reflog these days... +: >.git/logs/refs/heads/master +test_expect_success \ + "create $m (logged by touch)" \ + 'GIT_COMMITTER_DATE="2005-05-26 23:30" \ + git update-ref HEAD '"$A"' -m "Initial Creation" && + test '"$A"' = $(cat .git/'"$m"')' +test_expect_success \ + "update $m (logged by touch)" \ + 'GIT_COMMITTER_DATE="2005-05-26 23:31" \ + git update-ref HEAD'" $B $A "'-m "Switch" && + test '"$B"' = $(cat .git/'"$m"')' +test_expect_success \ + "set $m (logged by touch)" \ + 'GIT_COMMITTER_DATE="2005-05-26 23:41" \ + git update-ref HEAD'" $A && + test $A"' = $(cat .git/'"$m"')' + +cat >expect <<EOF +$Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 Initial Creation +$A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150260 +0000 Switch +$B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000 +EOF +test_expect_success \ + "verifying $m's log" \ + "diff expect .git/logs/$m" +rm -rf .git/$m .git/logs expect + +test_expect_success \ + 'enable core.logAllRefUpdates' \ + 'git config core.logAllRefUpdates true && + test true = $(git config --bool --get core.logAllRefUpdates)' + +test_expect_success \ + "create $m (logged by config)" \ + 'GIT_COMMITTER_DATE="2005-05-26 23:32" \ + git update-ref HEAD'" $A "'-m "Initial Creation" && + test '"$A"' = $(cat .git/'"$m"')' +test_expect_success \ + "update $m (logged by config)" \ + 'GIT_COMMITTER_DATE="2005-05-26 23:33" \ + git update-ref HEAD'" $B $A "'-m "Switch" && + test '"$B"' = $(cat .git/'"$m"')' +test_expect_success \ + "set $m (logged by config)" \ + 'GIT_COMMITTER_DATE="2005-05-26 23:43" \ + git update-ref HEAD '"$A && + test $A"' = $(cat .git/'"$m"')' + +cat >expect <<EOF +$Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 +0000 Initial Creation +$A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 +0000 Switch +$B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 +0000 +EOF +test_expect_success \ + "verifying $m's log" \ + 'diff expect .git/logs/$m' +rm -f .git/$m .git/logs/$m expect + +git update-ref $m $D +cat >.git/logs/$m <<EOF +0000000000000000000000000000000000000000 $C $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 -0500 +$C $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150350 -0500 +$A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 -0500 +$F $Z $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150680 -0500 +$Z $E $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 -0500 +EOF + +ed="Thu, 26 May 2005 18:32:00 -0500" +gd="Thu, 26 May 2005 18:33:00 -0500" +ld="Thu, 26 May 2005 18:43:00 -0500" +test_expect_success \ + 'Query "master@{May 25 2005}" (before history)' \ + 'rm -f o e + git rev-parse --verify "master@{May 25 2005}" >o 2>e && + test '"$C"' = $(cat o) && + test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"' +test_expect_success \ + "Query master@{2005-05-25} (before history)" \ + 'rm -f o e + git rev-parse --verify master@{2005-05-25} >o 2>e && + test '"$C"' = $(cat o) && + echo test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"' +test_expect_success \ + 'Query "master@{May 26 2005 23:31:59}" (1 second before history)' \ + 'rm -f o e + git rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e && + test '"$C"' = $(cat o) && + test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)"' +test_expect_success \ + 'Query "master@{May 26 2005 23:32:00}" (exactly history start)' \ + 'rm -f o e + git rev-parse --verify "master@{May 26 2005 23:32:00}" >o 2>e && + test '"$C"' = $(cat o) && + test "" = "$(cat e)"' +test_expect_success \ + 'Query "master@{May 26 2005 23:32:30}" (first non-creation change)' \ + 'rm -f o e + git rev-parse --verify "master@{May 26 2005 23:32:30}" >o 2>e && + test '"$A"' = $(cat o) && + test "" = "$(cat e)"' +test_expect_success \ + 'Query "master@{2005-05-26 23:33:01}" (middle of history with gap)' \ + 'rm -f o e + git rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e && + test '"$B"' = $(cat o) && + test "warning: Log .git/logs/'"$m has gap after $gd"'." = "$(cat e)"' +test_expect_success \ + 'Query "master@{2005-05-26 23:38:00}" (middle of history)' \ + 'rm -f o e + git rev-parse --verify "master@{2005-05-26 23:38:00}" >o 2>e && + test '"$Z"' = $(cat o) && + test "" = "$(cat e)"' +test_expect_success \ + 'Query "master@{2005-05-26 23:43:00}" (exact end of history)' \ + 'rm -f o e + git rev-parse --verify "master@{2005-05-26 23:43:00}" >o 2>e && + test '"$E"' = $(cat o) && + test "" = "$(cat e)"' +test_expect_success \ + 'Query "master@{2005-05-28}" (past end of history)' \ + 'rm -f o e + git rev-parse --verify "master@{2005-05-28}" >o 2>e && + test '"$D"' = $(cat o) && + test "warning: Log .git/logs/'"$m unexpectedly ended on $ld"'." = "$(cat e)"' + + +rm -f .git/$m .git/logs/$m expect + +test_expect_success \ + 'creating initial files' \ + 'echo TEST >F && + git add F && + GIT_AUTHOR_DATE="2005-05-26 23:30" \ + GIT_COMMITTER_DATE="2005-05-26 23:30" git-commit -m add -a && + h_TEST=$(git rev-parse --verify HEAD) + echo The other day this did not work. >M && + echo And then Bob told me how to fix it. >>M && + echo OTHER >F && + GIT_AUTHOR_DATE="2005-05-26 23:41" \ + GIT_COMMITTER_DATE="2005-05-26 23:41" git-commit -F M -a && + h_OTHER=$(git rev-parse --verify HEAD) && + GIT_AUTHOR_DATE="2005-05-26 23:44" \ + GIT_COMMITTER_DATE="2005-05-26 23:44" git-commit --amend && + h_FIXED=$(git rev-parse --verify HEAD) && + echo Merged initial commit and a later commit. >M && + echo $h_TEST >.git/MERGE_HEAD && + GIT_AUTHOR_DATE="2005-05-26 23:45" \ + GIT_COMMITTER_DATE="2005-05-26 23:45" git-commit -F M && + h_MERGED=$(git rev-parse --verify HEAD) && + rm -f M' + +cat >expect <<EOF +$Z $h_TEST $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 commit (initial): add +$h_TEST $h_OTHER $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000 commit: The other day this did not work. +$h_OTHER $h_FIXED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151040 +0000 commit (amend): The other day this did not work. +$h_FIXED $h_MERGED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151100 +0000 commit (merge): Merged initial commit and a later commit. +EOF +test_expect_success \ + 'git-commit logged updates' \ + "diff expect .git/logs/$m" +unset h_TEST h_OTHER h_FIXED h_MERGED + +test_expect_success \ + 'git cat-file blob master:F (expect OTHER)' \ + 'test OTHER = $(git cat-file blob master:F)' +test_expect_success \ + 'git cat-file blob master@{2005-05-26 23:30}:F (expect TEST)' \ + 'test TEST = $(git cat-file blob "master@{2005-05-26 23:30}:F")' +test_expect_success \ + 'git cat-file blob master@{2005-05-26 23:42}:F (expect OTHER)' \ + 'test OTHER = $(git cat-file blob "master@{2005-05-26 23:42}:F")' + +test_done diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh new file mode 100755 index 0000000000..5b24f05573 --- /dev/null +++ b/t/t1410-reflog.sh @@ -0,0 +1,219 @@ +#!/bin/sh +# +# Copyright (c) 2007 Junio C Hamano +# + +test_description='Test prune and reflog expiration' +. ./test-lib.sh + +check_have () { + gaah= && + for N in "$@" + do + eval "o=\$$N" && git cat-file -t $o || { + echo Gaah $N + gaah=$N + break + } + done && + test -z "$gaah" +} + +check_fsck () { + output=$(git fsck --full) + case "$1" in + '') + test -z "$output" ;; + *) + echo "$output" | grep "$1" ;; + esac +} + +corrupt () { + aa=${1%??????????????????????????????????????} zz=${1#??} + mv .git/objects/$aa/$zz .git/$aa$zz +} + +recover () { + aa=${1%??????????????????????????????????????} zz=${1#??} + mkdir -p .git/objects/$aa + mv .git/$aa$zz .git/objects/$aa/$zz +} + +check_dont_have () { + gaah= && + for N in "$@" + do + eval "o=\$$N" + git cat-file -t $o && { + echo Gaah $N + gaah=$N + break + } + done + test -z "$gaah" +} + +test_expect_success setup ' + mkdir -p A/B && + echo rat >C && + echo ox >A/D && + echo tiger >A/B/E && + git add . && + + test_tick && git commit -m rabbit && + H=`git rev-parse --verify HEAD` && + A=`git rev-parse --verify HEAD:A` && + B=`git rev-parse --verify HEAD:A/B` && + C=`git rev-parse --verify HEAD:C` && + D=`git rev-parse --verify HEAD:A/D` && + E=`git rev-parse --verify HEAD:A/B/E` && + check_fsck && + + chmod +x C && + ( test "`git config --bool core.filemode`" != false || + echo executable >>C ) && + git add C && + test_tick && git commit -m dragon && + L=`git rev-parse --verify HEAD` && + check_fsck && + + rm -f C A/B/E && + echo snake >F && + echo horse >A/G && + git add F A/G && + test_tick && git commit -a -m sheep && + F=`git rev-parse --verify HEAD:F` && + G=`git rev-parse --verify HEAD:A/G` && + I=`git rev-parse --verify HEAD:A` && + J=`git rev-parse --verify HEAD` && + check_fsck && + + rm -f A/G && + test_tick && git commit -a -m monkey && + K=`git rev-parse --verify HEAD` && + check_fsck && + + check_have A B C D E F G H I J K L && + + git prune && + + check_have A B C D E F G H I J K L && + + check_fsck && + + loglen=$(wc -l <.git/logs/refs/heads/master) && + test $loglen = 4 +' + +test_expect_success rewind ' + test_tick && git reset --hard HEAD~2 && + test -f C && + test -f A/B/E && + ! test -f F && + ! test -f A/G && + + check_have A B C D E F G H I J K L && + + git prune && + + check_have A B C D E F G H I J K L && + + loglen=$(wc -l <.git/logs/refs/heads/master) && + test $loglen = 5 +' + +test_expect_success 'corrupt and check' ' + + corrupt $F && + check_fsck "missing blob $F" + +' + +test_expect_success 'reflog expire --dry-run should not touch reflog' ' + + git reflog expire --dry-run \ + --expire=$(($test_tick - 10000)) \ + --expire-unreachable=$(($test_tick - 10000)) \ + --stale-fix \ + --all && + + loglen=$(wc -l <.git/logs/refs/heads/master) && + test $loglen = 5 && + + check_fsck "missing blob $F" +' + +test_expect_success 'reflog expire' ' + + git reflog expire --verbose \ + --expire=$(($test_tick - 10000)) \ + --expire-unreachable=$(($test_tick - 10000)) \ + --stale-fix \ + --all && + + loglen=$(wc -l <.git/logs/refs/heads/master) && + test $loglen = 2 && + + check_fsck "dangling commit $K" +' + +test_expect_success 'prune and fsck' ' + + git prune && + check_fsck && + + check_have A B C D E H L && + check_dont_have F G I J K + +' + +test_expect_success 'recover and check' ' + + recover $F && + check_fsck "dangling blob $F" + +' + +test_expect_success 'delete' ' + echo 1 > C && + test_tick && + git commit -m rat C && + + echo 2 > C && + test_tick && + git commit -m ox C && + + echo 3 > C && + test_tick && + git commit -m tiger C && + + HEAD_entry_count=$(git reflog | wc -l) + master_entry_count=$(git reflog show master | wc -l) + + test $HEAD_entry_count = 5 && + test $master_entry_count = 5 && + + + git reflog delete master@{1} && + git reflog show master > output && + test $(($master_entry_count - 1)) = $(wc -l < output) && + test $HEAD_entry_count = $(git reflog | wc -l) && + ! grep ox < output && + + master_entry_count=$(wc -l < output) + + git reflog delete HEAD@{1} && + test $(($HEAD_entry_count -1)) = $(git reflog | wc -l) && + test $master_entry_count = $(git reflog show master | wc -l) && + + HEAD_entry_count=$(git reflog | wc -l) + + git reflog delete master@{07.04.2005.15:15:00.-0700} && + git reflog show master > output && + test $(($master_entry_count - 1)) = $(wc -l < output) && + ! grep dragon < output + +' + +test_done diff --git a/t/t1420-lost-found.sh b/t/t1420-lost-found.sh new file mode 100755 index 0000000000..dc9e402c55 --- /dev/null +++ b/t/t1420-lost-found.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes E. Schindelin +# + +test_description='Test fsck --lost-found' +. ./test-lib.sh + +test_expect_success setup ' + git config core.logAllRefUpdates 0 && + : > file1 && + git add file1 && + test_tick && + git commit -m initial && + echo 1 > file1 && + echo 2 > file2 && + git add file1 file2 && + test_tick && + git commit -m second && + echo 3 > file3 && + git add file3 +' + +test_expect_success 'lost and found something' ' + git rev-parse HEAD > lost-commit && + git rev-parse :file3 > lost-other && + test_tick && + git reset --hard HEAD^ && + git fsck --lost-found && + test 2 = $(ls .git/lost-found/*/* | wc -l) && + test -f .git/lost-found/commit/$(cat lost-commit) && + test -f .git/lost-found/other/$(cat lost-other) +' + +test_done diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh new file mode 100755 index 0000000000..85da4caa7e --- /dev/null +++ b/t/t1500-rev-parse.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +test_description='test git rev-parse' +. ./test-lib.sh + +test_rev_parse() { + name=$1 + shift + + test_expect_success "$name: is-bare-repository" \ + "test '$1' = \"\$(git rev-parse --is-bare-repository)\"" + shift + [ $# -eq 0 ] && return + + test_expect_success "$name: is-inside-git-dir" \ + "test '$1' = \"\$(git rev-parse --is-inside-git-dir)\"" + shift + [ $# -eq 0 ] && return + + test_expect_success "$name: is-inside-work-tree" \ + "test '$1' = \"\$(git rev-parse --is-inside-work-tree)\"" + shift + [ $# -eq 0 ] && return + + test_expect_success "$name: prefix" \ + "test '$1' = \"\$(git rev-parse --show-prefix)\"" + shift + [ $# -eq 0 ] && return +} + +# label is-bare is-inside-git is-inside-work prefix + +test_rev_parse toplevel false false true '' + +cd .git || exit 1 +test_rev_parse .git/ false true false '' +cd objects || exit 1 +test_rev_parse .git/objects/ false true false '' +cd ../.. || exit 1 + +mkdir -p sub/dir || exit 1 +cd sub/dir || exit 1 +test_rev_parse subdirectory false false true sub/dir/ +cd ../.. || exit 1 + +git config core.bare true +test_rev_parse 'core.bare = true' true false false + +git config --unset core.bare +test_rev_parse 'core.bare undefined' false false true + +mkdir work || exit 1 +cd work || exit 1 +GIT_DIR=../.git +GIT_CONFIG="$(pwd)"/../.git/config +export GIT_DIR GIT_CONFIG + +git config core.bare false +test_rev_parse 'GIT_DIR=../.git, core.bare = false' false false true '' + +git config core.bare true +test_rev_parse 'GIT_DIR=../.git, core.bare = true' true false false '' + +git config --unset core.bare +test_rev_parse 'GIT_DIR=../.git, core.bare undefined' false false true '' + +mv ../.git ../repo.git || exit 1 +GIT_DIR=../repo.git +GIT_CONFIG="$(pwd)"/../repo.git/config + +git config core.bare false +test_rev_parse 'GIT_DIR=../repo.git, core.bare = false' false false true '' + +git config core.bare true +test_rev_parse 'GIT_DIR=../repo.git, core.bare = true' true false false '' + +git config --unset core.bare +test_rev_parse 'GIT_DIR=../repo.git, core.bare undefined' false false true '' + +test_done diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh new file mode 100755 index 0000000000..2ee88d8a06 --- /dev/null +++ b/t/t1501-worktree.sh @@ -0,0 +1,117 @@ +#!/bin/sh + +test_description='test separate work tree' +. ./test-lib.sh + +test_rev_parse() { + name=$1 + shift + + test_expect_success "$name: is-bare-repository" \ + "test '$1' = \"\$(git rev-parse --is-bare-repository)\"" + shift + [ $# -eq 0 ] && return + + test_expect_success "$name: is-inside-git-dir" \ + "test '$1' = \"\$(git rev-parse --is-inside-git-dir)\"" + shift + [ $# -eq 0 ] && return + + test_expect_success "$name: is-inside-work-tree" \ + "test '$1' = \"\$(git rev-parse --is-inside-work-tree)\"" + shift + [ $# -eq 0 ] && return + + test_expect_success "$name: prefix" \ + "test '$1' = \"\$(git rev-parse --show-prefix)\"" + shift + [ $# -eq 0 ] && return +} + +mkdir -p work/sub/dir || exit 1 +mv .git repo.git || exit 1 + +say "core.worktree = relative path" +GIT_DIR=repo.git +GIT_CONFIG="$(pwd)"/$GIT_DIR/config +export GIT_DIR GIT_CONFIG +unset GIT_WORK_TREE +git config core.worktree ../work +test_rev_parse 'outside' false false false +cd work || exit 1 +GIT_DIR=../repo.git +GIT_CONFIG="$(pwd)"/$GIT_DIR/config +test_rev_parse 'inside' false false true '' +cd sub/dir || exit 1 +GIT_DIR=../../../repo.git +GIT_CONFIG="$(pwd)"/$GIT_DIR/config +test_rev_parse 'subdirectory' false false true sub/dir/ +cd ../../.. || exit 1 + +say "core.worktree = absolute path" +GIT_DIR=$(pwd)/repo.git +GIT_CONFIG=$GIT_DIR/config +git config core.worktree "$(pwd)/work" +test_rev_parse 'outside' false false false +cd work || exit 1 +test_rev_parse 'inside' false false true '' +cd sub/dir || exit 1 +test_rev_parse 'subdirectory' false false true sub/dir/ +cd ../../.. || exit 1 + +say "GIT_WORK_TREE=relative path (override core.worktree)" +GIT_DIR=$(pwd)/repo.git +GIT_CONFIG=$GIT_DIR/config +git config core.worktree non-existent +GIT_WORK_TREE=work +export GIT_WORK_TREE +test_rev_parse 'outside' false false false +cd work || exit 1 +GIT_WORK_TREE=. +test_rev_parse 'inside' false false true '' +cd sub/dir || exit 1 +GIT_WORK_TREE=../.. +test_rev_parse 'subdirectory' false false true sub/dir/ +cd ../../.. || exit 1 + +mv work repo.git/work + +say "GIT_WORK_TREE=absolute path, work tree below git dir" +GIT_DIR=$(pwd)/repo.git +GIT_CONFIG=$GIT_DIR/config +GIT_WORK_TREE=$(pwd)/repo.git/work +test_rev_parse 'outside' false false false +cd repo.git || exit 1 +test_rev_parse 'in repo.git' false true false +cd objects || exit 1 +test_rev_parse 'in repo.git/objects' false true false +cd ../work || exit 1 +test_rev_parse 'in repo.git/work' false true true '' +cd sub/dir || exit 1 +test_rev_parse 'in repo.git/sub/dir' false true true sub/dir/ +cd ../../../.. || exit 1 + +test_expect_success 'repo finds its work tree' ' + (cd repo.git && + : > work/sub/dir/untracked && + test sub/dir/untracked = "$(git ls-files --others)") +' + +test_expect_success 'repo finds its work tree from work tree, too' ' + (cd repo.git/work/sub/dir && + : > tracked && + git --git-dir=../../.. add tracked && + cd ../../.. && + test sub/dir/tracked = "$(git ls-files)") +' + +test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' ' + cd repo.git/work/sub/dir && + GIT_DIR=../../.. GIT_WORK_TREE=../.. GIT_PAGER= \ + git diff --exit-code tracked && + echo changed > tracked && + ! GIT_DIR=../../.. GIT_WORK_TREE=../.. GIT_PAGER= \ + git diff --exit-code tracked +' + +test_done diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh new file mode 100755 index 0000000000..997002d4c4 --- /dev/null +++ b/t/t1502-rev-parse-parseopt.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +test_description='test git rev-parse --parseopt' +. ./test-lib.sh + +cat > expect.err <<EOF +usage: some-command [options] <args>... + + some-command does foo and bar! + + -h, --help show the help + --foo some nifty option --foo + --bar ... some cool option --bar with an argument + +An option group Header + -C[...] option C with an optional argument + +Extras + --extra1 line above used to cause a segfault but no longer does + +EOF + +test_expect_success 'test --parseopt help output' ' + git rev-parse --parseopt -- -h 2> output.err <<EOF +some-command [options] <args>... + +some-command does foo and bar! +-- +h,help show the help + +foo some nifty option --foo +bar= some cool option --bar with an argument + + An option group Header +C? option C with an optional argument + +Extras +extra1 line above used to cause a segfault but no longer does +EOF + test_cmp expect.err output.err +' + +test_done diff --git a/t/t1503-rev-parse-verify.sh b/t/t1503-rev-parse-verify.sh new file mode 100755 index 0000000000..95244c9bcf --- /dev/null +++ b/t/t1503-rev-parse-verify.sh @@ -0,0 +1,107 @@ +#!/bin/sh +# +# Copyright (c) 2008 Christian Couder +# +test_description='test git rev-parse --verify' + +exec </dev/null + +. ./test-lib.sh + +add_line_into_file() +{ + _line=$1 + _file=$2 + + if [ -f "$_file" ]; then + echo "$_line" >> $_file || return $? + MSG="Add <$_line> into <$_file>." + else + echo "$_line" > $_file || return $? + git add $_file || return $? + MSG="Create file <$_file> with <$_line> inside." + fi + + test_tick + git-commit --quiet -m "$MSG" $_file +} + +HASH1= +HASH2= +HASH3= +HASH4= + +test_expect_success 'set up basic repo with 1 file (hello) and 4 commits' ' + add_line_into_file "1: Hello World" hello && + HASH1=$(git rev-parse --verify HEAD) && + add_line_into_file "2: A new day for git" hello && + HASH2=$(git rev-parse --verify HEAD) && + add_line_into_file "3: Another new day for git" hello && + HASH3=$(git rev-parse --verify HEAD) && + add_line_into_file "4: Ciao for now" hello && + HASH4=$(git rev-parse --verify HEAD) +' + +test_expect_success 'works with one good rev' ' + rev_hash1=$(git rev-parse --verify $HASH1) && + test "$rev_hash1" = "$HASH1" && + rev_hash2=$(git rev-parse --verify $HASH2) && + test "$rev_hash2" = "$HASH2" && + rev_hash3=$(git rev-parse --verify $HASH3) && + test "$rev_hash3" = "$HASH3" && + rev_hash4=$(git rev-parse --verify $HASH4) && + test "$rev_hash4" = "$HASH4" && + rev_master=$(git rev-parse --verify master) && + test "$rev_master" = "$HASH4" && + rev_head=$(git rev-parse --verify HEAD) && + test "$rev_head" = "$HASH4" +' + +test_expect_success 'fails with any bad rev or many good revs' ' + test_must_fail git rev-parse --verify 2>error && + grep "single revision" error && + test_must_fail git rev-parse --verify foo 2>error && + grep "single revision" error && + test_must_fail git rev-parse --verify HEAD bar 2>error && + grep "single revision" error && + test_must_fail git rev-parse --verify baz HEAD 2>error && + grep "single revision" error && + test_must_fail git rev-parse --verify $HASH2 HEAD 2>error && + grep "single revision" error +' + +test_expect_success 'fails silently when using -q' ' + test_must_fail git rev-parse --verify --quiet 2>error && + test -z "$(cat error)" && + test_must_fail git rev-parse -q --verify foo 2>error && + test -z "$(cat error)" && + test_must_fail git rev-parse --verify -q HEAD bar 2>error && + test -z "$(cat error)" && + test_must_fail git rev-parse --quiet --verify baz HEAD 2>error && + test -z "$(cat error)" && + test_must_fail git rev-parse -q --verify $HASH2 HEAD 2>error && + test -z "$(cat error)" +' + +test_expect_success 'no stdout output on error' ' + test -z "$(git rev-parse --verify)" && + test -z "$(git rev-parse --verify foo)" && + test -z "$(git rev-parse --verify baz HEAD)" && + test -z "$(git rev-parse --verify HEAD bar)" && + test -z "$(git rev-parse --verify $HASH2 HEAD)" +' + +test_expect_success 'use --default' ' + git rev-parse --verify --default master && + git rev-parse --verify --default master HEAD && + git rev-parse --default master --verify && + git rev-parse --default master --verify HEAD && + git rev-parse --verify HEAD --default master && + test_must_fail git rev-parse --verify foo --default master && + test_must_fail git rev-parse --default HEAD --verify bar && + test_must_fail git rev-parse --verify --default HEAD baz && + test_must_fail git rev-parse --default foo --verify && + test_must_fail git rev-parse --verify --default bar +' + +test_done diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh new file mode 100755 index 0000000000..91b704a3a4 --- /dev/null +++ b/t/t1504-ceiling-dirs.sh @@ -0,0 +1,163 @@ +#!/bin/sh + +test_description='test GIT_CEILING_DIRECTORIES' +. ./test-lib.sh + +test_prefix() { + test_expect_success "$1" \ + "test '$2' = \"\$(git rev-parse --show-prefix)\"" +} + +test_fail() { + test_expect_code 128 "$1: prefix" \ + "git rev-parse --show-prefix" +} + +TRASH_ROOT="$(pwd)" +ROOT_PARENT=$(dirname "$TRASH_ROOT") + + +unset GIT_CEILING_DIRECTORIES +test_prefix no_ceil "" + +export GIT_CEILING_DIRECTORIES + +GIT_CEILING_DIRECTORIES="" +test_prefix ceil_empty "" + +GIT_CEILING_DIRECTORIES="$ROOT_PARENT" +test_prefix ceil_at_parent "" + +GIT_CEILING_DIRECTORIES="$ROOT_PARENT/" +test_prefix ceil_at_parent_slash "" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT" +test_prefix ceil_at_trash "" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/" +test_prefix ceil_at_trash_slash "" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub" +test_prefix ceil_at_sub "" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/" +test_prefix ceil_at_sub_slash "" + + +mkdir -p sub/dir || exit 1 +cd sub/dir || exit 1 + +unset GIT_CEILING_DIRECTORIES +test_prefix subdir_no_ceil "sub/dir/" + +export GIT_CEILING_DIRECTORIES + +GIT_CEILING_DIRECTORIES="" +test_prefix subdir_ceil_empty "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT" +test_fail subdir_ceil_at_trash + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/" +test_fail subdir_ceil_at_trash_slash + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub" +test_fail subdir_ceil_at_sub + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/" +test_fail subdir_ceil_at_sub_slash + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/dir" +test_prefix subdir_ceil_at_subdir "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/dir/" +test_prefix subdir_ceil_at_subdir_slash "sub/dir/" + + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/su" +test_prefix subdir_ceil_at_su "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/su/" +test_prefix subdir_ceil_at_su_slash "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/di" +test_prefix subdir_ceil_at_sub_di "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/di" +test_prefix subdir_ceil_at_sub_di_slash "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/subdi" +test_prefix subdir_ceil_at_subdi "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/subdi" +test_prefix subdir_ceil_at_subdi_slash "sub/dir/" + + +GIT_CEILING_DIRECTORIES="foo:$TRASH_ROOT/sub" +test_fail second_of_two + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub:bar" +test_fail first_of_two + +GIT_CEILING_DIRECTORIES="foo:$TRASH_ROOT/sub:bar" +test_fail second_of_three + + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub" +GIT_DIR=../../.git +export GIT_DIR +test_prefix git_dir_specified "" +unset GIT_DIR + + +cd ../.. || exit 1 +mkdir -p s/d || exit 1 +cd s/d || exit 1 + +unset GIT_CEILING_DIRECTORIES +test_prefix sd_no_ceil "s/d/" + +export GIT_CEILING_DIRECTORIES + +GIT_CEILING_DIRECTORIES="" +test_prefix sd_ceil_empty "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT" +test_fail sd_ceil_at_trash + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/" +test_fail sd_ceil_at_trash_slash + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s" +test_fail sd_ceil_at_s + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/" +test_fail sd_ceil_at_s_slash + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/d" +test_prefix sd_ceil_at_sd "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/d/" +test_prefix sd_ceil_at_sd_slash "s/d/" + + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/su" +test_prefix sd_ceil_at_su "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/su/" +test_prefix sd_ceil_at_su_slash "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/di" +test_prefix sd_ceil_at_s_di "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/di" +test_prefix sd_ceil_at_s_di_slash "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sdi" +test_prefix sd_ceil_at_sdi "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sdi" +test_prefix sd_ceil_at_sdi_slash "s/d/" + + +test_done diff --git a/t/t2000-checkout-cache-clash.sh b/t/t2000-checkout-cache-clash.sh new file mode 100755 index 0000000000..f7e1a735ec --- /dev/null +++ b/t/t2000-checkout-cache-clash.sh @@ -0,0 +1,51 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git checkout-index test. + +This test registers the following filesystem structure in the +cache: + + path0 - a file + path1/file1 - a file in a directory + +And then tries to checkout in a work tree that has the following: + + path0/file0 - a file in a directory + path1 - a file + +The git checkout-index command should fail when attempting to checkout +path0, finding it is occupied by a directory, and path1/file1, finding +path1 is occupied by a non-directory. With "-f" flag, it should remove +the conflicting paths and succeed. +' +. ./test-lib.sh + +date >path0 +mkdir path1 +date >path1/file1 + +test_expect_success \ + 'git update-index --add various paths.' \ + 'git update-index --add path0 path1/file1' + +rm -fr path0 path1 +mkdir path0 +date >path0/file0 +date >path1 + +test_expect_success \ + 'git checkout-index without -f should fail on conflicting work tree.' \ + 'test_must_fail git checkout-index -a' + +test_expect_success \ + 'git checkout-index with -f should succeed.' \ + 'git checkout-index -f -a' + +test_expect_success \ + 'git checkout-index conflicting paths.' \ + 'test -f path0 && test -d path1 && test -f path1/file1' + +test_done diff --git a/t/t2001-checkout-cache-clash.sh b/t/t2001-checkout-cache-clash.sh new file mode 100755 index 0000000000..ef007532b1 --- /dev/null +++ b/t/t2001-checkout-cache-clash.sh @@ -0,0 +1,86 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git checkout-index test. + +This test registers the following filesystem structure in the cache: + + path0/file0 - a file in a directory + path1/file1 - a file in a directory + +and attempts to check it out when the work tree has: + + path0/file0 - a file in a directory + path1 - a symlink pointing at "path0" + +Checkout cache should fail to extract path1/file1 because the leading +path path1 is occupied by a non-directory. With "-f" it should remove +the symlink path1 and create directory path1 and file path1/file1. +' +. ./test-lib.sh + +show_files() { + # show filesystem files, just [-dl] for type and name + find path? -ls | + sed -e 's/^[0-9]* * [0-9]* * \([-bcdl]\)[^ ]* *[0-9]* *[^ ]* *[^ ]* *[0-9]* [A-Z][a-z][a-z] [0-9][0-9] [^ ]* /fs: \1 /' + # what's in the cache, just mode and name + git ls-files --stage | + sed -e 's/^\([0-9]*\) [0-9a-f]* [0-3] /ca: \1 /' + # what's in the tree, just mode and name. + git ls-tree -r "$1" | + sed -e 's/^\([0-9]*\) [^ ]* [0-9a-f]* /tr: \1 /' +} + +mkdir path0 +date >path0/file0 +test_expect_success \ + 'git update-index --add path0/file0' \ + 'git update-index --add path0/file0' +test_expect_success \ + 'writing tree out with git write-tree' \ + 'tree1=$(git write-tree)' +test_debug 'show_files $tree1' + +mkdir path1 +date >path1/file1 +test_expect_success \ + 'git update-index --add path1/file1' \ + 'git update-index --add path1/file1' +test_expect_success \ + 'writing tree out with git write-tree' \ + 'tree2=$(git write-tree)' +test_debug 'show_files $tree2' + +rm -fr path1 +test_expect_success \ + 'read previously written tree and checkout.' \ + 'git read-tree -m $tree1 && git checkout-index -f -a' +test_debug 'show_files $tree1' + +ln -s path0 path1 +test_expect_success \ + 'git update-index --add a symlink.' \ + 'git update-index --add path1' +test_expect_success \ + 'writing tree out with git write-tree' \ + 'tree3=$(git write-tree)' +test_debug 'show_files $tree3' + +# Morten says "Got that?" here. +# Test begins. + +test_expect_success \ + 'read previously written tree and checkout.' \ + 'git read-tree $tree2 && git checkout-index -f -a' +test_debug 'show_files $tree2' + +test_expect_success \ + 'checking out conflicting path with -f' \ + 'test ! -h path0 && test -d path0 && + test ! -h path1 && test -d path1 && + test ! -h path0/file0 && test -f path0/file0 && + test ! -h path1/file1 && test -f path1/file1' + +test_done diff --git a/t/t2002-checkout-cache-u.sh b/t/t2002-checkout-cache-u.sh new file mode 100755 index 0000000000..70361c806e --- /dev/null +++ b/t/t2002-checkout-cache-u.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git checkout-index -u test. + +With -u flag, git checkout-index internally runs the equivalent of +git update-index --refresh on the checked out entry.' + +. ./test-lib.sh + +test_expect_success \ +'preparation' ' +echo frotz >path0 && +git update-index --add path0 && +t=$(git write-tree)' + +test_expect_success \ +'without -u, git checkout-index smudges stat information.' ' +rm -f path0 && +git read-tree $t && +git checkout-index -f -a && +test_must_fail git diff-files --exit-code' + +test_expect_success \ +'with -u, git checkout-index picks up stat information from new files.' ' +rm -f path0 && +git read-tree $t && +git checkout-index -u -f -a && +git diff-files --exit-code' + +test_done diff --git a/t/t2003-checkout-cache-mkdir.sh b/t/t2003-checkout-cache-mkdir.sh new file mode 100755 index 0000000000..71894b3743 --- /dev/null +++ b/t/t2003-checkout-cache-mkdir.sh @@ -0,0 +1,96 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git checkout-index --prefix test. + +This test makes sure that --prefix option works as advertised, and +also verifies that such leading path may contain symlinks, unlike +the GIT controlled paths. +' + +. ./test-lib.sh + +test_expect_success \ + 'setup' \ + 'mkdir path1 && + echo frotz >path0 && + echo rezrov >path1/file1 && + git update-index --add path0 path1/file1' + +test_expect_success \ + 'have symlink in place where dir is expected.' \ + 'rm -fr path0 path1 && + mkdir path2 && + ln -s path2 path1 && + git checkout-index -f -a && + test ! -h path1 && test -d path1 && + test -f path1/file1 && test ! -f path2/file1' + +test_expect_success \ + 'use --prefix=path2/' \ + 'rm -fr path0 path1 path2 && + mkdir path2 && + git checkout-index --prefix=path2/ -f -a && + test -f path2/path0 && + test -f path2/path1/file1 && + test ! -f path0 && + test ! -f path1/file1' + +test_expect_success \ + 'use --prefix=tmp-' \ + 'rm -fr path0 path1 path2 tmp* && + git checkout-index --prefix=tmp- -f -a && + test -f tmp-path0 && + test -f tmp-path1/file1 && + test ! -f path0 && + test ! -f path1/file1' + +test_expect_success \ + 'use --prefix=tmp- but with a conflicting file and dir' \ + 'rm -fr path0 path1 path2 tmp* && + echo nitfol >tmp-path1 && + mkdir tmp-path0 && + git checkout-index --prefix=tmp- -f -a && + test -f tmp-path0 && + test -f tmp-path1/file1 && + test ! -f path0 && + test ! -f path1/file1' + +# Linus fix #1 +test_expect_success \ + 'use --prefix=tmp/orary/ where tmp is a symlink' \ + 'rm -fr path0 path1 path2 tmp* && + mkdir tmp1 tmp1/orary && + ln -s tmp1 tmp && + git checkout-index --prefix=tmp/orary/ -f -a && + test -d tmp1/orary && + test -f tmp1/orary/path0 && + test -f tmp1/orary/path1/file1 && + test -h tmp' + +# Linus fix #2 +test_expect_success \ + 'use --prefix=tmp/orary- where tmp is a symlink' \ + 'rm -fr path0 path1 path2 tmp* && + mkdir tmp1 && + ln -s tmp1 tmp && + git checkout-index --prefix=tmp/orary- -f -a && + test -f tmp1/orary-path0 && + test -f tmp1/orary-path1/file1 && + test -h tmp' + +# Linus fix #3 +test_expect_success \ + 'use --prefix=tmp- where tmp-path1 is a symlink' \ + 'rm -fr path0 path1 path2 tmp* && + mkdir tmp1 && + ln -s tmp1 tmp-path1 && + git checkout-index --prefix=tmp- -f -a && + test -f tmp-path0 && + test ! -h tmp-path1 && + test -d tmp-path1 && + test -f tmp-path1/file1' + +test_done diff --git a/t/t2004-checkout-cache-temp.sh b/t/t2004-checkout-cache-temp.sh new file mode 100755 index 0000000000..39133b8c7a --- /dev/null +++ b/t/t2004-checkout-cache-temp.sh @@ -0,0 +1,212 @@ +#!/bin/sh +# +# Copyright (c) 2006 Shawn Pearce +# + +test_description='git checkout-index --temp test. + +With --temp flag, git checkout-index writes to temporary merge files +rather than the tracked path.' + +. ./test-lib.sh + +test_expect_success \ +'preparation' ' +mkdir asubdir && +echo tree1path0 >path0 && +echo tree1path1 >path1 && +echo tree1path3 >path3 && +echo tree1path4 >path4 && +echo tree1asubdir/path5 >asubdir/path5 && +git update-index --add path0 path1 path3 path4 asubdir/path5 && +t1=$(git write-tree) && +rm -f path* .merge_* out .git/index && +echo tree2path0 >path0 && +echo tree2path1 >path1 && +echo tree2path2 >path2 && +echo tree2path4 >path4 && +git update-index --add path0 path1 path2 path4 && +t2=$(git write-tree) && +rm -f path* .merge_* out .git/index && +echo tree2path0 >path0 && +echo tree3path1 >path1 && +echo tree3path2 >path2 && +echo tree3path3 >path3 && +git update-index --add path0 path1 path2 path3 && +t3=$(git write-tree)' + +test_expect_success \ +'checkout one stage 0 to temporary file' ' +rm -f path* .merge_* out .git/index && +git read-tree $t1 && +git checkout-index --temp -- path1 >out && +test $(wc -l <out) = 1 && +test $(cut "-d " -f2 out) = path1 && +p=$(cut "-d " -f1 out) && +test -f $p && +test $(cat $p) = tree1path1' + +test_expect_success \ +'checkout all stage 0 to temporary files' ' +rm -f path* .merge_* out .git/index && +git read-tree $t1 && +git checkout-index -a --temp >out && +test $(wc -l <out) = 5 && +for f in path0 path1 path3 path4 asubdir/path5 +do + test $(grep $f out | cut "-d " -f2) = $f && + p=$(grep $f out | cut "-d " -f1) && + test -f $p && + test $(cat $p) = tree1$f +done' + +test_expect_success \ +'prepare 3-way merge' ' +rm -f path* .merge_* out .git/index && +git read-tree -m $t1 $t2 $t3' + +test_expect_success \ +'checkout one stage 2 to temporary file' ' +rm -f path* .merge_* out && +git checkout-index --stage=2 --temp -- path1 >out && +test $(wc -l <out) = 1 && +test $(cut "-d " -f2 out) = path1 && +p=$(cut "-d " -f1 out) && +test -f $p && +test $(cat $p) = tree2path1' + +test_expect_success \ +'checkout all stage 2 to temporary files' ' +rm -f path* .merge_* out && +git checkout-index --all --stage=2 --temp >out && +test $(wc -l <out) = 3 && +for f in path1 path2 path4 +do + test $(grep $f out | cut "-d " -f2) = $f && + p=$(grep $f out | cut "-d " -f1) && + test -f $p && + test $(cat $p) = tree2$f +done' + +test_expect_success \ +'checkout all stages/one file to nothing' ' +rm -f path* .merge_* out && +git checkout-index --stage=all --temp -- path0 >out && +test $(wc -l <out) = 0' + +test_expect_success \ +'checkout all stages/one file to temporary files' ' +rm -f path* .merge_* out && +git checkout-index --stage=all --temp -- path1 >out && +test $(wc -l <out) = 1 && +test $(cut "-d " -f2 out) = path1 && +cut "-d " -f1 out | (read s1 s2 s3 && +test -f $s1 && +test -f $s2 && +test -f $s3 && +test $(cat $s1) = tree1path1 && +test $(cat $s2) = tree2path1 && +test $(cat $s3) = tree3path1)' + +test_expect_success \ +'checkout some stages/one file to temporary files' ' +rm -f path* .merge_* out && +git checkout-index --stage=all --temp -- path2 >out && +test $(wc -l <out) = 1 && +test $(cut "-d " -f2 out) = path2 && +cut "-d " -f1 out | (read s1 s2 s3 && +test $s1 = . && +test -f $s2 && +test -f $s3 && +test $(cat $s2) = tree2path2 && +test $(cat $s3) = tree3path2)' + +test_expect_success \ +'checkout all stages/all files to temporary files' ' +rm -f path* .merge_* out && +git checkout-index -a --stage=all --temp >out && +test $(wc -l <out) = 5' + +test_expect_success \ +'-- path0: no entry' ' +test x$(grep path0 out | cut "-d " -f2) = x' + +test_expect_success \ +'-- path1: all 3 stages' ' +test $(grep path1 out | cut "-d " -f2) = path1 && +grep path1 out | cut "-d " -f1 | (read s1 s2 s3 && +test -f $s1 && +test -f $s2 && +test -f $s3 && +test $(cat $s1) = tree1path1 && +test $(cat $s2) = tree2path1 && +test $(cat $s3) = tree3path1)' + +test_expect_success \ +'-- path2: no stage 1, have stage 2 and 3' ' +test $(grep path2 out | cut "-d " -f2) = path2 && +grep path2 out | cut "-d " -f1 | (read s1 s2 s3 && +test $s1 = . && +test -f $s2 && +test -f $s3 && +test $(cat $s2) = tree2path2 && +test $(cat $s3) = tree3path2)' + +test_expect_success \ +'-- path3: no stage 2, have stage 1 and 3' ' +test $(grep path3 out | cut "-d " -f2) = path3 && +grep path3 out | cut "-d " -f1 | (read s1 s2 s3 && +test -f $s1 && +test $s2 = . && +test -f $s3 && +test $(cat $s1) = tree1path3 && +test $(cat $s3) = tree3path3)' + +test_expect_success \ +'-- path4: no stage 3, have stage 1 and 3' ' +test $(grep path4 out | cut "-d " -f2) = path4 && +grep path4 out | cut "-d " -f1 | (read s1 s2 s3 && +test -f $s1 && +test -f $s2 && +test $s3 = . && +test $(cat $s1) = tree1path4 && +test $(cat $s2) = tree2path4)' + +test_expect_success \ +'-- asubdir/path5: no stage 2 and 3 have stage 1' ' +test $(grep asubdir/path5 out | cut "-d " -f2) = asubdir/path5 && +grep asubdir/path5 out | cut "-d " -f1 | (read s1 s2 s3 && +test -f $s1 && +test $s2 = . && +test $s3 = . && +test $(cat $s1) = tree1asubdir/path5)' + +test_expect_success \ +'checkout --temp within subdir' ' +(cd asubdir && + git checkout-index -a --stage=all >out && + test $(wc -l <out) = 1 && + test $(grep path5 out | cut "-d " -f2) = path5 && + grep path5 out | cut "-d " -f1 | (read s1 s2 s3 && + test -f ../$s1 && + test $s2 = . && + test $s3 = . && + test $(cat ../$s1) = tree1asubdir/path5) +)' + +test_expect_success \ +'checkout --temp symlink' ' +rm -f path* .merge_* out .git/index && +ln -s b a && +git update-index --add a && +t4=$(git write-tree) && +rm -f .git/index && +git read-tree $t4 && +git checkout-index --temp -a >out && +test $(wc -l <out) = 1 && +test $(cut "-d " -f2 out) = a && +p=$(cut "-d " -f1 out) && +test -f $p && +test $(cat $p) = b' + +test_done diff --git a/t/t2005-checkout-index-symlinks.sh b/t/t2005-checkout-index-symlinks.sh new file mode 100755 index 0000000000..a84c5a6af9 --- /dev/null +++ b/t/t2005-checkout-index-symlinks.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes Sixt +# + +test_description='git checkout-index on filesystem w/o symlinks test. + +This tests that git checkout-index creates a symbolic link as a plain +file if core.symlinks is false.' + +. ./test-lib.sh + +test_expect_success \ +'preparation' ' +git config core.symlinks false && +l=$(echo -n file | git-hash-object -t blob -w --stdin) && +echo "120000 $l symlink" | git update-index --index-info' + +test_expect_success \ +'the checked-out symlink must be a file' ' +git checkout-index symlink && +test -f symlink' + +test_expect_success \ +'the file must be the blob we added during the setup' ' +test "$(git-hash-object -t blob symlink)" = $l' + +test_done diff --git a/t/t2007-checkout-symlink.sh b/t/t2007-checkout-symlink.sh new file mode 100755 index 0000000000..0526fce163 --- /dev/null +++ b/t/t2007-checkout-symlink.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# +# Copyright (c) 2007 Junio C Hamano + +test_description='git checkout to switch between branches with symlink<->dir' + +. ./test-lib.sh + +test_expect_success setup ' + + mkdir frotz && + echo hello >frotz/filfre && + git add frotz/filfre && + test_tick && + git commit -m "master has file frotz/filfre" && + + git branch side && + + echo goodbye >nitfol && + git add nitfol + test_tick && + git commit -m "master adds file nitfol" && + + git checkout side && + + git rm --cached frotz/filfre && + mv frotz xyzzy && + ln -s xyzzy frotz && + git add xyzzy/filfre frotz && + test_tick && + git commit -m "side moves frotz/ to xyzzy/ and adds frotz->xyzzy/" + +' + +test_expect_success 'switch from symlink to dir' ' + + git checkout master + +' + +rm -fr frotz xyzzy nitfol && +git checkout -f master || exit + +test_expect_success 'switch from dir to symlink' ' + + git checkout side + +' + +test_done diff --git a/t/t2008-checkout-subdir.sh b/t/t2008-checkout-subdir.sh new file mode 100755 index 0000000000..3e098ab31e --- /dev/null +++ b/t/t2008-checkout-subdir.sh @@ -0,0 +1,82 @@ +#!/bin/sh +# +# Copyright (c) 2007 David Symonds + +test_description='git checkout from subdirectories' + +. ./test-lib.sh + +test_expect_success setup ' + + echo "base" > file0 && + git add file0 && + mkdir dir1 && + echo "hello" > dir1/file1 && + git add dir1/file1 && + mkdir dir2 && + echo "bonjour" > dir2/file2 && + git add dir2/file2 && + test_tick && + git commit -m "populate tree" + +' + +test_expect_success 'remove and restore with relative path' ' + + ( + cd dir1 && + rm ../file0 && + git checkout HEAD -- ../file0 && + test "base" = "$(cat ../file0)" && + rm ../dir2/file2 && + git checkout HEAD -- ../dir2/file2 && + test "bonjour" = "$(cat ../dir2/file2)" && + rm ../file0 ./file1 && + git checkout HEAD -- .. && + test "base" = "$(cat ../file0)" && + test "hello" = "$(cat file1)" + ) + +' + +test_expect_success 'checkout with empty prefix' ' + + rm file0 && + git checkout HEAD -- file0 && + test "base" = "$(cat file0)" + +' + +test_expect_success 'checkout with simple prefix' ' + + rm dir1/file1 && + git checkout HEAD -- dir1 && + test "hello" = "$(cat dir1/file1)" && + rm dir1/file1 && + git checkout HEAD -- dir1/file1 && + test "hello" = "$(cat dir1/file1)" + +' + +# This is not expected to work as ls-files was not designed +# to deal with such. Enable it when ls-files is updated. +: test_expect_success 'checkout with complex relative path' ' + + rm file1 && + git checkout HEAD -- ../dir1/../dir1/file1 && test -f ./file1 + +' + +test_expect_success 'relative path outside tree should fail' \ + 'test_must_fail git checkout HEAD -- ../../Makefile' + +test_expect_success 'incorrect relative path to file should fail (1)' \ + 'test_must_fail git checkout HEAD -- ../file0' + +test_expect_success 'incorrect relative path should fail (2)' \ + '( cd dir1 && test_must_fail git checkout HEAD -- ./file0 )' + +test_expect_success 'incorrect relative path should fail (3)' \ + '( cd dir1 && test_must_fail git checkout HEAD -- ../../file0 )' + +test_done diff --git a/t/t2009-checkout-statinfo.sh b/t/t2009-checkout-statinfo.sh new file mode 100755 index 0000000000..f3c2152087 --- /dev/null +++ b/t/t2009-checkout-statinfo.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +test_description='checkout should leave clean stat info' + +. ./test-lib.sh + +test_expect_success 'setup' ' + + echo hello >world && + git update-index --add world && + git commit -m initial && + git branch side && + echo goodbye >world && + git update-index --add world && + git commit -m second + +' + +test_expect_success 'branch switching' ' + + git reset --hard && + test "$(git diff-files --raw)" = "" && + + git checkout master && + test "$(git diff-files --raw)" = "" && + + git checkout side && + test "$(git diff-files --raw)" = "" && + + git checkout master && + test "$(git diff-files --raw)" = "" + +' + +test_expect_success 'path checkout' ' + + git reset --hard && + test "$(git diff-files --raw)" = "" && + + git checkout master world && + test "$(git diff-files --raw)" = "" && + + git checkout side world && + test "$(git diff-files --raw)" = "" && + + git checkout master world && + test "$(git diff-files --raw)" = "" + +' + +test_done + diff --git a/t/t2010-checkout-ambiguous.sh b/t/t2010-checkout-ambiguous.sh new file mode 100755 index 0000000000..7cc0a3582e --- /dev/null +++ b/t/t2010-checkout-ambiguous.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +test_description='checkout and pathspecs/refspecs ambiguities' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo hello >world && + echo hello >all && + git add all world && + git commit -m initial && + git branch world +' + +test_expect_success 'reference must be a tree' ' + test_must_fail git checkout $(git hash-object ./all) -- +' + +test_expect_success 'branch switching' ' + test "refs/heads/master" = "$(git symbolic-ref HEAD)" && + git checkout world -- && + test "refs/heads/world" = "$(git symbolic-ref HEAD)" +' + +test_expect_success 'checkout world from the index' ' + echo bye > world && + git checkout -- world && + git diff --exit-code --quiet +' + +test_expect_success 'non ambiguous call' ' + git checkout all +' + +test_expect_success 'allow the most common case' ' + git checkout world && + test "refs/heads/world" = "$(git symbolic-ref HEAD)" +' + +test_expect_success 'check ambiguity' ' + test_must_fail git checkout world all +' + +test_expect_success 'disambiguate checking out from a tree-ish' ' + echo bye > world && + git checkout world -- world && + git diff --exit-code --quiet +' + +test_done diff --git a/t/t2050-git-dir-relative.sh b/t/t2050-git-dir-relative.sh new file mode 100755 index 0000000000..88f268b9d7 --- /dev/null +++ b/t/t2050-git-dir-relative.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +test_description='check problems with relative GIT_DIR + +This test creates a working tree state with a file and subdir: + + top (committed several times) + subdir (a subdirectory) + +It creates a commit-hook and tests it, then moves .git +into the subdir while keeping the worktree location, +and tries commits from the top and the subdir, checking +that the commit-hook still gets called.' + +. ./test-lib.sh + +COMMIT_FILE="$(pwd)/output" +export COMMIT_FILE + +test_expect_success 'Setting up post-commit hook' ' +mkdir -p .git/hooks && +echo >.git/hooks/post-commit "#!/bin/sh +touch \"\${COMMIT_FILE}\" +echo Post commit hook was called." && +chmod +x .git/hooks/post-commit' + +test_expect_success 'post-commit hook used ordinarily' ' +echo initial >top && +git-add top +git-commit -m initial && +test -r "${COMMIT_FILE}" +' + +rm -rf "${COMMIT_FILE}" +mkdir subdir +mv .git subdir + +test_expect_success 'post-commit-hook created and used from top dir' ' +echo changed >top && +git --git-dir subdir/.git add top && +git --git-dir subdir/.git commit -m topcommit && +test -r "${COMMIT_FILE}" +' + +rm -rf "${COMMIT_FILE}" + +test_expect_success 'post-commit-hook from sub dir' ' +echo changed again >top +cd subdir && +git --git-dir .git --work-tree .. add ../top && +git --git-dir .git --work-tree .. commit -m subcommit && +test -r "${COMMIT_FILE}" +' + +test_done diff --git a/t/t2100-update-cache-badpath.sh b/t/t2100-update-cache-badpath.sh new file mode 100755 index 0000000000..6ef2dcfd8a --- /dev/null +++ b/t/t2100-update-cache-badpath.sh @@ -0,0 +1,51 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git update-index nonsense-path test. + +This test creates the following structure in the cache: + + path0 - a file + path1 - a symlink + path2/file2 - a file in a directory + path3/file3 - a file in a directory + +and tries to git update-index --add the following: + + path0/file0 - a file in a directory + path1/file1 - a file in a directory + path2 - a file + path3 - a symlink + +All of the attempts should fail. +' + +. ./test-lib.sh + +mkdir path2 path3 +date >path0 +ln -s xyzzy path1 +date >path2/file2 +date >path3/file3 + +test_expect_success \ + 'git update-index --add to add various paths.' \ + 'git update-index --add -- path0 path1 path2/file2 path3/file3' + +rm -fr path? + +mkdir path0 path1 +date >path2 +ln -s frotz path3 +date >path0/file0 +date >path1/file1 + +for p in path0/file0 path1/file1 path2 path3 +do + test_expect_success \ + "git update-index to add conflicting path $p should fail." \ + "test_must_fail git update-index --add -- $p" +done +test_done diff --git a/t/t2101-update-index-reupdate.sh b/t/t2101-update-index-reupdate.sh new file mode 100755 index 0000000000..59b560bfdf --- /dev/null +++ b/t/t2101-update-index-reupdate.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='git update-index --again test. +' + +. ./test-lib.sh + +cat > expected <<\EOF +100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0 file1 +100644 9db8893856a8a02eaa73470054b7c1c5a7c82e47 0 file2 +EOF +test_expect_success 'update-index --add' \ + 'echo hello world >file1 && + echo goodbye people >file2 && + git update-index --add file1 file2 && + git ls-files -s >current && + cmp current expected' + +test_expect_success 'update-index --again' \ + 'rm -f file1 && + echo hello everybody >file2 && + if git update-index --again + then + echo should have refused to remove file1 + exit 1 + else + echo happy - failed as expected + fi && + git ls-files -s >current && + cmp current expected' + +cat > expected <<\EOF +100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0 file2 +EOF +test_expect_success 'update-index --remove --again' \ + 'git update-index --remove --again && + git ls-files -s >current && + cmp current expected' + +test_expect_success 'first commit' 'git-commit -m initial' + +cat > expected <<\EOF +100644 53ab446c3f4e42ce9bb728a0ccb283a101be4979 0 dir1/file3 +100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0 file2 +EOF +test_expect_success 'update-index again' \ + 'mkdir -p dir1 && + echo hello world >dir1/file3 && + echo goodbye people >file2 && + git update-index --add file2 dir1/file3 && + echo hello everybody >file2 + echo happy >dir1/file3 && + git update-index --again && + git ls-files -s >current && + cmp current expected' + +cat > expected <<\EOF +100644 d7fb3f695f06c759dbf3ab00046e7cc2da22d10f 0 dir1/file3 +100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0 file2 +EOF +test_expect_success 'update-index --update from subdir' \ + 'echo not so happy >file2 && + cd dir1 && + cat ../file2 >file3 && + git update-index --again && + cd .. && + git ls-files -s >current && + cmp current expected' + +cat > expected <<\EOF +100644 594fb5bb1759d90998e2bf2a38261ae8e243c760 0 dir1/file3 +100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0 file2 +EOF +test_expect_success 'update-index --update with pathspec' \ + 'echo very happy >file2 && + cat file2 >dir1/file3 && + git update-index --again dir1/ && + git ls-files -s >current && + cmp current expected' + +test_done diff --git a/t/t2102-update-index-symlinks.sh b/t/t2102-update-index-symlinks.sh new file mode 100755 index 0000000000..19d0894d26 --- /dev/null +++ b/t/t2102-update-index-symlinks.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes Sixt +# + +test_description='git update-index on filesystem w/o symlinks test. + +This tests that git update-index keeps the symbolic link property +even if a plain file is in the working tree if core.symlinks is false.' + +. ./test-lib.sh + +test_expect_success \ +'preparation' ' +git config core.symlinks false && +l=$(echo -n file | git-hash-object -t blob -w --stdin) && +echo "120000 $l symlink" | git update-index --index-info' + +test_expect_success \ +'modify the symbolic link' ' +echo -n new-file > symlink && +git update-index symlink' + +test_expect_success \ +'the index entry must still be a symbolic link' ' +case "`git ls-files --stage --cached symlink`" in +120000" "*symlink) echo ok;; +*) echo fail; git ls-files --stage --cached symlink; (exit 1);; +esac' + +test_done diff --git a/t/t2103-update-index-ignore-missing.sh b/t/t2103-update-index-ignore-missing.sh new file mode 100755 index 0000000000..332694e7d3 --- /dev/null +++ b/t/t2103-update-index-ignore-missing.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +test_description='update-index with options' + +. ./test-lib.sh + +test_expect_success basics ' + >one && + >two && + >three && + + # need --add when adding + test_must_fail git update-index one && + test -z "$(git ls-files)" && + git update-index --add one && + test zone = "z$(git ls-files)" && + + # update-index is atomic + echo 1 >one && + test_must_fail git update-index one two && + echo "M one" >expect && + git diff-files --name-status >actual && + test_cmp expect actual && + + git update-index --add one two three && + for i in one three two; do echo $i; done >expect && + git ls-files >actual && + test_cmp expect actual && + + test_tick && + ( + test_create_repo xyzzy && + cd xyzzy && + >file && + git add file + git commit -m "sub initial" + ) && + git add xyzzy && + + test_tick && + git commit -m initial && + git tag initial +' + +test_expect_success '--ignore-missing --refresh' ' + git reset --hard initial && + echo 2 >one && + test_must_fail git update-index --refresh && + echo 1 >one && + git update-index --refresh && + rm -f two && + test_must_fail git update-index --refresh && + git update-index --ignore-missing --refresh + +' + +test_expect_success '--unmerged --refresh' ' + git reset --hard initial && + info=$(git ls-files -s one | sed -e "s/ 0 / 1 /") && + git rm --cached one && + echo "$info" | git update-index --index-info && + test_must_fail git update-index --refresh && + git update-index --unmerged --refresh && + echo 2 >two && + test_must_fail git update-index --unmerged --refresh >actual && + grep two actual && + ! grep one actual && + ! grep three actual +' + +test_expect_success '--ignore-submodules --refresh (1)' ' + git reset --hard initial && + rm -f two && + test_must_fail git update-index --ignore-submodules --refresh +' + +test_expect_success '--ignore-submodules --refresh (2)' ' + git reset --hard initial && + test_tick && + ( + cd xyzzy && + git commit -m "sub second" --allow-empty + ) && + test_must_fail git update-index --refresh && + test_must_fail git update-index --ignore-missing --refresh && + git update-index --ignore-submodules --refresh +' + +test_done diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh new file mode 100755 index 0000000000..f57a6e077c --- /dev/null +++ b/t/t2200-add-update.sh @@ -0,0 +1,131 @@ +#!/bin/sh + +test_description='git add -u + +This test creates a working tree state with three files: + + top (previously committed, modified) + dir/sub (previously committed, modified) + dir/other (untracked) + +and issues a git add -u with path limiting on "dir" to add +only the updates to dir/sub. + +Also tested are "git add -u" without limiting, and "git add -u" +without contents changes.' + +. ./test-lib.sh + +test_expect_success setup ' + echo initial >check && + echo initial >top && + echo initial >foo && + mkdir dir1 dir2 && + echo initial >dir1/sub1 && + echo initial >dir1/sub2 && + echo initial >dir2/sub3 && + git add check dir1 dir2 top foo && + test_tick + git-commit -m initial && + + echo changed >check && + echo changed >top && + echo changed >dir2/sub3 && + rm -f dir1/sub1 && + echo other >dir2/other +' + +test_expect_success update ' + git add -u dir1 dir2 +' + +test_expect_success 'update noticed a removal' ' + test "$(git-ls-files dir1/sub1)" = "" +' + +test_expect_success 'update touched correct path' ' + test "$(git-diff-files --name-status dir2/sub3)" = "" +' + +test_expect_success 'update did not touch other tracked files' ' + test "$(git-diff-files --name-status check)" = "M check" && + test "$(git-diff-files --name-status top)" = "M top" +' + +test_expect_success 'update did not touch untracked files' ' + test "$(git-ls-files dir2/other)" = "" +' + +test_expect_success 'cache tree has not been corrupted' ' + + git ls-files -s | + sed -e "s/ 0 / /" >expect && + git ls-tree -r $(git write-tree) | + sed -e "s/ blob / /" >current && + test_cmp expect current + +' + +test_expect_success 'update from a subdirectory' ' + ( + cd dir1 && + echo more >sub2 && + git add -u sub2 + ) +' + +test_expect_success 'change gets noticed' ' + + test "$(git diff-files --name-status dir1)" = "" + +' + +test_expect_success 'replace a file with a symlink' ' + + rm foo && + ln -s top foo && + git add -u -- foo + +' + +test_expect_success 'add everything changed' ' + + git add -u && + test -z "$(git diff-files)" + +' + +test_expect_success 'touch and then add -u' ' + + touch check && + git add -u && + test -z "$(git diff-files)" + +' + +test_expect_success 'touch and then add explicitly' ' + + touch check && + git add check && + test -z "$(git diff-files)" + +' + +test_expect_success 'add -n -u should not add but just report' ' + + ( + echo "add '\''check'\''" && + echo "remove '\''top'\''" + ) >expect && + before=$(git ls-files -s check top) && + echo changed >>check && + rm -f top && + git add -n -u >actual && + after=$(git ls-files -s check top) && + + test "$before" = "$after" && + test_cmp expect actual + +' + +test_done diff --git a/t/t2201-add-update-typechange.sh b/t/t2201-add-update-typechange.sh new file mode 100755 index 0000000000..d24c7d9e5f --- /dev/null +++ b/t/t2201-add-update-typechange.sh @@ -0,0 +1,140 @@ +#!/bin/sh + +test_description='more git add -u' + +. ./test-lib.sh + +_z40=0000000000000000000000000000000000000000 + +test_expect_success setup ' + >xyzzy && + _empty=$(git hash-object --stdin <xyzzy) && + >yomin && + >caskly && + ln -s frotz nitfol && + mkdir rezrov && + >rezrov/bozbar && + git add caskly xyzzy yomin nitfol rezrov/bozbar && + + test_tick && + git commit -m initial + +' + +test_expect_success modify ' + rm -f xyzzy yomin nitfol caskly && + # caskly disappears (not a submodule) + mkdir caskly && + # nitfol changes from symlink to regular + >nitfol && + # rezrov/bozbar disappears + rm -fr rezrov && + ln -s xyzzy rezrov && + # xyzzy disappears (not a submodule) + mkdir xyzzy && + echo gnusto >xyzzy/bozbar && + # yomin gets replaced with a submodule + mkdir yomin && + >yomin/yomin && + ( + cd yomin && + git init && + git add yomin && + git commit -m "sub initial" + ) && + yomin=$(GIT_DIR=yomin/.git git rev-parse HEAD) && + # yonk is added and then turned into a submodule + # this should appear as T in diff-files and as A in diff-index + >yonk && + git add yonk && + rm -f yonk && + mkdir yonk && + >yonk/yonk && + ( + cd yonk && + git init && + git add yonk && + git commit -m "sub initial" + ) && + yonk=$(GIT_DIR=yonk/.git git rev-parse HEAD) && + # zifmia is added and then removed + # this should appear in diff-files but not in diff-index. + >zifmia && + git add zifmia && + rm -f zifmia && + mkdir zifmia && + { + git ls-tree -r HEAD | + sed -e "s/^/:/" -e " + / caskly/{ + s/ caskly/ $_z40 D&/ + s/blob/000000/ + } + / nitfol/{ + s/ nitfol/ $_z40 T&/ + s/blob/100644/ + } + / rezrov.bozbar/{ + s/ rezrov.bozbar/ $_z40 D&/ + s/blob/000000/ + } + / xyzzy/{ + s/ xyzzy/ $_z40 D&/ + s/blob/000000/ + } + / yomin/{ + s/ yomin/ $_z40 T&/ + s/blob/160000/ + } + " + } >expect && + { + cat expect + echo ":100644 160000 $_empty $_z40 T yonk" + echo ":100644 000000 $_empty $_z40 D zifmia" + } >expect-files && + { + cat expect + echo ":000000 160000 $_z40 $_z40 A yonk" + } >expect-index && + { + echo "100644 $_empty 0 nitfol" + echo "160000 $yomin 0 yomin" + echo "160000 $yonk 0 yonk" + } >expect-final +' + +test_expect_success diff-files ' + git diff-files --raw >actual && + test_cmp expect-files actual +' + +test_expect_success diff-index ' + git diff-index --raw HEAD -- >actual && + test_cmp expect-index actual +' + +test_expect_success 'add -u' ' + rm -f ".git/saved-index" && + cp -p ".git/index" ".git/saved-index" && + git add -u && + git ls-files -s >actual && + test_cmp expect-final actual +' + +test_expect_success 'commit -a' ' + if test -f ".git/saved-index" + then + rm -f ".git/index" && + mv ".git/saved-index" ".git/index" + fi && + git commit -m "second" -a && + git ls-files -s >actual && + test_cmp expect-final actual && + rm -f .git/index && + git read-tree HEAD && + git ls-files -s >actual && + test_cmp expect-final actual +' + +test_done diff --git a/t/t2202-add-addremove.sh b/t/t2202-add-addremove.sh new file mode 100755 index 0000000000..6a8151064c --- /dev/null +++ b/t/t2202-add-addremove.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +test_description='git add --all' + +. ./test-lib.sh + +test_expect_success setup ' + ( + echo .gitignore + echo will-remove + ) >expect && + ( + echo actual + echo expect + echo ignored + ) >.gitignore && + >will-remove && + git add --all && + test_tick && + git commit -m initial && + git ls-files >actual && + test_cmp expect actual +' + +test_expect_success 'git add --all' ' + ( + echo .gitignore + echo not-ignored + echo "M .gitignore" + echo "A not-ignored" + echo "D will-remove" + ) >expect && + >ignored && + >not-ignored && + echo modification >>.gitignore && + rm -f will-remove && + git add --all && + git update-index --refresh && + git ls-files >actual && + git diff-index --name-status --cached HEAD >>actual && + test_cmp expect actual +' + +test_done diff --git a/t/t3000-ls-files-others.sh b/t/t3000-ls-files-others.sh new file mode 100755 index 0000000000..bc0a351392 --- /dev/null +++ b/t/t3000-ls-files-others.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git ls-files test (--others should pick up symlinks). + +This test runs git ls-files --others with the following on the +filesystem. + + path0 - a file + path1 - a symlink + path2/file2 - a file in a directory + path3-junk - a file to confuse things + path3/file3 - a file in a directory +' +. ./test-lib.sh + +date >path0 +ln -s xyzzy path1 +mkdir path2 path3 +date >path2/file2 +date >path2-junk +date >path3/file3 +date >path3-junk +git update-index --add path3-junk path3/file3 + +cat >expected1 <<EOF +expected1 +expected2 +output +path0 +path1 +path2-junk +path2/file2 +EOF +sed -e 's|path2/file2|path2/|' <expected1 >expected2 + +test_expect_success \ + 'git ls-files --others to show output.' \ + 'git ls-files --others >output' + +test_expect_success \ + 'git ls-files --others should pick up symlinks.' \ + 'diff output expected1' + +test_expect_success \ + 'git ls-files --others --directory to show output.' \ + 'git ls-files --others --directory >output' + + +test_expect_success \ + 'git ls-files --others --directory should not get confused.' \ + 'diff output expected2' + +test_done diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh new file mode 100755 index 0000000000..1caeacafa7 --- /dev/null +++ b/t/t3001-ls-files-others-exclude.sh @@ -0,0 +1,143 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git ls-files --others --exclude + +This test runs git ls-files --others and tests --exclude patterns. +' + +. ./test-lib.sh + +rm -fr one three +for dir in . one one/two three +do + mkdir -p $dir && + for i in 1 2 3 4 5 6 7 8 + do + >$dir/a.$i + done +done + +cat >expect <<EOF +a.2 +a.4 +a.5 +a.8 +one/a.3 +one/a.4 +one/a.5 +one/a.7 +one/two/a.2 +one/two/a.3 +one/two/a.5 +one/two/a.7 +one/two/a.8 +three/a.2 +three/a.3 +three/a.4 +three/a.5 +three/a.8 +EOF + +echo '.gitignore +output +expect +.gitignore +*.7 +!*.8' >.git/ignore + +echo '*.1 +/*.3 +!*.6' >.gitignore +echo '*.2 +two/*.4 +!*.7 +*.8' >one/.gitignore +echo '!*.2 +!*.8' >one/two/.gitignore + +test_expect_success \ + 'git ls-files --others with various exclude options.' \ + 'git ls-files --others \ + --exclude=\*.6 \ + --exclude-per-directory=.gitignore \ + --exclude-from=.git/ignore \ + >output && + test_cmp expect output' + +# Test \r\n (MSDOS-like systems) +printf '*.1\r\n/*.3\r\n!*.6\r\n' >.gitignore + +test_expect_success \ + 'git ls-files --others with \r\n line endings.' \ + 'git ls-files --others \ + --exclude=\*.6 \ + --exclude-per-directory=.gitignore \ + --exclude-from=.git/ignore \ + >output && + test_cmp expect output' + +cat > excludes-file << EOF +*.[1-8] +e* +EOF + +git config core.excludesFile excludes-file + +git status | grep "^# " > output + +cat > expect << EOF +# .gitignore +# a.6 +# one/ +# output +# three/ +EOF + +test_expect_success 'git-status honours core.excludesfile' \ + 'test_cmp expect output' + +test_expect_success 'trailing slash in exclude allows directory match(1)' ' + + git ls-files --others --exclude=one/ >output && + if grep "^one/" output + then + echo Ooops + false + else + : happy + fi + +' + +test_expect_success 'trailing slash in exclude allows directory match (2)' ' + + git ls-files --others --exclude=one/two/ >output && + if grep "^one/two/" output + then + echo Ooops + false + else + : happy + fi + +' + +test_expect_success 'trailing slash in exclude forces directory match (1)' ' + + >two + git ls-files --others --exclude=two/ >output && + grep "^two" output + +' + +test_expect_success 'trailing slash in exclude forces directory match (2)' ' + + git ls-files --others --exclude=one/a.1/ >output && + grep "^one/a.1" output + +' + +test_done diff --git a/t/t3002-ls-files-dashpath.sh b/t/t3002-ls-files-dashpath.sh new file mode 100755 index 0000000000..8704b04e1b --- /dev/null +++ b/t/t3002-ls-files-dashpath.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git ls-files test (-- to terminate the path list). + +This test runs git ls-files --others with the following on the +filesystem. + + path0 - a file + -foo - a file with a funny name. + -- - another file with a funny name. +' +. ./test-lib.sh + +test_expect_success \ + setup \ + 'echo frotz >path0 && + echo frotz >./-foo && + echo frotz >./--' + +test_expect_success \ + 'git ls-files without path restriction.' \ + 'git ls-files --others >output && + test_cmp output - <<EOF +-- +-foo +output +path0 +EOF +' + +test_expect_success \ + 'git ls-files with path restriction.' \ + 'git ls-files --others path0 >output && + test_cmp output - <<EOF +path0 +EOF +' + +test_expect_success \ + 'git ls-files with path restriction with --.' \ + 'git ls-files --others -- path0 >output && + test_cmp output - <<EOF +path0 +EOF +' + +test_expect_success \ + 'git ls-files with path restriction with -- --.' \ + 'git ls-files --others -- -- >output && + test_cmp output - <<EOF +-- +EOF +' + +test_expect_success \ + 'git ls-files with no path restriction.' \ + 'git ls-files --others -- >output && + test_cmp output - <<EOF +-- +-foo +output +path0 +EOF +' + +test_done diff --git a/t/t3010-ls-files-killed-modified.sh b/t/t3010-ls-files-killed-modified.sh new file mode 100755 index 0000000000..ec14040637 --- /dev/null +++ b/t/t3010-ls-files-killed-modified.sh @@ -0,0 +1,96 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git ls-files -k and -m flags test. + +This test prepares the following in the cache: + + path0 - a file + path1 - a symlink + path2/file2 - a file in a directory + path3/file3 - a file in a directory + +and the following on the filesystem: + + path0/file0 - a file in a directory + path1/file1 - a file in a directory + path2 - a file + path3 - a symlink + path4 - a file + path5 - a symlink + path6/file6 - a file in a directory + +git ls-files -k should report that existing filesystem +objects except path4, path5 and path6/file6 to be killed. + +Also for modification test, the cache and working tree have: + + path7 - an empty file, modified to a non-empty file. + path8 - a non-empty file, modified to an empty file. + path9 - an empty file, cache dirtied. + path10 - a non-empty file, cache dirtied. + +We should report path0, path1, path2/file2, path3/file3, path7 and path8 +modified without reporting path9 and path10. +' +. ./test-lib.sh + +date >path0 +ln -s xyzzy path1 +mkdir path2 path3 +date >path2/file2 +date >path3/file3 +: >path7 +date >path8 +: >path9 +date >path10 +test_expect_success \ + 'git update-index --add to add various paths.' \ + "git update-index --add -- path0 path1 path?/file? path7 path8 path9 path10" + +rm -fr path? ;# leave path10 alone +date >path2 +ln -s frotz path3 +ln -s nitfol path5 +mkdir path0 path1 path6 +date >path0/file0 +date >path1/file1 +date >path6/file6 +date >path7 +: >path8 +: >path9 +touch path10 + +test_expect_success \ + 'git ls-files -k to show killed files.' \ + 'git ls-files -k >.output' +cat >.expected <<EOF +path0/file0 +path1/file1 +path2 +path3 +EOF + +test_expect_success \ + 'validate git ls-files -k output.' \ + 'diff .output .expected' + +test_expect_success \ + 'git ls-files -m to show modified files.' \ + 'git ls-files -m >.output' +cat >.expected <<EOF +path0 +path1 +path2/file2 +path3/file3 +path7 +path8 +EOF + +test_expect_success \ + 'validate git ls-files -m output.' \ + 'diff .output .expected' + +test_done diff --git a/t/t3020-ls-files-error-unmatch.sh b/t/t3020-ls-files-error-unmatch.sh new file mode 100755 index 0000000000..af8c4121ab --- /dev/null +++ b/t/t3020-ls-files-error-unmatch.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# +# Copyright (c) 2006 Carl D. Worth +# + +test_description='git ls-files test for --error-unmatch option + +This test runs git ls-files --error-unmatch to ensure it correctly +returns an error when a non-existent path is provided on the command +line. +' +. ./test-lib.sh + +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.' \ + 'test_must_fail git ls-files --error-unmatch foo bar-does-not-match' + +test_expect_success \ + 'git ls-files --error-unmatch should succeed eith matched paths.' \ + 'git ls-files --error-unmatch foo bar' + +test_done +1 diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh new file mode 100755 index 0000000000..aff360303a --- /dev/null +++ b/t/t3030-merge-recursive.sh @@ -0,0 +1,527 @@ +#!/bin/sh + +test_description='merge-recursive backend test' + +. ./test-lib.sh + +test_expect_success 'setup 1' ' + + echo hello >a && + o0=$(git hash-object a) && + cp a b && + cp a c && + mkdir d && + cp a d/e && + + test_tick && + git add a b c d/e && + git commit -m initial && + c0=$(git rev-parse --verify HEAD) && + git branch side && + git branch df-1 && + git branch df-2 && + git branch df-3 && + git branch remove && + + echo hello >>a && + cp a d/e && + o1=$(git hash-object a) && + + git add a d/e && + + test_tick && + git commit -m "master modifies a and d/e" && + c1=$(git rev-parse --verify HEAD) && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "100644 blob $o1 a" + echo "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o1 d/e" + echo "100644 $o1 0 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o1 0 d/e" + ) >expected && + test_cmp expected actual +' + +test_expect_success 'setup 2' ' + + rm -rf [abcd] && + git checkout side && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "100644 blob $o0 a" + echo "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 $o0 0 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o0 0 d/e" + ) >expected && + test_cmp expected actual && + + echo goodbye >>a && + o2=$(git hash-object a) && + + git add a && + + test_tick && + git commit -m "side modifies a" && + c2=$(git rev-parse --verify HEAD) && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "100644 blob $o2 a" + echo "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 $o2 0 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o0 0 d/e" + ) >expected && + test_cmp expected actual +' + +test_expect_success 'setup 3' ' + + rm -rf [abcd] && + git checkout df-1 && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "100644 blob $o0 a" + echo "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 $o0 0 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o0 0 d/e" + ) >expected && + test_cmp expected actual && + + rm -f b && mkdir b && echo df-1 >b/c && git add b/c && + o3=$(git hash-object b/c) && + + test_tick && + git commit -m "df-1 makes b/c" && + c3=$(git rev-parse --verify HEAD) && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "100644 blob $o0 a" + echo "100644 blob $o3 b/c" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 $o0 0 a" + echo "100644 $o3 0 b/c" + echo "100644 $o0 0 c" + echo "100644 $o0 0 d/e" + ) >expected && + test_cmp expected actual +' + +test_expect_success 'setup 4' ' + + rm -rf [abcd] && + git checkout df-2 && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "100644 blob $o0 a" + echo "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 $o0 0 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o0 0 d/e" + ) >expected && + test_cmp expected actual && + + rm -f a && mkdir a && echo df-2 >a/c && git add a/c && + o4=$(git hash-object a/c) && + + test_tick && + git commit -m "df-2 makes a/c" && + c4=$(git rev-parse --verify HEAD) && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "100644 blob $o4 a/c" + echo "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 $o4 0 a/c" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o0 0 d/e" + ) >expected && + test_cmp expected actual +' + +test_expect_success 'setup 5' ' + + rm -rf [abcd] && + git checkout remove && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "100644 blob $o0 a" + echo "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 $o0 0 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o0 0 d/e" + ) >expected && + test_cmp expected actual && + + rm -f b && + echo remove-conflict >a && + + git add a && + git rm b && + o5=$(git hash-object a) && + + test_tick && + git commit -m "remove removes b and modifies a" && + c5=$(git rev-parse --verify HEAD) && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "100644 blob $o5 a" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 $o5 0 a" + echo "100644 $o0 0 c" + echo "100644 $o0 0 d/e" + ) >expected && + test_cmp expected actual + +' + +test_expect_success 'setup 6' ' + + rm -rf [abcd] && + git checkout df-3 && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "100644 blob $o0 a" + echo "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 $o0 0 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o0 0 d/e" + ) >expected && + test_cmp expected actual && + + rm -fr d && echo df-3 >d && git add d && + o6=$(git hash-object d) && + + test_tick && + git commit -m "df-3 makes d" && + c6=$(git rev-parse --verify HEAD) && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "100644 blob $o0 a" + echo "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o6 d" + echo "100644 $o0 0 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o6 0 d" + ) >expected && + test_cmp expected actual +' + +test_expect_success 'merge-recursive simple' ' + + rm -fr [abcd] && + git checkout -f "$c2" && + + git-merge-recursive "$c0" -- "$c2" "$c1" + status=$? + case "$status" in + 1) + : happy + ;; + *) + echo >&2 "why status $status!!!" + false + ;; + esac +' + +test_expect_success 'merge-recursive result' ' + + git ls-files -s >actual && + ( + echo "100644 $o0 1 a" + echo "100644 $o2 2 a" + echo "100644 $o1 3 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o1 0 d/e" + ) >expected && + test_cmp expected actual + +' + +test_expect_success 'merge-recursive remove conflict' ' + + rm -fr [abcd] && + git checkout -f "$c1" && + + git-merge-recursive "$c0" -- "$c1" "$c5" + status=$? + case "$status" in + 1) + : happy + ;; + *) + echo >&2 "why status $status!!!" + false + ;; + esac +' + +test_expect_success 'merge-recursive remove conflict' ' + + git ls-files -s >actual && + ( + echo "100644 $o0 1 a" + echo "100644 $o1 2 a" + echo "100644 $o5 3 a" + echo "100644 $o0 0 c" + echo "100644 $o1 0 d/e" + ) >expected && + test_cmp expected actual + +' + +test_expect_success 'merge-recursive d/f simple' ' + rm -fr [abcd] && + git reset --hard && + git checkout -f "$c1" && + + git-merge-recursive "$c0" -- "$c1" "$c3" +' + +test_expect_success 'merge-recursive result' ' + + git ls-files -s >actual && + ( + echo "100644 $o1 0 a" + echo "100644 $o3 0 b/c" + echo "100644 $o0 0 c" + echo "100644 $o1 0 d/e" + ) >expected && + test_cmp expected actual + +' + +test_expect_success 'merge-recursive d/f conflict' ' + + rm -fr [abcd] && + git reset --hard && + git checkout -f "$c1" && + + git-merge-recursive "$c0" -- "$c1" "$c4" + status=$? + case "$status" in + 1) + : happy + ;; + *) + echo >&2 "why status $status!!!" + false + ;; + esac +' + +test_expect_success 'merge-recursive d/f conflict result' ' + + git ls-files -s >actual && + ( + echo "100644 $o0 1 a" + echo "100644 $o1 2 a" + echo "100644 $o4 0 a/c" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o1 0 d/e" + ) >expected && + test_cmp expected actual + +' + +test_expect_success 'merge-recursive d/f conflict the other way' ' + + rm -fr [abcd] && + git reset --hard && + git checkout -f "$c4" && + + git-merge-recursive "$c0" -- "$c4" "$c1" + status=$? + case "$status" in + 1) + : happy + ;; + *) + echo >&2 "why status $status!!!" + false + ;; + esac +' + +test_expect_success 'merge-recursive d/f conflict result the other way' ' + + git ls-files -s >actual && + ( + echo "100644 $o0 1 a" + echo "100644 $o1 3 a" + echo "100644 $o4 0 a/c" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o1 0 d/e" + ) >expected && + test_cmp expected actual + +' + +test_expect_success 'merge-recursive d/f conflict' ' + + rm -fr [abcd] && + git reset --hard && + git checkout -f "$c1" && + + git-merge-recursive "$c0" -- "$c1" "$c6" + status=$? + case "$status" in + 1) + : happy + ;; + *) + echo >&2 "why status $status!!!" + false + ;; + esac +' + +test_expect_success 'merge-recursive d/f conflict result' ' + + git ls-files -s >actual && + ( + echo "100644 $o1 0 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o6 3 d" + echo "100644 $o0 1 d/e" + echo "100644 $o1 2 d/e" + ) >expected && + test_cmp expected actual + +' + +test_expect_success 'merge-recursive d/f conflict' ' + + rm -fr [abcd] && + git reset --hard && + git checkout -f "$c6" && + + git-merge-recursive "$c0" -- "$c6" "$c1" + status=$? + case "$status" in + 1) + : happy + ;; + *) + echo >&2 "why status $status!!!" + false + ;; + esac +' + +test_expect_success 'merge-recursive d/f conflict result' ' + + git ls-files -s >actual && + ( + echo "100644 $o1 0 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o6 2 d" + echo "100644 $o0 1 d/e" + echo "100644 $o1 3 d/e" + ) >expected && + test_cmp expected actual + +' + +test_expect_success 'reset and 3-way merge' ' + + git reset --hard "$c2" && + git read-tree -m "$c0" "$c2" "$c1" + +' + +test_expect_success 'reset and bind merge' ' + + git reset --hard master && + git read-tree --prefix=M/ master && + git ls-files -s >actual && + ( + echo "100644 $o1 0 M/a" + echo "100644 $o0 0 M/b" + echo "100644 $o0 0 M/c" + echo "100644 $o1 0 M/d/e" + echo "100644 $o1 0 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o1 0 d/e" + ) >expected && + test_cmp expected actual && + + git read-tree --prefix=a1/ master && + git ls-files -s >actual && + ( + echo "100644 $o1 0 M/a" + echo "100644 $o0 0 M/b" + echo "100644 $o0 0 M/c" + echo "100644 $o1 0 M/d/e" + echo "100644 $o1 0 a" + echo "100644 $o1 0 a1/a" + echo "100644 $o0 0 a1/b" + echo "100644 $o0 0 a1/c" + echo "100644 $o1 0 a1/d/e" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o1 0 d/e" + ) >expected && + test_cmp expected actual + + git read-tree --prefix=z/ master && + git ls-files -s >actual && + ( + echo "100644 $o1 0 M/a" + echo "100644 $o0 0 M/b" + echo "100644 $o0 0 M/c" + echo "100644 $o1 0 M/d/e" + echo "100644 $o1 0 a" + echo "100644 $o1 0 a1/a" + echo "100644 $o0 0 a1/b" + echo "100644 $o0 0 a1/c" + echo "100644 $o1 0 a1/d/e" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o1 0 d/e" + echo "100644 $o1 0 z/a" + echo "100644 $o0 0 z/b" + echo "100644 $o0 0 z/c" + echo "100644 $o1 0 z/d/e" + ) >expected && + test_cmp expected actual + +' + +test_done diff --git a/t/t3040-subprojects-basic.sh b/t/t3040-subprojects-basic.sh new file mode 100755 index 0000000000..f6973e96a5 --- /dev/null +++ b/t/t3040-subprojects-basic.sh @@ -0,0 +1,85 @@ +#!/bin/sh + +test_description='Basic subproject functionality' +. ./test-lib.sh + +test_expect_success 'Super project creation' \ + ': >Makefile && + git add Makefile && + git commit -m "Superproject created"' + + +cat >expected <<EOF +:000000 160000 00000... A sub1 +:000000 160000 00000... A sub2 +EOF +test_expect_success 'create subprojects' \ + 'mkdir sub1 && + ( cd sub1 && git init && : >Makefile && git add * && + git commit -q -m "subproject 1" ) && + mkdir sub2 && + ( cd sub2 && git init && : >Makefile && git add * && + git commit -q -m "subproject 2" ) && + git update-index --add sub1 && + git add sub2 && + git commit -q -m "subprojects added" && + git diff-tree --abbrev=5 HEAD^ HEAD |cut -d" " -f-3,5- >current && + test_cmp expected current' + +git branch save HEAD + +test_expect_success 'check if fsck ignores the subprojects' \ + 'git fsck --full' + +test_expect_success 'check if commit in a subproject detected' \ + '( cd sub1 && + echo "all:" >>Makefile && + echo " true" >>Makefile && + git commit -q -a -m "make all" ) && { + git diff-files --exit-code + test $? = 1 + }' + +test_expect_success 'check if a changed subproject HEAD can be committed' \ + 'git commit -q -a -m "sub1 changed" && { + git diff-tree --exit-code HEAD^ HEAD + test $? = 1 + }' + +test_expect_success 'check if diff-index works for subproject elements' \ + 'git diff-index --exit-code --cached save -- sub1 + test $? = 1' + +test_expect_success 'check if diff-tree works for subproject elements' \ + 'git diff-tree --exit-code HEAD^ HEAD -- sub1 + test $? = 1' + +test_expect_success 'check if git diff works for subproject elements' \ + 'git diff --exit-code HEAD^ HEAD + test $? = 1' + +test_expect_success 'check if clone works' \ + 'git ls-files -s >expected && + git clone -l -s . cloned && + ( cd cloned && git ls-files -s ) >current && + test_cmp expected current' + +test_expect_success 'removing and adding subproject' \ + 'git update-index --force-remove -- sub2 && + mv sub2 sub3 && + git add sub3 && + git commit -q -m "renaming a subproject" && { + git diff -M --name-status --exit-code HEAD^ HEAD + test $? = 1 + }' + +# the index must contain the object name the HEAD of the +# subproject sub1 was at the point "save" +test_expect_success 'checkout in superproject' \ + 'git checkout save && + git diff-index --exit-code --raw --cached save -- sub1' + +# just interesting what happened... +# git diff --name-status -M save master + +test_done diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh new file mode 100755 index 0000000000..4261e9641e --- /dev/null +++ b/t/t3050-subprojects-fetch.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +test_description='fetching and pushing project with subproject' + +. ./test-lib.sh + +test_expect_success setup ' + test_tick && + mkdir -p sub && ( + cd sub && + git init && + >subfile && + git add subfile + git commit -m "subproject commit #1" + ) && + >mainfile + git add sub mainfile && + test_tick && + git commit -m "superproject commit #1" +' + +test_expect_success clone ' + git clone "file://$(pwd)/.git" cloned && + (git rev-parse HEAD; git ls-files -s) >expected && + ( + cd cloned && + (git rev-parse HEAD; git ls-files -s) >../actual + ) && + test_cmp expected actual +' + +test_expect_success advance ' + echo more >mainfile && + git update-index --force-remove sub && + mv sub/.git sub/.git-disabled && + git add sub/subfile mainfile && + mv sub/.git-disabled sub/.git && + test_tick && + git commit -m "superproject commit #2" +' + +test_expect_success fetch ' + (git rev-parse HEAD; git ls-files -s) >expected && + ( + cd cloned && + git pull && + (git rev-parse HEAD; git ls-files -s) >../actual + ) && + test_cmp expected actual +' + +test_done diff --git a/t/t3060-ls-files-with-tree.sh b/t/t3060-ls-files-with-tree.sh new file mode 100755 index 0000000000..3ce501bb97 --- /dev/null +++ b/t/t3060-ls-files-with-tree.sh @@ -0,0 +1,71 @@ +#!/bin/sh +# +# Copyright (c) 2007 Carl D. Worth +# + +test_description='git ls-files test (--with-tree). + +This test runs git ls-files --with-tree and in particular in +a scenario known to trigger a crash with some versions of git. +' +. ./test-lib.sh + +test_expect_success setup ' + + # The bug we are exercising requires a fair number of entries + # in a sub-directory so that add_index_entry will trigger a + # realloc. + + echo file >expected && + mkdir sub && + bad= && + for n in 0 1 2 3 4 5 + do + for m in 0 1 2 3 4 5 6 7 8 9 + do + num=00$n$m && + >sub/file-$num && + echo file-$num >>expected || { + bad=t + break + } + done && test -z "$bad" || { + bad=t + break + } + done && test -z "$bad" && + git add . && + git commit -m "add a bunch of files" && + + # We remove them all so that we will have something to add + # back with --with-tree and so that we will definitely be + # under the realloc size to trigger the bug. + rm -rf sub && + git commit -a -m "remove them all" && + + # The bug also requires some entry before our directory so that + # prune_path will modify the_index.cache + + mkdir a_directory_that_sorts_before_sub && + >a_directory_that_sorts_before_sub/file && + mkdir sub && + >sub/file && + git add . +' + +# We have to run from a sub-directory to trigger prune_path +# Then we finally get to run our --with-tree test +cd sub + +test_expect_success 'git -ls-files --with-tree should succeed from subdir' ' + + git ls-files --with-tree=HEAD~1 >../output + +' + +cd .. +test_expect_success \ + 'git -ls-files --with-tree should add entries from named tree.' \ + 'test_cmp expected output' + +test_done diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh new file mode 100755 index 0000000000..6e6a2542a2 --- /dev/null +++ b/t/t3100-ls-tree-restrict.sh @@ -0,0 +1,158 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git ls-tree test. + +This test runs git ls-tree with the following in a tree. + + path0 - a file + path1 - a symlink + path2/foo - a file in a directory + path2/bazbo - a symlink in a directory + path2/baz/b - a file in a directory in a directory + +The new path restriction code should do the right thing for path2 and +path2/baz. Also path0/ should snow nothing. +' +. ./test-lib.sh + +test_expect_success \ + 'setup' \ + 'mkdir path2 path2/baz && + echo Hi >path0 && + ln -s path0 path1 && + echo Lo >path2/foo && + ln -s ../path1 path2/bazbo && + echo Mi >path2/baz/b && + find path? \( -type f -o -type l \) -print | + xargs git update-index --add && + tree=`git write-tree` && + echo $tree' + +_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' +_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" +test_output () { + sed -e "s/ $_x40 / X /" <current >check + test_cmp expected check +} + +test_expect_success \ + 'ls-tree plain' \ + 'git ls-tree $tree >current && + cat >expected <<\EOF && +100644 blob X path0 +120000 blob X path1 +040000 tree X path2 +EOF + test_output' + +test_expect_success \ + 'ls-tree recursive' \ + 'git ls-tree -r $tree >current && + cat >expected <<\EOF && +100644 blob X path0 +120000 blob X path1 +100644 blob X path2/baz/b +120000 blob X path2/bazbo +100644 blob X path2/foo +EOF + test_output' + +test_expect_success \ + 'ls-tree recursive with -t' \ + 'git ls-tree -r -t $tree >current && + cat >expected <<\EOF && +100644 blob X path0 +120000 blob X path1 +040000 tree X path2 +040000 tree X path2/baz +100644 blob X path2/baz/b +120000 blob X path2/bazbo +100644 blob X path2/foo +EOF + test_output' + +test_expect_success \ + 'ls-tree recursive with -d' \ + 'git ls-tree -r -d $tree >current && + cat >expected <<\EOF && +040000 tree X path2 +040000 tree X path2/baz +EOF + test_output' + +test_expect_success \ + 'ls-tree filtered with path' \ + 'git ls-tree $tree path >current && + cat >expected <<\EOF && +EOF + test_output' + + +# it used to be path1 and then path0, but with pathspec semantics +# they are shown in canonical order. +test_expect_success \ + 'ls-tree filtered with path1 path0' \ + 'git ls-tree $tree path1 path0 >current && + cat >expected <<\EOF && +100644 blob X path0 +120000 blob X path1 +EOF + test_output' + +test_expect_success \ + 'ls-tree filtered with path0/' \ + 'git ls-tree $tree path0/ >current && + cat >expected <<\EOF && +EOF + test_output' + +# It used to show path2 and its immediate children but +# with pathspec semantics it shows only path2 +test_expect_success \ + 'ls-tree filtered with path2' \ + 'git ls-tree $tree path2 >current && + cat >expected <<\EOF && +040000 tree X path2 +EOF + test_output' + +# ... and path2/ shows the children. +test_expect_success \ + 'ls-tree filtered with path2/' \ + 'git ls-tree $tree path2/ >current && + cat >expected <<\EOF && +040000 tree X path2/baz +120000 blob X path2/bazbo +100644 blob X path2/foo +EOF + test_output' + +# The same change -- exact match does not show children of +# path2/baz +test_expect_success \ + 'ls-tree filtered with path2/baz' \ + 'git ls-tree $tree path2/baz >current && + cat >expected <<\EOF && +040000 tree X path2/baz +EOF + test_output' + +test_expect_success \ + 'ls-tree filtered with path2/bak' \ + 'git ls-tree $tree path2/bak >current && + cat >expected <<\EOF && +EOF + test_output' + +test_expect_success \ + 'ls-tree -t filtered with path2/bak' \ + 'git ls-tree -t $tree path2/bak >current && + cat >expected <<\EOF && +040000 tree X path2 +EOF + test_output' + +test_done diff --git a/t/t3101-ls-tree-dirname.sh b/t/t3101-ls-tree-dirname.sh new file mode 100755 index 0000000000..4dd7d12bac --- /dev/null +++ b/t/t3101-ls-tree-dirname.sh @@ -0,0 +1,138 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# Copyright (c) 2005 Robert Fitzsimons +# + +test_description='git ls-tree directory and filenames handling. + +This test runs git ls-tree with the following in a tree. + + 1.txt - a file + 2.txt - a file + path0/a/b/c/1.txt - a file in a directory + path1/b/c/1.txt - a file in a directory + path2/1.txt - a file in a directory + path3/1.txt - a file in a directory + path3/2.txt - a file in a directory + +Test the handling of mulitple directories which have matching file +entries. Also test odd filename and missing entries handling. +' +. ./test-lib.sh + +test_expect_success \ + 'setup' \ + 'echo 111 >1.txt && + echo 222 >2.txt && + mkdir path0 path0/a path0/a/b path0/a/b/c && + echo 111 >path0/a/b/c/1.txt && + mkdir path1 path1/b path1/b/c && + echo 111 >path1/b/c/1.txt && + mkdir path2 && + echo 111 >path2/1.txt && + mkdir path3 && + echo 111 >path3/1.txt && + echo 222 >path3/2.txt && + find *.txt path* \( -type f -o -type l \) -print | + xargs git update-index --add && + tree=`git write-tree` && + echo $tree' + +_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' +_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" +test_output () { + sed -e "s/ $_x40 / X /" <current >check + test_cmp expected check +} + +test_expect_success \ + 'ls-tree plain' \ + 'git ls-tree $tree >current && + cat >expected <<\EOF && +100644 blob X 1.txt +100644 blob X 2.txt +040000 tree X path0 +040000 tree X path1 +040000 tree X path2 +040000 tree X path3 +EOF + test_output' + +# Recursive does not show tree nodes anymore... +test_expect_success \ + 'ls-tree recursive' \ + 'git ls-tree -r $tree >current && + cat >expected <<\EOF && +100644 blob X 1.txt +100644 blob X 2.txt +100644 blob X path0/a/b/c/1.txt +100644 blob X path1/b/c/1.txt +100644 blob X path2/1.txt +100644 blob X path3/1.txt +100644 blob X path3/2.txt +EOF + test_output' + +test_expect_success \ + 'ls-tree filter 1.txt' \ + 'git ls-tree $tree 1.txt >current && + cat >expected <<\EOF && +100644 blob X 1.txt +EOF + test_output' + +test_expect_success \ + 'ls-tree filter path1/b/c/1.txt' \ + 'git ls-tree $tree path1/b/c/1.txt >current && + cat >expected <<\EOF && +100644 blob X path1/b/c/1.txt +EOF + test_output' + +test_expect_success \ + 'ls-tree filter all 1.txt files' \ + 'git ls-tree $tree 1.txt path0/a/b/c/1.txt path1/b/c/1.txt path2/1.txt path3/1.txt >current && + cat >expected <<\EOF && +100644 blob X 1.txt +100644 blob X path0/a/b/c/1.txt +100644 blob X path1/b/c/1.txt +100644 blob X path2/1.txt +100644 blob X path3/1.txt +EOF + test_output' + +# I am not so sure about this one after ls-tree doing pathspec match. +# Having both path0/a and path0/a/b/c makes path0/a redundant, and +# it behaves as if path0/a/b/c, path1/b/c, path2 and path3 are specified. +test_expect_success \ + 'ls-tree filter directories' \ + 'git ls-tree $tree path3 path2 path0/a/b/c path1/b/c path0/a >current && + cat >expected <<\EOF && +040000 tree X path0/a/b/c +040000 tree X path1/b/c +040000 tree X path2 +040000 tree X path3 +EOF + test_output' + +# Again, duplicates are filtered away so this is equivalent to +# having 1.txt and path3 +test_expect_success \ + 'ls-tree filter odd names' \ + 'git ls-tree $tree 1.txt ./1.txt .//1.txt path3/1.txt path3/./1.txt path3 path3// >current && + cat >expected <<\EOF && +100644 blob X 1.txt +100644 blob X path3/1.txt +100644 blob X path3/2.txt +EOF + test_output' + +test_expect_success \ + 'ls-tree filter missing files and extra slashes' \ + 'git ls-tree $tree 1.txt/ abc.txt path3//23.txt path3/2.txt/// >current && + cat >expected <<\EOF && +EOF + test_output' + +test_done diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh new file mode 100755 index 0000000000..7a83fbfe4f --- /dev/null +++ b/t/t3200-branch.sh @@ -0,0 +1,461 @@ +#!/bin/sh +# +# Copyright (c) 2005 Amos Waterland +# + +test_description='git branch --foo should not create bogus branch + +This test runs git branch --help and checks that the argument is properly +handled. Specifically, that a bogus branch is not created. +' +. ./test-lib.sh + +test_expect_success \ + 'prepare a trivial repository' \ + 'echo Hello > A && + git update-index --add A && + git-commit -m "Initial commit." && + echo World >> A && + git update-index --add A && + git-commit -m "Second commit." && + HEAD=$(git rev-parse --verify HEAD)' + +test_expect_success \ + 'git branch --help should not have created a bogus branch' ' + git branch --help </dev/null >/dev/null 2>/dev/null; + ! test -f .git/refs/heads/--help +' + +test_expect_success \ + 'git branch abc should create a branch' \ + 'git branch abc && test -f .git/refs/heads/abc' + +test_expect_success \ + 'git branch a/b/c should create a branch' \ + 'git branch a/b/c && test -f .git/refs/heads/a/b/c' + +cat >expect <<EOF +0000000000000000000000000000000000000000 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master +EOF +test_expect_success \ + 'git branch -l d/e/f should create a branch and a log' \ + 'GIT_COMMITTER_DATE="2005-05-26 23:30" \ + git branch -l d/e/f && + test -f .git/refs/heads/d/e/f && + test -f .git/logs/refs/heads/d/e/f && + diff expect .git/logs/refs/heads/d/e/f' + +test_expect_success \ + 'git branch -d d/e/f should delete a branch and a log' \ + 'git branch -d d/e/f && + test ! -f .git/refs/heads/d/e/f && + test ! -f .git/logs/refs/heads/d/e/f' + +test_expect_success \ + 'git branch j/k should work after branch j has been deleted' \ + 'git branch j && + git branch -d j && + git branch j/k' + +test_expect_success \ + 'git branch l should work after branch l/m has been deleted' \ + 'git branch l/m && + git branch -d l/m && + git branch l' + +test_expect_success \ + 'git branch -m m m/m should work' \ + 'git branch -l m && + git branch -m m m/m && + test -f .git/logs/refs/heads/m/m' + +test_expect_success \ + 'git branch -m n/n n should work' \ + 'git branch -l n/n && + git branch -m n/n n + test -f .git/logs/refs/heads/n' + +test_expect_success 'git branch -m o/o o should fail when o/p exists' ' + git branch o/o && + git branch o/p && + test_must_fail git branch -m o/o o +' + +test_expect_success 'git branch -m q r/q should fail when r exists' ' + git branch q && + git branch r && + test_must_fail git branch -m q r/q +' + +mv .git/config .git/config-saved + +test_expect_success 'git branch -m q q2 without config should succeed' ' + git branch -m q q2 && + git branch -m q2 q +' + +mv .git/config-saved .git/config + +git config branch.s/s.dummy Hello + +test_expect_success \ + 'git branch -m s/s s should work when s/t is deleted' \ + 'git branch -l s/s && + test -f .git/logs/refs/heads/s/s && + git branch -l s/t && + test -f .git/logs/refs/heads/s/t && + git branch -d s/t && + git branch -m s/s s && + test -f .git/logs/refs/heads/s' + +test_expect_success 'config information was renamed, too' \ + "test $(git config branch.s.dummy) = Hello && + test_must_fail git config branch.s/s/dummy" + +test_expect_success \ + 'git branch -m u v should fail when the reflog for u is a symlink' ' + git branch -l u && + mv .git/logs/refs/heads/u real-u && + ln -s real-u .git/logs/refs/heads/u && + test_must_fail git branch -m u v +' + +test_expect_success 'test tracking setup via --track' \ + 'git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --track my1 local/master && + test $(git config branch.my1.remote) = local && + test $(git config branch.my1.merge) = refs/heads/master' + +test_expect_success 'test tracking setup (non-wildcard, matching)' \ + 'git config remote.local.url . && + git config remote.local.fetch refs/heads/master:refs/remotes/local/master && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --track my4 local/master && + test $(git config branch.my4.remote) = local && + test $(git config branch.my4.merge) = refs/heads/master' + +test_expect_success 'test tracking setup (non-wildcard, not matching)' \ + 'git config remote.local.url . && + git config remote.local.fetch refs/heads/s:refs/remotes/local/s && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --track my5 local/master && + ! test "$(git config branch.my5.remote)" = local && + ! test "$(git config branch.my5.merge)" = refs/heads/master' + +test_expect_success 'test tracking setup via config' \ + 'git config branch.autosetupmerge true && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch my3 local/master && + test $(git config branch.my3.remote) = local && + test $(git config branch.my3.merge) = refs/heads/master' + +test_expect_success 'test overriding tracking setup via --no-track' \ + 'git config branch.autosetupmerge true && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --no-track my2 local/master && + git config branch.autosetupmerge false && + ! test "$(git config branch.my2.remote)" = local && + ! test "$(git config branch.my2.merge)" = refs/heads/master' + +test_expect_success 'no tracking without .fetch entries' \ + 'git config branch.autosetupmerge true && + git branch my6 s && + git config branch.automsetupmerge false && + test -z "$(git config branch.my6.remote)" && + test -z "$(git config branch.my6.merge)"' + +test_expect_success 'test tracking setup via --track but deeper' \ + 'git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/o/o || git-fetch local) && + git branch --track my7 local/o/o && + test "$(git config branch.my7.remote)" = local && + test "$(git config branch.my7.merge)" = refs/heads/o/o' + +test_expect_success 'test deleting branch deletes branch config' \ + 'git branch -d my7 && + test -z "$(git config branch.my7.remote)" && + test -z "$(git config branch.my7.merge)"' + +test_expect_success 'test deleting branch without config' \ + 'git branch my7 s && + test "$(git branch -d my7 2>&1)" = "Deleted branch my7."' + +test_expect_success 'test --track without .fetch entries' \ + 'git branch --track my8 && + test "$(git config branch.my8.remote)" && + test "$(git config branch.my8.merge)"' + +test_expect_success \ + 'branch from non-branch HEAD w/autosetupmerge=always' \ + 'git config branch.autosetupmerge always && + git branch my9 HEAD^ && + git config branch.autosetupmerge false' + +test_expect_success \ + 'branch from non-branch HEAD w/--track causes failure' \ + 'test_must_fail git branch --track my10 HEAD^' + +# Keep this test last, as it changes the current branch +cat >expect <<EOF +0000000000000000000000000000000000000000 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master +EOF +test_expect_success \ + 'git checkout -b g/h/i -l should create a branch and a log' \ + 'GIT_COMMITTER_DATE="2005-05-26 23:30" \ + git-checkout -b g/h/i -l master && + test -f .git/refs/heads/g/h/i && + test -f .git/logs/refs/heads/g/h/i && + diff expect .git/logs/refs/heads/g/h/i' + +test_expect_success 'avoid ambiguous track' ' + git config branch.autosetupmerge true && + git config remote.ambi1.url lalala && + git config remote.ambi1.fetch refs/heads/lalala:refs/heads/master && + git config remote.ambi2.url lilili && + git config remote.ambi2.fetch refs/heads/lilili:refs/heads/master && + git branch all1 master && + test -z "$(git config branch.all1.merge)" +' + +test_expect_success 'autosetuprebase local on a tracked local branch' ' + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + git config branch.autosetuprebase local && + (git show-ref -q refs/remotes/local/o || git-fetch local) && + git branch mybase && + git branch --track myr1 mybase && + test "$(git config branch.myr1.remote)" = . && + test "$(git config branch.myr1.merge)" = refs/heads/mybase && + test "$(git config branch.myr1.rebase)" = true +' + +test_expect_success 'autosetuprebase always on a tracked local branch' ' + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + git config branch.autosetuprebase always && + (git show-ref -q refs/remotes/local/o || git-fetch local) && + git branch mybase2 && + git branch --track myr2 mybase && + test "$(git config branch.myr2.remote)" = . && + test "$(git config branch.myr2.merge)" = refs/heads/mybase && + test "$(git config branch.myr2.rebase)" = true +' + +test_expect_success 'autosetuprebase remote on a tracked local branch' ' + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + git config branch.autosetuprebase remote && + (git show-ref -q refs/remotes/local/o || git-fetch local) && + git branch mybase3 && + git branch --track myr3 mybase2 && + test "$(git config branch.myr3.remote)" = . && + test "$(git config branch.myr3.merge)" = refs/heads/mybase2 && + ! test "$(git config branch.myr3.rebase)" = true +' + +test_expect_success 'autosetuprebase never on a tracked local branch' ' + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + git config branch.autosetuprebase never && + (git show-ref -q refs/remotes/local/o || git-fetch local) && + git branch mybase4 && + git branch --track myr4 mybase2 && + test "$(git config branch.myr4.remote)" = . && + test "$(git config branch.myr4.merge)" = refs/heads/mybase2 && + ! test "$(git config branch.myr4.rebase)" = true +' + +test_expect_success 'autosetuprebase local on a tracked remote branch' ' + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + git config branch.autosetuprebase local && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --track myr5 local/master && + test "$(git config branch.myr5.remote)" = local && + test "$(git config branch.myr5.merge)" = refs/heads/master && + ! test "$(git config branch.myr5.rebase)" = true +' + +test_expect_success 'autosetuprebase never on a tracked remote branch' ' + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + git config branch.autosetuprebase never && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --track myr6 local/master && + test "$(git config branch.myr6.remote)" = local && + test "$(git config branch.myr6.merge)" = refs/heads/master && + ! test "$(git config branch.myr6.rebase)" = true +' + +test_expect_success 'autosetuprebase remote on a tracked remote branch' ' + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + git config branch.autosetuprebase remote && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --track myr7 local/master && + test "$(git config branch.myr7.remote)" = local && + test "$(git config branch.myr7.merge)" = refs/heads/master && + test "$(git config branch.myr7.rebase)" = true +' + +test_expect_success 'autosetuprebase always on a tracked remote branch' ' + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + git config branch.autosetuprebase remote && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --track myr8 local/master && + test "$(git config branch.myr8.remote)" = local && + test "$(git config branch.myr8.merge)" = refs/heads/master && + test "$(git config branch.myr8.rebase)" = true +' + +test_expect_success 'autosetuprebase unconfigured on a tracked remote branch' ' + git config --unset branch.autosetuprebase && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --track myr9 local/master && + test "$(git config branch.myr9.remote)" = local && + test "$(git config branch.myr9.merge)" = refs/heads/master && + test "z$(git config branch.myr9.rebase)" = z +' + +test_expect_success 'autosetuprebase unconfigured on a tracked local branch' ' + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/o || git-fetch local) && + git branch mybase10 && + git branch --track myr10 mybase2 && + test "$(git config branch.myr10.remote)" = . && + test "$(git config branch.myr10.merge)" = refs/heads/mybase2 && + test "z$(git config branch.myr10.rebase)" = z +' + +test_expect_success 'autosetuprebase unconfigured on untracked local branch' ' + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --no-track myr11 mybase2 && + test "z$(git config branch.myr11.remote)" = z && + test "z$(git config branch.myr11.merge)" = z && + test "z$(git config branch.myr11.rebase)" = z +' + +test_expect_success 'autosetuprebase unconfigured on untracked remote branch' ' + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --no-track myr12 local/master && + test "z$(git config branch.myr12.remote)" = z && + test "z$(git config branch.myr12.merge)" = z && + test "z$(git config branch.myr12.rebase)" = z +' + +test_expect_success 'autosetuprebase never on an untracked local branch' ' + git config branch.autosetuprebase never && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --no-track myr13 mybase2 && + test "z$(git config branch.myr13.remote)" = z && + test "z$(git config branch.myr13.merge)" = z && + test "z$(git config branch.myr13.rebase)" = z +' + +test_expect_success 'autosetuprebase local on an untracked local branch' ' + git config branch.autosetuprebase local && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --no-track myr14 mybase2 && + test "z$(git config branch.myr14.remote)" = z && + test "z$(git config branch.myr14.merge)" = z && + test "z$(git config branch.myr14.rebase)" = z +' + +test_expect_success 'autosetuprebase remote on an untracked local branch' ' + git config branch.autosetuprebase remote && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --no-track myr15 mybase2 && + test "z$(git config branch.myr15.remote)" = z && + test "z$(git config branch.myr15.merge)" = z && + test "z$(git config branch.myr15.rebase)" = z +' + +test_expect_success 'autosetuprebase always on an untracked local branch' ' + git config branch.autosetuprebase always && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --no-track myr16 mybase2 && + test "z$(git config branch.myr16.remote)" = z && + test "z$(git config branch.myr16.merge)" = z && + test "z$(git config branch.myr16.rebase)" = z +' + +test_expect_success 'autosetuprebase never on an untracked remote branch' ' + git config branch.autosetuprebase never && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --no-track myr17 local/master && + test "z$(git config branch.myr17.remote)" = z && + test "z$(git config branch.myr17.merge)" = z && + test "z$(git config branch.myr17.rebase)" = z +' + +test_expect_success 'autosetuprebase local on an untracked remote branch' ' + git config branch.autosetuprebase local && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --no-track myr18 local/master && + test "z$(git config branch.myr18.remote)" = z && + test "z$(git config branch.myr18.merge)" = z && + test "z$(git config branch.myr18.rebase)" = z +' + +test_expect_success 'autosetuprebase remote on an untracked remote branch' ' + git config branch.autosetuprebase remote && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --no-track myr19 local/master && + test "z$(git config branch.myr19.remote)" = z && + test "z$(git config branch.myr19.merge)" = z && + test "z$(git config branch.myr19.rebase)" = z +' + +test_expect_success 'autosetuprebase always on an untracked remote branch' ' + git config branch.autosetuprebase always && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --no-track myr20 local/master && + test "z$(git config branch.myr20.remote)" = z && + test "z$(git config branch.myr20.merge)" = z && + test "z$(git config branch.myr20.rebase)" = z +' + +test_expect_success 'detect misconfigured autosetuprebase (bad value)' ' + git config branch.autosetuprebase garbage && + test_must_fail git branch +' + +test_expect_success 'detect misconfigured autosetuprebase (no value)' ' + git config --unset branch.autosetuprebase && + echo "[branch] autosetuprebase" >> .git/config && + test_must_fail git branch && + git config --unset branch.autosetuprebase +' + +test_done diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh new file mode 100755 index 0000000000..f86f4bc5eb --- /dev/null +++ b/t/t3201-branch-contains.sh @@ -0,0 +1,98 @@ +#!/bin/sh + +test_description='branch --contains <commit>, --merged, and --no-merged' + +. ./test-lib.sh + +test_expect_success setup ' + + >file && + git add file && + test_tick && + git commit -m initial && + git branch side && + + echo 1 >file && + test_tick && + git commit -a -m "second on master" && + + git checkout side && + echo 1 >file && + test_tick && + git commit -a -m "second on side" && + + git merge master + +' + +test_expect_success 'branch --contains=master' ' + + git branch --contains=master >actual && + { + echo " master" && echo "* side" + } >expect && + test_cmp expect actual + +' + +test_expect_success 'branch --contains master' ' + + git branch --contains master >actual && + { + echo " master" && echo "* side" + } >expect && + test_cmp expect actual + +' + +test_expect_success 'branch --contains=side' ' + + git branch --contains=side >actual && + { + echo "* side" + } >expect && + test_cmp expect actual + +' + +test_expect_success 'side: branch --merged' ' + + git branch --merged >actual && + { + echo " master" && + echo "* side" + } >expect && + test_cmp expect actual + +' + +test_expect_success 'side: branch --no-merged' ' + + git branch --no-merged >actual && + >expect && + test_cmp expect actual + +' + +test_expect_success 'master: branch --merged' ' + + git checkout master && + git branch --merged >actual && + { + echo "* master" + } >expect && + test_cmp expect actual + +' + +test_expect_success 'master: branch --no-merged' ' + + git branch --no-merged >actual && + { + echo " side" + } >expect && + test_cmp expect actual + +' + +test_done diff --git a/t/t3202-show-branch-octopus.sh b/t/t3202-show-branch-octopus.sh new file mode 100755 index 0000000000..7fe4a6ecb0 --- /dev/null +++ b/t/t3202-show-branch-octopus.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +test_description='test show-branch with more than 8 heads' + +. ./test-lib.sh + +numbers="1 2 3 4 5 6 7 8 9 10" + +test_expect_success 'setup' ' + + > file && + git add file && + test_tick && + git commit -m initial && + + for i in $numbers + do + git checkout -b branch$i master && + > file$i && + git add file$i && + test_tick && + git commit -m branch$i || break + done + +' + +cat > expect << EOF +! [branch1] branch1 + ! [branch2] branch2 + ! [branch3] branch3 + ! [branch4] branch4 + ! [branch5] branch5 + ! [branch6] branch6 + ! [branch7] branch7 + ! [branch8] branch8 + ! [branch9] branch9 + * [branch10] branch10 +---------- + * [branch10] branch10 + + [branch9] branch9 + + [branch8] branch8 + + [branch7] branch7 + + [branch6] branch6 + + [branch5] branch5 + + [branch4] branch4 + + [branch3] branch3 + + [branch2] branch2 ++ [branch1] branch1 ++++++++++* [branch10^] initial +EOF + +test_expect_success 'show-branch with more than 8 branches' ' + + git show-branch $(for i in $numbers; do echo branch$i; done) > out && + test_cmp expect out + +' + +test_done diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh new file mode 100755 index 0000000000..c2dec1c632 --- /dev/null +++ b/t/t3210-pack-refs.sh @@ -0,0 +1,108 @@ +#!/bin/sh +# +# Copyright (c) 2005 Amos Waterland +# Copyright (c) 2006 Christian Couder +# + +test_description='git pack-refs should not change the branch semantic + +This test runs git pack-refs and git show-ref and checks that the branch +semantic is still the same. +' +. ./test-lib.sh + +echo '[core] logallrefupdates = true' >>.git/config + +test_expect_success \ + 'prepare a trivial repository' \ + 'echo Hello > A && + git update-index --add A && + git-commit -m "Initial commit." && + HEAD=$(git rev-parse --verify HEAD)' + +SHA1= + +test_expect_success \ + 'see if git show-ref works as expected' \ + 'git branch a && + SHA1=`cat .git/refs/heads/a` && + echo "$SHA1 refs/heads/a" >expect && + git show-ref a >result && + diff expect result' + +test_expect_success \ + 'see if a branch still exists when packed' \ + 'git branch b && + git pack-refs --all && + rm -f .git/refs/heads/b && + echo "$SHA1 refs/heads/b" >expect && + git show-ref b >result && + diff expect result' + +test_expect_success 'git branch c/d should barf if branch c exists' ' + git branch c && + git pack-refs --all && + rm -f .git/refs/heads/c && + test_must_fail git branch c/d +' + +test_expect_success \ + 'see if a branch still exists after git pack-refs --prune' \ + 'git branch e && + git pack-refs --all --prune && + echo "$SHA1 refs/heads/e" >expect && + git show-ref e >result && + diff expect result' + +test_expect_success 'see if git pack-refs --prune remove ref files' ' + git branch f && + git pack-refs --all --prune && + ! test -f .git/refs/heads/f +' + +test_expect_success \ + 'git branch g should work when git branch g/h has been deleted' \ + 'git branch g/h && + git pack-refs --all --prune && + git branch -d g/h && + git branch g && + git pack-refs --all && + git branch -d g' + +test_expect_success 'git branch i/j/k should barf if branch i exists' ' + git branch i && + git pack-refs --all --prune && + test_must_fail git branch i/j/k +' + +test_expect_success \ + 'test git branch k after branch k/l/m and k/lm have been deleted' \ + 'git branch k/l && + git branch k/lm && + git branch -d k/l && + git branch k/l/m && + git branch -d k/l/m && + git branch -d k/lm && + git branch k' + +test_expect_success \ + 'test git branch n after some branch deletion and pruning' \ + 'git branch n/o && + git branch n/op && + git branch -d n/o && + git branch n/o/p && + git branch -d n/op && + git pack-refs --all --prune && + git branch -d n/o/p && + git branch n' + +test_expect_success 'pack, prune and repack' ' + git-tag foo && + git pack-refs --all --prune && + git show-ref >all-of-them && + git pack-refs && + git show-ref >again && + diff all-of-them again +' + +test_done diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh new file mode 100755 index 0000000000..0574ef1f10 --- /dev/null +++ b/t/t3300-funny-names.sh @@ -0,0 +1,160 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Pathnames with funny characters. + +This test tries pathnames with funny characters in the working +tree, index, and tree objects. +' + +. ./test-lib.sh + +p0='no-funny' +p1='tabs ," (dq) and spaces' +p2='just space' + +cat >"$p0" <<\EOF +1. A quick brown fox jumps over the lazy cat, oops dog. +2. A quick brown fox jumps over the lazy cat, oops dog. +3. A quick brown fox jumps over the lazy cat, oops dog. +EOF + +cat >"$p1" "$p0" +echo 'Foo Bar Baz' >"$p2" + +test -f "$p1" && cmp "$p0" "$p1" || { + # since FAT/NTFS does not allow tabs in filenames, skip this test + say 'Your filesystem does not allow tabs in filenames, test skipped.' + test_done +} + +echo 'just space +no-funny' >expected +test_expect_success 'git ls-files no-funny' \ + 'git update-index --add "$p0" "$p2" && + git ls-files >current && + test_cmp expected current' + +t0=`git write-tree` +echo "$t0" >t0 + +cat > expected <<\EOF +just space +no-funny +"tabs\t,\" (dq) and spaces" +EOF +test_expect_success 'git ls-files with-funny' \ + 'git update-index --add "$p1" && + git ls-files >current && + test_cmp expected current' + +echo 'just space +no-funny +tabs ," (dq) and spaces' >expected +test_expect_success 'git ls-files -z with-funny' \ + 'git ls-files -z | perl -pe y/\\000/\\012/ >current && + test_cmp expected current' + +t1=`git write-tree` +echo "$t1" >t1 + +cat > expected <<\EOF +just space +no-funny +"tabs\t,\" (dq) and spaces" +EOF +test_expect_success 'git ls-tree with funny' \ + 'git ls-tree -r $t1 | sed -e "s/^[^ ]* //" >current && + test_cmp expected current' + +cat > expected <<\EOF +A "tabs\t,\" (dq) and spaces" +EOF +test_expect_success 'git diff-index with-funny' \ + 'git diff-index --name-status $t0 >current && + test_cmp expected current' + +test_expect_success 'git diff-tree with-funny' \ + 'git diff-tree --name-status $t0 $t1 >current && + test_cmp expected current' + +echo 'A +tabs ," (dq) and spaces' >expected +test_expect_success 'git diff-index -z with-funny' \ + 'git diff-index -z --name-status $t0 | perl -pe y/\\000/\\012/ >current && + test_cmp expected current' + +test_expect_success 'git diff-tree -z with-funny' \ + 'git diff-tree -z --name-status $t0 $t1 | perl -pe y/\\000/\\012/ >current && + test_cmp expected current' + +cat > expected <<\EOF +CNUM no-funny "tabs\t,\" (dq) and spaces" +EOF +test_expect_success 'git diff-tree -C with-funny' \ + 'git diff-tree -C --find-copies-harder --name-status \ + $t0 $t1 | sed -e 's/^C[0-9]*/CNUM/' >current && + test_cmp expected current' + +cat > expected <<\EOF +RNUM no-funny "tabs\t,\" (dq) and spaces" +EOF +test_expect_success 'git diff-tree delete with-funny' \ + 'git update-index --force-remove "$p0" && + git diff-index -M --name-status \ + $t0 | sed -e 's/^R[0-9]*/RNUM/' >current && + test_cmp expected current' + +cat > expected <<\EOF +diff --git a/no-funny "b/tabs\t,\" (dq) and spaces" +similarity index NUM% +rename from no-funny +rename to "tabs\t,\" (dq) and spaces" +EOF +test_expect_success 'git diff-tree delete with-funny' \ + 'git diff-index -M -p $t0 | + sed -e "s/index [0-9]*%/index NUM%/" >current && + test_cmp expected current' + +chmod +x "$p1" +cat > expected <<\EOF +diff --git a/no-funny "b/tabs\t,\" (dq) and spaces" +old mode 100644 +new mode 100755 +similarity index NUM% +rename from no-funny +rename to "tabs\t,\" (dq) and spaces" +EOF +test_expect_success 'git diff-tree delete with-funny' \ + 'git diff-index -M -p $t0 | + sed -e "s/index [0-9]*%/index NUM%/" >current && + test_cmp expected current' + +cat >expected <<\EOF + "tabs\t,\" (dq) and spaces" + 1 files changed, 0 insertions(+), 0 deletions(-) +EOF +test_expect_success 'git diff-tree rename with-funny applied' \ + 'git diff-index -M -p $t0 | + git apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current && + test_cmp expected current' + +cat > expected <<\EOF + no-funny + "tabs\t,\" (dq) and spaces" + 2 files changed, 3 insertions(+), 3 deletions(-) +EOF +test_expect_success 'git diff-tree delete with-funny applied' \ + 'git diff-index -p $t0 | + git apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current && + test_cmp expected current' + +test_expect_success 'git apply non-git diff' \ + 'git diff-index -p $t0 | + sed -ne "/^[-+@]/p" | + git apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current && + test_cmp expected current' + +test_done diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh new file mode 100755 index 0000000000..91bb5e1d9e --- /dev/null +++ b/t/t3400-rebase.sh @@ -0,0 +1,87 @@ +#!/bin/sh +# +# Copyright (c) 2005 Amos Waterland +# + +test_description='git rebase should not destroy author information + +This test runs git rebase and checks that the author information is not lost. +' +. ./test-lib.sh + +GIT_AUTHOR_EMAIL=bogus_email_address +export GIT_AUTHOR_EMAIL + +test_expect_success \ + 'prepare repository with topic branches' \ + 'echo First > A && + git update-index --add A && + git-commit -m "Add A." && + git checkout -b my-topic-branch && + echo Second > B && + git update-index --add B && + git-commit -m "Add B." && + git checkout -f master && + echo Third >> A && + git update-index A && + git-commit -m "Modify A." && + git checkout -b side my-topic-branch && + echo Side >> C && + git add C && + git commit -m "Add C" && + git checkout -b nonlinear my-topic-branch && + echo Edit >> B && + git add B && + git commit -m "Modify B" && + git merge side && + git checkout -b upstream-merged-nonlinear && + git merge master && + git checkout -f my-topic-branch && + git tag topic +' + +test_expect_success 'rebase against master' ' + git rebase master' + +test_expect_success \ + 'the rebase operation should not have destroyed author information' \ + '! (git log | grep "Author:" | grep "<>")' + +test_expect_success 'rebase after merge master' ' + git reset --hard topic && + git merge master && + git rebase master && + ! (git show | grep "^Merge:") +' + +test_expect_success 'rebase of history with merges is linearized' ' + git checkout nonlinear && + test 4 = $(git rev-list master.. | wc -l) && + git rebase master && + test 3 = $(git rev-list master.. | wc -l) +' + +test_expect_success \ + 'rebase of history with merges after upstream merge is linearized' ' + git checkout upstream-merged-nonlinear && + test 5 = $(git rev-list master.. | wc -l) && + git rebase master && + test 3 = $(git rev-list master.. | wc -l) +' + +test_expect_success 'rebase a single mode change' ' + git checkout master && + echo 1 > X && + git add X && + test_tick && + git commit -m prepare && + git checkout -b modechange HEAD^ && + echo 1 > X && + git add X && + chmod a+x A && + test_tick && + git commit -m modechange A X && + GIT_TRACE=1 git rebase master +' + +test_done diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh new file mode 100755 index 0000000000..166ddb1447 --- /dev/null +++ b/t/t3401-rebase-partial.sh @@ -0,0 +1,61 @@ +#!/bin/sh +# +# Copyright (c) 2006 Yann Dirson, based on t3400 by Amos Waterland +# + +test_description='git rebase should detect patches integrated upstream + +This test cherry-picks one local change of two into master branch, and +checks that git rebase succeeds with only the second patch in the +local branch. +' +. ./test-lib.sh + +test_expect_success \ + 'prepare repository with topic branch' \ + 'echo First > A && + git update-index --add A && + git-commit -m "Add A." && + + git-checkout -b my-topic-branch && + + echo Second > B && + git update-index --add B && + git-commit -m "Add B." && + + echo AnotherSecond > C && + git update-index --add C && + git-commit -m "Add C." && + + git-checkout -f master && + + echo Third >> A && + git update-index A && + git-commit -m "Modify A." +' + +test_expect_success \ + 'pick top patch from topic branch into master' \ + 'git cherry-pick my-topic-branch^0 && + git-checkout -f my-topic-branch && + git branch master-merge master && + git branch my-topic-branch-merge my-topic-branch +' + +test_debug \ + 'git cherry master && + git format-patch -k --stdout --full-index master >/dev/null && + gitk --all & sleep 1 +' + +test_expect_success \ + 'rebase topic branch against new master and check git-am did not get halted' \ + 'git-rebase master && test ! -d .git/rebase-apply' + +test_expect_success \ + 'rebase --merge topic branch that was partially merged upstream' \ + 'git-checkout -f my-topic-branch-merge && + git-rebase --merge master-merge && + test ! -d .git/rebase-merge' + +test_done diff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh new file mode 100755 index 0000000000..7b7d07269a --- /dev/null +++ b/t/t3402-rebase-merge.sh @@ -0,0 +1,111 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='git rebase --merge test' + +. ./test-lib.sh + +T="A quick brown fox +jumps over the lazy dog." +for i in 1 2 3 4 5 6 7 8 9 10 +do + echo "$i $T" +done >original + +test_expect_success setup ' + git add original && + git commit -m"initial" && + git branch side && + echo "11 $T" >>original && + git commit -a -m"master updates a bit." && + + echo "12 $T" >>original && + git commit -a -m"master updates a bit more." && + + git checkout side && + (echo "0 $T" ; cat original) >renamed && + git add renamed && + git update-index --force-remove original && + git commit -a -m"side renames and edits." && + + tr "[a-z]" "[A-Z]" <original >newfile && + git add newfile && + git commit -a -m"side edits further." && + + tr "[a-m]" "[A-M]" <original >newfile && + rm -f original && + git commit -a -m"side edits once again." && + + git branch test-rebase side && + git branch test-rebase-pick side && + git branch test-reference-pick side && + git checkout -b test-merge side +' + +test_expect_success 'reference merge' ' + git merge -s recursive "reference merge" HEAD master +' + +PRE_REBASE=$(git rev-parse test-rebase) +test_expect_success rebase ' + git checkout test-rebase && + GIT_TRACE=1 git rebase --merge master +' + +test_expect_success 'test-rebase@{1} is pre rebase' ' + test $PRE_REBASE = $(git rev-parse test-rebase@{1}) +' + +test_expect_success 'merge and rebase should match' ' + git diff-tree -r test-rebase test-merge >difference && + if test -s difference + then + cat difference + (exit 1) + else + echo happy + fi +' + +test_expect_success 'rebase the other way' ' + git reset --hard master && + git rebase --merge side +' + +test_expect_success 'merge and rebase should match' ' + git diff-tree -r test-rebase test-merge >difference && + if test -s difference + then + cat difference + (exit 1) + else + echo happy + fi +' + +test_expect_success 'picking rebase' ' + git reset --hard side && + git rebase --merge --onto master side^^ && + mb=$(git merge-base master HEAD) && + if test "$mb" = "$(git rev-parse master)" + then + echo happy + else + git show-branch + (exit 1) + fi && + f=$(git diff-tree --name-only HEAD^ HEAD) && + g=$(git diff-tree --name-only HEAD^^ HEAD^) && + case "$f,$g" in + newfile,newfile) + echo happy ;; + *) + echo "$f" + echo "$g" + (exit 1) + esac +' + +test_done diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh new file mode 100755 index 0000000000..0d33c71daa --- /dev/null +++ b/t/t3403-rebase-skip.sh @@ -0,0 +1,73 @@ +#!/bin/sh +# +# Copyright (c) 2006 Eric Wong +# + +test_description='git rebase --merge --skip tests' + +. ./test-lib.sh + +# we assume the default git-am -3 --skip strategy is tested independently +# and always works :) + +test_expect_success setup ' + echo hello > hello && + git add hello && + git commit -m "hello" && + git branch skip-reference && + + echo world >> hello && + git commit -a -m "hello world" && + echo goodbye >> hello && + git commit -a -m "goodbye" && + + git checkout -f skip-reference && + echo moo > hello && + git commit -a -m "we should skip this" && + echo moo > cow && + git add cow && + git commit -m "this should not be skipped" && + git branch pre-rebase skip-reference && + git branch skip-merge skip-reference + ' + +test_expect_success 'rebase with git am -3 (default)' ' + test_must_fail git rebase master +' + +test_expect_success 'rebase --skip with am -3' ' + git rebase --skip + ' + +test_expect_success 'rebase moves back to skip-reference' ' + test refs/heads/skip-reference = $(git symbolic-ref HEAD) && + git branch post-rebase && + git reset --hard pre-rebase && + test_must_fail git rebase master && + echo "hello" > hello && + git add hello && + git rebase --continue && + test refs/heads/skip-reference = $(git symbolic-ref HEAD) && + git reset --hard post-rebase +' + +test_expect_success 'checkout skip-merge' 'git checkout -f skip-merge' + +test_expect_success 'rebase with --merge' ' + test_must_fail git rebase --merge master +' + +test_expect_success 'rebase --skip with --merge' ' + git rebase --skip + ' + +test_expect_success 'merge and reference trees equal' \ + 'test -z "`git diff-tree skip-merge skip-reference`"' + +test_expect_success 'moved back to branch correctly' ' + test refs/heads/skip-merge = $(git symbolic-ref HEAD) +' + +test_debug 'gitk --all & sleep 1' + +test_done diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh new file mode 100755 index 0000000000..5aa487ac02 --- /dev/null +++ b/t/t3404-rebase-interactive.sh @@ -0,0 +1,422 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes E. Schindelin +# + +test_description='git rebase interactive + +This test runs git rebase "interactively", by faking an edit, and verifies +that the result still makes sense. +' +. ./test-lib.sh + +# set up two branches like this: +# +# A - B - C - D - E +# \ +# F - G - H +# \ +# I +# +# where B, D and G touch the same file. + +test_expect_success 'setup' ' + : > file1 && + git add file1 && + test_tick && + git commit -m A && + git tag A && + echo 1 > file1 && + test_tick && + git commit -m B file1 && + : > file2 && + git add file2 && + test_tick && + git commit -m C && + echo 2 > file1 && + test_tick && + git commit -m D file1 && + : > file3 && + git add file3 && + test_tick && + git commit -m E && + git checkout -b branch1 A && + : > file4 && + git add file4 && + test_tick && + git commit -m F && + git tag F && + echo 3 > file1 && + test_tick && + git commit -m G file1 && + : > file5 && + git add file5 && + test_tick && + git commit -m H && + git checkout -b branch2 F && + : > file6 && + git add file6 && + test_tick && + git commit -m I && + git tag I +' + +echo "#!$SHELL_PATH" >fake-editor.sh +cat >> fake-editor.sh <<\EOF +case "$1" in +*/COMMIT_EDITMSG) + test -z "$FAKE_COMMIT_MESSAGE" || echo "$FAKE_COMMIT_MESSAGE" > "$1" + test -z "$FAKE_COMMIT_AMEND" || echo "$FAKE_COMMIT_AMEND" >> "$1" + exit + ;; +esac +test -z "$EXPECT_COUNT" || + test "$EXPECT_COUNT" = $(sed -e '/^#/d' -e '/^$/d' < "$1" | wc -l) || + exit +test -z "$FAKE_LINES" && exit +grep -v '^#' < "$1" > "$1".tmp +rm -f "$1" +cat "$1".tmp +action=pick +for line in $FAKE_LINES; do + case $line in + squash|edit) + action="$line";; + *) + echo sed -n "${line}s/^pick/$action/p" + sed -n "${line}p" < "$1".tmp + sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1" + action=pick;; + esac +done +EOF + +test_set_editor "$(pwd)/fake-editor.sh" +chmod a+x fake-editor.sh + +test_expect_success 'no changes are a nop' ' + git rebase -i F && + test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" && + test $(git rev-parse I) = $(git rev-parse HEAD) +' + +test_expect_success 'test the [branch] option' ' + git checkout -b dead-end && + git rm file6 && + git commit -m "stop here" && + git rebase -i F branch2 && + test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" && + test $(git rev-parse I) = $(git rev-parse branch2) && + test $(git rev-parse I) = $(git rev-parse HEAD) +' + +test_expect_success 'test --onto <branch>' ' + git checkout -b test-onto branch2 && + git rebase -i --onto branch1 F && + test "$(git symbolic-ref -q HEAD)" = "refs/heads/test-onto" && + test $(git rev-parse HEAD^) = $(git rev-parse branch1) && + test $(git rev-parse I) = $(git rev-parse branch2) +' + +test_expect_success 'rebase on top of a non-conflicting commit' ' + git checkout branch1 && + git tag original-branch1 && + git rebase -i branch2 && + test file6 = $(git diff --name-only original-branch1) && + test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch1" && + test $(git rev-parse I) = $(git rev-parse branch2) && + test $(git rev-parse I) = $(git rev-parse HEAD~2) +' + +test_expect_success 'reflog for the branch shows state before rebase' ' + test $(git rev-parse branch1@{1}) = $(git rev-parse original-branch1) +' + +test_expect_success 'exchange two commits' ' + FAKE_LINES="2 1" git rebase -i HEAD~2 && + test H = $(git cat-file commit HEAD^ | sed -ne \$p) && + test G = $(git cat-file commit HEAD | sed -ne \$p) +' + +cat > expect << EOF +diff --git a/file1 b/file1 +index e69de29..00750ed 100644 +--- a/file1 ++++ b/file1 +@@ -0,0 +1 @@ ++3 +EOF + +cat > expect2 << EOF +<<<<<<< HEAD:file1 +2 +======= +3 +>>>>>>> b7ca976... G:file1 +EOF + +test_expect_success 'stop on conflicting pick' ' + git tag new-branch1 && + test_must_fail git rebase -i master && + test "$(git rev-parse HEAD~3)" = "$(git rev-parse master)" && + test_cmp expect .git/rebase-merge/patch && + test_cmp expect2 file1 && + test "$(git-diff --name-status | + sed -n -e "/^U/s/^U[^a-z]*//p")" = file1 && + test 4 = $(grep -v "^#" < .git/rebase-merge/done | wc -l) && + test 0 = $(grep -c "^[^#]" < .git/rebase-merge/git-rebase-todo) +' + +test_expect_success 'abort' ' + git rebase --abort && + test $(git rev-parse new-branch1) = $(git rev-parse HEAD) && + test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch1" && + ! test -d .git/rebase-merge +' + +test_expect_success 'retain authorship' ' + echo A > file7 && + git add file7 && + test_tick && + GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" && + git tag twerp && + git rebase -i --onto master HEAD^ && + git show HEAD | grep "^Author: Twerp Snog" +' + +test_expect_success 'squash' ' + git reset --hard twerp && + echo B > file7 && + test_tick && + GIT_AUTHOR_NAME="Nitfol" git commit -m "nitfol" file7 && + echo "******************************" && + FAKE_LINES="1 squash 2" git rebase -i --onto master HEAD~2 && + test B = $(cat file7) && + test $(git rev-parse HEAD^) = $(git rev-parse master) +' + +test_expect_success 'retain authorship when squashing' ' + git show HEAD | grep "^Author: Twerp Snog" +' + +test_expect_success '-p handles "no changes" gracefully' ' + HEAD=$(git rev-parse HEAD) && + git rebase -i -p HEAD^ && + git update-index --refresh && + git diff-files --quiet && + git diff-index --quiet --cached HEAD -- && + test $HEAD = $(git rev-parse HEAD) +' + +test_expect_success 'preserve merges with -p' ' + git checkout -b to-be-preserved master^ && + : > unrelated-file && + git add unrelated-file && + test_tick && + git commit -m "unrelated" && + git checkout -b another-branch master && + echo B > file1 && + test_tick && + git commit -m J file1 && + test_tick && + git merge to-be-preserved && + echo C > file1 && + test_tick && + git commit -m K file1 && + echo D > file1 && + test_tick && + git commit -m L1 file1 && + git checkout HEAD^ && + echo 1 > unrelated-file && + test_tick && + git commit -m L2 unrelated-file && + test_tick && + git merge another-branch && + echo E > file1 && + test_tick && + git commit -m M file1 && + git checkout -b to-be-rebased && + test_tick && + git rebase -i -p --onto branch1 master && + git update-index --refresh && + git diff-files --quiet && + git diff-index --quiet --cached HEAD -- && + test $(git rev-parse HEAD~6) = $(git rev-parse branch1) && + test $(git rev-parse HEAD~4^2) = $(git rev-parse to-be-preserved) && + test $(git rev-parse HEAD^^2^) = $(git rev-parse HEAD^^^) && + test $(git show HEAD~5:file1) = B && + test $(git show HEAD~3:file1) = C && + test $(git show HEAD:file1) = E && + test $(git show HEAD:unrelated-file) = 1 +' + +test_expect_success 'edit ancestor with -p' ' + FAKE_LINES="1 edit 2 3 4" git rebase -i -p HEAD~3 && + echo 2 > unrelated-file && + test_tick && + git commit -m L2-modified --amend unrelated-file && + git rebase --continue && + git update-index --refresh && + git diff-files --quiet && + git diff-index --quiet --cached HEAD -- && + test $(git show HEAD:unrelated-file) = 2 +' + +test_expect_success '--continue tries to commit' ' + test_tick && + test_must_fail git rebase -i --onto new-branch1 HEAD^ && + echo resolved > file1 && + git add file1 && + FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue && + test $(git rev-parse HEAD^) = $(git rev-parse new-branch1) && + git show HEAD | grep chouette +' + +test_expect_success 'verbose flag is heeded, even after --continue' ' + git reset --hard HEAD@{1} && + test_tick && + test_must_fail git rebase -v -i --onto new-branch1 HEAD^ && + echo resolved > file1 && + git add file1 && + git rebase --continue > output && + grep "^ file1 | 2 +-$" output +' + +test_expect_success 'multi-squash only fires up editor once' ' + base=$(git rev-parse HEAD~4) && + FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 squash 2 squash 3 squash 4" \ + git rebase -i $base && + test $base = $(git rev-parse HEAD^) && + test 1 = $(git show | grep ONCE | wc -l) +' + +test_expect_success 'squash works as expected' ' + for n in one two three four + do + echo $n >> file$n && + git add file$n && + git commit -m $n + done && + one=$(git rev-parse HEAD~3) && + FAKE_LINES="1 squash 3 2" git rebase -i HEAD~3 && + test $one = $(git rev-parse HEAD~2) +' + +test_expect_success 'interrupted squash works as expected' ' + for n in one two three four + do + echo $n >> conflict && + git add conflict && + git commit -m $n + done && + one=$(git rev-parse HEAD~3) && + ( + FAKE_LINES="1 squash 3 2" && + export FAKE_LINES && + test_must_fail git rebase -i HEAD~3 + ) && + (echo one; echo two; echo four) > conflict && + git add conflict && + test_must_fail git rebase --continue && + echo resolved > conflict && + git add conflict && + git rebase --continue && + test $one = $(git rev-parse HEAD~2) +' + +test_expect_success 'interrupted squash works as expected (case 2)' ' + for n in one two three four + do + echo $n >> conflict && + git add conflict && + git commit -m $n + done && + one=$(git rev-parse HEAD~3) && + ( + FAKE_LINES="3 squash 1 2" && + export FAKE_LINES && + test_must_fail git rebase -i HEAD~3 + ) && + (echo one; echo four) > conflict && + git add conflict && + test_must_fail git rebase --continue && + (echo one; echo two; echo four) > conflict && + git add conflict && + test_must_fail git rebase --continue && + echo resolved > conflict && + git add conflict && + git rebase --continue && + test $one = $(git rev-parse HEAD~2) +' + +test_expect_success 'ignore patch if in upstream' ' + HEAD=$(git rev-parse HEAD) && + git checkout -b has-cherry-picked HEAD^ && + echo unrelated > file7 && + git add file7 && + test_tick && + git commit -m "unrelated change" && + git cherry-pick $HEAD && + EXPECT_COUNT=1 git rebase -i $HEAD && + test $HEAD = $(git rev-parse HEAD^) +' + +test_expect_success '--continue tries to commit, even for "edit"' ' + parent=$(git rev-parse HEAD^) && + test_tick && + FAKE_LINES="edit 1" git rebase -i HEAD^ && + echo edited > file7 && + git add file7 && + FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue && + test edited = $(git show HEAD:file7) && + git show HEAD | grep chouette && + test $parent = $(git rev-parse HEAD^) +' + +test_expect_success 'rebase a detached HEAD' ' + grandparent=$(git rev-parse HEAD~2) && + git checkout $(git rev-parse HEAD) && + test_tick && + FAKE_LINES="2 1" git rebase -i HEAD~2 && + test $grandparent = $(git rev-parse HEAD~2) +' + +test_expect_success 'rebase a commit violating pre-commit' ' + + mkdir -p .git/hooks && + PRE_COMMIT=.git/hooks/pre-commit && + echo "#!/bin/sh" > $PRE_COMMIT && + echo "test -z \"\$(git diff --cached --check)\"" >> $PRE_COMMIT && + chmod a+x $PRE_COMMIT && + echo "monde! " >> file1 && + test_tick && + test_must_fail git commit -m doesnt-verify file1 && + git commit -m doesnt-verify --no-verify file1 && + test_tick && + FAKE_LINES=2 git rebase -i HEAD~2 + +' + +test_expect_success 'rebase with a file named HEAD in worktree' ' + + rm -fr .git/hooks && + git reset --hard && + git checkout -b branch3 A && + + ( + GIT_AUTHOR_NAME="Squashed Away" && + export GIT_AUTHOR_NAME && + >HEAD && + git add HEAD && + git commit -m "Add head" && + >BODY && + git add BODY && + git commit -m "Add body" + ) && + + FAKE_LINES="1 squash 2" git rebase -i to-be-rebased && + test "$(git show -s --pretty=format:%an)" = "Squashed Away" + +' + +test_done diff --git a/t/t3405-rebase-malformed.sh b/t/t3405-rebase-malformed.sh new file mode 100755 index 0000000000..e5ad67c643 --- /dev/null +++ b/t/t3405-rebase-malformed.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +test_description='rebase should not insist on git message convention' + +. ./test-lib.sh + +cat >F <<\EOF +This is an example of a commit log message +that does not conform to git commit convention. + +It has two paragraphs, but its first paragraph is not friendly +to oneline summary format. +EOF + +test_expect_success setup ' + + >file1 && + >file2 && + git add file1 file2 && + test_tick && + git commit -m "Initial commit" && + + git checkout -b side && + cat F >file2 && + git add file2 && + test_tick && + git commit -F F && + + git cat-file commit HEAD | sed -e "1,/^\$/d" >F0 && + + git checkout master && + + echo One >file1 && + test_tick && + git add file1 && + git commit -m "Second commit" +' + +test_expect_success rebase ' + + git rebase master side && + git cat-file commit HEAD | sed -e "1,/^\$/d" >F1 && + + test_cmp F0 F1 && + test_cmp F F0 +' + +test_done diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh new file mode 100755 index 0000000000..5391080943 --- /dev/null +++ b/t/t3406-rebase-message.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +test_description='messages from rebase operation' + +. ./test-lib.sh + +quick_one () { + echo "$1" >"file$1" && + git add "file$1" && + test_tick && + git commit -m "$1" +} + +test_expect_success setup ' + quick_one O && + git branch topic && + quick_one X && + quick_one A && + quick_one B && + quick_one Y && + + git checkout topic && + quick_one A && + quick_one B && + quick_one Z + +' + +cat >expect <<\EOF +Already applied: 0001 A +Already applied: 0002 B +Committed: 0003 Z +EOF + +test_expect_success 'rebase -m' ' + + git rebase -m master >report && + sed -n -e "/^Already applied: /p" \ + -e "/^Committed: /p" report >actual && + test_cmp expect actual + +' + +test_done diff --git a/t/t3407-rebase-abort.sh b/t/t3407-rebase-abort.sh new file mode 100755 index 0000000000..4de550a632 --- /dev/null +++ b/t/t3407-rebase-abort.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +test_description='git rebase --abort tests' + +. ./test-lib.sh + +### Test that we handle space characters properly +work_dir="$(pwd)/test dir" + +test_expect_success setup ' + mkdir -p "$work_dir" && + cd "$work_dir" && + git init && + echo a > a && + git add a && + git commit -m a && + git branch to-rebase && + + echo b > a && + git commit -a -m b && + echo c > a && + git commit -a -m c && + + git checkout to-rebase && + echo d > a && + git commit -a -m "merge should fail on this" && + echo e > a && + git commit -a -m "merge should fail on this, too" && + git branch pre-rebase +' + +testrebase() { + type=$1 + dotest=$2 + + test_expect_success "rebase$type --abort" ' + cd "$work_dir" && + # Clean up the state from the previous one + git reset --hard pre-rebase && + test_must_fail git rebase$type master && + test -d "$dotest" && + git rebase --abort && + test $(git rev-parse to-rebase) = $(git rev-parse pre-rebase) && + test ! -d "$dotest" + ' + + test_expect_success "rebase$type --abort after --skip" ' + cd "$work_dir" && + # Clean up the state from the previous one + git reset --hard pre-rebase && + test_must_fail git rebase$type master && + test -d "$dotest" && + test_must_fail git rebase --skip && + test $(git rev-parse HEAD) = $(git rev-parse master) && + git-rebase --abort && + test $(git rev-parse to-rebase) = $(git rev-parse pre-rebase) && + test ! -d "$dotest" + ' + + test_expect_success "rebase$type --abort after --continue" ' + cd "$work_dir" && + # Clean up the state from the previous one + git reset --hard pre-rebase && + test_must_fail git rebase$type master && + test -d "$dotest" && + echo c > a && + echo d >> a && + git add a && + test_must_fail git rebase --continue && + test $(git rev-parse HEAD) != $(git rev-parse master) && + git rebase --abort && + test $(git rev-parse to-rebase) = $(git rev-parse pre-rebase) && + test ! -d "$dotest" + ' +} + +testrebase "" .git/rebase-apply +testrebase " --merge" .git/rebase-merge + +test_done diff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh new file mode 100755 index 0000000000..e12cd578e8 --- /dev/null +++ b/t/t3408-rebase-multi-line.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +test_description='rebasing a commit with multi-line first paragraph.' + +. ./test-lib.sh + +test_expect_success setup ' + + >file && + git add file && + test_tick && + git commit -m initial && + + echo hello >file && + test_tick && + git commit -a -m "A sample commit log message that has a long +summary that spills over multiple lines. + +But otherwise with a sane description." + + git branch side && + + git reset --hard HEAD^ && + >elif && + git add elif && + test_tick && + git commit -m second + +' + +test_expect_success rebase ' + + git checkout side && + git rebase master && + git cat-file commit HEAD | sed -e "1,/^$/d" >actual && + git cat-file commit side@{1} | sed -e "1,/^$/d" >expect && + test_cmp expect actual + +' + +test_done diff --git a/t/t3500-cherry.sh b/t/t3500-cherry.sh new file mode 100755 index 0000000000..4911c48378 --- /dev/null +++ b/t/t3500-cherry.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Copyright (c) 2006 Yann Dirson, based on t3400 by Amos Waterland +# + +test_description='git cherry should detect patches integrated upstream + +This test cherry-picks one local change of two into master branch, and +checks that git cherry only returns the second patch in the local branch +' +. ./test-lib.sh + +GIT_AUTHOR_EMAIL=bogus_email_address +export GIT_AUTHOR_EMAIL + +test_expect_success \ + 'prepare repository with topic branch, and check cherry finds the 2 patches from there' \ + 'echo First > A && + git update-index --add A && + git-commit -m "Add A." && + + git-checkout -b my-topic-branch && + + echo Second > B && + git update-index --add B && + git-commit -m "Add B." && + + sleep 2 && + echo AnotherSecond > C && + git update-index --add C && + git-commit -m "Add C." && + + git-checkout -f master && + rm -f B C && + + echo Third >> A && + git update-index A && + git-commit -m "Modify A." && + + expr "$(echo $(git cherry master my-topic-branch) )" : "+ [^ ]* + .*" +' + +test_expect_success \ + 'check that cherry with limit returns only the top patch'\ + 'expr "$(echo $(git cherry master my-topic-branch my-topic-branch^1) )" : "+ [^ ]*" +' + +test_expect_success \ + 'cherry-pick one of the 2 patches, and check cherry recognized one and only one as new' \ + 'git cherry-pick my-topic-branch^0 && + echo $(git cherry master my-topic-branch) && + expr "$(echo $(git cherry master my-topic-branch) )" : "+ [^ ]* - .*" +' + +test_done diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh new file mode 100755 index 0000000000..6da212825a --- /dev/null +++ b/t/t3501-revert-cherry-pick.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +test_description='test cherry-pick and revert with renames + + -- + + rename2: renames oops to opos + + rename1: renames oops to spoo + + added: adds extra line to oops + ++ initial: has lines in oops + +' + +. ./test-lib.sh + +test_expect_success setup ' + + for l in a b c d e f g h i j k l m n o + do + echo $l$l$l$l$l$l$l$l$l + done >oops && + + test_tick && + git add oops && + git commit -m initial && + git tag initial && + + test_tick && + echo "Add extra line at the end" >>oops && + git commit -a -m added && + git tag added && + + test_tick && + git mv oops spoo && + git commit -m rename1 && + git tag rename1 && + + test_tick && + git checkout -b side initial && + git mv oops opos && + git commit -m rename2 && + git tag rename2 +' + +test_expect_success 'cherry-pick after renaming branch' ' + + git checkout rename2 && + git cherry-pick added && + test -f opos && + grep "Add extra line at the end" opos + +' + +test_expect_success 'revert after renaming branch' ' + + git checkout rename1 && + git revert added && + test -f spoo && + ! grep "Add extra line at the end" spoo + +' + +test_expect_success 'revert forbidden on dirty working tree' ' + + echo content >extra_file && + git add extra_file && + test_must_fail git revert HEAD 2>errors && + grep "Dirty index" errors + +' + +test_done diff --git a/t/t3502-cherry-pick-merge.sh b/t/t3502-cherry-pick-merge.sh new file mode 100755 index 0000000000..0ab52da902 --- /dev/null +++ b/t/t3502-cherry-pick-merge.sh @@ -0,0 +1,123 @@ +#!/bin/sh + +test_description='cherry picking and reverting a merge + + b---c + / / + initial---a + +' + +. ./test-lib.sh + +test_expect_success setup ' + + >A && + >B && + git add A B && + git commit -m "Initial" && + git tag initial && + git branch side && + echo new line >A && + git commit -m "add line to A" A && + git tag a && + git checkout side && + echo new line >B && + git commit -m "add line to B" B && + git tag b && + git checkout master && + git merge side && + git tag c + +' + +test_expect_success 'cherry-pick a non-merge with -m should fail' ' + + git reset --hard && + git checkout a^0 && + test_must_fail git cherry-pick -m 1 b && + git diff --exit-code a -- + +' + +test_expect_success 'cherry pick a merge without -m should fail' ' + + git reset --hard && + git checkout a^0 && + test_must_fail git cherry-pick c && + git diff --exit-code a -- + +' + +test_expect_success 'cherry pick a merge (1)' ' + + git reset --hard && + git checkout a^0 && + git cherry-pick -m 1 c && + git diff --exit-code c + +' + +test_expect_success 'cherry pick a merge (2)' ' + + git reset --hard && + git checkout b^0 && + git cherry-pick -m 2 c && + git diff --exit-code c + +' + +test_expect_success 'cherry pick a merge relative to nonexistent parent should fail' ' + + git reset --hard && + git checkout b^0 && + test_must_fail git cherry-pick -m 3 c + +' + +test_expect_success 'revert a non-merge with -m should fail' ' + + git reset --hard && + git checkout c^0 && + test_must_fail git revert -m 1 b && + git diff --exit-code c + +' + +test_expect_success 'revert a merge without -m should fail' ' + + git reset --hard && + git checkout c^0 && + test_must_fail git revert c && + git diff --exit-code c + +' + +test_expect_success 'revert a merge (1)' ' + + git reset --hard && + git checkout c^0 && + git revert -m 1 c && + git diff --exit-code a -- + +' + +test_expect_success 'revert a merge (2)' ' + + git reset --hard && + git checkout c^0 && + git revert -m 2 c && + git diff --exit-code b -- + +' + +test_expect_success 'revert a merge relative to nonexistent parent should fail' ' + + git reset --hard && + git checkout c^0 && + test_must_fail git revert -m 3 c && + git diff --exit-code c + +' + +test_done diff --git a/t/t3503-cherry-pick-root.sh b/t/t3503-cherry-pick-root.sh new file mode 100755 index 0000000000..b0faa29918 --- /dev/null +++ b/t/t3503-cherry-pick-root.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +test_description='test cherry-picking a root commit' + +. ./test-lib.sh + +test_expect_success setup ' + + echo first > file1 && + git add file1 && + test_tick && + git commit -m "first" && + + git symbolic-ref HEAD refs/heads/second && + rm .git/index file1 && + echo second > file2 && + git add file2 && + test_tick && + git commit -m "second" + +' + +test_expect_success 'cherry-pick a root commit' ' + + git cherry-pick master && + test first = $(cat file1) + +' + +test_done diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh new file mode 100755 index 0000000000..79c06adf1f --- /dev/null +++ b/t/t3600-rm.sh @@ -0,0 +1,232 @@ +#!/bin/sh +# +# Copyright (c) 2006 Carl D. Worth +# + +test_description='Test of the various options to git rm.' + +. ./test-lib.sh + +# Setup some files to be removed, some with funny characters +test_expect_success \ + 'Initialize test directory' \ + "touch -- foo bar baz 'space embedded' -q && + git add -- foo bar baz 'space embedded' -q && + git-commit -m 'add normal files' && + test_tabs=y && + if touch -- 'tab embedded' 'newline +embedded' + then + git add -- 'tab embedded' 'newline +embedded' && + git-commit -m 'add files with tabs and newlines' + else + say 'Your filesystem does not allow tabs in filenames.' + test_tabs=n + fi" + +# Later we will try removing an unremovable path to make sure +# git rm barfs, but if the test is run as root that cannot be +# arranged. +test_expect_success \ + 'Determine rm behavior' \ + ': >test-file + chmod a-w . + rm -f test-file + test -f test-file && test_failed_remove=y + chmod 775 . + rm -f test-file' + +test_expect_success \ + 'Pre-check that foo exists and is in index before git rm foo' \ + '[ -f foo ] && git ls-files --error-unmatch foo' + +test_expect_success \ + 'Test that git rm foo succeeds' \ + 'git rm --cached foo' + +test_expect_success \ + 'Test that git rm --cached foo succeeds if the index matches the file' \ + 'echo content > foo + git add foo + git rm --cached foo' + +test_expect_success \ + 'Test that git rm --cached foo succeeds if the index matches the file' \ + 'echo content > foo + git add foo + git commit -m foo + echo "other content" > foo + git rm --cached foo' + +test_expect_success \ + 'Test that git rm --cached foo fails if the index matches neither the file nor HEAD' ' + echo content > foo + git add foo + git commit -m foo + echo "other content" > foo + git add foo + echo "yet another content" > foo + test_must_fail git rm --cached foo +' + +test_expect_success \ + 'Test that git rm --cached -f foo works in case where --cached only did not' \ + 'echo content > foo + git add foo + git commit -m foo + echo "other content" > foo + git add foo + echo "yet another content" > foo + git rm --cached -f foo' + +test_expect_success \ + 'Post-check that foo exists but is not in index after git rm foo' \ + '[ -f foo ] && test_must_fail git ls-files --error-unmatch foo' + +test_expect_success \ + 'Pre-check that bar exists and is in index before "git rm bar"' \ + '[ -f bar ] && git ls-files --error-unmatch bar' + +test_expect_success \ + 'Test that "git rm bar" succeeds' \ + 'git rm bar' + +test_expect_success \ + 'Post-check that bar does not exist and is not in index after "git rm -f bar"' \ + '! [ -f bar ] && test_must_fail git ls-files --error-unmatch bar' + +test_expect_success \ + 'Test that "git rm -- -q" succeeds (remove a file that looks like an option)' \ + 'git rm -- -q' + +test "$test_tabs" = y && test_expect_success \ + "Test that \"git rm -f\" succeeds with embedded space, tab, or newline characters." \ + "git rm -f 'space embedded' 'tab embedded' 'newline +embedded'" + +if test "$test_failed_remove" = y; then +chmod a-w . +test_expect_success \ + 'Test that "git rm -f" fails if its rm fails' \ + 'test_must_fail git rm -f baz' +chmod 775 . +else + test_expect_success 'skipping removal failure (perhaps running as root?)' : +fi + +test_expect_success \ + 'When the rm in "git rm -f" fails, it should not remove the file from the index' \ + 'git ls-files --error-unmatch baz' + +test_expect_success 'Remove nonexistent file with --ignore-unmatch' ' + git rm --ignore-unmatch nonexistent +' + +test_expect_success '"rm" command printed' ' + echo frotz > test-file && + git add test-file && + git commit -m "add file for rm test" && + git rm test-file > rm-output && + test `grep "^rm " rm-output | wc -l` = 1 && + rm -f test-file rm-output && + git commit -m "remove file from rm test" +' + +test_expect_success '"rm" command suppressed with --quiet' ' + echo frotz > test-file && + git add test-file && + git commit -m "add file for rm --quiet test" && + git rm --quiet test-file > rm-output && + test `wc -l < rm-output` = 0 && + rm -f test-file rm-output && + git commit -m "remove file from rm --quiet test" +' + +# Now, failure cases. +test_expect_success 'Re-add foo and baz' ' + git add foo baz && + git ls-files --error-unmatch foo baz +' + +test_expect_success 'Modify foo -- rm should refuse' ' + echo >>foo && + test_must_fail git rm foo baz && + test -f foo && + test -f baz && + git ls-files --error-unmatch foo baz +' + +test_expect_success 'Modified foo -- rm -f should work' ' + git rm -f foo baz && + test ! -f foo && + test ! -f baz && + test_must_fail git ls-files --error-unmatch foo && + test_must_fail git ls-files --error-unmatch bar +' + +test_expect_success 'Re-add foo and baz for HEAD tests' ' + echo frotz >foo && + git checkout HEAD -- baz && + git add foo baz && + git ls-files --error-unmatch foo baz +' + +test_expect_success 'foo is different in index from HEAD -- rm should refuse' ' + test_must_fail git rm foo baz && + test -f foo && + test -f baz && + git ls-files --error-unmatch foo baz +' + +test_expect_success 'but with -f it should work.' ' + git rm -f foo baz && + test ! -f foo && + test ! -f baz && + test_must_fail git ls-files --error-unmatch foo + test_must_fail git ls-files --error-unmatch baz +' + +test_expect_success 'Recursive test setup' ' + mkdir -p frotz && + echo qfwfq >frotz/nitfol && + git add frotz && + git commit -m "subdir test" +' + +test_expect_success 'Recursive without -r fails' ' + test_must_fail git rm frotz && + test -d frotz && + test -f frotz/nitfol +' + +test_expect_success 'Recursive with -r but dirty' ' + echo qfwfq >>frotz/nitfol + test_must_fail git rm -r frotz && + test -d frotz && + test -f frotz/nitfol +' + +test_expect_success 'Recursive with -r -f' ' + git rm -f -r frotz && + ! test -f frotz/nitfol && + ! test -d frotz +' + +test_expect_success 'Remove nonexistent file returns nonzero exit status' ' + test_must_fail git rm nonexistent +' + +test_expect_success 'Call "rm" from outside the work tree' ' + mkdir repo && + cd repo && + git init && + echo something > somefile && + git add somefile && + git commit -m "add a file" && + (cd .. && + git --git-dir=repo/.git --work-tree=repo rm somefile) && + test_must_fail git ls-files --error-unmatch somefile +' + +test_done diff --git a/t/t3700-add.sh b/t/t3700-add.sh new file mode 100755 index 0000000000..2ac93a346d --- /dev/null +++ b/t/t3700-add.sh @@ -0,0 +1,233 @@ +#!/bin/sh +# +# Copyright (c) 2006 Carl D. Worth +# + +test_description='Test of git add, including the -- option.' + +. ./test-lib.sh + +test_expect_success \ + 'Test of git add' \ + 'touch foo && git add foo' + +test_expect_success \ + 'Post-check that foo is in the index' \ + 'git ls-files foo | grep foo' + +test_expect_success \ + 'Test that "git add -- -q" works' \ + 'touch -- -q && git add -- -q' + +test_expect_success \ + 'git add: Test that executable bit is not used if core.filemode=0' \ + 'git config core.filemode 0 && + echo foo >xfoo1 && + chmod 755 xfoo1 && + git add xfoo1 && + case "`git ls-files --stage xfoo1`" in + 100644" "*xfoo1) echo ok;; + *) echo fail; git ls-files --stage xfoo1; (exit 1);; + esac' + +test_expect_success 'git add: filemode=0 should not get confused by symlink' ' + rm -f xfoo1 && + ln -s foo xfoo1 && + git add xfoo1 && + case "`git ls-files --stage xfoo1`" in + 120000" "*xfoo1) echo ok;; + *) echo fail; git ls-files --stage xfoo1; (exit 1);; + esac +' + +test_expect_success \ + 'git update-index --add: Test that executable bit is not used...' \ + 'git config core.filemode 0 && + echo foo >xfoo2 && + chmod 755 xfoo2 && + git update-index --add xfoo2 && + case "`git ls-files --stage xfoo2`" in + 100644" "*xfoo2) echo ok;; + *) echo fail; git ls-files --stage xfoo2; (exit 1);; + esac' + +test_expect_success 'git add: filemode=0 should not get confused by symlink' ' + rm -f xfoo2 && + ln -s foo xfoo2 && + git update-index --add xfoo2 && + case "`git ls-files --stage xfoo2`" in + 120000" "*xfoo2) echo ok;; + *) echo fail; git ls-files --stage xfoo2; (exit 1);; + esac +' + +test_expect_success \ + 'git update-index --add: Test that executable bit is not used...' \ + 'git config core.filemode 0 && + ln -s xfoo2 xfoo3 && + git update-index --add xfoo3 && + case "`git ls-files --stage xfoo3`" in + 120000" "*xfoo3) echo ok;; + *) echo fail; git ls-files --stage xfoo3; (exit 1);; + esac' + +test_expect_success '.gitignore test setup' ' + echo "*.ig" >.gitignore && + mkdir c.if d.ig && + >a.ig && >b.if && + >c.if/c.if && >c.if/c.ig && + >d.ig/d.if && >d.ig/d.ig +' + +test_expect_success '.gitignore is honored' ' + git add . && + ! (git ls-files | grep "\\.ig") +' + +test_expect_success 'error out when attempting to add ignored ones without -f' ' + test_must_fail git add a.?? && + ! (git ls-files | grep "\\.ig") +' + +test_expect_success 'error out when attempting to add ignored ones without -f' ' + test_must_fail git add d.?? && + ! (git ls-files | grep "\\.ig") +' + +test_expect_success 'add ignored ones with -f' ' + git add -f a.?? && + git ls-files --error-unmatch a.ig +' + +test_expect_success 'add ignored ones with -f' ' + git add -f d.??/* && + git ls-files --error-unmatch d.ig/d.if d.ig/d.ig +' + +test_expect_success 'add ignored ones with -f' ' + rm -f .git/index && + git add -f d.?? && + git ls-files --error-unmatch d.ig/d.if d.ig/d.ig +' + +test_expect_success '.gitignore with subdirectory' ' + + rm -f .git/index && + mkdir -p sub/dir && + echo "!dir/a.*" >sub/.gitignore && + >sub/a.ig && + >sub/dir/a.ig && + git add sub/dir && + git ls-files --error-unmatch sub/dir/a.ig && + rm -f .git/index && + ( + cd sub/dir && + git add . + ) && + git ls-files --error-unmatch sub/dir/a.ig +' + +mkdir 1 1/2 1/3 +touch 1/2/a 1/3/b 1/2/c +test_expect_success 'check correct prefix detection' ' + rm -f .git/index && + git add 1/2/a 1/3/b 1/2/c +' + +test_expect_success 'git add with filemode=0, symlinks=0, and unmerged entries' ' + for s in 1 2 3 + do + echo $s > stage$s + echo "100755 $(git hash-object -w stage$s) $s file" + echo "120000 $(printf $s | git hash-object -w -t blob --stdin) $s symlink" + done | git update-index --index-info && + git config core.filemode 0 && + git config core.symlinks 0 && + echo new > file && + echo new > symlink && + git add file symlink && + git ls-files --stage | grep "^100755 .* 0 file$" && + git ls-files --stage | grep "^120000 .* 0 symlink$" +' + +test_expect_success 'git add with filemode=0, symlinks=0 prefers stage 2 over stage 1' ' + git rm --cached -f file symlink && + ( + echo "100644 $(git hash-object -w stage1) 1 file" + echo "100755 $(git hash-object -w stage2) 2 file" + echo "100644 $(printf 1 | git hash-object -w -t blob --stdin) 1 symlink" + echo "120000 $(printf 2 | git hash-object -w -t blob --stdin) 2 symlink" + ) | git update-index --index-info && + git config core.filemode 0 && + git config core.symlinks 0 && + echo new > file && + echo new > symlink && + git add file symlink && + git ls-files --stage | grep "^100755 .* 0 file$" && + git ls-files --stage | grep "^120000 .* 0 symlink$" +' + +test_expect_success 'git add --refresh' ' + >foo && git add foo && git commit -a -m "commit all" && + test -z "`git diff-index HEAD -- foo`" && + git read-tree HEAD && + case "`git diff-index HEAD -- foo`" in + :100644" "*"M foo") echo ok;; + *) echo fail; (exit 1);; + esac && + git add --refresh -- foo && + test -z "`git diff-index HEAD -- foo`" +' + +test_expect_success 'git add should fail atomically upon an unreadable file' ' + git reset --hard && + date >foo1 && + date >foo2 && + chmod 0 foo2 && + test_must_fail git add --verbose . && + ! ( git ls-files foo1 | grep foo1 ) +' + +rm -f foo2 + +test_expect_success 'git add --ignore-errors' ' + git reset --hard && + date >foo1 && + date >foo2 && + chmod 0 foo2 && + test_must_fail git add --verbose --ignore-errors . && + git ls-files foo1 | grep foo1 +' + +rm -f foo2 + +test_expect_success 'git add (add.ignore-errors)' ' + git config add.ignore-errors 1 && + git reset --hard && + date >foo1 && + date >foo2 && + chmod 0 foo2 && + test_must_fail git add --verbose . && + git ls-files foo1 | grep foo1 +' +rm -f foo2 + +test_expect_success 'git add (add.ignore-errors = false)' ' + git config add.ignore-errors 0 && + git reset --hard && + date >foo1 && + date >foo2 && + chmod 0 foo2 && + test_must_fail git add --verbose . && + ! ( git ls-files foo1 | grep foo1 ) +' + +test_expect_success 'git add '\''fo\[ou\]bar'\'' ignores foobar' ' + git reset --hard && + touch fo\[ou\]bar foobar && + git add '\''fo\[ou\]bar'\'' && + git ls-files fo\[ou\]bar | grep -F fo\[ou\]bar && + ! ( git ls-files foobar | grep foobar ) +' + +test_done diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh new file mode 100755 index 0000000000..e95663d8e6 --- /dev/null +++ b/t/t3701-add-interactive.sh @@ -0,0 +1,162 @@ +#!/bin/sh + +test_description='add -i basic tests' +. ./test-lib.sh + +test_expect_success 'setup (initial)' ' + echo content >file && + git add file && + echo more >>file && + echo lines >>file +' +test_expect_success 'status works (initial)' ' + git add -i </dev/null >output && + grep "+1/-0 *+2/-0 file" output +' +cat >expected <<EOF +new file mode 100644 +index 0000000..d95f3ad +--- /dev/null ++++ b/file +@@ -0,0 +1 @@ ++content +EOF +test_expect_success 'diff works (initial)' ' + (echo d; echo 1) | git add -i >output && + sed -ne "/new file/,/content/p" <output >diff && + test_cmp expected diff +' +test_expect_success 'revert works (initial)' ' + git add file && + (echo r; echo 1) | git add -i && + git ls-files >output && + ! grep . output +' + +test_expect_success 'setup (commit)' ' + echo baseline >file && + git add file && + git commit -m commit && + echo content >>file && + git add file && + echo more >>file && + echo lines >>file +' +test_expect_success 'status works (commit)' ' + git add -i </dev/null >output && + grep "+1/-0 *+2/-0 file" output +' +cat >expected <<EOF +index 180b47c..b6f2c08 100644 +--- a/file ++++ b/file +@@ -1 +1,2 @@ + baseline ++content +EOF +test_expect_success 'diff works (commit)' ' + (echo d; echo 1) | git add -i >output && + sed -ne "/^index/,/content/p" <output >diff && + test_cmp expected diff +' +test_expect_success 'revert works (commit)' ' + git add file && + (echo r; echo 1) | git add -i && + git add -i </dev/null >output && + grep "unchanged *+3/-0 file" output +' + +cat >expected <<EOF +EOF +cat >fake_editor.sh <<EOF +EOF +chmod a+x fake_editor.sh +test_set_editor "$(pwd)/fake_editor.sh" +test_expect_success 'dummy edit works' ' + (echo e; echo a) | git add -p && + git diff > diff && + test_cmp expected diff +' + +cat >patch <<EOF +@@ -1,1 +1,4 @@ + this ++patch +-doesn't + apply +EOF +echo "#!$SHELL_PATH" >fake_editor.sh +cat >>fake_editor.sh <<\EOF +mv -f "$1" oldpatch && +mv -f patch "$1" +EOF +chmod a+x fake_editor.sh +test_set_editor "$(pwd)/fake_editor.sh" +test_expect_success 'bad edit rejected' ' + git reset && + (echo e; echo n; echo d) | git add -p >output && + grep "hunk does not apply" output +' + +cat >patch <<EOF +this patch +is garbage +EOF +test_expect_success 'garbage edit rejected' ' + git reset && + (echo e; echo n; echo d) | git add -p >output && + grep "hunk does not apply" output +' + +cat >patch <<EOF +@@ -1,0 +1,0 @@ + baseline ++content ++newcontent ++lines +EOF +cat >expected <<EOF +diff --git a/file b/file +index b5dd6c9..f910ae9 100644 +--- a/file ++++ b/file +@@ -1,4 +1,4 @@ + baseline + content +-newcontent ++more + lines +EOF +test_expect_success 'real edit works' ' + (echo e; echo n; echo d) | git add -p && + git diff >output && + test_cmp expected output +' + +if test "$(git config --bool core.filemode)" = false +then + say 'skipping filemode tests (filesystem does not properly support modes)' +else + +test_expect_success 'patch does not affect mode' ' + git reset --hard && + echo content >>file && + chmod +x file && + printf "n\\ny\\n" | git add -p && + git show :file | grep content && + git diff file | grep "new mode" +' + +test_expect_success 'stage mode but not hunk' ' + git reset --hard && + echo content >>file && + chmod +x file && + printf "y\\nn\\n" | git add -p && + git diff --cached file | grep "new mode" && + git diff file | grep "+content" +' + +fi +# end of tests disabled when filemode is not usable + +test_done diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh new file mode 100755 index 0000000000..c851db8ca9 --- /dev/null +++ b/t/t3800-mktag.sh @@ -0,0 +1,363 @@ +#!/bin/sh +# +# + +test_description='git-mktag: tag object verify test' + +. ./test-lib.sh + +########################################################### +# check the tag.sig file, expecting verify_tag() to fail, +# and checking that the error message matches the pattern +# given in the expect.pat file. + +check_verify_failure () { + expect="$2" + test_expect_success "$1" ' + ( test_must_fail git-mktag <tag.sig 2>message ) && + grep "$expect" message + ' +} + +########################################################### +# 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) + +############################################################ +# 1. length check + +cat >tag.sig <<EOF +too short for a tag +EOF + +check_verify_failure 'Tag object length check' \ + '^error: .*size wrong.*$' + +############################################################ +# 2. object line label check + +cat >tag.sig <<EOF +xxxxxx 139e9b33986b1c2670fff52c5067603117b3e895 +type tag +tag mytag +tagger . <> 0 +0000 + +EOF + +check_verify_failure '"object" line label check' '^error: char0: .*"object "$' + +############################################################ +# 3. object line SHA1 check + +cat >tag.sig <<EOF +object zz9e9b33986b1c2670fff52c5067603117b3e895 +type tag +tag mytag +tagger . <> 0 +0000 + +EOF + +check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$' + +############################################################ +# 4. type line label check + +cat >tag.sig <<EOF +object 779e9b33986b1c2670fff52c5067603117b3e895 +xxxx tag +tag mytag +tagger . <> 0 +0000 + +EOF + +check_verify_failure '"type" line label check' '^error: char47: .*"\\ntype "$' + +############################################################ +# 5. type line eol check + +echo "object 779e9b33986b1c2670fff52c5067603117b3e895" >tag.sig +printf "type tagsssssssssssssssssssssssssssssss" >>tag.sig + +check_verify_failure '"type" line eol check' '^error: char48: .*"\\n"$' + +############################################################ +# 6. tag line label check #1 + +cat >tag.sig <<EOF +object 779e9b33986b1c2670fff52c5067603117b3e895 +type tag +xxx mytag +tagger . <> 0 +0000 + +EOF + +check_verify_failure '"tag" line label check #1' \ + '^error: char57: no "tag " found$' + +############################################################ +# 7. tag line label check #2 + +cat >tag.sig <<EOF +object 779e9b33986b1c2670fff52c5067603117b3e895 +type taggggggggggggggggggggggggggggggg +tag +EOF + +check_verify_failure '"tag" line label check #2' \ + '^error: char87: no "tag " found$' + +############################################################ +# 8. type line type-name length check + +cat >tag.sig <<EOF +object 779e9b33986b1c2670fff52c5067603117b3e895 +type taggggggggggggggggggggggggggggggg +tag mytag +EOF + +check_verify_failure '"type" line type-name length check' \ + '^error: char53: type too long$' + +############################################################ +# 9. verify object (SHA1/type) check + +cat >tag.sig <<EOF +object 779e9b33986b1c2670fff52c5067603117b3e895 +type tagggg +tag mytag +tagger . <> 0 +0000 + +EOF + +check_verify_failure 'verify object (SHA1/type) check' \ + '^error: char7: could not verify object.*$' + +############################################################ +# 10. verify tag-name check + +cat >tag.sig <<EOF +object $head +type commit +tag my tag +tagger . <> 0 +0000 + +EOF + +check_verify_failure 'verify tag-name check' \ + '^error: char67: could not verify tag name$' + +############################################################ +# 11. tagger line label check #1 + +cat >tag.sig <<EOF +object $head +type commit +tag mytag + +This is filler +EOF + +check_verify_failure '"tagger" line label check #1' \ + '^error: char70: could not find "tagger "$' + +############################################################ +# 12. tagger line label check #2 + +cat >tag.sig <<EOF +object $head +type commit +tag mytag +tagger + +This is filler +EOF + +check_verify_failure '"tagger" line label check #2' \ + '^error: char70: could not find "tagger "$' + +############################################################ +# 13. disallow missing tag author name + +cat >tag.sig <<EOF +object $head +type commit +tag mytag +tagger <> 0 +0000 + +This is filler +EOF + +check_verify_failure 'disallow missing tag author name' \ + '^error: char77: missing tagger name$' + +############################################################ +# 14. disallow missing tag author name + +cat >tag.sig <<EOF +object $head +type commit +tag mytag +tagger T A Gger < + > 0 +0000 + +EOF + +check_verify_failure 'disallow malformed tagger' \ + '^error: char77: malformed tagger field$' + +############################################################ +# 15. allow empty tag email + +cat >tag.sig <<EOF +object $head +type commit +tag mytag +tagger T A Gger <> 0 +0000 + +EOF + +test_expect_success \ + 'allow empty tag email' \ + 'git-mktag <tag.sig >.git/refs/tags/mytag 2>message' + +############################################################ +# 16. disallow spaces in tag email + +cat >tag.sig <<EOF +object $head +type commit +tag mytag +tagger T A Gger <tag ger@example.com> 0 +0000 + +EOF + +check_verify_failure 'disallow spaces in tag email' \ + '^error: char77: malformed tagger field$' + +############################################################ +# 17. disallow missing tag timestamp + +tr '_' ' ' >tag.sig <<EOF +object $head +type commit +tag mytag +tagger T A Gger <tagger@example.com>__ + +EOF + +check_verify_failure 'disallow missing tag timestamp' \ + '^error: char107: missing tag timestamp$' + +############################################################ +# 18. detect invalid tag timestamp1 + +cat >tag.sig <<EOF +object $head +type commit +tag mytag +tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008 + +EOF + +check_verify_failure 'detect invalid tag timestamp1' \ + '^error: char107: missing tag timestamp$' + +############################################################ +# 19. detect invalid tag timestamp2 + +cat >tag.sig <<EOF +object $head +type commit +tag mytag +tagger T A Gger <tagger@example.com> 2008-03-31T12:20:15-0500 + +EOF + +check_verify_failure 'detect invalid tag timestamp2' \ + '^error: char111: malformed tag timestamp$' + +############################################################ +# 20. detect invalid tag timezone1 + +cat >tag.sig <<EOF +object $head +type commit +tag mytag +tagger T A Gger <tagger@example.com> 1206478233 GMT + +EOF + +check_verify_failure 'detect invalid tag timezone1' \ + '^error: char118: malformed tag timezone$' + +############################################################ +# 21. detect invalid tag timezone2 + +cat >tag.sig <<EOF +object $head +type commit +tag mytag +tagger T A Gger <tagger@example.com> 1206478233 + 30 + +EOF + +check_verify_failure 'detect invalid tag timezone2' \ + '^error: char118: malformed tag timezone$' + +############################################################ +# 22. detect invalid tag timezone3 + +cat >tag.sig <<EOF +object $head +type commit +tag mytag +tagger T A Gger <tagger@example.com> 1206478233 -1430 + +EOF + +check_verify_failure 'detect invalid tag timezone3' \ + '^error: char118: malformed tag timezone$' + +############################################################ +# 23. detect invalid header entry + +cat >tag.sig <<EOF +object $head +type commit +tag mytag +tagger T A Gger <tagger@example.com> 1206478233 -0500 +this line should not be here + +EOF + +check_verify_failure 'detect invalid header entry' \ + '^error: char124: trailing garbage in tag header$' + +############################################################ +# 24. create valid tag + +cat >tag.sig <<EOF +object $head +type commit +tag mytag +tagger T A Gger <tagger@example.com> 1206478233 -0500 + +EOF + +test_expect_success \ + 'create valid tag' \ + 'git-mktag <tag.sig >.git/refs/tags/mytag 2>message' + +############################################################ +# 25. check mytag + +test_expect_success \ + 'check mytag' \ + 'git-tag -l | grep mytag' + + +test_done diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh new file mode 100755 index 0000000000..883281dbd6 --- /dev/null +++ b/t/t3900-i18n-commit.sh @@ -0,0 +1,122 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='commit and log output encodings' + +. ./test-lib.sh + +compare_with () { + git show -s $1 | sed -e '1,/^$/d' -e 's/^ //' >current && + test_cmp current "$2" +} + +test_expect_success setup ' + : >F && + git add F && + T=$(git write-tree) && + C=$(git commit-tree $T <../t3900/1-UTF-8.txt) && + git update-ref HEAD $C && + git-tag C0 +' + +test_expect_success 'no encoding header for base case' ' + E=$(git cat-file commit C0 | sed -ne "s/^encoding //p") && + test z = "z$E" +' + +for H in ISO-8859-1 EUCJP ISO-2022-JP +do + test_expect_success "$H setup" ' + git config i18n.commitencoding $H && + git-checkout -b $H C0 && + echo $H >F && + git-commit -a -F ../t3900/$H.txt + ' +done + +for H in ISO-8859-1 EUCJP ISO-2022-JP +do + test_expect_success "check encoding header for $H" ' + E=$(git cat-file commit '$H' | sed -ne "s/^encoding //p") && + test "z$E" = "z'$H'" + ' +done + +test_expect_success 'config to remove customization' ' + git config --unset-all i18n.commitencoding && + if Z=$(git config --get-all i18n.commitencoding) + then + echo Oops, should have failed. + false + else + test z = "z$Z" + fi && + git config i18n.commitencoding utf-8 +' + +test_expect_success 'ISO-8859-1 should be shown in UTF-8 now' ' + compare_with ISO-8859-1 ../t3900/1-UTF-8.txt +' + +for H in EUCJP ISO-2022-JP +do + test_expect_success "$H should be shown in UTF-8 now" ' + compare_with '$H' ../t3900/2-UTF-8.txt + ' +done + +test_expect_success 'config to add customization' ' + git config --unset-all i18n.commitencoding && + if Z=$(git config --get-all i18n.commitencoding) + then + echo Oops, should have failed. + false + else + test z = "z$Z" + fi +' + +for H in ISO-8859-1 EUCJP ISO-2022-JP +do + test_expect_success "$H should be shown in itself now" ' + git config i18n.commitencoding '$H' && + compare_with '$H' ../t3900/'$H'.txt + ' +done + +test_expect_success 'config to tweak customization' ' + git config i18n.logoutputencoding utf-8 +' + +test_expect_success 'ISO-8859-1 should be shown in UTF-8 now' ' + compare_with ISO-8859-1 ../t3900/1-UTF-8.txt +' + +for H in EUCJP ISO-2022-JP +do + test_expect_success "$H should be shown in UTF-8 now" ' + compare_with '$H' ../t3900/2-UTF-8.txt + ' +done + +for J in EUCJP ISO-2022-JP +do + git config i18n.logoutputencoding $J + for H in EUCJP ISO-2022-JP + do + test_expect_success "$H should be shown in $J now" ' + compare_with '$H' ../t3900/'$J'.txt + ' + done +done + +for H in ISO-8859-1 EUCJP ISO-2022-JP +do + test_expect_success "No conversion with $H" ' + compare_with "--encoding=none '$H'" ../t3900/'$H'.txt + ' +done + +test_done diff --git a/t/t3900/1-UTF-8.txt b/t/t3900/1-UTF-8.txt new file mode 100644 index 0000000000..ee31e19738 --- /dev/null +++ b/t/t3900/1-UTF-8.txt @@ -0,0 +1,3 @@ +ÄËÑÃÖ + +Ãbçdèfg diff --git a/t/t3900/2-UTF-8.txt b/t/t3900/2-UTF-8.txt new file mode 100644 index 0000000000..63f4f8f121 --- /dev/null +++ b/t/t3900/2-UTF-8.txt @@ -0,0 +1,4 @@ +ã¯ã‚Œã²ã»ãµ + +ã—ã¦ã„ã‚‹ã®ãŒã€ã„ã‚‹ã®ã§ã€‚ +濱浜ã»ã‚Œã·ã‚Šã½ã‚Œã¾ã³ãã‚Šã‚ã¸ã€‚ diff --git a/t/t3900/EUCJP.txt b/t/t3900/EUCJP.txt new file mode 100644 index 0000000000..546f2aac01 --- /dev/null +++ b/t/t3900/EUCJP.txt @@ -0,0 +1,4 @@ +¤Ï¤ì¤Ò¤Û¤Õ + +¤·¤Æ¤¤¤ë¤Î¤¬¡¢¤¤¤ë¤Î¤Ç¡£ +ßÀÉͤۤì¤×¤ê¤Ý¤ì¤Þ¤Ó¤°¤ê¤í¤Ø¡£ diff --git a/t/t3900/ISO-2022-JP.txt b/t/t3900/ISO-2022-JP.txt new file mode 100644 index 0000000000..74b533042f --- /dev/null +++ b/t/t3900/ISO-2022-JP.txt @@ -0,0 +1,4 @@ +$B$O$l$R$[$U(B + +$B$7$F$$$k$N$,!"$$$k$N$G!#(B +$B_@IM$[$l$W$j$]$l$^$S$0$j$m$X!#(B diff --git a/t/t3900/ISO-8859-1.txt b/t/t3900/ISO-8859-1.txt new file mode 100644 index 0000000000..7cbef0ee6f --- /dev/null +++ b/t/t3900/ISO-8859-1.txt @@ -0,0 +1,3 @@ +ÄËÑÏÖ + +Ábçdèfg diff --git a/t/t3901-8859-1.txt b/t/t3901-8859-1.txt new file mode 100755 index 0000000000..38c21a6a7f --- /dev/null +++ b/t/t3901-8859-1.txt @@ -0,0 +1,4 @@ +: to be sourced in t3901 -- this is latin-1 +GIT_AUTHOR_NAME="Áéí óú" && +GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME && +export GIT_AUTHOR_NAME GIT_COMMITTER_NAME diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh new file mode 100755 index 0000000000..235f372832 --- /dev/null +++ b/t/t3901-i18n-patch.sh @@ -0,0 +1,255 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='i18n settings and format-patch | am pipe' + +. ./test-lib.sh + +check_encoding () { + # Make sure characters are not corrupted + cnt="$1" header="$2" i=1 j=0 bad=0 + while test "$i" -le $cnt + do + git format-patch --encoding=UTF-8 --stdout HEAD~$i..HEAD~$j | + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD=20=C3=B3=C3=BA?=" && + git cat-file commit HEAD~$j | + case "$header" in + 8859) + grep "^encoding ISO-8859-1" ;; + *) + ! grep "^encoding ISO-8859-1" ;; + esac || { + bad=1 + break + } + j=$i + i=$(($i+1)) + done + (exit $bad) +} + +test_expect_success setup ' + git config i18n.commitencoding UTF-8 && + + # use UTF-8 in author and committer name to match the + # i18n.commitencoding settings + . ../t3901-utf8.txt && + + test_tick && + echo "$GIT_AUTHOR_NAME" >mine && + git add mine && + git commit -s -m "Initial commit" && + + test_tick && + echo Hello world >mine && + git add mine && + git commit -s -m "Second on main" && + + # the first commit on the side branch is UTF-8 + test_tick && + git checkout -b side master^ && + echo Another file >yours && + git add yours && + git commit -s -m "Second on side" && + + # the second one on the side branch is ISO-8859-1 + git config i18n.commitencoding ISO-8859-1 && + # use author and committer name in ISO-8859-1 to match it. + . ../t3901-8859-1.txt && + test_tick && + echo Yet another >theirs && + git add theirs && + git commit -s -m "Third on side" && + + # Back to default + git config i18n.commitencoding UTF-8 +' + +test_expect_success 'format-patch output (ISO-8859-1)' ' + git config i18n.logoutputencoding ISO-8859-1 && + + git format-patch --stdout master..HEAD^ >out-l1 && + git format-patch --stdout HEAD^ >out-l2 && + grep "^Content-Type: text/plain; charset=ISO-8859-1" out-l1 && + grep "^From: =?ISO-8859-1?q?=C1=E9=ED=20=F3=FA?=" out-l1 && + grep "^Content-Type: text/plain; charset=ISO-8859-1" out-l2 && + grep "^From: =?ISO-8859-1?q?=C1=E9=ED=20=F3=FA?=" out-l2 +' + +test_expect_success 'format-patch output (UTF-8)' ' + git config i18n.logoutputencoding UTF-8 && + + git format-patch --stdout master..HEAD^ >out-u1 && + git format-patch --stdout HEAD^ >out-u2 && + grep "^Content-Type: text/plain; charset=UTF-8" out-u1 && + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD=20=C3=B3=C3=BA?=" out-u1 && + grep "^Content-Type: text/plain; charset=UTF-8" out-u2 && + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD=20=C3=B3=C3=BA?=" out-u2 +' + +test_expect_success 'rebase (U/U)' ' + # We want the result of rebase in UTF-8 + git config i18n.commitencoding UTF-8 && + + # The test is about logoutputencoding not affecting the + # final outcome -- it is used internally to generate the + # patch and the log. + + git config i18n.logoutputencoding UTF-8 && + + # The result will be committed by GIT_COMMITTER_NAME -- + # we want UTF-8 encoded name. + . ../t3901-utf8.txt && + git checkout -b test && + git-rebase master && + + check_encoding 2 +' + +test_expect_success 'rebase (U/L)' ' + git config i18n.commitencoding UTF-8 && + git config i18n.logoutputencoding ISO-8859-1 && + . ../t3901-utf8.txt && + + git reset --hard side && + git-rebase master && + + check_encoding 2 +' + +test_expect_success 'rebase (L/L)' ' + # In this test we want ISO-8859-1 encoded commits as the result + git config i18n.commitencoding ISO-8859-1 && + git config i18n.logoutputencoding ISO-8859-1 && + . ../t3901-8859-1.txt && + + git reset --hard side && + git-rebase master && + + check_encoding 2 8859 +' + +test_expect_success 'rebase (L/U)' ' + # This is pathological -- use UTF-8 as intermediate form + # to get ISO-8859-1 results. + git config i18n.commitencoding ISO-8859-1 && + git config i18n.logoutputencoding UTF-8 && + . ../t3901-8859-1.txt && + + git reset --hard side && + git-rebase master && + + check_encoding 2 8859 +' + +test_expect_success 'cherry-pick(U/U)' ' + # Both the commitencoding and logoutputencoding is set to UTF-8. + + git config i18n.commitencoding UTF-8 && + git config i18n.logoutputencoding UTF-8 && + . ../t3901-utf8.txt && + + git reset --hard master && + git cherry-pick side^ && + git cherry-pick side && + git revert HEAD && + + check_encoding 3 +' + +test_expect_success 'cherry-pick(L/L)' ' + # Both the commitencoding and logoutputencoding is set to ISO-8859-1 + + git config i18n.commitencoding ISO-8859-1 && + git config i18n.logoutputencoding ISO-8859-1 && + . ../t3901-8859-1.txt && + + git reset --hard master && + git cherry-pick side^ && + git cherry-pick side && + git revert HEAD && + + check_encoding 3 8859 +' + +test_expect_success 'cherry-pick(U/L)' ' + # Commitencoding is set to UTF-8 but logoutputencoding is ISO-8859-1 + + git config i18n.commitencoding UTF-8 && + git config i18n.logoutputencoding ISO-8859-1 && + . ../t3901-utf8.txt && + + git reset --hard master && + git cherry-pick side^ && + git cherry-pick side && + git revert HEAD && + + check_encoding 3 +' + +test_expect_success 'cherry-pick(L/U)' ' + # Again, the commitencoding is set to ISO-8859-1 but + # logoutputencoding is set to UTF-8. + + git config i18n.commitencoding ISO-8859-1 && + git config i18n.logoutputencoding UTF-8 && + . ../t3901-8859-1.txt && + + git reset --hard master && + git cherry-pick side^ && + git cherry-pick side && + git revert HEAD && + + check_encoding 3 8859 +' + +test_expect_success 'rebase --merge (U/U)' ' + git config i18n.commitencoding UTF-8 && + git config i18n.logoutputencoding UTF-8 && + . ../t3901-utf8.txt && + + git reset --hard side && + git-rebase --merge master && + + check_encoding 2 +' + +test_expect_success 'rebase --merge (U/L)' ' + git config i18n.commitencoding UTF-8 && + git config i18n.logoutputencoding ISO-8859-1 && + . ../t3901-utf8.txt && + + git reset --hard side && + git-rebase --merge master && + + check_encoding 2 +' + +test_expect_success 'rebase --merge (L/L)' ' + # In this test we want ISO-8859-1 encoded commits as the result + git config i18n.commitencoding ISO-8859-1 && + git config i18n.logoutputencoding ISO-8859-1 && + . ../t3901-8859-1.txt && + + git reset --hard side && + git-rebase --merge master && + + check_encoding 2 8859 +' + +test_expect_success 'rebase --merge (L/U)' ' + # This is pathological -- use UTF-8 as intermediate form + # to get ISO-8859-1 results. + git config i18n.commitencoding ISO-8859-1 && + git config i18n.logoutputencoding UTF-8 && + . ../t3901-8859-1.txt && + + git reset --hard side && + git-rebase --merge master && + + check_encoding 2 8859 +' + +test_done diff --git a/t/t3901-utf8.txt b/t/t3901-utf8.txt new file mode 100755 index 0000000000..5f5205cd02 --- /dev/null +++ b/t/t3901-utf8.txt @@ -0,0 +1,4 @@ +: to be sourced in t3901 -- this is utf8 +GIT_AUTHOR_NAME="Ãéà óú" && +GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME && +export GIT_AUTHOR_NAME GIT_COMMITTER_NAME diff --git a/t/t3902-quoted.sh b/t/t3902-quoted.sh new file mode 100755 index 0000000000..fe4fb5116a --- /dev/null +++ b/t/t3902-quoted.sh @@ -0,0 +1,139 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='quoted output' + +. ./test-lib.sh + +P1='pathname with HT' +: >"$P1" 2>&1 && test -f "$P1" && rm -f "$P1" || { + echo >&2 'Filesystem does not support HT in names' + test_done +} + +FN='濱野' +GN='ç´”' +HT=' ' +LF=' +' +DQ='"' + +echo foo > "Name and an${HT}HT" +test -f "Name and an${HT}HT" || { + # since FAT/NTFS does not allow tabs in filenames, skip this test + say 'Your filesystem does not allow tabs in filenames, test skipped.' + test_done +} + +for_each_name () { + for name in \ + Name "Name and a${LF}LF" "Name and an${HT}HT" "Name${DQ}" \ + "$FN$HT$GN" "$FN$LF$GN" "$FN $GN" "$FN$GN" "$FN$DQ$GN" \ + "With SP in it" + do + eval "$1" + done +} + +test_expect_success setup ' + + for_each_name "echo initial >\"\$name\"" + git add . && + git commit -q -m Initial && + + for_each_name "echo second >\"\$name\"" && + git commit -a -m Second + + for_each_name "echo modified >\"\$name\"" + +' + +cat >expect.quoted <<\EOF +Name +"Name and a\nLF" +"Name and an\tHT" +"Name\"" +With SP in it +"\346\277\261\351\207\216\t\347\264\224" +"\346\277\261\351\207\216\n\347\264\224" +"\346\277\261\351\207\216 \347\264\224" +"\346\277\261\351\207\216\"\347\264\224" +"\346\277\261\351\207\216\347\264\224" +EOF + +cat >expect.raw <<\EOF +Name +"Name and a\nLF" +"Name and an\tHT" +"Name\"" +With SP in it +"濱野\tç´”" +"濱野\nç´”" +濱野 ç´” +"濱野\"ç´”" +濱野純 +EOF + +test_expect_success 'check fully quoted output from ls-files' ' + + git ls-files >current && test_cmp expect.quoted current + +' + +test_expect_success 'check fully quoted output from diff-files' ' + + git diff --name-only >current && + test_cmp expect.quoted current + +' + +test_expect_success 'check fully quoted output from diff-index' ' + + git diff --name-only HEAD >current && + test_cmp expect.quoted current + +' + +test_expect_success 'check fully quoted output from diff-tree' ' + + git diff --name-only HEAD^ HEAD >current && + test_cmp expect.quoted current + +' + +test_expect_success 'setting core.quotepath' ' + + git config --bool core.quotepath false + +' + +test_expect_success 'check fully quoted output from ls-files' ' + + git ls-files >current && test_cmp expect.raw current + +' + +test_expect_success 'check fully quoted output from diff-files' ' + + git diff --name-only >current && + test_cmp expect.raw current + +' + +test_expect_success 'check fully quoted output from diff-index' ' + + git diff --name-only HEAD >current && + test_cmp expect.raw current + +' + +test_expect_success 'check fully quoted output from diff-tree' ' + + git diff --name-only HEAD^ HEAD >current && + test_cmp expect.raw current + +' + +test_done diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh new file mode 100755 index 0000000000..8d4804b658 --- /dev/null +++ b/t/t3903-stash.sh @@ -0,0 +1,180 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes E Schindelin +# + +test_description='Test git-stash' + +. ./test-lib.sh + +test_expect_success 'stash some dirty working directory' ' + echo 1 > file && + git add file && + test_tick && + git commit -m initial && + echo 2 > file && + git add file && + echo 3 > file && + test_tick && + git stash && + git diff-files --quiet && + git diff-index --cached --quiet HEAD +' + +cat > expect << EOF +diff --git a/file b/file +index 0cfbf08..00750ed 100644 +--- a/file ++++ b/file +@@ -1 +1 @@ +-2 ++3 +EOF + +test_expect_success 'parents of stash' ' + test $(git rev-parse stash^) = $(git rev-parse HEAD) && + git diff stash^2..stash > output && + test_cmp output expect +' + +test_expect_success 'apply needs clean working directory' ' + echo 4 > other-file && + git add other-file && + echo 5 > other-file && + test_must_fail git stash apply +' + +test_expect_success 'apply stashed changes' ' + git add other-file && + test_tick && + git commit -m other-file && + git stash apply && + test 3 = $(cat file) && + test 1 = $(git show :file) && + test 1 = $(git show HEAD:file) +' + +test_expect_success 'apply stashed changes (including index)' ' + git reset --hard HEAD^ && + echo 6 > other-file && + git add other-file && + test_tick && + git commit -m other-file && + git stash apply --index && + test 3 = $(cat file) && + test 2 = $(git show :file) && + test 1 = $(git show HEAD:file) +' + +test_expect_success 'unstashing in a subdirectory' ' + git reset --hard HEAD && + mkdir subdir && + cd subdir && + git stash apply && + cd .. +' + +test_expect_success 'drop top stash' ' + git reset --hard && + git stash list > stashlist1 && + echo 7 > file && + git stash && + git stash drop && + git stash list > stashlist2 && + diff stashlist1 stashlist2 && + git stash apply && + test 3 = $(cat file) && + test 1 = $(git show :file) && + test 1 = $(git show HEAD:file) +' + +test_expect_success 'drop middle stash' ' + git reset --hard && + echo 8 > file && + git stash && + echo 9 > file && + git stash && + git stash drop stash@{1} && + test 2 = $(git stash list | wc -l) && + git stash apply && + test 9 = $(cat file) && + test 1 = $(git show :file) && + test 1 = $(git show HEAD:file) && + git reset --hard && + git stash drop && + git stash apply && + test 3 = $(cat file) && + test 1 = $(git show :file) && + test 1 = $(git show HEAD:file) +' + +test_expect_success 'stash pop' ' + git reset --hard && + git stash pop && + test 3 = $(cat file) && + test 1 = $(git show :file) && + test 1 = $(git show HEAD:file) && + test 0 = $(git stash list | wc -l) +' + +cat > expect << EOF +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..1fe912c +--- /dev/null ++++ b/file2 +@@ -0,0 +1 @@ ++bar2 +EOF + +cat > expect1 << EOF +diff --git a/file b/file +index 257cc56..5716ca5 100644 +--- a/file ++++ b/file +@@ -1 +1 @@ +-foo ++bar +EOF + +cat > expect2 << EOF +diff --git a/file b/file +index 7601807..5716ca5 100644 +--- a/file ++++ b/file +@@ -1 +1 @@ +-baz ++bar +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..1fe912c +--- /dev/null ++++ b/file2 +@@ -0,0 +1 @@ ++bar2 +EOF + +test_expect_success 'stash branch' ' + echo foo > file && + git commit file -m first + echo bar > file && + echo bar2 > file2 && + git add file2 && + git stash && + echo baz > file && + git commit file -m second && + git stash branch stashbranch && + test refs/heads/stashbranch = $(git symbolic-ref HEAD) && + test $(git rev-parse HEAD) = $(git rev-parse master^) && + git diff --cached > output && + test_cmp output expect && + git diff > output && + test_cmp output expect1 && + git add file && + git commit -m alternate\ second && + git diff master..stashbranch > output && + test_cmp output expect2 && + test 0 = $(git stash list | wc -l) +' + +test_done diff --git a/t/t4000-diff-format.sh b/t/t4000-diff-format.sh new file mode 100755 index 0000000000..c44b27aeb2 --- /dev/null +++ b/t/t4000-diff-format.sh @@ -0,0 +1,62 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Test built-in diff output engine. + +' +. ./test-lib.sh +. ../diff-lib.sh + +echo >path0 'Line 1 +Line 2 +line 3' +cat path0 >path1 +chmod +x path1 + +test_expect_success \ + 'update-index --add two files with and without +x.' \ + 'git update-index --add path0 path1' + +mv path0 path0- +sed -e 's/line/Line/' <path0- >path0 +chmod +x path0 +rm -f path1 +test_expect_success \ + 'git diff-files -p after editing work tree.' \ + 'git diff-files -p >current' + +# that's as far as it comes +if [ "$(git config --get core.filemode)" = false ] +then + say 'filemode disabled on the filesystem' + test_done +fi + +cat >expected <<\EOF +diff --git a/path0 b/path0 +old mode 100644 +new mode 100755 +--- a/path0 ++++ b/path0 +@@ -1,3 +1,3 @@ + Line 1 + Line 2 +-line 3 ++Line 3 +diff --git a/path1 b/path1 +deleted file mode 100755 +--- a/path1 ++++ /dev/null +@@ -1,3 +0,0 @@ +-Line 1 +-Line 2 +-line 3 +EOF + +test_expect_success \ + 'validate git diff-files -p output.' \ + 'compare_diff_patch current expected' + +test_done diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh new file mode 100755 index 0000000000..a32692417d --- /dev/null +++ b/t/t4001-diff-rename.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Test rename detection in diff engine. + +' +. ./test-lib.sh +. ../diff-lib.sh + +echo >path0 'Line 1 +Line 2 +Line 3 +Line 4 +Line 5 +Line 6 +Line 7 +Line 8 +Line 9 +Line 10 +line 11 +Line 12 +Line 13 +Line 14 +Line 15 +' + +test_expect_success \ + 'update-index --add a file.' \ + 'git update-index --add path0' + +test_expect_success \ + 'write that tree.' \ + 'tree=$(git write-tree) && echo $tree' + +sed -e 's/line/Line/' <path0 >path1 +rm -f path0 +test_expect_success \ + 'renamed and edited the file.' \ + 'git update-index --add --remove path0 path1' + +test_expect_success \ + 'git diff-index -p -M after rename and editing.' \ + 'git diff-index -p -M $tree >current' +cat >expected <<\EOF +diff --git a/path0 b/path1 +rename from path0 +rename to path1 +--- a/path0 ++++ b/path1 +@@ -8,7 +8,7 @@ Line 7 + Line 8 + Line 9 + Line 10 +-line 11 ++Line 11 + Line 12 + Line 13 + Line 14 +EOF + +test_expect_success \ + 'validate the output.' \ + 'compare_diff_patch current expected' + +test_expect_success 'favour same basenames over different ones' ' + cp path1 another-path && + git add another-path && + git commit -m 1 && + git rm path1 && + mkdir subdir && + git mv another-path subdir/path1 && + git status | grep "renamed: .*path1 -> subdir/path1"' + +test_expect_success 'favour same basenames even with minor differences' ' + git show HEAD:path1 | sed "s/15/16/" > subdir/path1 && + git status | grep "renamed: .*path1 -> subdir/path1"' + +test_done diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh new file mode 100755 index 0000000000..a4cfde6b29 --- /dev/null +++ b/t/t4002-diff-basic.sh @@ -0,0 +1,247 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Test diff raw-output. + +' +. ./test-lib.sh +. ../lib-read-tree-m-3way.sh + +cat >.test-plain-OA <<\EOF +:000000 100644 0000000000000000000000000000000000000000 ccba72ad3888a3520b39efcf780b9ee64167535d A AA +:000000 100644 0000000000000000000000000000000000000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 A AN +:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D DD +:000000 040000 0000000000000000000000000000000000000000 6d50f65d3bdab91c63444294d38f08aeff328e42 A DF +:100644 000000 141c1f1642328e4bc46a7d801a71da392e66791e 0000000000000000000000000000000000000000 D DM +:100644 000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 0000000000000000000000000000000000000000 D DN +:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A LL +:100644 100644 03f24c8c4700babccfd28b654e7e8eac402ad6cd 103d9f89b50b9aad03054b579be5e7aa665f2d57 M MD +:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 M MM +:100644 100644 bd084b0c27c7b6cc34f11d6d0509a29be3caf970 a716d58de4a570e0038f5c307bd8db34daea021f M MN +:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M SS +:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 4c86f9a85fbc5e6804ee2e17a797538fbe785bca M TT +:040000 040000 7d670fdcdb9929f6c7dac196ff78689cd1c566a1 5e5f22072bb39f6e12cf663a57cb634c76eefb49 M Z +EOF + +cat >.test-recursive-OA <<\EOF +:000000 100644 0000000000000000000000000000000000000000 ccba72ad3888a3520b39efcf780b9ee64167535d A AA +:000000 100644 0000000000000000000000000000000000000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 A AN +:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D DD +:000000 100644 0000000000000000000000000000000000000000 68a6d8b91da11045cf4aa3a5ab9f2a781c701249 A DF/DF +:100644 000000 141c1f1642328e4bc46a7d801a71da392e66791e 0000000000000000000000000000000000000000 D DM +:100644 000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 0000000000000000000000000000000000000000 D DN +:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A LL +:100644 100644 03f24c8c4700babccfd28b654e7e8eac402ad6cd 103d9f89b50b9aad03054b579be5e7aa665f2d57 M MD +:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 M MM +:100644 100644 bd084b0c27c7b6cc34f11d6d0509a29be3caf970 a716d58de4a570e0038f5c307bd8db34daea021f M MN +:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M SS +:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 4c86f9a85fbc5e6804ee2e17a797538fbe785bca M TT +:000000 100644 0000000000000000000000000000000000000000 8acb8e9750e3f644bf323fcf3d338849db106c77 A Z/AA +:000000 100644 0000000000000000000000000000000000000000 087494262084cefee7ed484d20c8dc0580791272 A Z/AN +:100644 000000 879007efae624d2b1307214b24a956f0a8d686a8 0000000000000000000000000000000000000000 D Z/DD +:100644 000000 9b541b2275c06e3a7b13f28badf5294e2ae63df4 0000000000000000000000000000000000000000 D Z/DM +:100644 000000 beb5d38c55283d280685ea21a0e50cfcc0ca064a 0000000000000000000000000000000000000000 D Z/DN +:100644 100644 d41fda41b7ec4de46b43cb7ea42a45001ae393d5 a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9 M Z/MD +:100644 100644 4ca22bae2527d3d9e1676498a0fba3b355bd1278 61422ba9c2c873416061a88cd40a59a35b576474 M Z/MM +:100644 100644 b16d7b25b869f2beb124efa53467d8a1550ad694 a5c544c21cfcb07eb80a4d89a5b7d1570002edfd M Z/MN +EOF +cat >.test-plain-OB <<\EOF +:000000 100644 0000000000000000000000000000000000000000 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 A AA +:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D DD +:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A DF +:100644 100644 141c1f1642328e4bc46a7d801a71da392e66791e 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 M DM +:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A LL +:100644 000000 03f24c8c4700babccfd28b654e7e8eac402ad6cd 0000000000000000000000000000000000000000 D MD +:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 19989d4559aae417fedee240ccf2ba315ea4dc2b M MM +:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A NA +:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D ND +:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M NM +:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M SS +:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M TT +:040000 040000 7d670fdcdb9929f6c7dac196ff78689cd1c566a1 1ba523955d5160681af65cb776411f574c1e8155 M Z +EOF +cat >.test-recursive-OB <<\EOF +:000000 100644 0000000000000000000000000000000000000000 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 A AA +:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D DD +:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A DF +:100644 100644 141c1f1642328e4bc46a7d801a71da392e66791e 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 M DM +:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A LL +:100644 000000 03f24c8c4700babccfd28b654e7e8eac402ad6cd 0000000000000000000000000000000000000000 D MD +:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 19989d4559aae417fedee240ccf2ba315ea4dc2b M MM +:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A NA +:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D ND +:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M NM +:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M SS +:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M TT +:000000 100644 0000000000000000000000000000000000000000 6c0b99286d0bce551ac4a7b3dff8b706edff3715 A Z/AA +:100644 000000 879007efae624d2b1307214b24a956f0a8d686a8 0000000000000000000000000000000000000000 D Z/DD +:100644 100644 9b541b2275c06e3a7b13f28badf5294e2ae63df4 d77371d15817fcaa57eeec27f770c505ba974ec1 M Z/DM +:100644 000000 d41fda41b7ec4de46b43cb7ea42a45001ae393d5 0000000000000000000000000000000000000000 D Z/MD +:100644 100644 4ca22bae2527d3d9e1676498a0fba3b355bd1278 697aad7715a1e7306ca76290a3dd4208fbaeddfa M Z/MM +:000000 100644 0000000000000000000000000000000000000000 d12979c22fff69c59ca9409e7a8fe3ee25eaee80 A Z/NA +:100644 000000 a18393c636b98e9bd7296b8b437ea4992b72440c 0000000000000000000000000000000000000000 D Z/ND +:100644 100644 3fdbe17fd013303a2e981e1ca1c6cd6e72789087 7e09d6a3a14bd630913e8c75693cea32157b606d M Z/NM +EOF +cat >.test-plain-AB <<\EOF +:100644 100644 ccba72ad3888a3520b39efcf780b9ee64167535d 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 M AA +:100644 000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 0000000000000000000000000000000000000000 D AN +:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A DF +:040000 000000 6d50f65d3bdab91c63444294d38f08aeff328e42 0000000000000000000000000000000000000000 D DF +:000000 100644 0000000000000000000000000000000000000000 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 A DM +:000000 100644 0000000000000000000000000000000000000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 A DN +:100644 000000 103d9f89b50b9aad03054b579be5e7aa665f2d57 0000000000000000000000000000000000000000 D MD +:100644 100644 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 19989d4559aae417fedee240ccf2ba315ea4dc2b M MM +:100644 100644 a716d58de4a570e0038f5c307bd8db34daea021f bd084b0c27c7b6cc34f11d6d0509a29be3caf970 M MN +:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A NA +:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D ND +:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M NM +:100644 100644 4c86f9a85fbc5e6804ee2e17a797538fbe785bca c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M TT +:040000 040000 5e5f22072bb39f6e12cf663a57cb634c76eefb49 1ba523955d5160681af65cb776411f574c1e8155 M Z +EOF +cat >.test-recursive-AB <<\EOF +:100644 100644 ccba72ad3888a3520b39efcf780b9ee64167535d 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 M AA +:100644 000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 0000000000000000000000000000000000000000 D AN +:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A DF +:100644 000000 68a6d8b91da11045cf4aa3a5ab9f2a781c701249 0000000000000000000000000000000000000000 D DF/DF +:000000 100644 0000000000000000000000000000000000000000 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 A DM +:000000 100644 0000000000000000000000000000000000000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 A DN +:100644 000000 103d9f89b50b9aad03054b579be5e7aa665f2d57 0000000000000000000000000000000000000000 D MD +:100644 100644 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 19989d4559aae417fedee240ccf2ba315ea4dc2b M MM +:100644 100644 a716d58de4a570e0038f5c307bd8db34daea021f bd084b0c27c7b6cc34f11d6d0509a29be3caf970 M MN +:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A NA +:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D ND +:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M NM +:100644 100644 4c86f9a85fbc5e6804ee2e17a797538fbe785bca c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M TT +:100644 100644 8acb8e9750e3f644bf323fcf3d338849db106c77 6c0b99286d0bce551ac4a7b3dff8b706edff3715 M Z/AA +:100644 000000 087494262084cefee7ed484d20c8dc0580791272 0000000000000000000000000000000000000000 D Z/AN +:000000 100644 0000000000000000000000000000000000000000 d77371d15817fcaa57eeec27f770c505ba974ec1 A Z/DM +:000000 100644 0000000000000000000000000000000000000000 beb5d38c55283d280685ea21a0e50cfcc0ca064a A Z/DN +:100644 000000 a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9 0000000000000000000000000000000000000000 D Z/MD +:100644 100644 61422ba9c2c873416061a88cd40a59a35b576474 697aad7715a1e7306ca76290a3dd4208fbaeddfa M Z/MM +:100644 100644 a5c544c21cfcb07eb80a4d89a5b7d1570002edfd b16d7b25b869f2beb124efa53467d8a1550ad694 M Z/MN +:000000 100644 0000000000000000000000000000000000000000 d12979c22fff69c59ca9409e7a8fe3ee25eaee80 A Z/NA +:100644 000000 a18393c636b98e9bd7296b8b437ea4992b72440c 0000000000000000000000000000000000000000 D Z/ND +:100644 100644 3fdbe17fd013303a2e981e1ca1c6cd6e72789087 7e09d6a3a14bd630913e8c75693cea32157b606d M Z/NM +EOF + +x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' +x40="$x40$x40$x40$x40$x40$x40$x40$x40" +z40='0000000000000000000000000000000000000000' +cmp_diff_files_output () { + # diff-files never reports additions. Also it does not fill in the + # object ID for the changed files because it wants you to look at the + # filesystem. + sed <"$2" >.test-tmp \ + -e '/^:000000 /d;s/'$x40'\( [MCRNDU][0-9]*\) /'$z40'\1 /' && + diff "$1" .test-tmp +} + +test_expect_success \ + 'diff-tree of known trees.' \ + 'git diff-tree $tree_O $tree_A >.test-a && + cmp -s .test-a .test-plain-OA' + +test_expect_success \ + 'diff-tree of known trees.' \ + 'git diff-tree -r $tree_O $tree_A >.test-a && + cmp -s .test-a .test-recursive-OA' + +test_expect_success \ + 'diff-tree of known trees.' \ + 'git diff-tree $tree_O $tree_B >.test-a && + cmp -s .test-a .test-plain-OB' + +test_expect_success \ + 'diff-tree of known trees.' \ + 'git diff-tree -r $tree_O $tree_B >.test-a && + cmp -s .test-a .test-recursive-OB' + +test_expect_success \ + 'diff-tree of known trees.' \ + 'git diff-tree $tree_A $tree_B >.test-a && + cmp -s .test-a .test-plain-AB' + +test_expect_success \ + 'diff-tree of known trees.' \ + 'git diff-tree -r $tree_A $tree_B >.test-a && + cmp -s .test-a .test-recursive-AB' + +test_expect_success \ + 'diff-cache O with A in cache' \ + 'git read-tree $tree_A && + git diff-index --cached $tree_O >.test-a && + cmp -s .test-a .test-recursive-OA' + +test_expect_success \ + 'diff-cache O with B in cache' \ + 'git read-tree $tree_B && + git diff-index --cached $tree_O >.test-a && + cmp -s .test-a .test-recursive-OB' + +test_expect_success \ + 'diff-cache A with B in cache' \ + 'git read-tree $tree_B && + git diff-index --cached $tree_A >.test-a && + cmp -s .test-a .test-recursive-AB' + +test_expect_success \ + 'diff-files with O in cache and A checked out' \ + 'rm -fr Z [A-Z][A-Z] && + git read-tree $tree_A && + git checkout-index -f -a && + git read-tree --reset $tree_O || return 1 + git update-index --refresh >/dev/null ;# this can exit non-zero + git diff-files >.test-a && + cmp_diff_files_output .test-a .test-recursive-OA' + +test_expect_success \ + 'diff-files with O in cache and B checked out' \ + 'rm -fr Z [A-Z][A-Z] && + git read-tree $tree_B && + git checkout-index -f -a && + git read-tree --reset $tree_O || return 1 + git update-index --refresh >/dev/null ;# this can exit non-zero + git diff-files >.test-a && + cmp_diff_files_output .test-a .test-recursive-OB' + +test_expect_success \ + 'diff-files with A in cache and B checked out' \ + 'rm -fr Z [A-Z][A-Z] && + git read-tree $tree_B && + git checkout-index -f -a && + git read-tree --reset $tree_A || return 1 + git update-index --refresh >/dev/null ;# this can exit non-zero + git diff-files >.test-a && + cmp_diff_files_output .test-a .test-recursive-AB' + +################################################################ +# Now we have established the baseline, we do not have to +# rely on individual object ID values that much. + +test_expect_success \ + 'diff-tree O A == diff-tree -R A O' \ + 'git diff-tree $tree_O $tree_A >.test-a && + git diff-tree -R $tree_A $tree_O >.test-b && + cmp -s .test-a .test-b' + +test_expect_success \ + 'diff-tree -r O A == diff-tree -r -R A O' \ + 'git diff-tree -r $tree_O $tree_A >.test-a && + git diff-tree -r -R $tree_A $tree_O >.test-b && + cmp -s .test-a .test-b' + +test_expect_success \ + 'diff-tree B A == diff-tree -R A B' \ + 'git diff-tree $tree_B $tree_A >.test-a && + git diff-tree -R $tree_A $tree_B >.test-b && + cmp -s .test-a .test-b' + +test_expect_success \ + 'diff-tree -r B A == diff-tree -r -R A B' \ + 'git diff-tree -r $tree_B $tree_A >.test-a && + git diff-tree -r -R $tree_A $tree_B >.test-b && + cmp -s .test-a .test-b' + +test_done diff --git a/t/t4003-diff-rename-1.sh b/t/t4003-diff-rename-1.sh new file mode 100755 index 0000000000..8b1f875286 --- /dev/null +++ b/t/t4003-diff-rename-1.sh @@ -0,0 +1,128 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='More rename detection + +' +. ./test-lib.sh +. ../diff-lib.sh ;# test-lib chdir's into trash + +test_expect_success \ + 'prepare reference tree' \ + 'cat ../../COPYING >COPYING && + echo frotz >rezrov && + git update-index --add COPYING rezrov && + tree=$(git write-tree) && + echo $tree' + +test_expect_success \ + 'prepare work tree' \ + 'sed -e 's/HOWEVER/However/' <COPYING >COPYING.1 && + sed -e 's/GPL/G.P.L/g' <COPYING >COPYING.2 && + rm -f COPYING && + git update-index --add --remove COPYING COPYING.?' + +# tree has COPYING and rezrov. work tree has COPYING.1 and COPYING.2, +# both are slightly edited, and unchanged rezrov. So we say you +# copy-and-edit one, and rename-and-edit the other. We do not say +# anything about rezrov. + +GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree >current +cat >expected <<\EOF +diff --git a/COPYING b/COPYING.1 +copy from COPYING +copy to COPYING.1 +--- a/COPYING ++++ b/COPYING.1 +@@ -6 +6 @@ +- HOWEVER, in order to allow a migration to GPLv3 if that seems like ++ However, in order to allow a migration to GPLv3 if that seems like +diff --git a/COPYING b/COPYING.2 +rename from COPYING +rename to COPYING.2 +--- a/COPYING ++++ b/COPYING.2 +@@ -2 +2 @@ +- Note that the only valid version of the GPL as far as this project ++ Note that the only valid version of the G.P.L as far as this project +@@ -6 +6 @@ +- HOWEVER, in order to allow a migration to GPLv3 if that seems like ++ HOWEVER, in order to allow a migration to G.P.Lv3 if that seems like +@@ -12 +12 @@ +- This file is licensed under the GPL v2, or a later version ++ This file is licensed under the G.P.L v2, or a later version +EOF + +test_expect_success \ + 'validate output from rename/copy detection (#1)' \ + 'compare_diff_patch current expected' + +test_expect_success \ + 'prepare work tree again' \ + 'mv COPYING.2 COPYING && + git update-index --add --remove COPYING COPYING.1 COPYING.2' + +# tree has COPYING and rezrov. work tree has COPYING and COPYING.1, +# both are slightly edited, and unchanged rezrov. So we say you +# edited one, and copy-and-edit the other. We do not say +# anything about rezrov. + +GIT_DIFF_OPTS=--unified=0 git diff-index -C -p $tree >current +cat >expected <<\EOF +diff --git a/COPYING b/COPYING +--- a/COPYING ++++ b/COPYING +@@ -2 +2 @@ +- Note that the only valid version of the GPL as far as this project ++ Note that the only valid version of the G.P.L as far as this project +@@ -6 +6 @@ +- HOWEVER, in order to allow a migration to GPLv3 if that seems like ++ HOWEVER, in order to allow a migration to G.P.Lv3 if that seems like +@@ -12 +12 @@ +- This file is licensed under the GPL v2, or a later version ++ This file is licensed under the G.P.L v2, or a later version +diff --git a/COPYING b/COPYING.1 +copy from COPYING +copy to COPYING.1 +--- a/COPYING ++++ b/COPYING.1 +@@ -6 +6 @@ +- HOWEVER, in order to allow a migration to GPLv3 if that seems like ++ However, in order to allow a migration to GPLv3 if that seems like +EOF + +test_expect_success \ + 'validate output from rename/copy detection (#2)' \ + 'compare_diff_patch current expected' + +test_expect_success \ + 'prepare work tree once again' \ + 'cat ../../COPYING >COPYING && + git update-index --add --remove COPYING COPYING.1' + +# tree has COPYING and rezrov. work tree has COPYING and COPYING.1, +# but COPYING is not edited. We say you copy-and-edit COPYING.1; this +# is only possible because -C mode now reports the unmodified file to +# the diff-core. Unchanged rezrov, although being fed to +# git diff-index as well, should not be mentioned. + +GIT_DIFF_OPTS=--unified=0 \ + git diff-index -C --find-copies-harder -p $tree >current +cat >expected <<\EOF +diff --git a/COPYING b/COPYING.1 +copy from COPYING +copy to COPYING.1 +--- a/COPYING ++++ b/COPYING.1 +@@ -6 +6 @@ +- HOWEVER, in order to allow a migration to GPLv3 if that seems like ++ However, in order to allow a migration to GPLv3 if that seems like +EOF + +test_expect_success \ + 'validate output from rename/copy detection (#3)' \ + 'compare_diff_patch current expected' + +test_done diff --git a/t/t4004-diff-rename-symlink.sh b/t/t4004-diff-rename-symlink.sh new file mode 100755 index 0000000000..3d25be7a67 --- /dev/null +++ b/t/t4004-diff-rename-symlink.sh @@ -0,0 +1,67 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='More rename detection tests. + +The rename detection logic should be able to detect pure rename or +copy of symbolic links, but should not produce rename/copy followed +by an edit for them. +' +. ./test-lib.sh +. ../diff-lib.sh + +test_expect_success \ + 'prepare reference tree' \ + 'echo xyzzy | tr -d '\\\\'012 >yomin && + ln -s xyzzy frotz && + git update-index --add frotz yomin && + tree=$(git write-tree) && + echo $tree' + +test_expect_success \ + 'prepare work tree' \ + 'mv frotz rezrov && + rm -f yomin && + ln -s xyzzy nitfol && + ln -s xzzzy bozbar && + git update-index --add --remove frotz rezrov nitfol bozbar yomin' + +# tree has frotz pointing at xyzzy, and yomin that contains xyzzy to +# confuse things. work tree has rezrov (xyzzy) nitfol (xyzzy) and +# bozbar (xzzzy). +# rezrov and nitfol are rename/copy of frotz and bozbar should be +# a new creation. + +GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree >current +cat >expected <<\EOF +diff --git a/bozbar b/bozbar +new file mode 120000 +--- /dev/null ++++ b/bozbar +@@ -0,0 +1 @@ ++xzzzy +\ No newline at end of file +diff --git a/frotz b/nitfol +similarity index 100% +copy from frotz +copy to nitfol +diff --git a/frotz b/rezrov +similarity index 100% +rename from frotz +rename to rezrov +diff --git a/yomin b/yomin +deleted file mode 100644 +--- a/yomin ++++ /dev/null +@@ -1 +0,0 @@ +-xyzzy +\ No newline at end of file +EOF + +test_expect_success \ + 'validate diff output' \ + 'compare_diff_patch current expected' + +test_done diff --git a/t/t4005-diff-rename-2.sh b/t/t4005-diff-rename-2.sh new file mode 100755 index 0000000000..6630017312 --- /dev/null +++ b/t/t4005-diff-rename-2.sh @@ -0,0 +1,86 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Same rename detection as t4003 but testing diff-raw. + +' +. ./test-lib.sh +. ../diff-lib.sh ;# test-lib chdir's into trash + +test_expect_success \ + 'prepare reference tree' \ + 'cat ../../COPYING >COPYING && + echo frotz >rezrov && + git update-index --add COPYING rezrov && + tree=$(git write-tree) && + echo $tree' + +test_expect_success \ + 'prepare work tree' \ + 'sed -e 's/HOWEVER/However/' <COPYING >COPYING.1 && + sed -e 's/GPL/G.P.L/g' <COPYING >COPYING.2 && + rm -f COPYING && + git update-index --add --remove COPYING COPYING.?' + +# tree has COPYING and rezrov. work tree has COPYING.1 and COPYING.2, +# both are slightly edited, and unchanged rezrov. We say COPYING.1 +# and COPYING.2 are based on COPYING, and do not say anything about +# rezrov. + +git diff-index -M $tree >current + +cat >expected <<\EOF +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 COPYING COPYING.1 +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 R1234 COPYING COPYING.2 +EOF + +test_expect_success \ + 'validate output from rename/copy detection (#1)' \ + 'compare_diff_raw current expected' + +################################################################ + +test_expect_success \ + 'prepare work tree again' \ + 'mv COPYING.2 COPYING && + git update-index --add --remove COPYING COPYING.1 COPYING.2' + +# tree has COPYING and rezrov. work tree has COPYING and COPYING.1, +# both are slightly edited, and unchanged rezrov. We say COPYING.1 +# is based on COPYING and COPYING is still there, and do not say anything +# about rezrov. + +git diff-index -C $tree >current +cat >expected <<\EOF +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 M COPYING +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 COPYING COPYING.1 +EOF + +test_expect_success \ + 'validate output from rename/copy detection (#2)' \ + 'compare_diff_raw current expected' + +################################################################ + +# tree has COPYING and rezrov. work tree has the same COPYING and +# copy-edited COPYING.1, and unchanged rezrov. We should not say +# anything about rezrov nor COPYING, since the revised again diff-raw +# nows how to say Copy. + +test_expect_success \ + 'prepare work tree once again' \ + 'cat ../../COPYING >COPYING && + git update-index --add --remove COPYING COPYING.1' + +git diff-index -C --find-copies-harder $tree >current +cat >expected <<\EOF +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 COPYING COPYING.1 +EOF + +test_expect_success \ + 'validate output from rename/copy detection (#3)' \ + 'compare_diff_raw current expected' + +test_done diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh new file mode 100755 index 0000000000..4e92fce1d0 --- /dev/null +++ b/t/t4006-diff-mode.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Test mode change diffs. + +' +. ./test-lib.sh + +test_expect_success \ + 'setup' \ + 'echo frotz >rezrov && + git update-index --add rezrov && + tree=`git write-tree` && + echo $tree' + +if [ "$(git config --get core.filemode)" = false ] +then + say 'filemode disabled on the filesystem, using update-index --chmod=+x' + test_expect_success \ + 'git update-index --chmod=+x' \ + 'git update-index rezrov && + git update-index --chmod=+x rezrov && + git diff-index $tree >current' +else + test_expect_success \ + 'chmod' \ + 'chmod +x rezrov && + git update-index rezrov && + git diff-index $tree >current' +fi + +_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' +_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" +sed -e 's/\(:100644 100755\) \('"$_x40"'\) \2 /\1 X X /' <current >check +echo ":100644 100755 X X M rezrov" >expected + +test_expect_success \ + 'verify' \ + 'test_cmp expected check' + +test_done diff --git a/t/t4007-rename-3.sh b/t/t4007-rename-3.sh new file mode 100755 index 0000000000..104a4e1492 --- /dev/null +++ b/t/t4007-rename-3.sh @@ -0,0 +1,90 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Rename interaction with pathspec. + +' +. ./test-lib.sh +. ../diff-lib.sh ;# test-lib chdir's into trash + +test_expect_success \ + 'prepare reference tree' \ + 'mkdir path0 path1 && + cp ../../COPYING path0/COPYING && + git update-index --add path0/COPYING && + tree=$(git write-tree) && + echo $tree' + +test_expect_success \ + 'prepare work tree' \ + 'cp path0/COPYING path1/COPYING && + git update-index --add --remove path0/COPYING path1/COPYING' + +# In the tree, there is only path0/COPYING. In the cache, path0 and +# path1 both have COPYING and the latter is a copy of path0/COPYING. +# Comparing the full tree with cache should tell us so. + +git diff-index -C --find-copies-harder $tree >current + +cat >expected <<\EOF +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 C100 path0/COPYING path1/COPYING +EOF + +test_expect_success \ + 'validate the result (#1)' \ + 'compare_diff_raw current expected' + +# In the tree, there is only path0/COPYING. In the cache, path0 and +# path1 both have COPYING and the latter is a copy of path0/COPYING. +# However when we say we care only about path1, we should just see +# path1/COPYING suddenly appearing from nowhere, not detected as +# a copy from path0/COPYING. + +git diff-index -C $tree path1 >current + +cat >expected <<\EOF +:000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 A path1/COPYING +EOF + +test_expect_success \ + 'validate the result (#2)' \ + 'compare_diff_raw current expected' + +test_expect_success \ + 'tweak work tree' \ + 'rm -f path0/COPYING && + git update-index --remove path0/COPYING' + +# In the tree, there is only path0/COPYING. In the cache, path0 does +# not have COPYING anymore and path1 has COPYING which is a copy of +# path0/COPYING. Showing the full tree with cache should tell us about +# the rename. + +git diff-index -C $tree >current + +cat >expected <<\EOF +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 R100 path0/COPYING path1/COPYING +EOF + +test_expect_success \ + 'validate the result (#3)' \ + 'compare_diff_raw current expected' + +# In the tree, there is only path0/COPYING. In the cache, path0 does +# not have COPYING anymore and path1 has COPYING which is a copy of +# path0/COPYING. When we say we care only about path1, we should just +# see path1/COPYING appearing from nowhere. + +git diff-index -C $tree path1 >current + +cat >expected <<\EOF +:000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 A path1/COPYING +EOF + +test_expect_success \ + 'validate the result (#4)' \ + 'compare_diff_raw current expected' + +test_done diff --git a/t/t4008-diff-break-rewrite.sh b/t/t4008-diff-break-rewrite.sh new file mode 100755 index 0000000000..26c2e4aa65 --- /dev/null +++ b/t/t4008-diff-break-rewrite.sh @@ -0,0 +1,188 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Break and then rename + +We have two very different files, file0 and file1, registered in a tree. + +We update file1 so drastically that it is more similar to file0, and +then remove file0. With -B, changes to file1 should be broken into +separate delete and create, resulting in removal of file0, removal of +original file1 and creation of completely rewritten file1. + +Further, with -B and -M together, these three modifications should +turn into rename-edit of file0 into file1. + +Starting from the same two files in the tree, we swap file0 and file1. +With -B, this should be detected as two complete rewrites, resulting in +four changes in total. + +Further, with -B and -M together, these should turn into two renames. +' +. ./test-lib.sh +. ../diff-lib.sh ;# test-lib chdir's into trash + +test_expect_success \ + setup \ + 'cat ../../README >file0 && + cat ../../COPYING >file1 && + git update-index --add file0 file1 && + tree=$(git write-tree) && + echo "$tree"' + +test_expect_success \ + 'change file1 with copy-edit of file0 and remove file0' \ + 'sed -e "s/git/GIT/" file0 >file1 && + rm -f file0 && + git update-index --remove file0 file1' + +test_expect_success \ + 'run diff with -B' \ + 'git diff-index -B --cached "$tree" >current' + +cat >expected <<\EOF +:100644 000000 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 0000000000000000000000000000000000000000 D file0 +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 11e331465a89c394dc25c780de230043750c1ec8 M100 file1 +EOF + +test_expect_success \ + 'validate result of -B (#1)' \ + 'compare_diff_raw expected current' + +test_expect_success \ + 'run diff with -B and -M' \ + 'git diff-index -B -M "$tree" >current' + +cat >expected <<\EOF +:100644 100644 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 08bb2fb671deff4c03a4d4a0a1315dff98d5732c R100 file0 file1 +EOF + +test_expect_success \ + 'validate result of -B -M (#2)' \ + 'compare_diff_raw expected current' + +test_expect_success \ + 'swap file0 and file1' \ + 'rm -f file0 file1 && + git read-tree -m $tree && + git checkout-index -f -u -a && + mv file0 tmp && + mv file1 file0 && + mv tmp file1 && + git update-index file0 file1' + +test_expect_success \ + 'run diff with -B' \ + 'git diff-index -B "$tree" >current' + +cat >expected <<\EOF +:100644 100644 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 6ff87c4664981e4397625791c8ea3bbb5f2279a3 M100 file0 +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 M100 file1 +EOF + +test_expect_success \ + 'validate result of -B (#3)' \ + 'compare_diff_raw expected current' + +test_expect_success \ + 'run diff with -B and -M' \ + 'git diff-index -B -M "$tree" >current' + +cat >expected <<\EOF +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 R100 file1 file0 +:100644 100644 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 R100 file0 file1 +EOF + +test_expect_success \ + 'validate result of -B -M (#4)' \ + 'compare_diff_raw expected current' + +test_expect_success \ + 'make file0 into something completely different' \ + 'rm -f file0 && + ln -s frotz file0 && + git update-index file0 file1' + +test_expect_success \ + 'run diff with -B' \ + 'git diff-index -B "$tree" >current' + +cat >expected <<\EOF +:100644 120000 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 67be421f88824578857624f7b3dc75e99a8a1481 T file0 +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 M100 file1 +EOF + +test_expect_success \ + 'validate result of -B (#5)' \ + 'compare_diff_raw expected current' + +test_expect_success \ + 'run diff with -B -M' \ + 'git diff-index -B -M "$tree" >current' + +# file0 changed from regular to symlink. file1 is very close to the preimage of file0. +# because we break file0, file1 can become a rename of it. +cat >expected <<\EOF +:100644 120000 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 67be421f88824578857624f7b3dc75e99a8a1481 T file0 +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 R file0 file1 +EOF + +test_expect_success \ + 'validate result of -B -M (#6)' \ + 'compare_diff_raw expected current' + +test_expect_success \ + 'run diff with -M' \ + 'git diff-index -M "$tree" >current' + +# This should not mistake file0 as the copy source of new file1 +# due to type differences. +cat >expected <<\EOF +:100644 120000 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 67be421f88824578857624f7b3dc75e99a8a1481 T file0 +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 M file1 +EOF + +test_expect_success \ + 'validate result of -M (#7)' \ + 'compare_diff_raw expected current' + +test_expect_success \ + 'file1 edited to look like file0 and file0 rename-edited to file2' \ + 'rm -f file0 file1 && + git read-tree -m $tree && + git checkout-index -f -u -a && + sed -e "s/git/GIT/" file0 >file1 && + sed -e "s/git/GET/" file0 >file2 && + rm -f file0 + git update-index --add --remove file0 file1 file2' + +test_expect_success \ + 'run diff with -B' \ + 'git diff-index -B "$tree" >current' + +cat >expected <<\EOF +:100644 000000 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 0000000000000000000000000000000000000000 D file0 +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 08bb2fb671deff4c03a4d4a0a1315dff98d5732c M100 file1 +:000000 100644 0000000000000000000000000000000000000000 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 A file2 +EOF + +test_expect_success \ + 'validate result of -B (#8)' \ + 'compare_diff_raw expected current' + +test_expect_success \ + 'run diff with -B -M' \ + 'git diff-index -B -M "$tree" >current' + +cat >expected <<\EOF +:100644 100644 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 08bb2fb671deff4c03a4d4a0a1315dff98d5732c C095 file0 file1 +:100644 100644 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 59f832e5c8b3f7e486be15ad0cd3e95ba9af8998 R095 file0 file2 +EOF + +test_expect_success \ + 'validate result of -B -M (#9)' \ + 'compare_diff_raw expected current' + +test_done diff --git a/t/t4009-diff-rename-4.sh b/t/t4009-diff-rename-4.sh new file mode 100755 index 0000000000..d2b45e7b8f --- /dev/null +++ b/t/t4009-diff-rename-4.sh @@ -0,0 +1,95 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Same rename detection as t4003 but testing diff-raw -z. + +' +. ./test-lib.sh +. ../diff-lib.sh ;# test-lib chdir's into trash + +test_expect_success \ + 'prepare reference tree' \ + 'cat ../../COPYING >COPYING && + echo frotz >rezrov && + git update-index --add COPYING rezrov && + tree=$(git write-tree) && + echo $tree' + +test_expect_success \ + 'prepare work tree' \ + 'sed -e 's/HOWEVER/However/' <COPYING >COPYING.1 && + sed -e 's/GPL/G.P.L/g' <COPYING >COPYING.2 && + rm -f COPYING && + git update-index --add --remove COPYING COPYING.?' + +# tree has COPYING and rezrov. work tree has COPYING.1 and COPYING.2, +# both are slightly edited, and unchanged rezrov. We say COPYING.1 +# and COPYING.2 are based on COPYING, and do not say anything about +# rezrov. + +git diff-index -z -M $tree >current + +cat >expected <<\EOF +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 +COPYING +COPYING.1 +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 R1234 +COPYING +COPYING.2 +EOF + +test_expect_success \ + 'validate output from rename/copy detection (#1)' \ + 'compare_diff_raw_z current expected' + +################################################################ + +test_expect_success \ + 'prepare work tree again' \ + 'mv COPYING.2 COPYING && + git update-index --add --remove COPYING COPYING.1 COPYING.2' + +# tree has COPYING and rezrov. work tree has COPYING and COPYING.1, +# both are slightly edited, and unchanged rezrov. We say COPYING.1 +# is based on COPYING and COPYING is still there, and do not say anything +# about rezrov. + +git diff-index -z -C $tree >current +cat >expected <<\EOF +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 M +COPYING +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 +COPYING +COPYING.1 +EOF + +test_expect_success \ + 'validate output from rename/copy detection (#2)' \ + 'compare_diff_raw_z current expected' + +################################################################ + +# tree has COPYING and rezrov. work tree has the same COPYING and +# copy-edited COPYING.1, and unchanged rezrov. We should not say +# anything about rezrov nor COPYING, since the revised again diff-raw +# nows how to say Copy. + +test_expect_success \ + 'prepare work tree once again' \ + 'cat ../../COPYING >COPYING && + git update-index --add --remove COPYING COPYING.1' + +git diff-index -z -C --find-copies-harder $tree >current +cat >expected <<\EOF +:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 +COPYING +COPYING.1 +EOF + +test_expect_success \ + 'validate output from rename/copy detection (#3)' \ + 'compare_diff_raw_z current expected' + +test_done diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh new file mode 100755 index 0000000000..ad3d9e4845 --- /dev/null +++ b/t/t4010-diff-pathspec.sh @@ -0,0 +1,65 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Pathspec restrictions + +Prepare: + file0 + path1/file1 +' +. ./test-lib.sh +. ../diff-lib.sh ;# test-lib chdir's into trash + +test_expect_success \ + setup \ + 'echo frotz >file0 && + mkdir path1 && + echo rezrov >path1/file1 && + git update-index --add file0 path1/file1 && + tree=`git write-tree` && + echo "$tree" && + echo nitfol >file0 && + echo yomin >path1/file1 && + git update-index file0 path1/file1' + +cat >expected <<\EOF +EOF +test_expect_success \ + 'limit to path should show nothing' \ + 'git diff-index --cached $tree -- path >current && + compare_diff_raw current expected' + +cat >expected <<\EOF +:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M path1/file1 +EOF +test_expect_success \ + 'limit to path1 should show path1/file1' \ + 'git diff-index --cached $tree -- path1 >current && + compare_diff_raw current expected' + +cat >expected <<\EOF +:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M path1/file1 +EOF +test_expect_success \ + 'limit to path1/ should show path1/file1' \ + 'git diff-index --cached $tree -- path1/ >current && + compare_diff_raw current expected' + +cat >expected <<\EOF +:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M file0 +EOF +test_expect_success \ + 'limit to file0 should show file0' \ + 'git diff-index --cached $tree -- file0 >current && + compare_diff_raw current expected' + +cat >expected <<\EOF +EOF +test_expect_success \ + 'limit to file0/ should emit nothing.' \ + 'git diff-index --cached $tree -- file0/ >current && + compare_diff_raw current expected' + +test_done diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh new file mode 100755 index 0000000000..c6d13693ba --- /dev/null +++ b/t/t4011-diff-symlink.sh @@ -0,0 +1,85 @@ +#!/bin/sh +# +# Copyright (c) 2005 Johannes Schindelin +# + +test_description='Test diff of symlinks. + +' +. ./test-lib.sh +. ../diff-lib.sh + +cat > expected << EOF +diff --git a/frotz b/frotz +new file mode 120000 +index 0000000..7c465af +--- /dev/null ++++ b/frotz +@@ -0,0 +1 @@ ++xyzzy +\ No newline at end of file +EOF + +test_expect_success \ + 'diff new symlink' \ + 'ln -s xyzzy frotz && + git update-index && + tree=$(git write-tree) && + git update-index --add frotz && + GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree > current && + compare_diff_patch current expected' + +test_expect_success \ + 'diff unchanged symlink' \ + 'tree=$(git write-tree) && + git update-index frotz && + test -z "$(git diff-index --name-only $tree)"' + +cat > expected << EOF +diff --git a/frotz b/frotz +deleted file mode 120000 +index 7c465af..0000000 +--- a/frotz ++++ /dev/null +@@ -1 +0,0 @@ +-xyzzy +\ No newline at end of file +EOF + +test_expect_success \ + 'diff removed symlink' \ + 'rm frotz && + git diff-index -M -p $tree > current && + compare_diff_patch current expected' + +cat > expected << EOF +diff --git a/frotz b/frotz +EOF + +test_expect_success \ + 'diff identical, but newly created symlink' \ + 'sleep 3 && + ln -s xyzzy frotz && + git diff-index -M -p $tree > current && + compare_diff_patch current expected' + +cat > expected << EOF +diff --git a/frotz b/frotz +index 7c465af..df1db54 120000 +--- a/frotz ++++ b/frotz +@@ -1 +1 @@ +-xyzzy +\ No newline at end of file ++yxyyz +\ No newline at end of file +EOF + +test_expect_success \ + 'diff different symlink' \ + 'rm frotz && + ln -s yxyyz frotz && + git diff-index -M -p $tree > current && + compare_diff_patch current expected' + +test_done diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh new file mode 100755 index 0000000000..eced1f30fb --- /dev/null +++ b/t/t4012-diff-binary.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='Binary diff and apply +' + +. ./test-lib.sh + +test_expect_success 'prepare repository' \ + 'echo AIT >a && echo BIT >b && echo CIT >c && echo DIT >d && + git update-index --add a b c d && + echo git >a && + cat ../test4012.png >b && + echo git >c && + cat b b >d' + +cat > expected <<\EOF + a | 2 +- + b | Bin + c | 2 +- + d | Bin + 4 files changed, 2 insertions(+), 2 deletions(-) +EOF +test_expect_success 'diff without --binary' \ + 'git diff | git apply --stat --summary >current && + cmp current expected' + +test_expect_success 'diff with --binary' \ + 'git diff --binary | git apply --stat --summary >current && + cmp current expected' + +# apply needs to be able to skip the binary material correctly +# in order to report the line number of a corrupt patch. +test_expect_success 'apply detecting corrupt patch correctly' \ + 'git diff | sed -e 's/-CIT/xCIT/' >broken && + if git apply --stat --summary broken 2>detected + then + echo unhappy - should have detected an error + (exit 1) + else + echo happy + fi && + detected=`cat detected` && + detected=`expr "$detected" : "fatal.*at line \\([0-9]*\\)\$"` && + detected=`sed -ne "${detected}p" broken` && + test "$detected" = xCIT' + +test_expect_success 'apply detecting corrupt patch correctly' \ + 'git diff --binary | sed -e 's/-CIT/xCIT/' >broken && + if git apply --stat --summary broken 2>detected + then + echo unhappy - should have detected an error + (exit 1) + else + echo happy + fi && + detected=`cat detected` && + detected=`expr "$detected" : "fatal.*at line \\([0-9]*\\)\$"` && + detected=`sed -ne "${detected}p" broken` && + test "$detected" = xCIT' + +test_expect_success 'initial commit' 'git-commit -a -m initial' + +# Try removal (b), modification (d), and creation (e). +test_expect_success 'diff-index with --binary' \ + 'echo AIT >a && mv b e && echo CIT >c && cat e >d && + git update-index --add --remove a b c d e && + tree0=`git write-tree` && + git diff --cached --binary >current && + git apply --stat --summary current' + +test_expect_success 'apply binary patch' \ + 'git-reset --hard && + git apply --binary --index <current && + tree1=`git write-tree` && + test "$tree1" = "$tree0"' + +test_done diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh new file mode 100755 index 0000000000..9337b81064 --- /dev/null +++ b/t/t4013-diff-various.sh @@ -0,0 +1,263 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='Various diff formatting options' + +. ./test-lib.sh + +LF=' +' + +test_expect_success setup ' + + GIT_AUTHOR_DATE="2006-06-26 00:00:00 +0000" && + GIT_COMMITTER_DATE="2006-06-26 00:00:00 +0000" && + export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && + + mkdir dir && + mkdir dir2 && + for i in 1 2 3; do echo $i; done >file0 && + for i in A B; do echo $i; done >dir/sub && + cat file0 >file2 && + git add file0 file2 dir/sub && + git commit -m Initial && + + git branch initial && + git branch side && + + GIT_AUTHOR_DATE="2006-06-26 00:01:00 +0000" && + GIT_COMMITTER_DATE="2006-06-26 00:01:00 +0000" && + export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && + + for i in 4 5 6; do echo $i; done >>file0 && + for i in C D; do echo $i; done >>dir/sub && + rm -f file2 && + git update-index --remove file0 file2 dir/sub && + git commit -m "Second${LF}${LF}This is the second commit." && + + GIT_AUTHOR_DATE="2006-06-26 00:02:00 +0000" && + GIT_COMMITTER_DATE="2006-06-26 00:02:00 +0000" && + export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && + + for i in A B C; do echo $i; done >file1 && + git add file1 && + for i in E F; do echo $i; done >>dir/sub && + git update-index dir/sub && + git commit -m Third && + + GIT_AUTHOR_DATE="2006-06-26 00:03:00 +0000" && + GIT_COMMITTER_DATE="2006-06-26 00:03:00 +0000" && + export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && + + git checkout side && + for i in A B C; do echo $i; done >>file0 && + for i in 1 2; do echo $i; done >>dir/sub && + cat dir/sub >file3 && + git add file3 && + git update-index file0 dir/sub && + git commit -m Side && + + GIT_AUTHOR_DATE="2006-06-26 00:04:00 +0000" && + GIT_COMMITTER_DATE="2006-06-26 00:04:00 +0000" && + export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && + + git checkout master && + git pull -s ours . side && + + GIT_AUTHOR_DATE="2006-06-26 00:05:00 +0000" && + GIT_COMMITTER_DATE="2006-06-26 00:05:00 +0000" && + export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && + + for i in A B C; do echo $i; done >>file0 && + for i in 1 2; do echo $i; done >>dir/sub && + git update-index file0 dir/sub && + + git config log.showroot false && + git commit --amend && + git show-branch +' + +: <<\EOF +! [initial] Initial + * [master] Merge branch 'side' + ! [side] Side +--- + - [master] Merge branch 'side' + *+ [side] Side + * [master^] Second ++*+ [initial] Initial +EOF + +V=`git version | sed -e 's/^git version //' -e 's/\./\\./g'` +while read cmd +do + case "$cmd" in + '' | '#'*) continue ;; + esac + test=`echo "$cmd" | sed -e 's|[/ ][/ ]*|_|g'` + cnt=`expr $test_count + 1` + pfx=`printf "%04d" $cnt` + expect="../t4013/diff.$test" + actual="$pfx-diff.$test" + + test_expect_success "git $cmd" ' + { + echo "\$ git $cmd" + git $cmd | + sed -e "s/^\\(-*\\)$V\\(-*\\)\$/\\1g-i-t--v-e-r-s-i-o-n\2/" \ + -e "s/^\\(.*mixed; boundary=\"-*\\)$V\\(-*\\)\"\$/\\1g-i-t--v-e-r-s-i-o-n\2\"/" + echo "\$" + } >"$actual" && + if test -f "$expect" + then + test_cmp "$expect" "$actual" && + rm -f "$actual" + else + # this is to help developing new tests. + cp "$actual" "$expect" + false + fi + ' +done <<\EOF +diff-tree initial +diff-tree -r initial +diff-tree -r --abbrev initial +diff-tree -r --abbrev=4 initial +diff-tree --root initial +diff-tree --root --abbrev initial +diff-tree --root -r initial +diff-tree --root -r --abbrev initial +diff-tree --root -r --abbrev=4 initial +diff-tree -p initial +diff-tree --root -p initial +diff-tree --patch-with-stat initial +diff-tree --root --patch-with-stat initial +diff-tree --patch-with-raw initial +diff-tree --root --patch-with-raw initial + +diff-tree --pretty initial +diff-tree --pretty --root initial +diff-tree --pretty -p initial +diff-tree --pretty --stat initial +diff-tree --pretty --summary initial +diff-tree --pretty --stat --summary initial +diff-tree --pretty --root -p initial +diff-tree --pretty --root --stat initial +# improved by Timo's patch +diff-tree --pretty --root --summary initial +# improved by Timo's patch +diff-tree --pretty --root --summary -r initial +diff-tree --pretty --root --stat --summary initial +diff-tree --pretty --patch-with-stat initial +diff-tree --pretty --root --patch-with-stat initial +diff-tree --pretty --patch-with-raw initial +diff-tree --pretty --root --patch-with-raw initial + +diff-tree --pretty=oneline initial +diff-tree --pretty=oneline --root initial +diff-tree --pretty=oneline -p initial +diff-tree --pretty=oneline --root -p initial +diff-tree --pretty=oneline --patch-with-stat initial +# improved by Timo's patch +diff-tree --pretty=oneline --root --patch-with-stat initial +diff-tree --pretty=oneline --patch-with-raw initial +diff-tree --pretty=oneline --root --patch-with-raw initial + +diff-tree --pretty side +diff-tree --pretty -p side +diff-tree --pretty --patch-with-stat side + +diff-tree master +diff-tree -p master +diff-tree -p -m master +diff-tree -c master +diff-tree -c --abbrev master +diff-tree --cc master +# stat only should show the diffstat with the first parent +diff-tree -c --stat master +diff-tree --cc --stat master +diff-tree -c --stat --summary master +diff-tree --cc --stat --summary master +# stat summary should show the diffstat and summary with the first parent +diff-tree -c --stat --summary side +diff-tree --cc --stat --summary side +# improved by Timo's patch +diff-tree --cc --patch-with-stat master +# improved by Timo's patch +diff-tree --cc --patch-with-stat --summary master +# this is correct +diff-tree --cc --patch-with-stat --summary side + +log master +log -p master +log --root master +log --root -p master +log --patch-with-stat master +log --root --patch-with-stat master +log --root --patch-with-stat --summary master +# improved by Timo's patch +log --root -c --patch-with-stat --summary master +# improved by Timo's patch +log --root --cc --patch-with-stat --summary master +log -SF master +log -SF -p master + +whatchanged master +whatchanged -p master +whatchanged --root master +whatchanged --root -p master +whatchanged --patch-with-stat master +whatchanged --root --patch-with-stat master +whatchanged --root --patch-with-stat --summary master +# improved by Timo's patch +whatchanged --root -c --patch-with-stat --summary master +# improved by Timo's patch +whatchanged --root --cc --patch-with-stat --summary master +whatchanged -SF master +whatchanged -SF -p master + +log --patch-with-stat master -- dir/ +whatchanged --patch-with-stat master -- dir/ +log --patch-with-stat --summary master -- dir/ +whatchanged --patch-with-stat --summary master -- dir/ + +show initial +show --root initial +show side +show master +show --stat side +show --stat --summary side +show --patch-with-stat side +show --patch-with-raw side +show --patch-with-stat --summary side + +format-patch --stdout initial..side +format-patch --stdout initial..master^ +format-patch --stdout initial..master +format-patch --attach --stdout initial..side +format-patch --attach --stdout initial..master^ +format-patch --attach --stdout initial..master +format-patch --inline --stdout initial..side +format-patch --inline --stdout initial..master^ +format-patch --inline --stdout initial..master +format-patch --inline --stdout --subject-prefix=TESTCASE initial..master +config format.subjectprefix DIFFERENT_PREFIX +format-patch --inline --stdout initial..master^^ +format-patch --stdout --cover-letter -n initial..master^ + +diff --abbrev initial..side +diff -r initial..side +diff --stat initial..side +diff -r --stat initial..side +diff initial..side +diff --patch-with-stat initial..side +diff --patch-with-raw initial..side +diff --patch-with-stat -r initial..side +diff --patch-with-raw -r initial..side +diff --name-status dir2 dir +diff --no-index --name-status dir2 dir +EOF + +test_done diff --git a/t/t4013/diff.config_format.subjectprefix_DIFFERENT_PREFIX b/t/t4013/diff.config_format.subjectprefix_DIFFERENT_PREFIX new file mode 100644 index 0000000000..78f8970e2b --- /dev/null +++ b/t/t4013/diff.config_format.subjectprefix_DIFFERENT_PREFIX @@ -0,0 +1,2 @@ +$ git config format.subjectprefix DIFFERENT_PREFIX +$ diff --git a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master new file mode 100644 index 0000000000..3a9f78a09d --- /dev/null +++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master @@ -0,0 +1,34 @@ +$ git diff-tree --cc --patch-with-stat --summary master +59d314ad6f356dd08601a4cd5e530381da3e3c64 + dir/sub | 2 ++ + file0 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + +diff --cc 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 --cc 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.diff-tree_--cc_--patch-with-stat_--summary_side b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side new file mode 100644 index 0000000000..a61ad8cb13 --- /dev/null +++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side @@ -0,0 +1,39 @@ +$ git diff-tree --cc --patch-with-stat --summary side +c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + +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 +$ diff --git a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master new file mode 100644 index 0000000000..49f23b9215 --- /dev/null +++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master @@ -0,0 +1,34 @@ +$ git diff-tree --cc --patch-with-stat master +59d314ad6f356dd08601a4cd5e530381da3e3c64 + dir/sub | 2 ++ + file0 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + +diff --cc 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 --cc 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.diff-tree_--cc_--stat_--summary_master b/t/t4013/diff.diff-tree_--cc_--stat_--summary_master new file mode 100644 index 0000000000..cc6eb3b3d5 --- /dev/null +++ b/t/t4013/diff.diff-tree_--cc_--stat_--summary_master @@ -0,0 +1,6 @@ +$ git diff-tree --cc --stat --summary master +59d314ad6f356dd08601a4cd5e530381da3e3c64 + dir/sub | 2 ++ + file0 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) +$ diff --git a/t/t4013/diff.diff-tree_--cc_--stat_--summary_side b/t/t4013/diff.diff-tree_--cc_--stat_--summary_side new file mode 100644 index 0000000000..50362be7bf --- /dev/null +++ b/t/t4013/diff.diff-tree_--cc_--stat_--summary_side @@ -0,0 +1,8 @@ +$ git diff-tree --cc --stat --summary side +c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 +$ diff --git a/t/t4013/diff.diff-tree_--cc_--stat_master b/t/t4013/diff.diff-tree_--cc_--stat_master new file mode 100644 index 0000000000..fae7f33255 --- /dev/null +++ b/t/t4013/diff.diff-tree_--cc_--stat_master @@ -0,0 +1,6 @@ +$ git diff-tree --cc --stat master +59d314ad6f356dd08601a4cd5e530381da3e3c64 + dir/sub | 2 ++ + file0 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) +$ diff --git a/t/t4013/diff.diff-tree_--cc_master b/t/t4013/diff.diff-tree_--cc_master new file mode 100644 index 0000000000..5ecb4e14ae --- /dev/null +++ b/t/t4013/diff.diff-tree_--cc_master @@ -0,0 +1,30 @@ +$ git diff-tree --cc master +59d314ad6f356dd08601a4cd5e530381da3e3c64 +diff --cc 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 --cc 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.diff-tree_--patch-with-raw_initial b/t/t4013/diff.diff-tree_--patch-with-raw_initial new file mode 100644 index 0000000000..fc177ab3f2 --- /dev/null +++ b/t/t4013/diff.diff-tree_--patch-with-raw_initial @@ -0,0 +1,2 @@ +$ git diff-tree --patch-with-raw initial +$ diff --git a/t/t4013/diff.diff-tree_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--patch-with-stat_initial new file mode 100644 index 0000000000..bd905b1c57 --- /dev/null +++ b/t/t4013/diff.diff-tree_--patch-with-stat_initial @@ -0,0 +1,2 @@ +$ git diff-tree --patch-with-stat initial +$ diff --git a/t/t4013/diff.diff-tree_--pretty=oneline_--patch-with-raw_initial b/t/t4013/diff.diff-tree_--pretty=oneline_--patch-with-raw_initial new file mode 100644 index 0000000000..7bb8b45e3e --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty=oneline_--patch-with-raw_initial @@ -0,0 +1,2 @@ +$ git diff-tree --pretty=oneline --patch-with-raw initial +$ diff --git a/t/t4013/diff.diff-tree_--pretty=oneline_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--pretty=oneline_--patch-with-stat_initial new file mode 100644 index 0000000000..cbdde4f400 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty=oneline_--patch-with-stat_initial @@ -0,0 +1,2 @@ +$ git diff-tree --pretty=oneline --patch-with-stat initial +$ diff --git a/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-raw_initial b/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-raw_initial new file mode 100644 index 0000000000..cd79f1a0ff --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-raw_initial @@ -0,0 +1,33 @@ +$ git diff-tree --pretty=oneline --root --patch-with-raw initial +444ac553ac7612cc88969031b02b3767fb8a353a Initial +:000000 100644 0000000000000000000000000000000000000000 35d242ba79ae89ac695e26b3d4c27a8e6f028f9e A dir/sub +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file0 +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file2 + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial new file mode 100644 index 0000000000..d5c333a378 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial @@ -0,0 +1,34 @@ +$ git diff-tree --pretty=oneline --root --patch-with-stat initial +444ac553ac7612cc88969031b02b3767fb8a353a Initial + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.diff-tree_--pretty=oneline_--root_-p_initial b/t/t4013/diff.diff-tree_--pretty=oneline_--root_-p_initial new file mode 100644 index 0000000000..3c5092c699 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty=oneline_--root_-p_initial @@ -0,0 +1,29 @@ +$ git diff-tree --pretty=oneline --root -p initial +444ac553ac7612cc88969031b02b3767fb8a353a Initial +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.diff-tree_--pretty=oneline_--root_initial b/t/t4013/diff.diff-tree_--pretty=oneline_--root_initial new file mode 100644 index 0000000000..08920ac658 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty=oneline_--root_initial @@ -0,0 +1,6 @@ +$ git diff-tree --pretty=oneline --root initial +444ac553ac7612cc88969031b02b3767fb8a353a Initial +:000000 040000 0000000000000000000000000000000000000000 da7a33fa77d8066d6698643940ce5860fe2d7fb3 A dir +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file0 +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file2 +$ diff --git a/t/t4013/diff.diff-tree_--pretty=oneline_-p_initial b/t/t4013/diff.diff-tree_--pretty=oneline_-p_initial new file mode 100644 index 0000000000..94b76bfef1 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty=oneline_-p_initial @@ -0,0 +1,2 @@ +$ git diff-tree --pretty=oneline -p initial +$ diff --git a/t/t4013/diff.diff-tree_--pretty=oneline_initial b/t/t4013/diff.diff-tree_--pretty=oneline_initial new file mode 100644 index 0000000000..d50970d574 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty=oneline_initial @@ -0,0 +1,2 @@ +$ git diff-tree --pretty=oneline initial +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--patch-with-raw_initial b/t/t4013/diff.diff-tree_--pretty_--patch-with-raw_initial new file mode 100644 index 0000000000..3a85316d8a --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--patch-with-raw_initial @@ -0,0 +1,2 @@ +$ git diff-tree --pretty --patch-with-raw initial +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_initial new file mode 100644 index 0000000000..2e08239a46 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_initial @@ -0,0 +1,2 @@ +$ git diff-tree --pretty --patch-with-stat initial +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side b/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side new file mode 100644 index 0000000000..4d30e7eddc --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side @@ -0,0 +1,43 @@ +$ git diff-tree --pretty --patch-with-stat side +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + +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 +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-raw_initial b/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-raw_initial new file mode 100644 index 0000000000..a3203bd19b --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-raw_initial @@ -0,0 +1,38 @@ +$ git diff-tree --pretty --root --patch-with-raw initial +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial + +:000000 100644 0000000000000000000000000000000000000000 35d242ba79ae89ac695e26b3d4c27a8e6f028f9e A dir/sub +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file0 +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file2 + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial new file mode 100644 index 0000000000..7dfa6af3c9 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial @@ -0,0 +1,39 @@ +$ git diff-tree --pretty --root --patch-with-stat initial +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial new file mode 100644 index 0000000000..43bfce253e --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial @@ -0,0 +1,15 @@ +$ git diff-tree --pretty --root --stat --summary initial +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial + + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) + create mode 100644 dir/sub + create mode 100644 file0 + create mode 100644 file2 +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial b/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial new file mode 100644 index 0000000000..9154aa4d47 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial @@ -0,0 +1,12 @@ +$ git diff-tree --pretty --root --stat initial +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial + + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--summary_-r_initial b/t/t4013/diff.diff-tree_--pretty_--root_--summary_-r_initial new file mode 100644 index 0000000000..ccdaafb377 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--root_--summary_-r_initial @@ -0,0 +1,11 @@ +$ git diff-tree --pretty --root --summary -r initial +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial + + create mode 100644 dir/sub + create mode 100644 file0 + create mode 100644 file2 +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--summary_initial b/t/t4013/diff.diff-tree_--pretty_--root_--summary_initial new file mode 100644 index 0000000000..58e5f74aea --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--root_--summary_initial @@ -0,0 +1,11 @@ +$ git diff-tree --pretty --root --summary initial +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial + + create mode 100644 dir/sub + create mode 100644 file0 + create mode 100644 file2 +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--root_-p_initial b/t/t4013/diff.diff-tree_--pretty_--root_-p_initial new file mode 100644 index 0000000000..d0411f64ec --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--root_-p_initial @@ -0,0 +1,34 @@ +$ git diff-tree --pretty --root -p initial +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--root_initial b/t/t4013/diff.diff-tree_--pretty_--root_initial new file mode 100644 index 0000000000..94e32eabb1 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--root_initial @@ -0,0 +1,11 @@ +$ git diff-tree --pretty --root initial +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial + +:000000 040000 0000000000000000000000000000000000000000 da7a33fa77d8066d6698643940ce5860fe2d7fb3 A dir +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file0 +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file2 +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--stat_--summary_initial b/t/t4013/diff.diff-tree_--pretty_--stat_--summary_initial new file mode 100644 index 0000000000..c22983ac4a --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--stat_--summary_initial @@ -0,0 +1,2 @@ +$ git diff-tree --pretty --stat --summary initial +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--stat_initial b/t/t4013/diff.diff-tree_--pretty_--stat_initial new file mode 100644 index 0000000000..8fdcfb4c0a --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--stat_initial @@ -0,0 +1,2 @@ +$ git diff-tree --pretty --stat initial +$ diff --git a/t/t4013/diff.diff-tree_--pretty_--summary_initial b/t/t4013/diff.diff-tree_--pretty_--summary_initial new file mode 100644 index 0000000000..9bc2c4fbad --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_--summary_initial @@ -0,0 +1,2 @@ +$ git diff-tree --pretty --summary initial +$ diff --git a/t/t4013/diff.diff-tree_--pretty_-p_initial b/t/t4013/diff.diff-tree_--pretty_-p_initial new file mode 100644 index 0000000000..3c9942faf4 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_-p_initial @@ -0,0 +1,2 @@ +$ git diff-tree --pretty -p initial +$ diff --git a/t/t4013/diff.diff-tree_--pretty_-p_side b/t/t4013/diff.diff-tree_--pretty_-p_side new file mode 100644 index 0000000000..b993aa7b89 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_-p_side @@ -0,0 +1,38 @@ +$ git diff-tree --pretty -p side +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 +$ diff --git a/t/t4013/diff.diff-tree_--pretty_initial b/t/t4013/diff.diff-tree_--pretty_initial new file mode 100644 index 0000000000..14715bf7d0 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_initial @@ -0,0 +1,2 @@ +$ git diff-tree --pretty initial +$ diff --git a/t/t4013/diff.diff-tree_--pretty_side b/t/t4013/diff.diff-tree_--pretty_side new file mode 100644 index 0000000000..e9b6e1c102 --- /dev/null +++ b/t/t4013/diff.diff-tree_--pretty_side @@ -0,0 +1,11 @@ +$ git diff-tree --pretty side +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side + +:040000 040000 da7a33fa77d8066d6698643940ce5860fe2d7fb3 f977ed46ae6873c1c30ab878e15a4accedc3618b M dir +:100644 100644 01e79c32a8c99c557f0757da7cb6d65b3414466d f4615da674c09df322d6ba8d6b21ecfb1b1ba510 M file0 +:000000 100644 0000000000000000000000000000000000000000 7289e35bff32727c08dda207511bec138fdb9ea5 A file3 +$ diff --git a/t/t4013/diff.diff-tree_--root_--abbrev_initial b/t/t4013/diff.diff-tree_--root_--abbrev_initial new file mode 100644 index 0000000000..5aa84b2a86 --- /dev/null +++ b/t/t4013/diff.diff-tree_--root_--abbrev_initial @@ -0,0 +1,6 @@ +$ git diff-tree --root --abbrev initial +444ac553ac7612cc88969031b02b3767fb8a353a +:000000 040000 0000000... da7a33f... A dir +:000000 100644 0000000... 01e79c3... A file0 +:000000 100644 0000000... 01e79c3... A file2 +$ diff --git a/t/t4013/diff.diff-tree_--root_--patch-with-raw_initial b/t/t4013/diff.diff-tree_--root_--patch-with-raw_initial new file mode 100644 index 0000000000..d295e475dd --- /dev/null +++ b/t/t4013/diff.diff-tree_--root_--patch-with-raw_initial @@ -0,0 +1,33 @@ +$ git diff-tree --root --patch-with-raw initial +444ac553ac7612cc88969031b02b3767fb8a353a +:000000 100644 0000000000000000000000000000000000000000 35d242ba79ae89ac695e26b3d4c27a8e6f028f9e A dir/sub +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file0 +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file2 + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial new file mode 100644 index 0000000000..1562b62708 --- /dev/null +++ b/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial @@ -0,0 +1,34 @@ +$ git diff-tree --root --patch-with-stat initial +444ac553ac7612cc88969031b02b3767fb8a353a + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.diff-tree_--root_-p_initial b/t/t4013/diff.diff-tree_--root_-p_initial new file mode 100644 index 0000000000..3219c72fcb --- /dev/null +++ b/t/t4013/diff.diff-tree_--root_-p_initial @@ -0,0 +1,29 @@ +$ git diff-tree --root -p initial +444ac553ac7612cc88969031b02b3767fb8a353a +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.diff-tree_--root_-r_--abbrev=4_initial b/t/t4013/diff.diff-tree_--root_-r_--abbrev=4_initial new file mode 100644 index 0000000000..0c5361688c --- /dev/null +++ b/t/t4013/diff.diff-tree_--root_-r_--abbrev=4_initial @@ -0,0 +1,6 @@ +$ git diff-tree --root -r --abbrev=4 initial +444ac553ac7612cc88969031b02b3767fb8a353a +:000000 100644 0000... 35d2... A dir/sub +:000000 100644 0000... 01e7... A file0 +:000000 100644 0000... 01e7... A file2 +$ diff --git a/t/t4013/diff.diff-tree_--root_-r_--abbrev_initial b/t/t4013/diff.diff-tree_--root_-r_--abbrev_initial new file mode 100644 index 0000000000..c7b460faf6 --- /dev/null +++ b/t/t4013/diff.diff-tree_--root_-r_--abbrev_initial @@ -0,0 +1,6 @@ +$ git diff-tree --root -r --abbrev initial +444ac553ac7612cc88969031b02b3767fb8a353a +:000000 100644 0000000... 35d242b... A dir/sub +:000000 100644 0000000... 01e79c3... A file0 +:000000 100644 0000000... 01e79c3... A file2 +$ diff --git a/t/t4013/diff.diff-tree_--root_-r_initial b/t/t4013/diff.diff-tree_--root_-r_initial new file mode 100644 index 0000000000..eed435e175 --- /dev/null +++ b/t/t4013/diff.diff-tree_--root_-r_initial @@ -0,0 +1,6 @@ +$ git diff-tree --root -r initial +444ac553ac7612cc88969031b02b3767fb8a353a +:000000 100644 0000000000000000000000000000000000000000 35d242ba79ae89ac695e26b3d4c27a8e6f028f9e A dir/sub +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file0 +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file2 +$ diff --git a/t/t4013/diff.diff-tree_--root_initial b/t/t4013/diff.diff-tree_--root_initial new file mode 100644 index 0000000000..ddf6b068ab --- /dev/null +++ b/t/t4013/diff.diff-tree_--root_initial @@ -0,0 +1,6 @@ +$ git diff-tree --root initial +444ac553ac7612cc88969031b02b3767fb8a353a +:000000 040000 0000000000000000000000000000000000000000 da7a33fa77d8066d6698643940ce5860fe2d7fb3 A dir +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file0 +:000000 100644 0000000000000000000000000000000000000000 01e79c32a8c99c557f0757da7cb6d65b3414466d A file2 +$ diff --git a/t/t4013/diff.diff-tree_-c_--abbrev_master b/t/t4013/diff.diff-tree_-c_--abbrev_master new file mode 100644 index 0000000000..b8e4aa2530 --- /dev/null +++ b/t/t4013/diff.diff-tree_-c_--abbrev_master @@ -0,0 +1,5 @@ +$ git diff-tree -c --abbrev master +59d314ad6f356dd08601a4cd5e530381da3e3c64 +::100644 100644 100644 cead32e... 7289e35... 992913c... MM dir/sub +::100644 100644 100644 b414108... f4615da... 10a8a9f... MM file0 +$ diff --git a/t/t4013/diff.diff-tree_-c_--stat_--summary_master b/t/t4013/diff.diff-tree_-c_--stat_--summary_master new file mode 100644 index 0000000000..ac9f641fb4 --- /dev/null +++ b/t/t4013/diff.diff-tree_-c_--stat_--summary_master @@ -0,0 +1,6 @@ +$ git diff-tree -c --stat --summary master +59d314ad6f356dd08601a4cd5e530381da3e3c64 + dir/sub | 2 ++ + file0 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) +$ diff --git a/t/t4013/diff.diff-tree_-c_--stat_--summary_side b/t/t4013/diff.diff-tree_-c_--stat_--summary_side new file mode 100644 index 0000000000..2afcca11f4 --- /dev/null +++ b/t/t4013/diff.diff-tree_-c_--stat_--summary_side @@ -0,0 +1,8 @@ +$ git diff-tree -c --stat --summary side +c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 +$ diff --git a/t/t4013/diff.diff-tree_-c_--stat_master b/t/t4013/diff.diff-tree_-c_--stat_master new file mode 100644 index 0000000000..c2fe6a98c5 --- /dev/null +++ b/t/t4013/diff.diff-tree_-c_--stat_master @@ -0,0 +1,6 @@ +$ git diff-tree -c --stat master +59d314ad6f356dd08601a4cd5e530381da3e3c64 + dir/sub | 2 ++ + file0 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) +$ diff --git a/t/t4013/diff.diff-tree_-c_master b/t/t4013/diff.diff-tree_-c_master new file mode 100644 index 0000000000..e2d2bb2611 --- /dev/null +++ b/t/t4013/diff.diff-tree_-c_master @@ -0,0 +1,5 @@ +$ git diff-tree -c master +59d314ad6f356dd08601a4cd5e530381da3e3c64 +::100644 100644 100644 cead32e925b1420c84c14cbf7cf755e7e45af8ad 7289e35bff32727c08dda207511bec138fdb9ea5 992913c5aa0a5476d10c49ed0f21fc0c6d1aedf3 MM dir/sub +::100644 100644 100644 b414108e81e5091fe0974a1858b4d0d22b107f70 f4615da674c09df322d6ba8d6b21ecfb1b1ba510 10a8a9f3657f91a156b9f0184ed79a20adef9f7f MM file0 +$ diff --git a/t/t4013/diff.diff-tree_-p_-m_master b/t/t4013/diff.diff-tree_-p_-m_master new file mode 100644 index 0000000000..b60bea039d --- /dev/null +++ b/t/t4013/diff.diff-tree_-p_-m_master @@ -0,0 +1,80 @@ +$ git diff-tree -p -m master +59d314ad6f356dd08601a4cd5e530381da3e3c64 +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 +59d314ad6f356dd08601a4cd5e530381da3e3c64 +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/t4013/diff.diff-tree_-p_initial b/t/t4013/diff.diff-tree_-p_initial new file mode 100644 index 0000000000..e20ce88370 --- /dev/null +++ b/t/t4013/diff.diff-tree_-p_initial @@ -0,0 +1,2 @@ +$ git diff-tree -p initial +$ diff --git a/t/t4013/diff.diff-tree_-p_master b/t/t4013/diff.diff-tree_-p_master new file mode 100644 index 0000000000..b182875fb2 --- /dev/null +++ b/t/t4013/diff.diff-tree_-p_master @@ -0,0 +1,2 @@ +$ git diff-tree -p master +$ diff --git a/t/t4013/diff.diff-tree_-r_--abbrev=4_initial b/t/t4013/diff.diff-tree_-r_--abbrev=4_initial new file mode 100644 index 0000000000..c5a3aa5aa4 --- /dev/null +++ b/t/t4013/diff.diff-tree_-r_--abbrev=4_initial @@ -0,0 +1,2 @@ +$ git diff-tree -r --abbrev=4 initial +$ diff --git a/t/t4013/diff.diff-tree_-r_--abbrev_initial b/t/t4013/diff.diff-tree_-r_--abbrev_initial new file mode 100644 index 0000000000..0b689b773c --- /dev/null +++ b/t/t4013/diff.diff-tree_-r_--abbrev_initial @@ -0,0 +1,2 @@ +$ git diff-tree -r --abbrev initial +$ diff --git a/t/t4013/diff.diff-tree_-r_initial b/t/t4013/diff.diff-tree_-r_initial new file mode 100644 index 0000000000..1765d83ce4 --- /dev/null +++ b/t/t4013/diff.diff-tree_-r_initial @@ -0,0 +1,2 @@ +$ git diff-tree -r initial +$ diff --git a/t/t4013/diff.diff-tree_initial b/t/t4013/diff.diff-tree_initial new file mode 100644 index 0000000000..b49fc53457 --- /dev/null +++ b/t/t4013/diff.diff-tree_initial @@ -0,0 +1,2 @@ +$ git diff-tree initial +$ diff --git a/t/t4013/diff.diff-tree_master b/t/t4013/diff.diff-tree_master new file mode 100644 index 0000000000..fe9226f8a1 --- /dev/null +++ b/t/t4013/diff.diff-tree_master @@ -0,0 +1,2 @@ +$ git diff-tree master +$ diff --git a/t/t4013/diff.diff_--abbrev_initial..side b/t/t4013/diff.diff_--abbrev_initial..side new file mode 100644 index 0000000000..a88e66f817 --- /dev/null +++ b/t/t4013/diff.diff_--abbrev_initial..side @@ -0,0 +1,32 @@ +$ git diff --abbrev initial..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 +$ diff --git a/t/t4013/diff.diff_--name-status_dir2_dir b/t/t4013/diff.diff_--name-status_dir2_dir new file mode 100644 index 0000000000..d0d96aaa91 --- /dev/null +++ b/t/t4013/diff.diff_--name-status_dir2_dir @@ -0,0 +1,2 @@ +$ git diff --name-status dir2 dir +$ diff --git a/t/t4013/diff.diff_--no-index_--name-status_dir2_dir b/t/t4013/diff.diff_--no-index_--name-status_dir2_dir new file mode 100644 index 0000000000..6a47584777 --- /dev/null +++ b/t/t4013/diff.diff_--no-index_--name-status_dir2_dir @@ -0,0 +1,3 @@ +$ git diff --no-index --name-status dir2 dir +A dir/sub +$ diff --git a/t/t4013/diff.diff_--patch-with-raw_-r_initial..side b/t/t4013/diff.diff_--patch-with-raw_-r_initial..side new file mode 100644 index 0000000000..3590dc79a6 --- /dev/null +++ b/t/t4013/diff.diff_--patch-with-raw_-r_initial..side @@ -0,0 +1,36 @@ +$ git diff --patch-with-raw -r initial..side +:100644 100644 35d242b... 7289e35... M dir/sub +:100644 100644 01e79c3... f4615da... M file0 +:000000 100644 0000000... 7289e35... A file3 + +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 +$ diff --git a/t/t4013/diff.diff_--patch-with-raw_initial..side b/t/t4013/diff.diff_--patch-with-raw_initial..side new file mode 100644 index 0000000000..b21d5dc6f3 --- /dev/null +++ b/t/t4013/diff.diff_--patch-with-raw_initial..side @@ -0,0 +1,36 @@ +$ git diff --patch-with-raw initial..side +:100644 100644 35d242b... 7289e35... M dir/sub +:100644 100644 01e79c3... f4615da... M file0 +:000000 100644 0000000... 7289e35... A file3 + +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 +$ diff --git a/t/t4013/diff.diff_--patch-with-stat_-r_initial..side b/t/t4013/diff.diff_--patch-with-stat_-r_initial..side new file mode 100644 index 0000000000..9ed317a198 --- /dev/null +++ b/t/t4013/diff.diff_--patch-with-stat_-r_initial..side @@ -0,0 +1,37 @@ +$ git diff --patch-with-stat -r initial..side + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + +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 +$ diff --git a/t/t4013/diff.diff_--patch-with-stat_initial..side b/t/t4013/diff.diff_--patch-with-stat_initial..side new file mode 100644 index 0000000000..8b50629e66 --- /dev/null +++ b/t/t4013/diff.diff_--patch-with-stat_initial..side @@ -0,0 +1,37 @@ +$ git diff --patch-with-stat initial..side + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + +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 +$ diff --git a/t/t4013/diff.diff_--stat_initial..side b/t/t4013/diff.diff_--stat_initial..side new file mode 100644 index 0000000000..0517b5d631 --- /dev/null +++ b/t/t4013/diff.diff_--stat_initial..side @@ -0,0 +1,6 @@ +$ git diff --stat initial..side + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) +$ diff --git a/t/t4013/diff.diff_-r_--stat_initial..side b/t/t4013/diff.diff_-r_--stat_initial..side new file mode 100644 index 0000000000..245220d3f9 --- /dev/null +++ b/t/t4013/diff.diff_-r_--stat_initial..side @@ -0,0 +1,6 @@ +$ git diff -r --stat initial..side + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) +$ diff --git a/t/t4013/diff.diff_-r_initial..side b/t/t4013/diff.diff_-r_initial..side new file mode 100644 index 0000000000..5bb2fe2f28 --- /dev/null +++ b/t/t4013/diff.diff_-r_initial..side @@ -0,0 +1,32 @@ +$ git diff -r initial..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 +$ diff --git a/t/t4013/diff.diff_initial..side b/t/t4013/diff.diff_initial..side new file mode 100644 index 0000000000..c8adaf5958 --- /dev/null +++ b/t/t4013/diff.diff_initial..side @@ -0,0 +1,32 @@ +$ git diff initial..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 +$ diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..master b/t/t4013/diff.format-patch_--attach_--stdout_initial..master new file mode 100644 index 0000000000..43346b9ba4 --- /dev/null +++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master @@ -0,0 +1,170 @@ +$ git format-patch --attach --stdout initial..master +From 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:01:00 +0000 +Subject: [PATCH] Second +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + + +This is the second commit. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: attachment; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + + +From 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:02:00 +0000 +Subject: [PATCH] Third +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: attachment; filename="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + + +From c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:03:00 +0000 +Subject: [PATCH] Side +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: attachment; filename="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + +$ diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..master^ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master^ new file mode 100644 index 0000000000..d7490a9fd7 --- /dev/null +++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master^ @@ -0,0 +1,110 @@ +$ git format-patch --attach --stdout initial..master^ +From 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:01:00 +0000 +Subject: [PATCH] Second +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + + +This is the second commit. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: attachment; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + + +From 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:02:00 +0000 +Subject: [PATCH] Third +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: attachment; filename="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + +$ diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..side b/t/t4013/diff.format-patch_--attach_--stdout_initial..side new file mode 100644 index 0000000000..38f790290a --- /dev/null +++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..side @@ -0,0 +1,61 @@ +$ git format-patch --attach --stdout initial..side +From c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:03:00 +0000 +Subject: [PATCH] Side +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: attachment; filename="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + +$ diff --git a/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master b/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master new file mode 100644 index 0000000000..fca5cce373 --- /dev/null +++ b/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master @@ -0,0 +1,170 @@ +$ git format-patch --inline --stdout --subject-prefix=TESTCASE initial..master +From 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:01:00 +0000 +Subject: [TESTCASE] Second +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + + +This is the second commit. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + + +From 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:02:00 +0000 +Subject: [TESTCASE] Third +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + + +From c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:03:00 +0000 +Subject: [TESTCASE] Side +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + +$ diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master b/t/t4013/diff.format-patch_--inline_--stdout_initial..master new file mode 100644 index 0000000000..6d6fac3908 --- /dev/null +++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master @@ -0,0 +1,170 @@ +$ git format-patch --inline --stdout initial..master +From 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:01:00 +0000 +Subject: [PATCH] Second +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + + +This is the second commit. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + + +From 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:02:00 +0000 +Subject: [PATCH] Third +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + + +From c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:03:00 +0000 +Subject: [PATCH] Side +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + +$ diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^ new file mode 100644 index 0000000000..18a1110def --- /dev/null +++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^ @@ -0,0 +1,110 @@ +$ git format-patch --inline --stdout initial..master^ +From 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:01:00 +0000 +Subject: [PATCH] Second +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + + +This is the second commit. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + + +From 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:02:00 +0000 +Subject: [PATCH] Third +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename="9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + +$ diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^ new file mode 100644 index 0000000000..4f258b8858 --- /dev/null +++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^ @@ -0,0 +1,62 @@ +$ git format-patch --inline --stdout initial..master^^ +From 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:01:00 +0000 +Subject: [DIFFERENT_PREFIX] Second +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + + +This is the second commit. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + +$ diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..side b/t/t4013/diff.format-patch_--inline_--stdout_initial..side new file mode 100644 index 0000000000..e86dce69a3 --- /dev/null +++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..side @@ -0,0 +1,61 @@ +$ git format-patch --inline --stdout initial..side +From c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:03:00 +0000 +Subject: [PATCH] Side +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + + +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename="c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a.diff" + +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 + +--------------g-i-t--v-e-r-s-i-o-n-- + + +$ diff --git a/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^ b/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^ new file mode 100644 index 0000000000..8dab4bf93e --- /dev/null +++ b/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^ @@ -0,0 +1,100 @@ +$ git format-patch --stdout --cover-letter -n initial..master^ +From 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Mon Sep 17 00:00:00 2001 +From: C O Mitter <committer@example.com> +Date: Mon, 26 Jun 2006 00:05:00 +0000 +Subject: [DIFFERENT_PREFIX 0/2] *** SUBJECT HERE *** + +*** BLURB HERE *** + +A U Thor (2): + Second + Third + + dir/sub | 4 ++++ + file0 | 3 +++ + file1 | 3 +++ + file2 | 3 --- + 4 files changed, 10 insertions(+), 3 deletions(-) + create mode 100644 file1 + delete mode 100644 file2 + +From 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:01:00 +0000 +Subject: [DIFFERENT_PREFIX 1/2] Second + +This is the second commit. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + +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 +-- +g-i-t--v-e-r-s-i-o-n + + +From 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:02:00 +0000 +Subject: [DIFFERENT_PREFIX 2/2] Third + +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + +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 +-- +g-i-t--v-e-r-s-i-o-n + +$ diff --git a/t/t4013/diff.format-patch_--stdout_initial..master b/t/t4013/diff.format-patch_--stdout_initial..master new file mode 100644 index 0000000000..8b88ca4927 --- /dev/null +++ b/t/t4013/diff.format-patch_--stdout_initial..master @@ -0,0 +1,127 @@ +$ git format-patch --stdout initial..master +From 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:01:00 +0000 +Subject: [PATCH] Second + +This is the second commit. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + +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 +-- +g-i-t--v-e-r-s-i-o-n + + +From 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:02:00 +0000 +Subject: [PATCH] Third + +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + +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 +-- +g-i-t--v-e-r-s-i-o-n + + +From c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:03:00 +0000 +Subject: [PATCH] Side + +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + +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 +-- +g-i-t--v-e-r-s-i-o-n + +$ diff --git a/t/t4013/diff.format-patch_--stdout_initial..master^ b/t/t4013/diff.format-patch_--stdout_initial..master^ new file mode 100644 index 0000000000..47a4b88637 --- /dev/null +++ b/t/t4013/diff.format-patch_--stdout_initial..master^ @@ -0,0 +1,81 @@ +$ git format-patch --stdout initial..master^ +From 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:01:00 +0000 +Subject: [PATCH] Second + +This is the second commit. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + +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 +-- +g-i-t--v-e-r-s-i-o-n + + +From 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:02:00 +0000 +Subject: [PATCH] Third + +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + +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 +-- +g-i-t--v-e-r-s-i-o-n + +$ diff --git a/t/t4013/diff.format-patch_--stdout_initial..side b/t/t4013/diff.format-patch_--stdout_initial..side new file mode 100644 index 0000000000..e765088475 --- /dev/null +++ b/t/t4013/diff.format-patch_--stdout_initial..side @@ -0,0 +1,47 @@ +$ git format-patch --stdout initial..side +From c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Mon, 26 Jun 2006 00:03:00 +0000 +Subject: [PATCH] Side + +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + +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 +-- +g-i-t--v-e-r-s-i-o-n + +$ diff --git a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ new file mode 100644 index 0000000000..3ceb8e73c5 --- /dev/null +++ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ @@ -0,0 +1,74 @@ +$ git log --patch-with-stat --summary master -- dir/ +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 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +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 + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third +--- + dir/sub | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +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 + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. +--- + dir/sub | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +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 + +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_--patch-with-stat_master b/t/t4013/diff.log_--patch-with-stat_master new file mode 100644 index 0000000000..43d77761f9 --- /dev/null +++ b/t/t4013/diff.log_--patch-with-stat_master @@ -0,0 +1,129 @@ +$ git log --patch-with-stat 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 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + +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 +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + +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. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + +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_--patch-with-stat_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_ new file mode 100644 index 0000000000..5187a26816 --- /dev/null +++ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_ @@ -0,0 +1,74 @@ +$ git log --patch-with-stat master -- dir/ +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 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +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 + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third +--- + dir/sub | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +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 + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. +--- + dir/sub | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +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 + +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_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master new file mode 100644 index 0000000000..c9640976a8 --- /dev/null +++ b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master @@ -0,0 +1,199 @@ +$ git log --root --cc --patch-with-stat --summary 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' + + dir/sub | 2 ++ + file0 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + +diff --cc 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 --cc file0 +index b414108,f4615da..10a8a9f +--- a/file0 ++++ b/file0 +@@@ -1,6 -1,6 +1,9 @@@ + 1 + 2 + 3 + +4 + +5 + +6 ++ A ++ B ++ C + +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + +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 +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + +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. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + +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 +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) + create mode 100644 dir/sub + create mode 100644 file0 + create mode 100644 file2 + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master new file mode 100644 index 0000000000..ad050af55f --- /dev/null +++ b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master @@ -0,0 +1,167 @@ +$ git log --root --patch-with-stat --summary 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 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + +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 +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + +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. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + +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 +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) + create mode 100644 dir/sub + create mode 100644 file0 + create mode 100644 file2 + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.log_--root_--patch-with-stat_master b/t/t4013/diff.log_--root_--patch-with-stat_master new file mode 100644 index 0000000000..628c6c03bc --- /dev/null +++ b/t/t4013/diff.log_--root_--patch-with-stat_master @@ -0,0 +1,161 @@ +$ git log --root --patch-with-stat 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 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + +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 +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + +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. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + +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 +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master new file mode 100644 index 0000000000..5d4e0f13b5 --- /dev/null +++ b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master @@ -0,0 +1,199 @@ +$ git log --root -c --patch-with-stat --summary 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' + + dir/sub | 2 ++ + file0 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + +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 + +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + +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 +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + +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. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + +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 +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) + create mode 100644 dir/sub + create mode 100644 file0 + create mode 100644 file2 + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.log_--root_-p_master b/t/t4013/diff.log_--root_-p_master new file mode 100644 index 0000000000..217a2eb203 --- /dev/null +++ b/t/t4013/diff.log_--root_-p_master @@ -0,0 +1,142 @@ +$ git log --root -p 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 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/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.log_--root_master b/t/t4013/diff.log_--root_master new file mode 100644 index 0000000000..e17ccfc234 --- /dev/null +++ b/t/t4013/diff.log_--root_master @@ -0,0 +1,34 @@ +$ git log --root 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 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +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 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial +$ diff --git a/t/t4013/diff.log_-SF_-p_master b/t/t4013/diff.log_-SF_-p_master new file mode 100644 index 0000000000..5e32438972 --- /dev/null +++ b/t/t4013/diff.log_-SF_-p_master @@ -0,0 +1,18 @@ +$ git log -SF -p master +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/t/t4013/diff.log_-SF_master b/t/t4013/diff.log_-SF_master new file mode 100644 index 0000000000..c1599f2f52 --- /dev/null +++ b/t/t4013/diff.log_-SF_master @@ -0,0 +1,7 @@ +$ git log -SF master +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third +$ diff --git a/t/t4013/diff.log_-p_master b/t/t4013/diff.log_-p_master new file mode 100644 index 0000000000..f8fefef2c3 --- /dev/null +++ b/t/t4013/diff.log_-p_master @@ -0,0 +1,115 @@ +$ git log -p 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 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_master b/t/t4013/diff.log_master new file mode 100644 index 0000000000..e9d9e7b40a --- /dev/null +++ b/t/t4013/diff.log_master @@ -0,0 +1,34 @@ +$ git log 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 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +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 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial +$ diff --git a/t/t4013/diff.show_--patch-with-raw_side b/t/t4013/diff.show_--patch-with-raw_side new file mode 100644 index 0000000000..221b46a7cc --- /dev/null +++ b/t/t4013/diff.show_--patch-with-raw_side @@ -0,0 +1,42 @@ +$ git show --patch-with-raw side +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side + +:100644 100644 35d242b... 7289e35... M dir/sub +:100644 100644 01e79c3... f4615da... M file0 +:000000 100644 0000000... 7289e35... A file3 + +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 +$ diff --git a/t/t4013/diff.show_--patch-with-stat_--summary_side b/t/t4013/diff.show_--patch-with-stat_--summary_side new file mode 100644 index 0000000000..377f2b7b7a --- /dev/null +++ b/t/t4013/diff.show_--patch-with-stat_--summary_side @@ -0,0 +1,44 @@ +$ git show --patch-with-stat --summary side +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + +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 +$ diff --git a/t/t4013/diff.show_--patch-with-stat_side b/t/t4013/diff.show_--patch-with-stat_side new file mode 100644 index 0000000000..fb14c530d2 --- /dev/null +++ b/t/t4013/diff.show_--patch-with-stat_side @@ -0,0 +1,43 @@ +$ git show --patch-with-stat side +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + +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 +$ diff --git a/t/t4013/diff.show_--root_initial b/t/t4013/diff.show_--root_initial new file mode 100644 index 0000000000..8c89136c4d --- /dev/null +++ b/t/t4013/diff.show_--root_initial @@ -0,0 +1,34 @@ +$ git show --root initial +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.show_--stat_--summary_side b/t/t4013/diff.show_--stat_--summary_side new file mode 100644 index 0000000000..5bd5977628 --- /dev/null +++ b/t/t4013/diff.show_--stat_--summary_side @@ -0,0 +1,13 @@ +$ git show --stat --summary side +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side + + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 +$ diff --git a/t/t4013/diff.show_--stat_side b/t/t4013/diff.show_--stat_side new file mode 100644 index 0000000000..3b22327e48 --- /dev/null +++ b/t/t4013/diff.show_--stat_side @@ -0,0 +1,12 @@ +$ git show --stat side +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side + + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) +$ diff --git a/t/t4013/diff.show_initial b/t/t4013/diff.show_initial new file mode 100644 index 0000000000..4c4066ae48 --- /dev/null +++ b/t/t4013/diff.show_initial @@ -0,0 +1,7 @@ +$ git show initial +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_master b/t/t4013/diff.show_master new file mode 100644 index 0000000000..9e6e1f2710 --- /dev/null +++ b/t/t4013/diff.show_master @@ -0,0 +1,36 @@ +$ git show 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 --cc 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 --cc 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_side b/t/t4013/diff.show_side new file mode 100644 index 0000000000..530a073b19 --- /dev/null +++ b/t/t4013/diff.show_side @@ -0,0 +1,38 @@ +$ git show side +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 +$ diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_ b/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_ new file mode 100644 index 0000000000..6a467cccc1 --- /dev/null +++ b/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_ @@ -0,0 +1,61 @@ +$ git whatchanged --patch-with-stat --summary master -- dir/ +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +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 + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third +--- + dir/sub | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +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 + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. +--- + dir/sub | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +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/t/t4013/diff.whatchanged_--patch-with-stat_master b/t/t4013/diff.whatchanged_--patch-with-stat_master new file mode 100644 index 0000000000..1e1bbe1963 --- /dev/null +++ b/t/t4013/diff.whatchanged_--patch-with-stat_master @@ -0,0 +1,116 @@ +$ git whatchanged --patch-with-stat master +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + +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 +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + +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. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + +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 +$ diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_ b/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_ new file mode 100644 index 0000000000..13789f169b --- /dev/null +++ b/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_ @@ -0,0 +1,61 @@ +$ git whatchanged --patch-with-stat master -- dir/ +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +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 + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third +--- + dir/sub | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +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 + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. +--- + dir/sub | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +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/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master new file mode 100644 index 0000000000..5facf2543d --- /dev/null +++ b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master @@ -0,0 +1,199 @@ +$ git whatchanged --root --cc --patch-with-stat --summary 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' + + dir/sub | 2 ++ + file0 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + +diff --cc 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 --cc file0 +index b414108,f4615da..10a8a9f +--- a/file0 ++++ b/file0 +@@@ -1,6 -1,6 +1,9 @@@ + 1 + 2 + 3 + +4 + +5 + +6 ++ A ++ B ++ C + +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + +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 +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + +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. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + +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 +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) + create mode 100644 dir/sub + create mode 100644 file0 + create mode 100644 file2 + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master new file mode 100644 index 0000000000..0291153587 --- /dev/null +++ b/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master @@ -0,0 +1,160 @@ +$ git whatchanged --root --patch-with-stat --summary master +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + +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 +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + +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. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + +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 +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) + create mode 100644 dir/sub + create mode 100644 file0 + create mode 100644 file2 + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.whatchanged_--root_--patch-with-stat_master b/t/t4013/diff.whatchanged_--root_--patch-with-stat_master new file mode 100644 index 0000000000..9b0349cd55 --- /dev/null +++ b/t/t4013/diff.whatchanged_--root_--patch-with-stat_master @@ -0,0 +1,154 @@ +$ git whatchanged --root --patch-with-stat master +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + +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 +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + +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. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + +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 +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master new file mode 100644 index 0000000000..10f6767e49 --- /dev/null +++ b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master @@ -0,0 +1,199 @@ +$ git whatchanged --root -c --patch-with-stat --summary 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' + + dir/sub | 2 ++ + file0 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + +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 + +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side +--- + dir/sub | 2 ++ + file0 | 3 +++ + file3 | 4 ++++ + 3 files changed, 9 insertions(+), 0 deletions(-) + create mode 100644 file3 + +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 +--- + dir/sub | 2 ++ + file1 | 3 +++ + 2 files changed, 5 insertions(+), 0 deletions(-) + create mode 100644 file1 + +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. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 + +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 +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 +++ + 3 files changed, 8 insertions(+), 0 deletions(-) + create mode 100644 dir/sub + create mode 100644 file0 + create mode 100644 file2 + +diff --git a/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.whatchanged_--root_-p_master b/t/t4013/diff.whatchanged_--root_-p_master new file mode 100644 index 0000000000..ebf1f0661e --- /dev/null +++ b/t/t4013/diff.whatchanged_--root_-p_master @@ -0,0 +1,135 @@ +$ git whatchanged --root -p master +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/dir/sub b/dir/sub +new file mode 100644 +index 0000000..35d242b +--- /dev/null ++++ b/dir/sub +@@ -0,0 +1,2 @@ ++A ++B +diff --git a/file0 b/file0 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file0 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +diff --git a/file2 b/file2 +new file mode 100644 +index 0000000..01e79c3 +--- /dev/null ++++ b/file2 +@@ -0,0 +1,3 @@ ++1 ++2 ++3 +$ diff --git a/t/t4013/diff.whatchanged_--root_master b/t/t4013/diff.whatchanged_--root_master new file mode 100644 index 0000000000..a405cb6138 --- /dev/null +++ b/t/t4013/diff.whatchanged_--root_master @@ -0,0 +1,42 @@ +$ git whatchanged --root master +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side + +:100644 100644 35d242b... 7289e35... M dir/sub +:100644 100644 01e79c3... f4615da... M file0 +:000000 100644 0000000... 7289e35... A file3 + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third + +:100644 100644 8422d40... cead32e... M dir/sub +:000000 100644 0000000... b1e6722... A file1 + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. + +:100644 100644 35d242b... 8422d40... M dir/sub +:100644 100644 01e79c3... b414108... M file0 +:100644 000000 01e79c3... 0000000... D file2 + +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial + +:000000 100644 0000000... 35d242b... A dir/sub +:000000 100644 0000000... 01e79c3... A file0 +:000000 100644 0000000... 01e79c3... A file2 +$ diff --git a/t/t4013/diff.whatchanged_-SF_-p_master b/t/t4013/diff.whatchanged_-SF_-p_master new file mode 100644 index 0000000000..f39da84822 --- /dev/null +++ b/t/t4013/diff.whatchanged_-SF_-p_master @@ -0,0 +1,18 @@ +$ git whatchanged -SF -p master +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/t/t4013/diff.whatchanged_-SF_master b/t/t4013/diff.whatchanged_-SF_master new file mode 100644 index 0000000000..0499321d0e --- /dev/null +++ b/t/t4013/diff.whatchanged_-SF_master @@ -0,0 +1,9 @@ +$ git whatchanged -SF master +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third + +:100644 100644 8422d40... cead32e... M dir/sub +$ diff --git a/t/t4013/diff.whatchanged_-p_master b/t/t4013/diff.whatchanged_-p_master new file mode 100644 index 0000000000..f18d43209c --- /dev/null +++ b/t/t4013/diff.whatchanged_-p_master @@ -0,0 +1,102 @@ +$ git whatchanged -p master +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 +$ diff --git a/t/t4013/diff.whatchanged_master b/t/t4013/diff.whatchanged_master new file mode 100644 index 0000000000..cd3bcc2c72 --- /dev/null +++ b/t/t4013/diff.whatchanged_master @@ -0,0 +1,32 @@ +$ git whatchanged master +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side + +:100644 100644 35d242b... 7289e35... M dir/sub +:100644 100644 01e79c3... f4615da... M file0 +:000000 100644 0000000... 7289e35... A file3 + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third + +:100644 100644 8422d40... cead32e... M dir/sub +:000000 100644 0000000... b1e6722... A file1 + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor <author@example.com> +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. + +:100644 100644 35d242b... 8422d40... M dir/sub +:100644 100644 01e79c3... b414108... M file0 +:100644 000000 01e79c3... 0000000... D file2 +$ diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh new file mode 100755 index 0000000000..7fe853c20d --- /dev/null +++ b/t/t4014-format-patch.sh @@ -0,0 +1,233 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='Format-patch skipping already incorporated patches' + +. ./test-lib.sh + +test_expect_success setup ' + + for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file && + cat file >elif && + git add file elif && + git commit -m Initial && + git checkout -b side && + + for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file && + chmod +x elif && + git update-index file elif && + git update-index --chmod=+x elif && + git commit -m "Side changes #1" && + + for i in D E F; do echo "$i"; done >>file && + git update-index file && + git commit -m "Side changes #2" && + git tag C2 && + + for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file && + git update-index file && + git commit -m "Side changes #3 with \\n backslash-n in it." && + + git checkout master && + git diff-tree -p C2 | git apply --index && + git commit -m "Master accepts moral equivalent of #2" + +' + +test_expect_success "format-patch --ignore-if-in-upstream" ' + + git format-patch --stdout master..side >patch0 && + cnt=`grep "^From " patch0 | wc -l` && + test $cnt = 3 + +' + +test_expect_success "format-patch --ignore-if-in-upstream" ' + + git format-patch --stdout \ + --ignore-if-in-upstream master..side >patch1 && + cnt=`grep "^From " patch1 | wc -l` && + test $cnt = 2 + +' + +test_expect_success "format-patch result applies" ' + + git checkout -b rebuild-0 master && + git am -3 patch0 && + cnt=`git rev-list master.. | wc -l` && + test $cnt = 2 +' + +test_expect_success "format-patch --ignore-if-in-upstream result applies" ' + + git checkout -b rebuild-1 master && + git am -3 patch1 && + cnt=`git rev-list master.. | wc -l` && + test $cnt = 2 +' + +test_expect_success 'commit did not screw up the log message' ' + + git cat-file commit side | grep "^Side .* with .* backslash-n" + +' + +test_expect_success 'format-patch did not screw up the log message' ' + + grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 && + grep "^Subject: .*Side changes #3 with .* backslash-n" patch1 + +' + +test_expect_success 'replay did not screw up the log message' ' + + git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n" + +' + +test_expect_success 'extra headers' ' + + git config format.headers "To: R. E. Cipient <rcipient@example.com> +" && + git config --add format.headers "Cc: S. E. Cipient <scipient@example.com> +" && + git format-patch --stdout master..side > patch2 && + sed -e "/^$/q" patch2 > hdrs2 && + grep "^To: R. E. Cipient <rcipient@example.com>$" hdrs2 && + grep "^Cc: S. E. Cipient <scipient@example.com>$" hdrs2 + +' + +test_expect_success 'extra headers without newlines' ' + + git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" && + git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>" && + git format-patch --stdout master..side >patch3 && + sed -e "/^$/q" patch3 > hdrs3 && + grep "^To: R. E. Cipient <rcipient@example.com>$" hdrs3 && + grep "^Cc: S. E. Cipient <scipient@example.com>$" hdrs3 + +' + +test_expect_success 'extra headers with multiple To:s' ' + + git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" && + git config --add format.headers "To: S. E. Cipient <scipient@example.com>" && + git format-patch --stdout master..side > patch4 && + sed -e "/^$/q" patch4 > hdrs4 && + grep "^To: R. E. Cipient <rcipient@example.com>,$" hdrs4 && + grep "^ *S. E. Cipient <scipient@example.com>$" hdrs4 +' + +test_expect_success 'additional command line cc' ' + + git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" && + git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^$/q" >patch5 && + grep "^Cc: R. E. Cipient <rcipient@example.com>,$" patch5 && + grep "^ *S. E. Cipient <scipient@example.com>$" patch5 +' + +test_expect_success 'multiple files' ' + + rm -rf patches/ && + git checkout side && + git format-patch -o patches/ master && + ls patches/0001-Side-changes-1.patch patches/0002-Side-changes-2.patch patches/0003-Side-changes-3-with-n-backslash-n-in-it.patch +' + +test_expect_success 'thread' ' + + rm -rf patches/ && + git checkout side && + git format-patch --thread -o patches/ master && + FIRST_MID=$(grep "Message-Id:" patches/0001-* | sed "s/^[^<]*\(<[^>]*>\).*$/\1/") && + for i in patches/0002-* patches/0003-* + do + grep "References: $FIRST_MID" $i && + grep "In-Reply-To: $FIRST_MID" $i || break + done +' + +test_expect_success 'thread in-reply-to' ' + + rm -rf patches/ && + git checkout side && + git format-patch --in-reply-to="<test.message>" --thread -o patches/ master && + FIRST_MID="<test.message>" && + for i in patches/* + do + grep "References: $FIRST_MID" $i && + grep "In-Reply-To: $FIRST_MID" $i || break + done +' + +test_expect_success 'thread cover-letter' ' + + rm -rf patches/ && + git checkout side && + git format-patch --cover-letter --thread -o patches/ master && + FIRST_MID=$(grep "Message-Id:" patches/0000-* | sed "s/^[^<]*\(<[^>]*>\).*$/\1/") && + for i in patches/0001-* patches/0002-* patches/0003-* + do + grep "References: $FIRST_MID" $i && + grep "In-Reply-To: $FIRST_MID" $i || break + done +' + +test_expect_success 'thread cover-letter in-reply-to' ' + + rm -rf patches/ && + git checkout side && + git format-patch --cover-letter --in-reply-to="<test.message>" --thread -o patches/ master && + FIRST_MID="<test.message>" && + for i in patches/* + do + grep "References: $FIRST_MID" $i && + grep "In-Reply-To: $FIRST_MID" $i || break + done +' + +test_expect_success 'excessive subject' ' + + rm -rf patches/ && + git checkout side && + for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file && + git update-index file && + git commit -m "This is an excessively long subject line for a message due to the habit some projects have of not having a short, one-line subject at the start of the commit message, but rather sticking a whole paragraph right at the start as the only thing in the commit message. It had better not become the filename for the patch." && + git format-patch -o patches/ master..side && + ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch +' + +test_expect_success 'cover-letter inherits diff options' ' + + git mv file foo && + git commit -m foo && + git format-patch --cover-letter -1 && + ! grep "file => foo .* 0 *$" 0000-cover-letter.patch && + git format-patch --cover-letter -1 -M && + grep "file => foo .* 0 *$" 0000-cover-letter.patch + +' + +cat > expect << EOF + This is an excessively long subject line for a message due to the + habit some projects have of not having a short, one-line subject at + the start of the commit message, but rather sticking a whole + paragraph right at the start as the only thing in the commit + message. It had better not become the filename for the patch. + foo + +EOF + +test_expect_success 'shortlog of cover-letter wraps overly-long onelines' ' + + git format-patch --cover-letter -2 && + sed -e "1,/A U Thor/d" -e "/^$/q" < 0000-cover-letter.patch > output && + test_cmp expect output + +' + +test_done diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh new file mode 100755 index 0000000000..a27fccc8dc --- /dev/null +++ b/t/t4015-diff-whitespace.sh @@ -0,0 +1,344 @@ +#!/bin/sh +# +# Copyright (c) 2006 Johannes E. Schindelin +# + +test_description='Test special whitespace in diff engine. + +' +. ./test-lib.sh +. ../diff-lib.sh + +# Ray Lehtiniemi's example + +cat << EOF > x +do { + nothing; +} while (0); +EOF + +git update-index --add x + +cat << EOF > x +do +{ + nothing; +} +while (0); +EOF + +cat << EOF > expect +diff --git a/x b/x +index adf3937..6edc172 100644 +--- a/x ++++ b/x +@@ -1,3 +1,5 @@ +-do { ++do ++{ + nothing; +-} while (0); ++} ++while (0); +EOF + +git diff > out +test_expect_success "Ray's example without options" 'test_cmp expect out' + +git diff -w > out +test_expect_success "Ray's example with -w" 'test_cmp expect out' + +git diff -b > out +test_expect_success "Ray's example with -b" 'test_cmp expect out' + +tr 'Q' '\015' << EOF > x +whitespace at beginning +whitespace change +whitespace in the middle +whitespace at end +unchanged line +CR at endQ +EOF + +git update-index x + +tr '_' ' ' << EOF > x + whitespace at beginning +whitespace change +white space in the middle +whitespace at end__ +unchanged line +CR at end +EOF + +tr 'Q_' '\015 ' << EOF > expect +diff --git a/x b/x +index d99af23..8b32fb5 100644 +--- a/x ++++ b/x +@@ -1,6 +1,6 @@ +-whitespace at beginning +-whitespace change +-whitespace in the middle +-whitespace at end ++ whitespace at beginning ++whitespace change ++white space in the middle ++whitespace at end__ + unchanged line +-CR at endQ ++CR at end +EOF +git diff > out +test_expect_success 'another test, without options' 'test_cmp expect out' + +cat << EOF > expect +diff --git a/x b/x +index d99af23..8b32fb5 100644 +EOF +git diff -w > out +test_expect_success 'another test, with -w' 'test_cmp expect out' + +tr 'Q' '\015' << EOF > expect +diff --git a/x b/x +index d99af23..8b32fb5 100644 +--- a/x ++++ b/x +@@ -1,6 +1,6 @@ +-whitespace at beginning ++ whitespace at beginning + whitespace change +-whitespace in the middle ++white space in the middle + whitespace at end + unchanged line + CR at endQ +EOF +git diff -b > out +test_expect_success 'another test, with -b' 'test_cmp expect out' + +test_expect_success 'check mixed spaces and tabs in indent' ' + + # This is indented with SP HT SP. + echo " foo();" > x && + git diff --check | grep "space before tab in indent" + +' + +test_expect_success 'check mixed tabs and spaces in indent' ' + + # This is indented with HT SP HT. + echo " foo();" > x && + git diff --check | grep "space before tab in indent" + +' + +test_expect_success 'check with no whitespace errors' ' + + git commit -m "snapshot" && + echo "foo();" > x && + git diff --check + +' + +test_expect_success 'check with trailing whitespace' ' + + echo "foo(); " > x && + test_must_fail git diff --check + +' + +test_expect_success 'check with space before tab in indent' ' + + # indent has space followed by hard tab + echo " foo();" > x && + test_must_fail git diff --check + +' + +test_expect_success '--check and --exit-code are not exclusive' ' + + git checkout x && + git diff --check --exit-code + +' + +test_expect_success '--check and --quiet are not exclusive' ' + + git diff --check --quiet + +' + +test_expect_success 'check staged with no whitespace errors' ' + + echo "foo();" > x && + git add x && + git diff --cached --check + +' + +test_expect_success 'check staged with trailing whitespace' ' + + echo "foo(); " > x && + git add x && + test_must_fail git diff --cached --check + +' + +test_expect_success 'check staged with space before tab in indent' ' + + # indent has space followed by hard tab + echo " foo();" > x && + git add x && + test_must_fail git diff --cached --check + +' + +test_expect_success 'check with no whitespace errors (diff-index)' ' + + echo "foo();" > x && + git add x && + git diff-index --check HEAD + +' + +test_expect_success 'check with trailing whitespace (diff-index)' ' + + echo "foo(); " > x && + git add x && + test_must_fail git diff-index --check HEAD + +' + +test_expect_success 'check with space before tab in indent (diff-index)' ' + + # indent has space followed by hard tab + echo " foo();" > x && + git add x && + test_must_fail git diff-index --check HEAD + +' + +test_expect_success 'check staged with no whitespace errors (diff-index)' ' + + echo "foo();" > x && + git add x && + git diff-index --cached --check HEAD + +' + +test_expect_success 'check staged with trailing whitespace (diff-index)' ' + + echo "foo(); " > x && + git add x && + test_must_fail git diff-index --cached --check HEAD + +' + +test_expect_success 'check staged with space before tab in indent (diff-index)' ' + + # indent has space followed by hard tab + echo " foo();" > x && + git add x && + test_must_fail git diff-index --cached --check HEAD + +' + +test_expect_success 'check with no whitespace errors (diff-tree)' ' + + echo "foo();" > x && + git commit -m "new commit" x && + git diff-tree --check HEAD^ HEAD + +' + +test_expect_success 'check with trailing whitespace (diff-tree)' ' + + echo "foo(); " > x && + git commit -m "another commit" x && + test_must_fail git diff-tree --check HEAD^ HEAD + +' + +test_expect_success 'check with space before tab in indent (diff-tree)' ' + + # indent has space followed by hard tab + echo " foo();" > x && + git commit -m "yet another" x && + test_must_fail git diff-tree --check HEAD^ HEAD + +' + +test_expect_success 'check trailing whitespace (trailing-space: off)' ' + + git config core.whitespace "-trailing-space" && + echo "foo (); " > x && + git diff --check + +' + +test_expect_success 'check trailing whitespace (trailing-space: on)' ' + + git config core.whitespace "trailing-space" && + echo "foo (); " > x && + test_must_fail git diff --check + +' + +test_expect_success 'check space before tab in indent (space-before-tab: off)' ' + + # indent contains space followed by HT + git config core.whitespace "-space-before-tab" && + echo " foo ();" > x && + git diff --check + +' + +test_expect_success 'check space before tab in indent (space-before-tab: on)' ' + + # indent contains space followed by HT + git config core.whitespace "space-before-tab" && + echo " foo (); " > x && + test_must_fail git diff --check + +' + +test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' ' + + git config core.whitespace "-indent-with-non-tab" + echo " foo ();" > x && + git diff --check + +' + +test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' ' + + git config core.whitespace "indent-with-non-tab" && + echo " foo ();" > x && + test_must_fail git diff --check + +' + +test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' ' + + git config core.whitespace "indent-with-non-tab" && + echo " foo ();" > x && + test_must_fail git diff --check + +' + +test_expect_success 'line numbers in --check output are correct' ' + + echo "" > x && + echo "foo(); " >> x && + git diff --check | grep "x:2:" + +' + +test_expect_success 'checkdiff detects trailing blank lines' ' + echo "foo();" >x && + echo "" >>x && + git diff --check | grep "ends with blank" +' + +test_done diff --git a/t/t4016-diff-quote.sh b/t/t4016-diff-quote.sh new file mode 100755 index 0000000000..f07035ab7e --- /dev/null +++ b/t/t4016-diff-quote.sh @@ -0,0 +1,70 @@ +#!/bin/sh +# +# Copyright (c) 2007 Junio C Hamano +# + +test_description='Quoting paths in diff output. +' + +. ./test-lib.sh + +P0='pathname' +P1='pathname with HT' +P2='pathname with SP' +P3='pathname +with LF' +: >"$P1" 2>&1 && test -f "$P1" && rm -f "$P1" || { + echo >&2 'Filesystem does not support tabs in names' + test_done +} + +test_expect_success setup ' + echo P0.0 >"$P0.0" && + echo P0.1 >"$P0.1" && + echo P0.2 >"$P0.2" && + echo P0.3 >"$P0.3" && + echo P1.0 >"$P1.0" && + echo P1.2 >"$P1.2" && + echo P1.3 >"$P1.3" && + git add . && + git commit -m initial && + git mv "$P0.0" "R$P0.0" && + git mv "$P0.1" "R$P1.0" && + git mv "$P0.2" "R$P2.0" && + git mv "$P0.3" "R$P3.0" && + git mv "$P1.0" "R$P0.1" && + git mv "$P1.2" "R$P2.1" && + git mv "$P1.3" "R$P3.1" && + : +' + +cat >expect <<\EOF + rename pathname.1 => "Rpathname\twith HT.0" (100%) + rename pathname.3 => "Rpathname\nwith LF.0" (100%) + rename "pathname\twith HT.3" => "Rpathname\nwith LF.1" (100%) + rename pathname.2 => Rpathname with SP.0 (100%) + rename "pathname\twith HT.2" => Rpathname with SP.1 (100%) + rename pathname.0 => Rpathname.0 (100%) + rename "pathname\twith HT.0" => Rpathname.1 (100%) +EOF +test_expect_success 'git diff --summary -M HEAD' ' + git diff --summary -M HEAD >actual && + test_cmp expect actual +' + +cat >expect <<\EOF + pathname.1 => "Rpathname\twith HT.0" | 0 + pathname.3 => "Rpathname\nwith LF.0" | 0 + "pathname\twith HT.3" => "Rpathname\nwith LF.1" | 0 + pathname.2 => Rpathname with SP.0 | 0 + "pathname\twith HT.2" => Rpathname with SP.1 | 0 + pathname.0 => Rpathname.0 | 0 + "pathname\twith HT.0" => Rpathname.1 | 0 + 7 files changed, 0 insertions(+), 0 deletions(-) +EOF +test_expect_success 'git diff --stat -M HEAD' ' + git diff --stat -M HEAD >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t4017-diff-retval.sh b/t/t4017-diff-retval.sh new file mode 100755 index 0000000000..60dd2014d5 --- /dev/null +++ b/t/t4017-diff-retval.sh @@ -0,0 +1,130 @@ +#!/bin/sh + +test_description='Return value of diffs' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo 1 >a && + git add . && + git commit -m first && + echo 2 >b && + git add . && + git commit -a -m second +' + +test_expect_success 'git diff-tree HEAD^ HEAD' ' + git diff-tree --exit-code HEAD^ HEAD + test $? = 1 +' +test_expect_success 'git diff-tree HEAD^ HEAD -- a' ' + git diff-tree --exit-code HEAD^ HEAD -- a + test $? = 0 +' +test_expect_success 'git diff-tree HEAD^ HEAD -- b' ' + git diff-tree --exit-code HEAD^ HEAD -- b + test $? = 1 +' +test_expect_success 'echo HEAD | git diff-tree --stdin' ' + echo $(git rev-parse HEAD) | git diff-tree --exit-code --stdin + test $? = 1 +' +test_expect_success 'git diff-tree HEAD HEAD' ' + git diff-tree --exit-code HEAD HEAD + test $? = 0 +' +test_expect_success 'git diff-files' ' + git diff-files --exit-code + test $? = 0 +' +test_expect_success 'git diff-index --cached HEAD' ' + git diff-index --exit-code --cached HEAD + test $? = 0 +' +test_expect_success 'git diff-index --cached HEAD^' ' + git diff-index --exit-code --cached HEAD^ + test $? = 1 +' +test_expect_success 'git diff-index --cached HEAD^' ' + echo text >>b && + echo 3 >c && + git add . && { + git diff-index --exit-code --cached HEAD^ + test $? = 1 + } +' +test_expect_success 'git diff-tree -Stext HEAD^ HEAD -- b' ' + git commit -m "text in b" && { + git diff-tree -p --exit-code -Stext HEAD^ HEAD -- b + test $? = 1 + } +' +test_expect_success 'git diff-tree -Snot-found HEAD^ HEAD -- b' ' + git diff-tree -p --exit-code -Snot-found HEAD^ HEAD -- b + test $? = 0 +' +test_expect_success 'git diff-files' ' + echo 3 >>c && { + git diff-files --exit-code + test $? = 1 + } +' +test_expect_success 'git diff-index --cached HEAD' ' + git update-index c && { + git diff-index --exit-code --cached HEAD + test $? = 1 + } +' + +test_expect_success '--check --exit-code returns 0 for no difference' ' + + git diff --check --exit-code + +' + +test_expect_success '--check --exit-code returns 1 for a clean difference' ' + + echo "good" > a && + git diff --check --exit-code + test $? = 1 + +' + +test_expect_success '--check --exit-code returns 3 for a dirty difference' ' + + echo "bad " >> a && + git diff --check --exit-code + test $? = 3 + +' + +test_expect_success '--check with --no-pager returns 2 for dirty difference' ' + + git --no-pager diff --check + test $? = 2 + +' + + +test_expect_success 'check should test not just the last line' ' + echo "" >>a && + git --no-pager diff --check + test $? = 2 + +' + +test_expect_success 'check detects leftover conflict markers' ' + git reset --hard && + git checkout HEAD^ && + echo binary >>b && + git commit -m "side" b && + test_must_fail git merge master && + git add b && ( + git --no-pager diff --cached --check >test.out + test $? = 2 + ) && + test 3 = $(grep "conflict marker" test.out | wc -l) && + git reset --hard +' + +test_done diff --git a/t/t4017-quiet.sh b/t/t4017-quiet.sh new file mode 100755 index 0000000000..e747e84227 --- /dev/null +++ b/t/t4017-quiet.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +test_description='Return value of diffs' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo 1 >a && + git add . && + git commit -m first && + echo 2 >b && + git add . && + git commit -a -m second +' + +test_expect_success 'git diff-tree HEAD^ HEAD' ' + git diff-tree --quiet HEAD^ HEAD >cnt + test $? = 1 && test $(wc -l <cnt) = 0 +' +test_expect_success 'git diff-tree HEAD^ HEAD -- a' ' + git diff-tree --quiet HEAD^ HEAD -- a >cnt + test $? = 0 && test $(wc -l <cnt) = 0 +' +test_expect_success 'git diff-tree HEAD^ HEAD -- b' ' + git diff-tree --quiet HEAD^ HEAD -- b >cnt + test $? = 1 && test $(wc -l <cnt) = 0 +' +# this diff outputs one line: sha1 of the given head +test_expect_success 'echo HEAD | git diff-tree --stdin' ' + echo $(git rev-parse HEAD) | git diff-tree --quiet --stdin >cnt + test $? = 1 && test $(wc -l <cnt) = 1 +' +test_expect_success 'git diff-tree HEAD HEAD' ' + git diff-tree --quiet HEAD HEAD >cnt + test $? = 0 && test $(wc -l <cnt) = 0 +' +test_expect_success 'git diff-files' ' + git diff-files --quiet >cnt + test $? = 0 && test $(wc -l <cnt) = 0 +' +test_expect_success 'git diff-index --cached HEAD' ' + git diff-index --quiet --cached HEAD >cnt + test $? = 0 && test $(wc -l <cnt) = 0 +' +test_expect_success 'git diff-index --cached HEAD^' ' + git diff-index --quiet --cached HEAD^ >cnt + test $? = 1 && test $(wc -l <cnt) = 0 +' +test_expect_success 'git diff-index --cached HEAD^' ' + echo text >>b && + echo 3 >c && + git add . && { + git diff-index --quiet --cached HEAD^ >cnt + test $? = 1 && test $(wc -l <cnt) = 0 + } +' +test_expect_success 'git diff-tree -Stext HEAD^ HEAD -- b' ' + git commit -m "text in b" && { + git diff-tree --quiet -Stext HEAD^ HEAD -- b >cnt + test $? = 1 && test $(wc -l <cnt) = 0 + } +' +test_expect_success 'git diff-tree -Snot-found HEAD^ HEAD -- b' ' + git diff-tree --quiet -Snot-found HEAD^ HEAD -- b >cnt + test $? = 0 && test $(wc -l <cnt) = 0 +' +test_expect_success 'git diff-files' ' + echo 3 >>c && { + git diff-files --quiet >cnt + test $? = 1 && test $(wc -l <cnt) = 0 + } +' +test_expect_success 'git diff-index --cached HEAD' ' + git update-index c && { + git diff-index --quiet --cached HEAD >cnt + test $? = 1 && test $(wc -l <cnt) = 0 + } +' + +test_done diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh new file mode 100755 index 0000000000..833d6cbcfc --- /dev/null +++ b/t/t4018-diff-funcname.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes E. Schindelin +# + +test_description='Test custom diff function name patterns' + +. ./test-lib.sh + +LF=' +' + +cat > Beer.java << EOF +public class Beer +{ + int special; + public static void main(String args[]) + { + String s=" "; + for(int x = 99; x > 0; x--) + { + System.out.print(x + " bottles of beer on the wall " + + x + " bottles of beer\n" + + "Take one down, pass it around, " + (x - 1) + + " bottles of beer on the wall.\n"); + } + System.out.print("Go to the store, buy some more,\n" + + "99 bottles of beer on the wall.\n"); + } +} +EOF + +sed 's/beer\\/beer,\\/' < Beer.java > Beer-correct.java + +test_expect_success 'default behaviour' ' + git diff --no-index Beer.java Beer-correct.java | + grep "^@@.*@@ public class Beer" +' + +test_expect_success 'preset java pattern' ' + echo "*.java diff=java" >.gitattributes && + git diff --no-index Beer.java Beer-correct.java | + grep "^@@.*@@ public static void main(" +' + +git config diff.java.funcname '!static +!String +[^ ].*s.*' + +test_expect_success 'custom pattern' ' + git diff --no-index Beer.java Beer-correct.java | + grep "^@@.*@@ int special;$" +' + +test_expect_success 'last regexp must not be negated' ' + git config diff.java.funcname "!static" && + test_must_fail git diff --no-index Beer.java Beer-correct.java +' + +test_done diff --git a/t/t4019-diff-wserror.sh b/t/t4019-diff-wserror.sh new file mode 100755 index 0000000000..7eae1f4500 --- /dev/null +++ b/t/t4019-diff-wserror.sh @@ -0,0 +1,181 @@ +#!/bin/sh + +test_description='diff whitespace error detection' + +. ./test-lib.sh + +test_expect_success setup ' + + git config diff.color.whitespace "blue reverse" && + >F && + git add F && + echo " Eight SP indent" >>F && + echo " HT and SP indent" >>F && + echo "With trailing SP " >>F && + echo "Carriage ReturnQ" | tr Q "\015" >>F && + echo "No problem" >>F && + echo >>F + +' + +blue_grep='7;34m' ;# ESC [ 7 ; 3 4 m + +test_expect_success default ' + + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight normal >/dev/null && + grep HT error >/dev/null && + grep With error >/dev/null && + grep Return error >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'without -trail' ' + + git config core.whitespace -trail + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight normal >/dev/null && + grep HT error >/dev/null && + grep With normal >/dev/null && + grep Return normal >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'without -trail (attribute)' ' + + git config --unset core.whitespace + echo "F whitespace=-trail" >.gitattributes + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight normal >/dev/null && + grep HT error >/dev/null && + grep With normal >/dev/null && + grep Return normal >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'without -space' ' + + rm -f .gitattributes + git config core.whitespace -space + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight normal >/dev/null && + grep HT normal >/dev/null && + grep With error >/dev/null && + grep Return error >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'without -space (attribute)' ' + + git config --unset core.whitespace + echo "F whitespace=-space" >.gitattributes + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight normal >/dev/null && + grep HT normal >/dev/null && + grep With error >/dev/null && + grep Return error >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'with indent-non-tab only' ' + + rm -f .gitattributes + git config core.whitespace indent,-trailing,-space + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight error >/dev/null && + grep HT normal >/dev/null && + grep With normal >/dev/null && + grep Return normal >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'with indent-non-tab only (attribute)' ' + + git config --unset core.whitespace + echo "F whitespace=indent,-trailing,-space" >.gitattributes + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight error >/dev/null && + grep HT normal >/dev/null && + grep With normal >/dev/null && + grep Return normal >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'with cr-at-eol' ' + + rm -f .gitattributes + git config core.whitespace cr-at-eol + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight normal >/dev/null && + grep HT error >/dev/null && + grep With error >/dev/null && + grep Return normal >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'with cr-at-eol (attribute)' ' + + git config --unset core.whitespace + echo "F whitespace=trailing,cr-at-eol" >.gitattributes + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight normal >/dev/null && + grep HT error >/dev/null && + grep With error >/dev/null && + grep Return normal >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'trailing empty lines (1)' ' + + rm -f .gitattributes && + test_must_fail git diff --check >output && + grep "ends with blank lines." output && + grep "trailing whitespace" output + +' + +test_expect_success 'trailing empty lines (2)' ' + + echo "F -whitespace" >.gitattributes && + git diff --check >output && + ! test -s output + +' + +test_done diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh new file mode 100755 index 0000000000..637b4e19d5 --- /dev/null +++ b/t/t4020-diff-external.sh @@ -0,0 +1,110 @@ +#!/bin/sh + +test_description='external diff interface test' + +. ./test-lib.sh + +_z40=0000000000000000000000000000000000000000 + +test_expect_success setup ' + + test_tick && + echo initial >file && + git add file && + git commit -m initial && + + test_tick && + echo second >file && + git add file && + git commit -m second && + + test_tick && + echo third >file +' + +test_expect_success 'GIT_EXTERNAL_DIFF environment' ' + + GIT_EXTERNAL_DIFF=echo git diff | { + read path oldfile oldhex oldmode newfile newhex newmode && + test "z$path" = zfile && + test "z$oldmode" = z100644 && + test "z$newhex" = "z$_z40" && + test "z$newmode" = z100644 && + oh=$(git rev-parse --verify HEAD:file) && + test "z$oh" = "z$oldhex" + } + +' + +test_expect_success 'GIT_EXTERNAL_DIFF environment should apply only to diff' ' + + GIT_EXTERNAL_DIFF=echo git log -p -1 HEAD | + grep "^diff --git a/file b/file" + +' + +test_expect_success 'diff attribute' ' + + git config diff.parrot.command echo && + + echo >.gitattributes "file diff=parrot" && + + git diff | { + read path oldfile oldhex oldmode newfile newhex newmode && + test "z$path" = zfile && + test "z$oldmode" = z100644 && + test "z$newhex" = "z$_z40" && + test "z$newmode" = z100644 && + oh=$(git rev-parse --verify HEAD:file) && + test "z$oh" = "z$oldhex" + } + +' + +test_expect_success 'diff attribute should apply only to diff' ' + + git log -p -1 HEAD | + grep "^diff --git a/file b/file" + +' + +test_expect_success 'diff attribute' ' + + git config --unset diff.parrot.command && + git config diff.color.command echo && + + echo >.gitattributes "file diff=color" && + + git diff | { + read path oldfile oldhex oldmode newfile newhex newmode && + test "z$path" = zfile && + test "z$oldmode" = z100644 && + test "z$newhex" = "z$_z40" && + test "z$newmode" = z100644 && + oh=$(git rev-parse --verify HEAD:file) && + test "z$oh" = "z$oldhex" + } + +' + +test_expect_success 'diff attribute should apply only to diff' ' + + git log -p -1 HEAD | + grep "^diff --git a/file b/file" + +' + +test_expect_success 'no diff with -diff' ' + echo >.gitattributes "file -diff" && + git diff | grep Binary +' + +echo NULZbetweenZwords | perl -pe 'y/Z/\000/' > file + +test_expect_success 'force diff with "diff"' ' + echo >.gitattributes "file diff" && + git diff >actual && + test_cmp ../t4020/diff.NUL actual +' + +test_done diff --git a/t/t4020/diff.NUL b/t/t4020/diff.NUL Binary files differnew file mode 100644 index 0000000000..db2f89090c --- /dev/null +++ b/t/t4020/diff.NUL diff --git a/t/t4021-format-patch-numbered.sh b/t/t4021-format-patch-numbered.sh new file mode 100755 index 0000000000..43d64bbd82 --- /dev/null +++ b/t/t4021-format-patch-numbered.sh @@ -0,0 +1,106 @@ +#!/bin/sh +# +# Copyright (c) 2006 Brian C Gernhardt +# + +test_description='Format-patch numbering options' + +. ./test-lib.sh + +test_expect_success setup ' + + echo A > file && + git add file && + git commit -m First && + + echo B >> file && + git commit -a -m Second && + + echo C >> file && + git commit -a -m Third + +' + +# Each of these gets used multiple times. + +test_num_no_numbered() { + cnt=$(grep "^Subject: \[PATCH\]" $1 | wc -l) && + test $cnt = $2 +} + +test_single_no_numbered() { + test_num_no_numbered $1 1 +} + +test_no_numbered() { + test_num_no_numbered $1 2 +} + +test_single_numbered() { + grep "^Subject: \[PATCH 1/1\]" $1 +} + +test_numbered() { + grep "^Subject: \[PATCH 1/2\]" $1 && + grep "^Subject: \[PATCH 2/2\]" $1 +} + +test_expect_success 'Default: no numbered' ' + + git format-patch --stdout HEAD~2 >patch0 && + test_no_numbered patch0 + +' + +test_expect_success 'Use --numbered' ' + + git format-patch --numbered --stdout HEAD~2 >patch1 && + test_numbered patch1 + +' + +test_expect_success 'format.numbered = true' ' + + git config format.numbered true && + git format-patch --stdout HEAD~2 >patch2 && + test_numbered patch2 + +' + +test_expect_success 'format.numbered && single patch' ' + + git format-patch --stdout HEAD^ > patch3 && + test_single_numbered patch3 + +' + +test_expect_success 'format.numbered && --no-numbered' ' + + git format-patch --no-numbered --stdout HEAD~2 >patch4 && + test_no_numbered patch4 + +' + +test_expect_success 'format.numbered = auto' ' + + git config format.numbered auto + git format-patch --stdout HEAD~2 > patch5 && + test_numbered patch5 + +' + +test_expect_success 'format.numbered = auto && single patch' ' + + git format-patch --stdout HEAD^ > patch6 && + test_single_no_numbered patch6 + +' + +test_expect_success 'format.numbered = auto && --no-numbered' ' + + git format-patch --no-numbered --stdout HEAD~2 > patch7 && + test_no_numbered patch7 + +' + +test_done diff --git a/t/t4021-format-patch-signer-mime.sh b/t/t4021-format-patch-signer-mime.sh new file mode 100755 index 0000000000..ba43f18549 --- /dev/null +++ b/t/t4021-format-patch-signer-mime.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +test_description='format-patch -s should force MIME encoding as needed' + +. ./test-lib.sh + +test_expect_success setup ' + + >F && + git add F && + git commit -m initial && + echo new line >F && + + test_tick && + git commit -m "This adds some lines to F" F + +' + +test_expect_success 'format normally' ' + + git format-patch --stdout -1 >output && + ! grep Content-Type output + +' + +test_expect_success 'format with signoff without funny signer name' ' + + git format-patch -s --stdout -1 >output && + ! grep Content-Type output + +' + +test_expect_success 'format with non ASCII signer name' ' + + GIT_COMMITTER_NAME="ã¯ã¾ã® ãµã«ãŠã†" \ + git format-patch -s --stdout -1 >output && + grep Content-Type output + +' + +test_expect_success 'attach and signoff do not duplicate mime headers' ' + + GIT_COMMITTER_NAME="ã¯ã¾ã® ãµã«ãŠã†" \ + git format-patch -s --stdout -1 --attach >output && + test `grep -ci ^MIME-Version: output` = 1 + +' + +test_done + diff --git a/t/t4022-diff-rewrite.sh b/t/t4022-diff-rewrite.sh new file mode 100755 index 0000000000..bf996fc414 --- /dev/null +++ b/t/t4022-diff-rewrite.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +test_description='rewrite diff' + +. ./test-lib.sh + +test_expect_success setup ' + + cat ../../COPYING >test && + git add test && + tr \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM" \ + <../../COPYING >test + +' + +test_expect_success 'detect rewrite' ' + + actual=$(git diff-files -B --summary test) && + expr "$actual" : " rewrite test ([0-9]*%)$" || { + echo "Eh? <<$actual>>" + false + } + +' + +test_done + diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh new file mode 100755 index 0000000000..4dbfc6e8b7 --- /dev/null +++ b/t/t4023-diff-rename-typechange.sh @@ -0,0 +1,86 @@ +#!/bin/sh + +test_description='typechange rename detection' + +. ./test-lib.sh + +test_expect_success setup ' + + rm -f foo bar && + cat ../../COPYING >foo && + ln -s linklink bar && + git add foo bar && + git commit -a -m Initial && + git tag one && + + rm -f foo bar && + cat ../../COPYING >bar && + ln -s linklink foo && + git add foo bar && + git commit -a -m Second && + git tag two && + + rm -f foo bar && + cat ../../COPYING >foo && + git add foo && + git commit -a -m Third && + git tag three && + + mv foo bar && + ln -s linklink foo && + git add foo bar && + git commit -a -m Fourth && + git tag four && + + # This is purely for sanity check + + rm -f foo bar && + cat ../../COPYING >foo && + cat ../../Makefile >bar && + git add foo bar && + git commit -a -m Fifth && + git tag five && + + rm -f foo bar && + cat ../../Makefile >foo && + cat ../../COPYING >bar && + git add foo bar && + git commit -a -m Sixth && + git tag six + +' + +test_expect_success 'cross renames to be detected for regular files' ' + + git diff-tree five six -r --name-status -B -M | sort >actual && + { + echo "R100 foo bar" + echo "R100 bar foo" + } | sort >expect && + test_cmp expect actual + +' + +test_expect_success 'cross renames to be detected for typechange' ' + + git diff-tree one two -r --name-status -B -M | sort >actual && + { + echo "R100 foo bar" + echo "R100 bar foo" + } | sort >expect && + test_cmp expect actual + +' + +test_expect_success 'moves and renames' ' + + git diff-tree three four -r --name-status -B -M | sort >actual && + { + echo "R100 foo bar" + echo "T100 foo" + } | sort >expect && + test_cmp expect actual + +' + +test_done diff --git a/t/t4024-diff-optimize-common.sh b/t/t4024-diff-optimize-common.sh new file mode 100755 index 0000000000..c4d733f5db --- /dev/null +++ b/t/t4024-diff-optimize-common.sh @@ -0,0 +1,157 @@ +#!/bin/sh + +test_description='common tail optimization' + +. ./test-lib.sh + +z=zzzzzzzz ;# 8 +z="$z$z$z$z$z$z$z$z" ;# 64 +z="$z$z$z$z$z$z$z$z" ;# 512 +z="$z$z$z$z" ;# 2048 +z2047=$(expr "$z" : '.\(.*\)') ; #2047 + +x=zzzzzzzzzz ;# 10 +y="$x$x$x$x$x$x$x$x$x$x" ;# 100 +z="$y$y$y$y$y$y$y$y$y$y" ;# 1000 +z1000=$z +z100=$y +z10=$x + +zs() { + count="$1" + while test "$count" -ge 1000 + do + count=$(($count - 1000)) + printf "%s" $z1000 + done + while test "$count" -ge 100 + do + count=$(($count - 100)) + printf "%s" $z100 + done + while test "$count" -ge 10 + do + count=$(($count - 10)) + printf "%s" $z10 + done + while test "$count" -ge 1 + do + count=$(($count - 1)) + printf "z" + done +} + +zc () { + sed -e "/^index/d" \ + -e "s/$z1000/Q/g" \ + -e "s/QQQQQQQQQ/Z9000/g" \ + -e "s/QQQQQQQQ/Z8000/g" \ + -e "s/QQQQQQQ/Z7000/g" \ + -e "s/QQQQQQ/Z6000/g" \ + -e "s/QQQQQ/Z5000/g" \ + -e "s/QQQQ/Z4000/g" \ + -e "s/QQQ/Z3000/g" \ + -e "s/QQ/Z2000/g" \ + -e "s/Q/Z1000/g" \ + -e "s/$z100/Q/g" \ + -e "s/QQQQQQQQQ/Z900/g" \ + -e "s/QQQQQQQQ/Z800/g" \ + -e "s/QQQQQQQ/Z700/g" \ + -e "s/QQQQQQ/Z600/g" \ + -e "s/QQQQQ/Z500/g" \ + -e "s/QQQQ/Z400/g" \ + -e "s/QQQ/Z300/g" \ + -e "s/QQ/Z200/g" \ + -e "s/Q/Z100/g" \ + -e "s/000Z//g" \ + -e "s/$z10/Q/g" \ + -e "s/QQQQQQQQQ/Z90/g" \ + -e "s/QQQQQQQQ/Z80/g" \ + -e "s/QQQQQQQ/Z70/g" \ + -e "s/QQQQQQ/Z60/g" \ + -e "s/QQQQQ/Z50/g" \ + -e "s/QQQQ/Z40/g" \ + -e "s/QQQ/Z30/g" \ + -e "s/QQ/Z20/g" \ + -e "s/Q/Z10/g" \ + -e "s/00Z//g" \ + -e "s/z/Q/g" \ + -e "s/QQQQQQQQQ/Z9/g" \ + -e "s/QQQQQQQQ/Z8/g" \ + -e "s/QQQQQQQ/Z7/g" \ + -e "s/QQQQQQ/Z6/g" \ + -e "s/QQQQQ/Z5/g" \ + -e "s/QQQQ/Z4/g" \ + -e "s/QQQ/Z3/g" \ + -e "s/QQ/Z2/g" \ + -e "s/Q/Z1/g" \ + -e "s/0Z//g" \ + ; +} + +expect_pattern () { + cnt="$1" + cat <<EOF +diff --git a/file-a$cnt b/file-a$cnt +--- a/file-a$cnt ++++ b/file-a$cnt +@@ -1 +1 @@ +-Z${cnt}a ++Z${cnt}A +diff --git a/file-b$cnt b/file-b$cnt +--- a/file-b$cnt ++++ b/file-b$cnt +@@ -1 +1 @@ +-b ++B +diff --git a/file-c$cnt b/file-c$cnt +--- a/file-c$cnt ++++ b/file-c$cnt +@@ -1 +1 @@ +-cZ$cnt +\ No newline at end of file ++CZ$cnt +\ No newline at end of file +diff --git a/file-d$cnt b/file-d$cnt +--- a/file-d$cnt ++++ b/file-d$cnt +@@ -1 +1 @@ +-d ++D +EOF +} + +sample='1023 1024 1025 2047 4095' + +test_expect_success setup ' + + for n in $sample + do + ( zs $n ; echo a ) >file-a$n && + ( echo b; zs $n; echo ) >file-b$n && + ( printf c; zs $n ) >file-c$n && + ( echo d; zs $n ) >file-d$n && + + git add file-a$n file-b$n file-c$n file-d$n && + + ( zs $n ; echo A ) >file-a$n && + ( echo B; zs $n; echo ) >file-b$n && + ( printf C; zs $n ) >file-c$n && + ( echo D; zs $n ) >file-d$n && + + expect_pattern $n || break + + done >expect +' + +test_expect_success 'diff -U0' ' + + for n in $sample + do + git diff -U0 file-?$n + done | zc >actual && + test_cmp expect actual + +' + +test_done diff --git a/t/t4025-hunk-header.sh b/t/t4025-hunk-header.sh new file mode 100755 index 0000000000..7a3dbc1ea2 --- /dev/null +++ b/t/t4025-hunk-header.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +test_description='diff hunk header truncation' + +. ./test-lib.sh + +N='日本語' +N1='æ—¥' +N2='日本' +NS="$N$N$N$N$N$N$N$N$N$N$N$N$N" + +test_expect_success setup ' + + ( + echo "A $NS" + for c in B C D E F G H I J K + do + echo " $c" + done + echo "L $NS" + for c in M N O P Q R S T U V + do + echo " $c" + done + ) >file && + git add file && + + sed -e "/^ [EP]/s/$/ modified/" <file >file+ && + mv file+ file + +' + +test_expect_success 'hunk header truncation with an overly long line' ' + + git diff | sed -n -e "s/^.*@@//p" >actual && + ( + echo " A $N$N$N$N$N$N$N$N$N2" + echo " L $N$N$N$N$N$N$N$N$N1" + ) >expected && + test_cmp actual expected + +' + +test_done diff --git a/t/t4026-color.sh b/t/t4026-color.sh new file mode 100755 index 0000000000..b61e5169f4 --- /dev/null +++ b/t/t4026-color.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# +# Copyright (c) 2008 Timo Hirvonen +# + +test_description='Test diff/status color escape codes' +. ./test-lib.sh + +color() +{ + git config diff.color.new "$1" && + test "`git config --get-color diff.color.new`" = "$2" +} + +invalid_color() +{ + git config diff.color.new "$1" && + test -z "`git config --get-color diff.color.new 2>/dev/null`" +} + +test_expect_success 'reset' ' + color "reset" "[m" +' + +test_expect_success 'attribute before color name' ' + color "bold red" "[1;31m" +' + +test_expect_success 'color name before attribute' ' + color "red bold" "[1;31m" +' + +test_expect_success 'attr fg bg' ' + color "ul blue red" "[4;34;41m" +' + +test_expect_success 'fg attr bg' ' + color "blue ul red" "[4;34;41m" +' + +test_expect_success 'fg bg attr' ' + color "blue red ul" "[4;34;41m" +' + +test_expect_success '256 colors' ' + color "254 bold 255" "[1;38;5;254;48;5;255m" +' + +test_expect_success 'color too small' ' + invalid_color "-2" +' + +test_expect_success 'color too big' ' + invalid_color "256" +' + +test_expect_success 'extra character after color number' ' + invalid_color "3X" +' + +test_expect_success 'extra character after color name' ' + invalid_color "redX" +' + +test_expect_success 'extra character after attribute' ' + invalid_color "dimX" +' + +test_done diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh new file mode 100755 index 0000000000..ba6679c6e4 --- /dev/null +++ b/t/t4027-diff-submodule.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +test_description='difference in submodules' + +. ./test-lib.sh +. ../diff-lib.sh + +_z40=0000000000000000000000000000000000000000 +test_expect_success setup ' + test_tick && + test_create_repo sub && + ( + cd sub && + echo hello >world && + git add world && + git commit -m submodule + ) && + + test_tick && + echo frotz >nitfol && + git add nitfol sub && + git commit -m superproject && + + ( + cd sub && + echo goodbye >world && + git add world && + git commit -m "submodule #2" + ) && + + set x $( + cd sub && + git rev-list HEAD + ) && + echo ":160000 160000 $3 $_z40 M sub" >expect +' + +test_expect_success 'git diff --raw HEAD' ' + git diff --raw --abbrev=40 HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'git diff-index --raw HEAD' ' + git diff-index --raw HEAD >actual.index && + test_cmp expect actual.index +' + +test_expect_success 'git diff-files --raw' ' + git diff-files --raw >actual.files && + test_cmp expect actual.files +' + +test_expect_success 'git diff (empty submodule dir)' ' + : >empty && + rm -rf sub/* sub/.git && + git diff > actual.empty && + test_cmp empty actual.empty +' + +test_done diff --git a/t/t4028-format-patch-mime-headers.sh b/t/t4028-format-patch-mime-headers.sh new file mode 100755 index 0000000000..204ba673cb --- /dev/null +++ b/t/t4028-format-patch-mime-headers.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +test_description='format-patch mime headers and extra headers do not conflict' +. ./test-lib.sh + +test_expect_success 'create commit with utf-8 body' ' + echo content >file && + git add file && + git commit -m one && + echo more >>file && + git commit -a -m "two + + utf-8 body: ñ" +' + +test_expect_success 'patch has mime headers' ' + rm -f 0001-two.patch && + git format-patch HEAD^ && + grep -i "content-type: text/plain; charset=utf-8" 0001-two.patch +' + +test_expect_success 'patch has mime and extra headers' ' + rm -f 0001-two.patch && + git config format.headers "x-foo: bar" && + git format-patch HEAD^ && + grep -i "x-foo: bar" 0001-two.patch && + grep -i "content-type: text/plain; charset=utf-8" 0001-two.patch +' + +test_done diff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh new file mode 100755 index 0000000000..e0c67740a5 --- /dev/null +++ b/t/t4100-apply-stat.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git apply --stat --summary test, with --recount + +' +. ./test-lib.sh + +UNC='s/^\(@@ -[1-9][0-9]*\),[0-9]* \(+[1-9][0-9]*\),[0-9]* @@/\1,999 \2,999 @@/' + +num=0 +while read title +do + num=$(( $num + 1 )) + test_expect_success "$title" ' + git apply --stat --summary \ + <"$TEST_DIRECTORY/t4100/t-apply-$num.patch" >current && + test_cmp ../t4100/t-apply-$num.expect current + ' + + test_expect_success "$title with recount" ' + sed -e "$UNC" <"$TEST_DIRECTORY/t4100/t-apply-$num.patch" | + git apply --recount --stat --summary >current && + test_cmp ../t4100/t-apply-$num.expect current + ' +done <<\EOF +rename +copy +rewrite +mode +non git (1) +non git (2) +non git (3) +incomplete (1) +incomplete (2) +EOF + +test_done diff --git a/t/t4100/t-apply-1.expect b/t/t4100/t-apply-1.expect new file mode 100644 index 0000000000..540e64db85 --- /dev/null +++ b/t/t4100/t-apply-1.expect @@ -0,0 +1,11 @@ + Documentation/git-ssh-pull.txt | 12 ++++++------ + Documentation/git-ssh-push.txt | 10 +++++----- + Documentation/git.txt | 6 +++--- + Makefile | 6 +++--- + ssh-pull.c | 4 ++-- + ssh-push.c | 14 +++++++------- + 6 files changed, 26 insertions(+), 26 deletions(-) + rename Documentation/{git-rpull.txt => git-ssh-pull.txt} (90%) + rename Documentation/{git-rpush.txt => git-ssh-push.txt} (71%) + rename rpull.c => ssh-pull.c (97%) + rename rpush.c => ssh-push.c (93%) diff --git a/t/t4100/t-apply-1.patch b/t/t4100/t-apply-1.patch new file mode 100644 index 0000000000..90ab54f0f5 --- /dev/null +++ b/t/t4100/t-apply-1.patch @@ -0,0 +1,194 @@ +418aaf847a8b3ffffb4f777a2dd5262ca5ce0ef7 (from dc93841715dfa9a9cdda6f2c4a25eec831ea7aa0) +diff --git a/Documentation/git-rpull.txt b/Documentation/git-ssh-pull.txt +similarity index 90% +rename from Documentation/git-rpull.txt +rename to Documentation/git-ssh-pull.txt +--- a/Documentation/git-rpull.txt ++++ b/Documentation/git-ssh-pull.txt +@@ -1,21 +1,21 @@ +-git-rpull(1) +-============ ++git-ssh-pull(1) ++=============== + v0.1, May 2005 + + NAME + ---- +-git-rpull - Pulls from a remote repository over ssh connection ++git-ssh-pull - Pulls from a remote repository over ssh connection + + + + SYNOPSIS + -------- +-'git-rpull' [-c] [-t] [-a] [-d] [-v] [--recover] commit-id url ++'git-ssh-pull' [-c] [-t] [-a] [-d] [-v] [--recover] commit-id url + + DESCRIPTION + ----------- +-Pulls from a remote repository over ssh connection, invoking git-rpush on +-the other end. ++Pulls from a remote repository over ssh connection, invoking git-ssh-push ++on the other end. + + OPTIONS + ------- +diff --git a/Documentation/git-rpush.txt b/Documentation/git-ssh-push.txt +similarity index 71% +rename from Documentation/git-rpush.txt +rename to Documentation/git-ssh-push.txt +--- a/Documentation/git-rpush.txt ++++ b/Documentation/git-ssh-push.txt +@@ -1,19 +1,19 @@ +-git-rpush(1) +-============ ++git-ssh-push(1) ++=============== + v0.1, May 2005 + + NAME + ---- +-git-rpush - Helper "server-side" program used by git-rpull ++git-ssh-push - Helper "server-side" program used by git-ssh-pull + + + SYNOPSIS + -------- +-'git-rpush' ++'git-ssh-push' + + DESCRIPTION + ----------- +-Helper "server-side" program used by git-rpull. ++Helper "server-side" program used by git-ssh-pull. + + + Author +diff --git a/Documentation/git.txt b/Documentation/git.txt +--- a/Documentation/git.txt ++++ b/Documentation/git.txt +@@ -148,7 +148,7 @@ link:git-resolve-script.html[git-resolve + link:git-tag-script.html[git-tag-script]:: + An example script to create a tag object signed with GPG + +-link:git-rpull.html[git-rpull]:: ++link:git-ssh-pull.html[git-ssh-pull]:: + Pulls from a remote repository over ssh connection + + Interogators: +@@ -156,8 +156,8 @@ Interogators: + link:git-diff-helper.html[git-diff-helper]:: + Generates patch format output for git-diff-* + +-link:git-rpush.html[git-rpush]:: +- Helper "server-side" program used by git-rpull ++link:git-ssh-push.html[git-ssh-push]:: ++ Helper "server-side" program used by git-ssh-pull + + + +diff --git a/Makefile b/Makefile +--- a/Makefile ++++ b/Makefile +@@ -30,7 +30,7 @@ PROG= git-update-index git-diff-files + git-checkout-cache git-diff-tree git-rev-tree git-ls-files \ + git-check-files git-ls-tree git-merge-base git-merge-cache \ + git-unpack-file git-export git-diff-cache git-convert-cache \ +- git-http-pull git-rpush git-rpull git-rev-list git-mktag \ ++ git-http-pull git-ssh-push git-ssh-pull git-rev-list git-mktag \ + git-diff-helper git-tar-tree git-local-pull git-write-blob \ + git-get-tar-commit-id git-mkdelta git-apply git-stripspace + +@@ -105,8 +105,8 @@ git-diff-cache: diff-cache.c + git-convert-cache: convert-cache.c + git-http-pull: http-pull.c pull.c + git-local-pull: local-pull.c pull.c +-git-rpush: rsh.c +-git-rpull: rsh.c pull.c ++git-ssh-push: rsh.c ++git-ssh-pull: rsh.c pull.c + git-rev-list: rev-list.c + git-mktag: mktag.c + git-diff-helper: diff-helper.c +diff --git a/rpull.c b/ssh-pull.c +similarity index 97% +rename from rpull.c +rename to ssh-pull.c +--- a/rpull.c ++++ b/ssh-pull.c +@@ -64,13 +64,13 @@ int main(int argc, char **argv) + arg++; + } + if (argc < arg + 2) { +- usage("git-rpull [-c] [-t] [-a] [-v] [-d] [--recover] commit-id url"); ++ usage("git-ssh-pull [-c] [-t] [-a] [-v] [-d] [--recover] commit-id url"); + return 1; + } + commit_id = argv[arg]; + url = argv[arg + 1]; + +- if (setup_connection(&fd_in, &fd_out, "git-rpush", url, arg, argv + 1)) ++ if (setup_connection(&fd_in, &fd_out, "git-ssh-push", url, arg, argv + 1)) + return 1; + + if (get_version()) +diff --git a/rpush.c b/ssh-push.c +similarity index 93% +rename from rpush.c +rename to ssh-push.c +--- a/rpush.c ++++ b/ssh-push.c +@@ -16,7 +16,7 @@ int serve_object(int fd_in, int fd_out) + do { + size = read(fd_in, sha1 + posn, 20 - posn); + if (size < 0) { +- perror("git-rpush: read "); ++ perror("git-ssh-push: read "); + return -1; + } + if (!size) +@@ -30,7 +30,7 @@ int serve_object(int fd_in, int fd_out) + buf = map_sha1_file(sha1, &objsize); + + if (!buf) { +- fprintf(stderr, "git-rpush: could not find %s\n", ++ fprintf(stderr, "git-ssh-push: could not find %s\n", + sha1_to_hex(sha1)); + remote = -1; + } +@@ -45,9 +45,9 @@ int serve_object(int fd_in, int fd_out) + size = write(fd_out, buf + posn, objsize - posn); + if (size <= 0) { + if (!size) { +- fprintf(stderr, "git-rpush: write closed"); ++ fprintf(stderr, "git-ssh-push: write closed"); + } else { +- perror("git-rpush: write "); ++ perror("git-ssh-push: write "); + } + return -1; + } +@@ -71,7 +71,7 @@ void service(int fd_in, int fd_out) { + retval = read(fd_in, &type, 1); + if (retval < 1) { + if (retval < 0) +- perror("rpush: read "); ++ perror("git-ssh-push: read "); + return; + } + if (type == 'v' && serve_version(fd_in, fd_out)) +@@ -91,12 +91,12 @@ int main(int argc, char **argv) + arg++; + } + if (argc < arg + 2) { +- usage("git-rpush [-c] [-t] [-a] commit-id url"); ++ usage("git-ssh-push [-c] [-t] [-a] commit-id url"); + return 1; + } + commit_id = argv[arg]; + url = argv[arg + 1]; +- if (setup_connection(&fd_in, &fd_out, "git-rpull", url, arg, argv + 1)) ++ if (setup_connection(&fd_in, &fd_out, "git-ssh-pull", url, arg, argv + 1)) + return 1; + + service(fd_in, fd_out); diff --git a/t/t4100/t-apply-2.expect b/t/t4100/t-apply-2.expect new file mode 100644 index 0000000000..d1e6459749 --- /dev/null +++ b/t/t4100/t-apply-2.expect @@ -0,0 +1,5 @@ + Makefile | 2 +- + git-fetch-script | 5 ----- + git-pull-script | 34 +--------------------------------- + 3 files changed, 2 insertions(+), 39 deletions(-) + copy git-pull-script => git-fetch-script (87%) diff --git a/t/t4100/t-apply-2.patch b/t/t4100/t-apply-2.patch new file mode 100644 index 0000000000..f5c7d601fc --- /dev/null +++ b/t/t4100/t-apply-2.patch @@ -0,0 +1,72 @@ +7ef76925d9c19ef74874e1735e2436e56d0c4897 (from 6b14d7faf0bad026a81a27bac07b47691f621b8f) +diff --git a/Makefile b/Makefile +--- a/Makefile ++++ b/Makefile +@@ -20,7 +20,7 @@ INSTALL=install + + SCRIPTS=git-apply-patch-script git-merge-one-file-script git-prune-script \ + git-pull-script git-tag-script git-resolve-script git-whatchanged \ +- git-deltafy-script ++ git-deltafy-script git-fetch-script + + PROG= git-update-index git-diff-files git-init-db git-write-tree \ + git-read-tree git-commit-tree git-cat-file git-fsck-cache \ +diff --git a/git-pull-script b/git-fetch-script +similarity index 87% +copy from git-pull-script +copy to git-fetch-script +--- a/git-pull-script ++++ b/git-fetch-script +@@ -39,8 +39,3 @@ download_one "$merge_repo/$merge_name" " + + echo "Getting object database" + download_objects "$merge_repo" "$(cat "$GIT_DIR"/MERGE_HEAD)" +- +-git-resolve-script \ +- "$(cat "$GIT_DIR"/HEAD)" \ +- "$(cat "$GIT_DIR"/MERGE_HEAD)" \ +- "$merge_repo" +diff --git a/git-pull-script b/git-pull-script +--- a/git-pull-script ++++ b/git-pull-script +@@ -6,39 +6,7 @@ merge_name=${2:-HEAD} + : ${GIT_DIR=.git} + : ${GIT_OBJECT_DIRECTORY="${SHA1_FILE_DIRECTORY-"$GIT_DIR/objects"}"} + +-download_one () { +- # remote_path="$1" local_file="$2" +- case "$1" in +- http://*) +- wget -q -O "$2" "$1" ;; +- /*) +- test -f "$1" && cat >"$2" "$1" ;; +- *) +- rsync -L "$1" "$2" ;; +- esac +-} +- +-download_objects () { +- # remote_repo="$1" head_sha1="$2" +- case "$1" in +- http://*) +- git-http-pull -a "$2" "$1/" +- ;; +- /*) +- git-local-pull -l -a "$2" "$1/" +- ;; +- *) +- rsync -avz --ignore-existing \ +- "$1/objects/." "$GIT_OBJECT_DIRECTORY"/. +- ;; +- esac +-} +- +-echo "Getting remote $merge_name" +-download_one "$merge_repo/$merge_name" "$GIT_DIR"/MERGE_HEAD +- +-echo "Getting object database" +-download_objects "$merge_repo" "$(cat "$GIT_DIR"/MERGE_HEAD)" ++git-fetch-script "$merge_repo" "$merge_name" + + git-resolve-script \ + "$(cat "$GIT_DIR"/HEAD)" \ diff --git a/t/t4100/t-apply-3.expect b/t/t4100/t-apply-3.expect new file mode 100644 index 0000000000..912a552a7a --- /dev/null +++ b/t/t4100/t-apply-3.expect @@ -0,0 +1,7 @@ + Documentation/git-ls-tree.txt | 20 +- + ls-tree.c | 459 ++++++++++++++++++++++------------------- + t/t3100-ls-tree-restrict.sh | 3 + tree.c | 2 + tree.h | 1 + 5 files changed, 262 insertions(+), 223 deletions(-) + rewrite ls-tree.c (82%) diff --git a/t/t4100/t-apply-3.patch b/t/t4100/t-apply-3.patch new file mode 100644 index 0000000000..90cdbaa5bb --- /dev/null +++ b/t/t4100/t-apply-3.patch @@ -0,0 +1,567 @@ +6af1f0192ff8740fe77db7cf02c739ccfbdf119c (from 2bc2564145835996734d6ed5d1880f85b17233d6) +diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt +--- a/Documentation/git-ls-tree.txt ++++ b/Documentation/git-ls-tree.txt +@@ -4,23 +4,26 @@ v0.1, May 2005 + + NAME + ---- +-git-ls-tree - Displays a tree object in human readable form ++git-ls-tree - Lists the contents of a tree object. + + + SYNOPSIS + -------- +-'git-ls-tree' [-r] [-z] <tree-ish> [paths...] ++'git-ls-tree' [-d] [-r] [-z] <tree-ish> [paths...] + + DESCRIPTION + ----------- +-Converts the tree object to a human readable (and script processable) +-form. ++Lists the contents of a tree object, like what "/bin/ls -a" does ++in the current working directory. + + OPTIONS + ------- + <tree-ish>:: + Id of a tree. + ++-d:: ++ show only the named tree entry itself, not its children ++ + -r:: + recurse into sub-trees + +@@ -28,18 +31,19 @@ OPTIONS + \0 line termination on output + + paths:: +- Optionally, restrict the output of git-ls-tree to specific +- paths. Directories will only list their tree blob ids. +- Implies -r. ++ When paths are given, shows them. Otherwise implicitly ++ uses the root level of the tree as the sole path argument. ++ + + Output Format + ------------- +- <mode>\t <type>\t <object>\t <file> ++ <mode> SP <type> SP <object> TAB <file> + + + Author + ------ + Written by Linus Torvalds <torvalds@osdl.org> ++Completely rewritten from scratch by Junio C Hamano <junkio@cox.net> + + Documentation + -------------- +diff --git a/ls-tree.c b/ls-tree.c +dissimilarity index 82% +--- ls-tree.c ++++ ls-tree.c +@@ -1,212 +1,247 @@ +-/* +- * GIT - The information manager from hell +- * +- * Copyright (C) Linus Torvalds, 2005 +- */ +-#include "cache.h" +- +-static int line_termination = '\n'; +-static int recursive = 0; +- +-struct path_prefix { +- struct path_prefix *prev; +- const char *name; +-}; +- +-#define DEBUG(fmt, ...) +- +-static int string_path_prefix(char *buff, size_t blen, struct path_prefix *prefix) +-{ +- int len = 0; +- if (prefix) { +- if (prefix->prev) { +- len = string_path_prefix(buff,blen,prefix->prev); +- buff += len; +- blen -= len; +- if (blen > 0) { +- *buff = '/'; +- len++; +- buff++; +- blen--; +- } +- } +- strncpy(buff,prefix->name,blen); +- return len + strlen(prefix->name); +- } +- +- return 0; +-} +- +-static void print_path_prefix(struct path_prefix *prefix) +-{ +- if (prefix) { +- if (prefix->prev) { +- print_path_prefix(prefix->prev); +- putchar('/'); +- } +- fputs(prefix->name, stdout); +- } +-} +- +-/* +- * return: +- * -1 if prefix is *not* a subset of path +- * 0 if prefix == path +- * 1 if prefix is a subset of path +- */ +-static int pathcmp(const char *path, struct path_prefix *prefix) +-{ +- char buff[PATH_MAX]; +- int len,slen; +- +- if (prefix == NULL) +- return 1; +- +- len = string_path_prefix(buff, sizeof buff, prefix); +- slen = strlen(path); +- +- if (slen < len) +- return -1; +- +- if (strncmp(path,buff,len) == 0) { +- if (slen == len) +- return 0; +- else +- return 1; +- } +- +- return -1; +-} +- +-/* +- * match may be NULL, or a *sorted* list of paths +- */ +-static void list_recursive(void *buffer, +- const char *type, +- unsigned long size, +- struct path_prefix *prefix, +- char **match, int matches) +-{ +- struct path_prefix this_prefix; +- this_prefix.prev = prefix; +- +- if (strcmp(type, "tree")) +- die("expected a 'tree' node"); +- +- if (matches) +- recursive = 1; +- +- while (size) { +- int namelen = strlen(buffer)+1; +- void *eltbuf = NULL; +- char elttype[20]; +- unsigned long eltsize; +- unsigned char *sha1 = buffer + namelen; +- char *path = strchr(buffer, ' ') + 1; +- unsigned int mode; +- const char *matched = NULL; +- int mtype = -1; +- int mindex; +- +- if (size < namelen + 20 || sscanf(buffer, "%o", &mode) != 1) +- die("corrupt 'tree' file"); +- buffer = sha1 + 20; +- size -= namelen + 20; +- +- this_prefix.name = path; +- for ( mindex = 0; mindex < matches; mindex++) { +- mtype = pathcmp(match[mindex],&this_prefix); +- if (mtype >= 0) { +- matched = match[mindex]; +- break; +- } +- } +- +- /* +- * If we're not matching, or if this is an exact match, +- * print out the info +- */ +- if (!matches || (matched != NULL && mtype == 0)) { +- printf("%06o %s %s\t", mode, +- S_ISDIR(mode) ? "tree" : "blob", +- sha1_to_hex(sha1)); +- print_path_prefix(&this_prefix); +- putchar(line_termination); +- } +- +- if (! recursive || ! S_ISDIR(mode)) +- continue; +- +- if (matches && ! matched) +- continue; +- +- if (! (eltbuf = read_sha1_file(sha1, elttype, &eltsize)) ) { +- error("cannot read %s", sha1_to_hex(sha1)); +- continue; +- } +- +- /* If this is an exact directory match, we may have +- * directory files following this path. Match on them. +- * Otherwise, we're at a pach subcomponent, and we need +- * to try to match again. +- */ +- if (mtype == 0) +- mindex++; +- +- list_recursive(eltbuf, elttype, eltsize, &this_prefix, &match[mindex], matches-mindex); +- free(eltbuf); +- } +-} +- +-static int qcmp(const void *a, const void *b) +-{ +- return strcmp(*(char **)a, *(char **)b); +-} +- +-static int list(unsigned char *sha1,char **path) +-{ +- void *buffer; +- unsigned long size; +- int npaths; +- +- for (npaths = 0; path[npaths] != NULL; npaths++) +- ; +- +- qsort(path,npaths,sizeof(char *),qcmp); +- +- buffer = read_object_with_reference(sha1, "tree", &size, NULL); +- if (!buffer) +- die("unable to read sha1 file"); +- list_recursive(buffer, "tree", size, NULL, path, npaths); +- free(buffer); +- return 0; +-} +- +-static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key> [paths...]"; +- +-int main(int argc, char **argv) +-{ +- unsigned char sha1[20]; +- +- while (1 < argc && argv[1][0] == '-') { +- switch (argv[1][1]) { +- case 'z': +- line_termination = 0; +- break; +- case 'r': +- recursive = 1; +- break; +- default: +- usage(ls_tree_usage); +- } +- argc--; argv++; +- } +- +- if (argc < 2) +- usage(ls_tree_usage); +- if (get_sha1(argv[1], sha1) < 0) +- usage(ls_tree_usage); +- if (list(sha1, &argv[2]) < 0) +- die("list failed"); +- return 0; +-} ++/* ++ * GIT - The information manager from hell ++ * ++ * Copyright (C) Linus Torvalds, 2005 ++ */ ++#include "cache.h" ++#include "blob.h" ++#include "tree.h" ++ ++static int line_termination = '\n'; ++#define LS_RECURSIVE 1 ++#define LS_TREE_ONLY 2 ++static int ls_options = 0; ++ ++static struct tree_entry_list root_entry; ++ ++static void prepare_root(unsigned char *sha1) ++{ ++ unsigned char rsha[20]; ++ unsigned long size; ++ void *buf; ++ struct tree *root_tree; ++ ++ buf = read_object_with_reference(sha1, "tree", &size, rsha); ++ free(buf); ++ if (!buf) ++ die("Could not read %s", sha1_to_hex(sha1)); ++ ++ root_tree = lookup_tree(rsha); ++ if (!root_tree) ++ die("Could not read %s", sha1_to_hex(sha1)); ++ ++ /* Prepare a fake entry */ ++ root_entry.directory = 1; ++ root_entry.executable = root_entry.symlink = 0; ++ root_entry.mode = S_IFDIR; ++ root_entry.name = ""; ++ root_entry.item.tree = root_tree; ++ root_entry.parent = NULL; ++} ++ ++static int prepare_children(struct tree_entry_list *elem) ++{ ++ if (!elem->directory) ++ return -1; ++ if (!elem->item.tree->object.parsed) { ++ struct tree_entry_list *e; ++ if (parse_tree(elem->item.tree)) ++ return -1; ++ /* Set up the parent link */ ++ for (e = elem->item.tree->entries; e; e = e->next) ++ e->parent = elem; ++ } ++ return 0; ++} ++ ++static struct tree_entry_list *find_entry_0(struct tree_entry_list *elem, ++ const char *path, ++ const char *path_end) ++{ ++ const char *ep; ++ int len; ++ ++ while (path < path_end) { ++ if (prepare_children(elem)) ++ return NULL; ++ ++ /* In elem->tree->entries, find the one that has name ++ * that matches what is between path and ep. ++ */ ++ elem = elem->item.tree->entries; ++ ++ ep = strchr(path, '/'); ++ if (!ep || path_end <= ep) ++ ep = path_end; ++ len = ep - path; ++ ++ while (elem) { ++ if ((strlen(elem->name) == len) && ++ !strncmp(elem->name, path, len)) ++ break; ++ elem = elem->next; ++ } ++ if (path_end <= ep || !elem) ++ return elem; ++ while (*ep == '/' && ep < path_end) ++ ep++; ++ path = ep; ++ } ++ return NULL; ++} ++ ++static struct tree_entry_list *find_entry(const char *path, ++ const char *path_end) ++{ ++ /* Find tree element, descending from root, that ++ * corresponds to the named path, lazily expanding ++ * the tree if possible. ++ */ ++ if (path == path_end) { ++ /* Special. This is the root level */ ++ return &root_entry; ++ } ++ return find_entry_0(&root_entry, path, path_end); ++} ++ ++static void show_entry_name(struct tree_entry_list *e) ++{ ++ /* This is yucky. The root level is there for ++ * our convenience but we really want to do a ++ * forest. ++ */ ++ if (e->parent && e->parent != &root_entry) { ++ show_entry_name(e->parent); ++ putchar('/'); ++ } ++ printf("%s", e->name); ++} ++ ++static const char *entry_type(struct tree_entry_list *e) ++{ ++ return (e->directory ? "tree" : "blob"); ++} ++ ++static const char *entry_hex(struct tree_entry_list *e) ++{ ++ return sha1_to_hex(e->directory ++ ? e->item.tree->object.sha1 ++ : e->item.blob->object.sha1); ++} ++ ++/* forward declaration for mutually recursive routines */ ++static int show_entry(struct tree_entry_list *, int); ++ ++static int show_children(struct tree_entry_list *e, int level) ++{ ++ if (prepare_children(e)) ++ die("internal error: ls-tree show_children called with non tree"); ++ e = e->item.tree->entries; ++ while (e) { ++ show_entry(e, level); ++ e = e->next; ++ } ++ return 0; ++} ++ ++static int show_entry(struct tree_entry_list *e, int level) ++{ ++ int err = 0; ++ ++ if (e != &root_entry) { ++ printf("%06o %s %s ", e->mode, entry_type(e), ++ entry_hex(e)); ++ show_entry_name(e); ++ putchar(line_termination); ++ } ++ ++ if (e->directory) { ++ /* If this is a directory, we have the following cases: ++ * (1) This is the top-level request (explicit path from the ++ * command line, or "root" if there is no command line). ++ * a. Without any flag. We show direct children. We do not ++ * recurse into them. ++ * b. With -r. We do recurse into children. ++ * c. With -d. We do not recurse into children. ++ * (2) We came here because our caller is either (1-a) or ++ * (1-b). ++ * a. Without any flag. We do not show our children (which ++ * are grandchildren for the original request). ++ * b. With -r. We continue to recurse into our children. ++ * c. With -d. We should not have come here to begin with. ++ */ ++ if (level == 0 && !(ls_options & LS_TREE_ONLY)) ++ /* case (1)-a and (1)-b */ ++ err = err | show_children(e, level+1); ++ else if (level && ls_options & LS_RECURSIVE) ++ /* case (2)-b */ ++ err = err | show_children(e, level+1); ++ } ++ return err; ++} ++ ++static int list_one(const char *path, const char *path_end) ++{ ++ int err = 0; ++ struct tree_entry_list *e = find_entry(path, path_end); ++ if (!e) { ++ /* traditionally ls-tree does not complain about ++ * missing path. We may change this later to match ++ * what "/bin/ls -a" does, which is to complain. ++ */ ++ return err; ++ } ++ err = err | show_entry(e, 0); ++ return err; ++} ++ ++static int list(char **path) ++{ ++ int i; ++ int err = 0; ++ for (i = 0; path[i]; i++) { ++ int len = strlen(path[i]); ++ while (0 <= len && path[i][len] == '/') ++ len--; ++ err = err | list_one(path[i], path[i] + len); ++ } ++ return err; ++} ++ ++static const char *ls_tree_usage = ++ "git-ls-tree [-d] [-r] [-z] <tree-ish> [path...]"; ++ ++int main(int argc, char **argv) ++{ ++ static char *path0[] = { "", NULL }; ++ char **path; ++ unsigned char sha1[20]; ++ ++ while (1 < argc && argv[1][0] == '-') { ++ switch (argv[1][1]) { ++ case 'z': ++ line_termination = 0; ++ break; ++ case 'r': ++ ls_options |= LS_RECURSIVE; ++ break; ++ case 'd': ++ ls_options |= LS_TREE_ONLY; ++ break; ++ default: ++ usage(ls_tree_usage); ++ } ++ argc--; argv++; ++ } ++ ++ if (argc < 2) ++ usage(ls_tree_usage); ++ if (get_sha1(argv[1], sha1) < 0) ++ usage(ls_tree_usage); ++ ++ path = (argc == 2) ? path0 : (argv + 2); ++ prepare_root(sha1); ++ if (list(path) < 0) ++ die("list failed"); ++ return 0; ++} +diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh +--- a/t/t3100-ls-tree-restrict.sh ++++ b/t/t3100-ls-tree-restrict.sh +@@ -74,8 +74,8 @@ test_expect_success \ + 'ls-tree filtered' \ + 'git-ls-tree $tree path1 path0 >current && + cat >expected <<\EOF && +-100644 blob X path0 + 120000 blob X path1 ++100644 blob X path0 + EOF + test_output' + +@@ -85,7 +85,6 @@ test_expect_success \ + cat >expected <<\EOF && + 040000 tree X path2 + 040000 tree X path2/baz +-100644 blob X path2/baz/b + 120000 blob X path2/bazbo + 100644 blob X path2/foo + EOF +diff --git a/tree.c b/tree.c +--- a/tree.c ++++ b/tree.c +@@ -133,7 +133,7 @@ int parse_tree_buffer(struct tree *item, + } + if (obj) + add_ref(&item->object, obj); +- ++ entry->parent = NULL; /* needs to be filled by the user */ + *list_p = entry; + list_p = &entry->next; + } +diff --git a/tree.h b/tree.h +--- a/tree.h ++++ b/tree.h +@@ -16,6 +16,7 @@ struct tree_entry_list { + struct tree *tree; + struct blob *blob; + } item; ++ struct tree_entry_list *parent; + }; + + struct tree { diff --git a/t/t4100/t-apply-4.expect b/t/t4100/t-apply-4.expect new file mode 100644 index 0000000000..1ec028b3d0 --- /dev/null +++ b/t/t4100/t-apply-4.expect @@ -0,0 +1,5 @@ + t/t0000-basic.sh | 0 + t/test-lib.sh | 0 + 2 files changed, 0 insertions(+), 0 deletions(-) + mode change 100644 => 100755 t/t0000-basic.sh + mode change 100644 => 100755 t/test-lib.sh diff --git a/t/t4100/t-apply-4.patch b/t/t4100/t-apply-4.patch new file mode 100644 index 0000000000..4a56ab5cf4 --- /dev/null +++ b/t/t4100/t-apply-4.patch @@ -0,0 +1,7 @@ +ceede59ea90cebad52ba9c8263fef3fb6ef17593 (from 368f99d57e8ed17243f2e164431449d48bfca2fb) +diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh +old mode 100644 +new mode 100755 +diff --git a/t/test-lib.sh b/t/test-lib.sh +old mode 100644 +new mode 100755 diff --git a/t/t4100/t-apply-5.expect b/t/t4100/t-apply-5.expect new file mode 100644 index 0000000000..b387df15d4 --- /dev/null +++ b/t/t4100/t-apply-5.expect @@ -0,0 +1,19 @@ + Documentation/git-rpull.txt | 50 ------------------- + Documentation/git-rpush.txt | 30 ------------ + Documentation/git-ssh-pull.txt | 50 +++++++++++++++++++ + Documentation/git-ssh-push.txt | 30 ++++++++++++ + Documentation/git.txt | 6 +- + Makefile | 6 +- + rpull.c | 83 -------------------------------- + rpush.c | 104 ---------------------------------------- + ssh-pull.c | 83 ++++++++++++++++++++++++++++++++ + ssh-push.c | 104 ++++++++++++++++++++++++++++++++++++++++ + 10 files changed, 273 insertions(+), 273 deletions(-) + delete Documentation/git-rpull.txt + delete Documentation/git-rpush.txt + create Documentation/git-ssh-pull.txt + create Documentation/git-ssh-push.txt + delete rpull.c + delete rpush.c + create ssh-pull.c + create ssh-push.c diff --git a/t/t4100/t-apply-5.patch b/t/t4100/t-apply-5.patch new file mode 100644 index 0000000000..5f6ddc1059 --- /dev/null +++ b/t/t4100/t-apply-5.patch @@ -0,0 +1,612 @@ +diff a/Documentation/git-rpull.txt b/Documentation/git-rpull.txt +--- a/Documentation/git-rpull.txt ++++ /dev/null +@@ -1,50 +0,0 @@ +-git-rpull(1) +-============ +-v0.1, May 2005 +- +-NAME +----- +-git-rpull - Pulls from a remote repository over ssh connection +- +- +- +-SYNOPSIS +--------- +-'git-rpull' [-c] [-t] [-a] [-d] [-v] [--recover] commit-id url +- +-DESCRIPTION +------------ +-Pulls from a remote repository over ssh connection, invoking git-rpush on +-the other end. +- +-OPTIONS +-------- +--c:: +- Get the commit objects. +--t:: +- Get trees associated with the commit objects. +--a:: +- Get all the objects. +--d:: +- Do not check for delta base objects (use this option +- only when you know the remote repository is not +- deltified). +---recover:: +- Check dependency of deltified object more carefully than +- usual, to recover after earlier pull that was interrupted. +--v:: +- Report what is downloaded. +- +- +-Author +------- +-Written by Linus Torvalds <torvalds@osdl.org> +- +-Documentation +--------------- +-Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>. +- +-GIT +---- +-Part of the link:git.html[git] suite +- +diff a/Documentation/git-rpush.txt b/Documentation/git-rpush.txt +--- a/Documentation/git-rpush.txt ++++ /dev/null +@@ -1,30 +0,0 @@ +-git-rpush(1) +-============ +-v0.1, May 2005 +- +-NAME +----- +-git-rpush - Helper "server-side" program used by git-rpull +- +- +-SYNOPSIS +--------- +-'git-rpush' +- +-DESCRIPTION +------------ +-Helper "server-side" program used by git-rpull. +- +- +-Author +------- +-Written by Linus Torvalds <torvalds@osdl.org> +- +-Documentation +--------------- +-Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>. +- +-GIT +---- +-Part of the link:git.html[git] suite +- +diff a/Documentation/git-ssh-pull.txt b/Documentation/git-ssh-pull.txt +--- /dev/null ++++ b/Documentation/git-ssh-pull.txt +@@ -0,0 +1,50 @@ ++git-ssh-pull(1) ++=============== ++v0.1, May 2005 ++ ++NAME ++---- ++git-ssh-pull - Pulls from a remote repository over ssh connection ++ ++ ++ ++SYNOPSIS ++-------- ++'git-ssh-pull' [-c] [-t] [-a] [-d] [-v] [--recover] commit-id url ++ ++DESCRIPTION ++----------- ++Pulls from a remote repository over ssh connection, invoking git-ssh-push ++on the other end. ++ ++OPTIONS ++------- ++-c:: ++ Get the commit objects. ++-t:: ++ Get trees associated with the commit objects. ++-a:: ++ Get all the objects. ++-d:: ++ Do not check for delta base objects (use this option ++ only when you know the remote repository is not ++ deltified). ++--recover:: ++ Check dependency of deltified object more carefully than ++ usual, to recover after earlier pull that was interrupted. ++-v:: ++ Report what is downloaded. ++ ++ ++Author ++------ ++Written by Linus Torvalds <torvalds@osdl.org> ++ ++Documentation ++-------------- ++Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>. ++ ++GIT ++--- ++Part of the link:git.html[git] suite ++ +diff a/Documentation/git-ssh-push.txt b/Documentation/git-ssh-push.txt +--- /dev/null ++++ b/Documentation/git-ssh-push.txt +@@ -0,0 +1,30 @@ ++git-ssh-push(1) ++=============== ++v0.1, May 2005 ++ ++NAME ++---- ++git-ssh-push - Helper "server-side" program used by git-ssh-pull ++ ++ ++SYNOPSIS ++-------- ++'git-ssh-push' ++ ++DESCRIPTION ++----------- ++Helper "server-side" program used by git-ssh-pull. ++ ++ ++Author ++------ ++Written by Linus Torvalds <torvalds@osdl.org> ++ ++Documentation ++-------------- ++Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>. ++ ++GIT ++--- ++Part of the link:git.html[git] suite ++ +diff a/Documentation/git.txt b/Documentation/git.txt +--- a/Documentation/git.txt ++++ b/Documentation/git.txt +@@ -148,7 +148,7 @@ link:git-resolve-script.html[git-resolve + link:git-tag-script.html[git-tag-script]:: + An example script to create a tag object signed with GPG + +-link:git-rpull.html[git-rpull]:: ++link:git-ssh-pull.html[git-ssh-pull]:: + Pulls from a remote repository over ssh connection + + Interogators: +@@ -156,8 +156,8 @@ Interogators: + link:git-diff-helper.html[git-diff-helper]:: + Generates patch format output for git-diff-* + +-link:git-rpush.html[git-rpush]:: +- Helper "server-side" program used by git-rpull ++link:git-ssh-push.html[git-ssh-push]:: ++ Helper "server-side" program used by git-ssh-pull + + + +diff a/Makefile b/Makefile +--- a/Makefile ++++ b/Makefile +@@ -30,7 +30,7 @@ PROG= git-update-index git-diff-files + git-checkout-cache git-diff-tree git-rev-tree git-ls-files \ + git-check-files git-ls-tree git-merge-base git-merge-cache \ + git-unpack-file git-export git-diff-cache git-convert-cache \ +- git-http-pull git-rpush git-rpull git-rev-list git-mktag \ ++ git-http-pull git-ssh-push git-ssh-pull git-rev-list git-mktag \ + git-diff-helper git-tar-tree git-local-pull git-write-blob \ + git-get-tar-commit-id git-mkdelta git-apply git-stripspace + +@@ -105,8 +105,8 @@ git-diff-cache: diff-cache.c + git-convert-cache: convert-cache.c + git-http-pull: http-pull.c pull.c + git-local-pull: local-pull.c pull.c +-git-rpush: rsh.c +-git-rpull: rsh.c pull.c ++git-ssh-push: rsh.c ++git-ssh-pull: rsh.c pull.c + git-rev-list: rev-list.c + git-mktag: mktag.c + git-diff-helper: diff-helper.c +diff a/rpull.c b/rpull.c +--- a/rpull.c ++++ /dev/null +@@ -1,83 +0,0 @@ +-#include "cache.h" +-#include "commit.h" +-#include "rsh.h" +-#include "pull.h" +- +-static int fd_in; +-static int fd_out; +- +-static unsigned char remote_version = 0; +-static unsigned char local_version = 1; +- +-int fetch(unsigned char *sha1) +-{ +- int ret; +- signed char remote; +- char type = 'o'; +- if (has_sha1_file(sha1)) +- return 0; +- write(fd_out, &type, 1); +- write(fd_out, sha1, 20); +- if (read(fd_in, &remote, 1) < 1) +- return -1; +- if (remote < 0) +- return remote; +- ret = write_sha1_from_fd(sha1, fd_in); +- if (!ret) +- pull_say("got %s\n", sha1_to_hex(sha1)); +- return ret; +-} +- +-int get_version(void) +-{ +- char type = 'v'; +- write(fd_out, &type, 1); +- write(fd_out, &local_version, 1); +- if (read(fd_in, &remote_version, 1) < 1) { +- return error("Couldn't read version from remote end"); +- } +- return 0; +-} +- +-int main(int argc, char **argv) +-{ +- char *commit_id; +- char *url; +- int arg = 1; +- +- while (arg < argc && argv[arg][0] == '-') { +- if (argv[arg][1] == 't') { +- get_tree = 1; +- } else if (argv[arg][1] == 'c') { +- get_history = 1; +- } else if (argv[arg][1] == 'd') { +- get_delta = 0; +- } else if (!strcmp(argv[arg], "--recover")) { +- get_delta = 2; +- } else if (argv[arg][1] == 'a') { +- get_all = 1; +- get_tree = 1; +- get_history = 1; +- } else if (argv[arg][1] == 'v') { +- get_verbosely = 1; +- } +- arg++; +- } +- if (argc < arg + 2) { +- usage("git-rpull [-c] [-t] [-a] [-v] [-d] [--recover] commit-id url"); +- return 1; +- } +- commit_id = argv[arg]; +- url = argv[arg + 1]; +- +- if (setup_connection(&fd_in, &fd_out, "git-rpush", url, arg, argv + 1)) +- return 1; +- +- if (get_version()) +- return 1; +- +- if (pull(commit_id)) +- return 1; +- +- return 0; +-} +diff a/rpush.c b/rpush.c +--- a/rpush.c ++++ /dev/null +@@ -1,104 +0,0 @@ +-#include "cache.h" +-#include "rsh.h" +-#include <sys/socket.h> +-#include <errno.h> +- +-unsigned char local_version = 1; +-unsigned char remote_version = 0; +- +-int serve_object(int fd_in, int fd_out) { +- ssize_t size; +- int posn = 0; +- char sha1[20]; +- unsigned long objsize; +- void *buf; +- signed char remote; +- do { +- size = read(fd_in, sha1 + posn, 20 - posn); +- if (size < 0) { +- perror("git-rpush: read "); +- return -1; +- } +- if (!size) +- return -1; +- posn += size; +- } while (posn < 20); +- +- /* fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1)); */ +- remote = 0; +- +- buf = map_sha1_file(sha1, &objsize); +- +- if (!buf) { +- fprintf(stderr, "git-rpush: could not find %s\n", +- sha1_to_hex(sha1)); +- remote = -1; +- } +- +- write(fd_out, &remote, 1); +- +- if (remote < 0) +- return 0; +- +- posn = 0; +- do { +- size = write(fd_out, buf + posn, objsize - posn); +- if (size <= 0) { +- if (!size) { +- fprintf(stderr, "git-rpush: write closed"); +- } else { +- perror("git-rpush: write "); +- } +- return -1; +- } +- posn += size; +- } while (posn < objsize); +- return 0; +-} +- +-int serve_version(int fd_in, int fd_out) +-{ +- if (read(fd_in, &remote_version, 1) < 1) +- return -1; +- write(fd_out, &local_version, 1); +- return 0; +-} +- +-void service(int fd_in, int fd_out) { +- char type; +- int retval; +- do { +- retval = read(fd_in, &type, 1); +- if (retval < 1) { +- if (retval < 0) +- perror("rpush: read "); +- return; +- } +- if (type == 'v' && serve_version(fd_in, fd_out)) +- return; +- if (type == 'o' && serve_object(fd_in, fd_out)) +- return; +- } while (1); +-} +- +-int main(int argc, char **argv) +-{ +- int arg = 1; +- char *commit_id; +- char *url; +- int fd_in, fd_out; +- while (arg < argc && argv[arg][0] == '-') { +- arg++; +- } +- if (argc < arg + 2) { +- usage("git-rpush [-c] [-t] [-a] commit-id url"); +- return 1; +- } +- commit_id = argv[arg]; +- url = argv[arg + 1]; +- if (setup_connection(&fd_in, &fd_out, "git-rpull", url, arg, argv + 1)) +- return 1; +- +- service(fd_in, fd_out); +- return 0; +-} +diff a/ssh-pull.c b/ssh-pull.c +--- /dev/null ++++ b/ssh-pull.c +@@ -0,0 +1,83 @@ ++#include "cache.h" ++#include "commit.h" ++#include "rsh.h" ++#include "pull.h" ++ ++static int fd_in; ++static int fd_out; ++ ++static unsigned char remote_version = 0; ++static unsigned char local_version = 1; ++ ++int fetch(unsigned char *sha1) ++{ ++ int ret; ++ signed char remote; ++ char type = 'o'; ++ if (has_sha1_file(sha1)) ++ return 0; ++ write(fd_out, &type, 1); ++ write(fd_out, sha1, 20); ++ if (read(fd_in, &remote, 1) < 1) ++ return -1; ++ if (remote < 0) ++ return remote; ++ ret = write_sha1_from_fd(sha1, fd_in); ++ if (!ret) ++ pull_say("got %s\n", sha1_to_hex(sha1)); ++ return ret; ++} ++ ++int get_version(void) ++{ ++ char type = 'v'; ++ write(fd_out, &type, 1); ++ write(fd_out, &local_version, 1); ++ if (read(fd_in, &remote_version, 1) < 1) { ++ return error("Couldn't read version from remote end"); ++ } ++ return 0; ++} ++ ++int main(int argc, char **argv) ++{ ++ char *commit_id; ++ char *url; ++ int arg = 1; ++ ++ while (arg < argc && argv[arg][0] == '-') { ++ if (argv[arg][1] == 't') { ++ get_tree = 1; ++ } else if (argv[arg][1] == 'c') { ++ get_history = 1; ++ } else if (argv[arg][1] == 'd') { ++ get_delta = 0; ++ } else if (!strcmp(argv[arg], "--recover")) { ++ get_delta = 2; ++ } else if (argv[arg][1] == 'a') { ++ get_all = 1; ++ get_tree = 1; ++ get_history = 1; ++ } else if (argv[arg][1] == 'v') { ++ get_verbosely = 1; ++ } ++ arg++; ++ } ++ if (argc < arg + 2) { ++ usage("git-ssh-pull [-c] [-t] [-a] [-v] [-d] [--recover] commit-id url"); ++ return 1; ++ } ++ commit_id = argv[arg]; ++ url = argv[arg + 1]; ++ ++ if (setup_connection(&fd_in, &fd_out, "git-ssh-push", url, arg, argv + 1)) ++ return 1; ++ ++ if (get_version()) ++ return 1; ++ ++ if (pull(commit_id)) ++ return 1; ++ ++ return 0; ++} +diff a/ssh-push.c b/ssh-push.c +--- /dev/null ++++ b/ssh-push.c +@@ -0,0 +1,104 @@ ++#include "cache.h" ++#include "rsh.h" ++#include <sys/socket.h> ++#include <errno.h> ++ ++unsigned char local_version = 1; ++unsigned char remote_version = 0; ++ ++int serve_object(int fd_in, int fd_out) { ++ ssize_t size; ++ int posn = 0; ++ char sha1[20]; ++ unsigned long objsize; ++ void *buf; ++ signed char remote; ++ do { ++ size = read(fd_in, sha1 + posn, 20 - posn); ++ if (size < 0) { ++ perror("git-ssh-push: read "); ++ return -1; ++ } ++ if (!size) ++ return -1; ++ posn += size; ++ } while (posn < 20); ++ ++ /* fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1)); */ ++ remote = 0; ++ ++ buf = map_sha1_file(sha1, &objsize); ++ ++ if (!buf) { ++ fprintf(stderr, "git-ssh-push: could not find %s\n", ++ sha1_to_hex(sha1)); ++ remote = -1; ++ } ++ ++ write(fd_out, &remote, 1); ++ ++ if (remote < 0) ++ return 0; ++ ++ posn = 0; ++ do { ++ size = write(fd_out, buf + posn, objsize - posn); ++ if (size <= 0) { ++ if (!size) { ++ fprintf(stderr, "git-ssh-push: write closed"); ++ } else { ++ perror("git-ssh-push: write "); ++ } ++ return -1; ++ } ++ posn += size; ++ } while (posn < objsize); ++ return 0; ++} ++ ++int serve_version(int fd_in, int fd_out) ++{ ++ if (read(fd_in, &remote_version, 1) < 1) ++ return -1; ++ write(fd_out, &local_version, 1); ++ return 0; ++} ++ ++void service(int fd_in, int fd_out) { ++ char type; ++ int retval; ++ do { ++ retval = read(fd_in, &type, 1); ++ if (retval < 1) { ++ if (retval < 0) ++ perror("git-ssh-push: read "); ++ return; ++ } ++ if (type == 'v' && serve_version(fd_in, fd_out)) ++ return; ++ if (type == 'o' && serve_object(fd_in, fd_out)) ++ return; ++ } while (1); ++} ++ ++int main(int argc, char **argv) ++{ ++ int arg = 1; ++ char *commit_id; ++ char *url; ++ int fd_in, fd_out; ++ while (arg < argc && argv[arg][0] == '-') { ++ arg++; ++ } ++ if (argc < arg + 2) { ++ usage("git-ssh-push [-c] [-t] [-a] commit-id url"); ++ return 1; ++ } ++ commit_id = argv[arg]; ++ url = argv[arg + 1]; ++ if (setup_connection(&fd_in, &fd_out, "git-ssh-pull", url, arg, argv + 1)) ++ return 1; ++ ++ service(fd_in, fd_out); ++ return 0; ++} diff --git a/t/t4100/t-apply-6.expect b/t/t4100/t-apply-6.expect new file mode 100644 index 0000000000..1c343d459e --- /dev/null +++ b/t/t4100/t-apply-6.expect @@ -0,0 +1,5 @@ + Makefile | 2 +- + git-fetch-script | 41 +++++++++++++++++++++++++++++++++++++++++ + git-pull-script | 34 +--------------------------------- + 3 files changed, 43 insertions(+), 34 deletions(-) + create git-fetch-script diff --git a/t/t4100/t-apply-6.patch b/t/t4100/t-apply-6.patch new file mode 100644 index 0000000000..a72729a712 --- /dev/null +++ b/t/t4100/t-apply-6.patch @@ -0,0 +1,101 @@ +diff a/Makefile b/Makefile +--- a/Makefile ++++ b/Makefile +@@ -20,7 +20,7 @@ INSTALL=install + + SCRIPTS=git-apply-patch-script git-merge-one-file-script git-prune-script \ + git-pull-script git-tag-script git-resolve-script git-whatchanged \ +- git-deltafy-script ++ git-deltafy-script git-fetch-script + + PROG= git-update-index git-diff-files git-init-db git-write-tree \ + git-read-tree git-commit-tree git-cat-file git-fsck-cache \ +diff a/git-fetch-script b/git-fetch-script +--- /dev/null ++++ b/git-fetch-script +@@ -0,0 +1,41 @@ ++#!/bin/sh ++# ++merge_repo=$1 ++merge_name=${2:-HEAD} ++ ++: ${GIT_DIR=.git} ++: ${GIT_OBJECT_DIRECTORY="${SHA1_FILE_DIRECTORY-"$GIT_DIR/objects"}"} ++ ++download_one () { ++ # remote_path="$1" local_file="$2" ++ case "$1" in ++ http://*) ++ wget -q -O "$2" "$1" ;; ++ /*) ++ test -f "$1" && cat >"$2" "$1" ;; ++ *) ++ rsync -L "$1" "$2" ;; ++ esac ++} ++ ++download_objects () { ++ # remote_repo="$1" head_sha1="$2" ++ case "$1" in ++ http://*) ++ git-http-pull -a "$2" "$1/" ++ ;; ++ /*) ++ git-local-pull -l -a "$2" "$1/" ++ ;; ++ *) ++ rsync -avz --ignore-existing \ ++ "$1/objects/." "$GIT_OBJECT_DIRECTORY"/. ++ ;; ++ esac ++} ++ ++echo "Getting remote $merge_name" ++download_one "$merge_repo/$merge_name" "$GIT_DIR"/MERGE_HEAD ++ ++echo "Getting object database" ++download_objects "$merge_repo" "$(cat "$GIT_DIR"/MERGE_HEAD)" +diff a/git-pull-script b/git-pull-script +--- a/git-pull-script ++++ b/git-pull-script +@@ -6,39 +6,7 @@ merge_name=${2:-HEAD} + : ${GIT_DIR=.git} + : ${GIT_OBJECT_DIRECTORY="${SHA1_FILE_DIRECTORY-"$GIT_DIR/objects"}"} + +-download_one () { +- # remote_path="$1" local_file="$2" +- case "$1" in +- http://*) +- wget -q -O "$2" "$1" ;; +- /*) +- test -f "$1" && cat >"$2" "$1" ;; +- *) +- rsync -L "$1" "$2" ;; +- esac +-} +- +-download_objects () { +- # remote_repo="$1" head_sha1="$2" +- case "$1" in +- http://*) +- git-http-pull -a "$2" "$1/" +- ;; +- /*) +- git-local-pull -l -a "$2" "$1/" +- ;; +- *) +- rsync -avz --ignore-existing \ +- "$1/objects/." "$GIT_OBJECT_DIRECTORY"/. +- ;; +- esac +-} +- +-echo "Getting remote $merge_name" +-download_one "$merge_repo/$merge_name" "$GIT_DIR"/MERGE_HEAD +- +-echo "Getting object database" +-download_objects "$merge_repo" "$(cat "$GIT_DIR"/MERGE_HEAD)" ++git-fetch-script "$merge_repo" "$merge_name" + + git-resolve-script \ + "$(cat "$GIT_DIR"/HEAD)" \ diff --git a/t/t4100/t-apply-7.expect b/t/t4100/t-apply-7.expect new file mode 100644 index 0000000000..1283164d99 --- /dev/null +++ b/t/t4100/t-apply-7.expect @@ -0,0 +1,6 @@ + Documentation/git-ls-tree.txt | 20 +- + ls-tree.c | 333 +++++++++++++++++++++++------------------ + t/t3100-ls-tree-restrict.sh | 3 + tree.c | 2 + tree.h | 1 + 5 files changed, 199 insertions(+), 160 deletions(-) diff --git a/t/t4100/t-apply-7.patch b/t/t4100/t-apply-7.patch new file mode 100644 index 0000000000..07c6589e74 --- /dev/null +++ b/t/t4100/t-apply-7.patch @@ -0,0 +1,494 @@ +diff a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt +--- a/Documentation/git-ls-tree.txt ++++ b/Documentation/git-ls-tree.txt +@@ -4,23 +4,26 @@ v0.1, May 2005 + + NAME + ---- +-git-ls-tree - Displays a tree object in human readable form ++git-ls-tree - Lists the contents of a tree object. + + + SYNOPSIS + -------- +-'git-ls-tree' [-r] [-z] <tree-ish> [paths...] ++'git-ls-tree' [-d] [-r] [-z] <tree-ish> [paths...] + + DESCRIPTION + ----------- +-Converts the tree object to a human readable (and script processable) +-form. ++Lists the contents of a tree object, like what "/bin/ls -a" does ++in the current working directory. + + OPTIONS + ------- + <tree-ish>:: + Id of a tree. + ++-d:: ++ show only the named tree entry itself, not its children ++ + -r:: + recurse into sub-trees + +@@ -28,18 +31,19 @@ OPTIONS + \0 line termination on output + + paths:: +- Optionally, restrict the output of git-ls-tree to specific +- paths. Directories will only list their tree blob ids. +- Implies -r. ++ When paths are given, shows them. Otherwise implicitly ++ uses the root level of the tree as the sole path argument. ++ + + Output Format + ------------- +- <mode>\t <type>\t <object>\t <file> ++ <mode> SP <type> SP <object> TAB <file> + + + Author + ------ + Written by Linus Torvalds <torvalds@osdl.org> ++Completely rewritten from scratch by Junio C Hamano <junkio@cox.net> + + Documentation + -------------- +diff a/ls-tree.c b/ls-tree.c +--- a/ls-tree.c ++++ b/ls-tree.c +@@ -4,188 +4,217 @@ + * Copyright (C) Linus Torvalds, 2005 + */ + #include "cache.h" ++#include "blob.h" ++#include "tree.h" + + static int line_termination = '\n'; +-static int recursive = 0; ++#define LS_RECURSIVE 1 ++#define LS_TREE_ONLY 2 ++static int ls_options = 0; + +-struct path_prefix { +- struct path_prefix *prev; +- const char *name; +-}; +- +-#define DEBUG(fmt, ...) +- +-static int string_path_prefix(char *buff, size_t blen, struct path_prefix *prefix) +-{ +- int len = 0; +- if (prefix) { +- if (prefix->prev) { +- len = string_path_prefix(buff,blen,prefix->prev); +- buff += len; +- blen -= len; +- if (blen > 0) { +- *buff = '/'; +- len++; +- buff++; +- blen--; +- } +- } +- strncpy(buff,prefix->name,blen); +- return len + strlen(prefix->name); +- } ++static struct tree_entry_list root_entry; + +- return 0; ++static void prepare_root(unsigned char *sha1) ++{ ++ unsigned char rsha[20]; ++ unsigned long size; ++ void *buf; ++ struct tree *root_tree; ++ ++ buf = read_object_with_reference(sha1, "tree", &size, rsha); ++ free(buf); ++ if (!buf) ++ die("Could not read %s", sha1_to_hex(sha1)); ++ ++ root_tree = lookup_tree(rsha); ++ if (!root_tree) ++ die("Could not read %s", sha1_to_hex(sha1)); ++ ++ /* Prepare a fake entry */ ++ root_entry.directory = 1; ++ root_entry.executable = root_entry.symlink = 0; ++ root_entry.mode = S_IFDIR; ++ root_entry.name = ""; ++ root_entry.item.tree = root_tree; ++ root_entry.parent = NULL; + } + +-static void print_path_prefix(struct path_prefix *prefix) ++static int prepare_children(struct tree_entry_list *elem) + { +- if (prefix) { +- if (prefix->prev) { +- print_path_prefix(prefix->prev); +- putchar('/'); +- } +- fputs(prefix->name, stdout); ++ if (!elem->directory) ++ return -1; ++ if (!elem->item.tree->object.parsed) { ++ struct tree_entry_list *e; ++ if (parse_tree(elem->item.tree)) ++ return -1; ++ /* Set up the parent link */ ++ for (e = elem->item.tree->entries; e; e = e->next) ++ e->parent = elem; + } ++ return 0; + } + +-/* +- * return: +- * -1 if prefix is *not* a subset of path +- * 0 if prefix == path +- * 1 if prefix is a subset of path +- */ +-static int pathcmp(const char *path, struct path_prefix *prefix) +-{ +- char buff[PATH_MAX]; +- int len,slen; ++static struct tree_entry_list *find_entry_0(struct tree_entry_list *elem, ++ const char *path, ++ const char *path_end) ++{ ++ const char *ep; ++ int len; ++ ++ while (path < path_end) { ++ if (prepare_children(elem)) ++ return NULL; + +- if (prefix == NULL) +- return 1; ++ /* In elem->tree->entries, find the one that has name ++ * that matches what is between path and ep. ++ */ ++ elem = elem->item.tree->entries; + +- len = string_path_prefix(buff, sizeof buff, prefix); +- slen = strlen(path); ++ ep = strchr(path, '/'); ++ if (!ep || path_end <= ep) ++ ep = path_end; ++ len = ep - path; ++ ++ while (elem) { ++ if ((strlen(elem->name) == len) && ++ !strncmp(elem->name, path, len)) ++ break; ++ elem = elem->next; ++ } ++ if (path_end <= ep || !elem) ++ return elem; ++ while (*ep == '/' && ep < path_end) ++ ep++; ++ path = ep; ++ } ++ return NULL; ++} + +- if (slen < len) +- return -1; ++static struct tree_entry_list *find_entry(const char *path, ++ const char *path_end) ++{ ++ /* Find tree element, descending from root, that ++ * corresponds to the named path, lazily expanding ++ * the tree if possible. ++ */ ++ if (path == path_end) { ++ /* Special. This is the root level */ ++ return &root_entry; ++ } ++ return find_entry_0(&root_entry, path, path_end); ++} + +- if (strncmp(path,buff,len) == 0) { +- if (slen == len) +- return 0; +- else +- return 1; ++static void show_entry_name(struct tree_entry_list *e) ++{ ++ /* This is yucky. The root level is there for ++ * our convenience but we really want to do a ++ * forest. ++ */ ++ if (e->parent && e->parent != &root_entry) { ++ show_entry_name(e->parent); ++ putchar('/'); + } ++ printf("%s", e->name); ++} + +- return -1; +-} ++static const char *entry_type(struct tree_entry_list *e) ++{ ++ return (e->directory ? "tree" : "blob"); ++} + +-/* +- * match may be NULL, or a *sorted* list of paths +- */ +-static void list_recursive(void *buffer, +- const char *type, +- unsigned long size, +- struct path_prefix *prefix, +- char **match, int matches) +-{ +- struct path_prefix this_prefix; +- this_prefix.prev = prefix; +- +- if (strcmp(type, "tree")) +- die("expected a 'tree' node"); +- +- if (matches) +- recursive = 1; +- +- while (size) { +- int namelen = strlen(buffer)+1; +- void *eltbuf = NULL; +- char elttype[20]; +- unsigned long eltsize; +- unsigned char *sha1 = buffer + namelen; +- char *path = strchr(buffer, ' ') + 1; +- unsigned int mode; +- const char *matched = NULL; +- int mtype = -1; +- int mindex; +- +- if (size < namelen + 20 || sscanf(buffer, "%o", &mode) != 1) +- die("corrupt 'tree' file"); +- buffer = sha1 + 20; +- size -= namelen + 20; +- +- this_prefix.name = path; +- for ( mindex = 0; mindex < matches; mindex++) { +- mtype = pathcmp(match[mindex],&this_prefix); +- if (mtype >= 0) { +- matched = match[mindex]; +- break; +- } +- } ++static const char *entry_hex(struct tree_entry_list *e) ++{ ++ return sha1_to_hex(e->directory ++ ? e->item.tree->object.sha1 ++ : e->item.blob->object.sha1); ++} + +- /* +- * If we're not matching, or if this is an exact match, +- * print out the info +- */ +- if (!matches || (matched != NULL && mtype == 0)) { +- printf("%06o %s %s\t", mode, +- S_ISDIR(mode) ? "tree" : "blob", +- sha1_to_hex(sha1)); +- print_path_prefix(&this_prefix); +- putchar(line_termination); +- } ++/* forward declaration for mutually recursive routines */ ++static int show_entry(struct tree_entry_list *, int); + +- if (! recursive || ! S_ISDIR(mode)) +- continue; ++static int show_children(struct tree_entry_list *e, int level) ++{ ++ if (prepare_children(e)) ++ die("internal error: ls-tree show_children called with non tree"); ++ e = e->item.tree->entries; ++ while (e) { ++ show_entry(e, level); ++ e = e->next; ++ } ++ return 0; ++} + +- if (matches && ! matched) +- continue; ++static int show_entry(struct tree_entry_list *e, int level) ++{ ++ int err = 0; + +- if (! (eltbuf = read_sha1_file(sha1, elttype, &eltsize)) ) { +- error("cannot read %s", sha1_to_hex(sha1)); +- continue; +- } ++ if (e != &root_entry) { ++ printf("%06o %s %s ", e->mode, entry_type(e), ++ entry_hex(e)); ++ show_entry_name(e); ++ putchar(line_termination); ++ } + +- /* If this is an exact directory match, we may have +- * directory files following this path. Match on them. +- * Otherwise, we're at a pach subcomponent, and we need +- * to try to match again. ++ if (e->directory) { ++ /* If this is a directory, we have the following cases: ++ * (1) This is the top-level request (explicit path from the ++ * command line, or "root" if there is no command line). ++ * a. Without any flag. We show direct children. We do not ++ * recurse into them. ++ * b. With -r. We do recurse into children. ++ * c. With -d. We do not recurse into children. ++ * (2) We came here because our caller is either (1-a) or ++ * (1-b). ++ * a. Without any flag. We do not show our children (which ++ * are grandchildren for the original request). ++ * b. With -r. We continue to recurse into our children. ++ * c. With -d. We should not have come here to begin with. + */ +- if (mtype == 0) +- mindex++; +- +- list_recursive(eltbuf, elttype, eltsize, &this_prefix, &match[mindex], matches-mindex); +- free(eltbuf); ++ if (level == 0 && !(ls_options & LS_TREE_ONLY)) ++ /* case (1)-a and (1)-b */ ++ err = err | show_children(e, level+1); ++ else if (level && ls_options & LS_RECURSIVE) ++ /* case (2)-b */ ++ err = err | show_children(e, level+1); + } ++ return err; + } + +-static int qcmp(const void *a, const void *b) ++static int list_one(const char *path, const char *path_end) + { +- return strcmp(*(char **)a, *(char **)b); ++ int err = 0; ++ struct tree_entry_list *e = find_entry(path, path_end); ++ if (!e) { ++ /* traditionally ls-tree does not complain about ++ * missing path. We may change this later to match ++ * what "/bin/ls -a" does, which is to complain. ++ */ ++ return err; ++ } ++ err = err | show_entry(e, 0); ++ return err; + } + +-static int list(unsigned char *sha1,char **path) ++static int list(char **path) + { +- void *buffer; +- unsigned long size; +- int npaths; +- +- for (npaths = 0; path[npaths] != NULL; npaths++) +- ; +- +- qsort(path,npaths,sizeof(char *),qcmp); +- +- buffer = read_object_with_reference(sha1, "tree", &size, NULL); +- if (!buffer) +- die("unable to read sha1 file"); +- list_recursive(buffer, "tree", size, NULL, path, npaths); +- free(buffer); +- return 0; ++ int i; ++ int err = 0; ++ for (i = 0; path[i]; i++) { ++ int len = strlen(path[i]); ++ while (0 <= len && path[i][len] == '/') ++ len--; ++ err = err | list_one(path[i], path[i] + len); ++ } ++ return err; + } + +-static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key> [paths...]"; ++static const char *ls_tree_usage = ++ "git-ls-tree [-d] [-r] [-z] <tree-ish> [path...]"; + + int main(int argc, char **argv) + { ++ static char *path0[] = { "", NULL }; ++ char **path; + unsigned char sha1[20]; + + while (1 < argc && argv[1][0] == '-') { +@@ -194,7 +223,10 @@ int main(int argc, char **argv) + line_termination = 0; + break; + case 'r': +- recursive = 1; ++ ls_options |= LS_RECURSIVE; ++ break; ++ case 'd': ++ ls_options |= LS_TREE_ONLY; + break; + default: + usage(ls_tree_usage); +@@ -206,7 +238,10 @@ int main(int argc, char **argv) + usage(ls_tree_usage); + if (get_sha1(argv[1], sha1) < 0) + usage(ls_tree_usage); +- if (list(sha1, &argv[2]) < 0) ++ ++ path = (argc == 2) ? path0 : (argv + 2); ++ prepare_root(sha1); ++ if (list(path) < 0) + die("list failed"); + return 0; + } +diff a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh +--- a/t/t3100-ls-tree-restrict.sh ++++ b/t/t3100-ls-tree-restrict.sh +@@ -74,8 +74,8 @@ test_expect_success \ + 'ls-tree filtered' \ + 'git-ls-tree $tree path1 path0 >current && + cat >expected <<\EOF && +-100644 blob X path0 + 120000 blob X path1 ++100644 blob X path0 + EOF + test_output' + +@@ -85,7 +85,6 @@ test_expect_success \ + cat >expected <<\EOF && + 040000 tree X path2 + 040000 tree X path2/baz +-100644 blob X path2/baz/b + 120000 blob X path2/bazbo + 100644 blob X path2/foo + EOF +diff a/tree.c b/tree.c +--- a/tree.c ++++ b/tree.c +@@ -133,7 +133,7 @@ int parse_tree_buffer(struct tree *item, + } + if (obj) + add_ref(&item->object, obj); +- ++ entry->parent = NULL; /* needs to be filled by the user */ + *list_p = entry; + list_p = &entry->next; + } +diff a/tree.h b/tree.h +--- a/tree.h ++++ b/tree.h +@@ -16,6 +16,7 @@ struct tree_entry_list { + struct tree *tree; + struct blob *blob; + } item; ++ struct tree_entry_list *parent; + }; + + struct tree { diff --git a/t/t4100/t-apply-8.expect b/t/t4100/t-apply-8.expect new file mode 100644 index 0000000000..eef7f2e65c --- /dev/null +++ b/t/t4100/t-apply-8.expect @@ -0,0 +1,2 @@ + t/t4100-apply-stat.sh | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/t/t4100/t-apply-8.patch b/t/t4100/t-apply-8.patch new file mode 100644 index 0000000000..5ca13e6594 --- /dev/null +++ b/t/t4100/t-apply-8.patch @@ -0,0 +1,11 @@ +diff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh +index be837bb..0798c64 100755 +--- a/t/t4100-apply-stat.sh ++++ b/t/t4100-apply-stat.sh +@@ -35,4 +35,4 @@ non git (2) + non git (3) + EOF + +-test_done ++test_done +\ No newline at end of file diff --git a/t/t4100/t-apply-9.expect b/t/t4100/t-apply-9.expect new file mode 100644 index 0000000000..eef7f2e65c --- /dev/null +++ b/t/t4100/t-apply-9.expect @@ -0,0 +1,2 @@ + t/t4100-apply-stat.sh | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/t/t4100/t-apply-9.patch b/t/t4100/t-apply-9.patch new file mode 100644 index 0000000000..875d57d567 --- /dev/null +++ b/t/t4100/t-apply-9.patch @@ -0,0 +1,11 @@ +diff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh +index 0798c64..be837bb 100755 +--- a/t/t4100-apply-stat.sh ++++ b/t/t4100-apply-stat.sh +@@ -35,4 +35,4 @@ non git (2) + non git (3) + EOF + +-test_done +\ No newline at end of file ++test_done diff --git a/t/t4101-apply-nonl.sh b/t/t4101-apply-nonl.sh new file mode 100755 index 0000000000..da8abcf364 --- /dev/null +++ b/t/t4101-apply-nonl.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git apply should handle files with incomplete lines. + +' +. ./test-lib.sh + +# setup + +(echo a; echo b) >frotz.0 +(echo a; echo b; echo c) >frotz.1 +(echo a; echo b | tr -d '\012') >frotz.2 +(echo a; echo c; echo b | tr -d '\012') >frotz.3 + +for i in 0 1 2 3 +do + for j in 0 1 2 3 + do + test $i -eq $j && continue + cat frotz.$i >frotz + test_expect_success \ + "apply diff between $i and $j" \ + "git apply <../t4101/diff.$i-$j && diff frotz.$j frotz" + done +done + +test_done diff --git a/t/t4101/diff.0-1 b/t/t4101/diff.0-1 new file mode 100644 index 0000000000..1010a88f47 --- /dev/null +++ b/t/t4101/diff.0-1 @@ -0,0 +1,6 @@ +--- a/frotz ++++ b/frotz +@@ -1,2 +1,3 @@ + a + b ++c diff --git a/t/t4101/diff.0-2 b/t/t4101/diff.0-2 new file mode 100644 index 0000000000..36460a243a --- /dev/null +++ b/t/t4101/diff.0-2 @@ -0,0 +1,7 @@ +--- a/frotz ++++ b/frotz +@@ -1,2 +1,2 @@ + a +-b ++b +\ No newline at end of file diff --git a/t/t4101/diff.0-3 b/t/t4101/diff.0-3 new file mode 100644 index 0000000000..b281c43e5b --- /dev/null +++ b/t/t4101/diff.0-3 @@ -0,0 +1,8 @@ +--- a/frotz ++++ b/frotz +@@ -1,2 +1,3 @@ + a +-b ++c ++b +\ No newline at end of file diff --git a/t/t4101/diff.1-0 b/t/t4101/diff.1-0 new file mode 100644 index 0000000000..f0a2e92770 --- /dev/null +++ b/t/t4101/diff.1-0 @@ -0,0 +1,6 @@ +--- a/frotz ++++ b/frotz +@@ -1,3 +1,2 @@ + a + b +-c diff --git a/t/t4101/diff.1-2 b/t/t4101/diff.1-2 new file mode 100644 index 0000000000..2a440a5ce2 --- /dev/null +++ b/t/t4101/diff.1-2 @@ -0,0 +1,8 @@ +--- a/frotz ++++ b/frotz +@@ -1,3 +1,2 @@ + a +-b +-c ++b +\ No newline at end of file diff --git a/t/t4101/diff.1-3 b/t/t4101/diff.1-3 new file mode 100644 index 0000000000..61aff975b6 --- /dev/null +++ b/t/t4101/diff.1-3 @@ -0,0 +1,8 @@ +--- a/frotz ++++ b/frotz +@@ -1,3 +1,3 @@ + a +-b + c ++b +\ No newline at end of file diff --git a/t/t4101/diff.2-0 b/t/t4101/diff.2-0 new file mode 100644 index 0000000000..c2e71ee344 --- /dev/null +++ b/t/t4101/diff.2-0 @@ -0,0 +1,7 @@ +--- a/frotz ++++ b/frotz +@@ -1,2 +1,2 @@ + a +-b +\ No newline at end of file ++b diff --git a/t/t4101/diff.2-1 b/t/t4101/diff.2-1 new file mode 100644 index 0000000000..a66d9fd3a1 --- /dev/null +++ b/t/t4101/diff.2-1 @@ -0,0 +1,8 @@ +--- a/frotz ++++ b/frotz +@@ -1,2 +1,3 @@ + a +-b +\ No newline at end of file ++b ++c diff --git a/t/t4101/diff.2-3 b/t/t4101/diff.2-3 new file mode 100644 index 0000000000..5633c831de --- /dev/null +++ b/t/t4101/diff.2-3 @@ -0,0 +1,7 @@ +--- a/frotz ++++ b/frotz +@@ -1,2 +1,3 @@ + a ++c + b +\ No newline at end of file diff --git a/t/t4101/diff.3-0 b/t/t4101/diff.3-0 new file mode 100644 index 0000000000..10b1a41edf --- /dev/null +++ b/t/t4101/diff.3-0 @@ -0,0 +1,8 @@ +--- a/frotz ++++ b/frotz +@@ -1,3 +1,2 @@ + a +-c +-b +\ No newline at end of file ++b diff --git a/t/t4101/diff.3-1 b/t/t4101/diff.3-1 new file mode 100644 index 0000000000..c799c60fb9 --- /dev/null +++ b/t/t4101/diff.3-1 @@ -0,0 +1,8 @@ +--- a/frotz ++++ b/frotz +@@ -1,3 +1,3 @@ + a ++b + c +-b +\ No newline at end of file diff --git a/t/t4101/diff.3-2 b/t/t4101/diff.3-2 new file mode 100644 index 0000000000..f8d1ba6dc2 --- /dev/null +++ b/t/t4101/diff.3-2 @@ -0,0 +1,7 @@ +--- a/frotz ++++ b/frotz +@@ -1,3 +1,2 @@ + a +-c + b +\ No newline at end of file diff --git a/t/t4102-apply-rename.sh b/t/t4102-apply-rename.sh new file mode 100755 index 0000000000..d42abff1ad --- /dev/null +++ b/t/t4102-apply-rename.sh @@ -0,0 +1,62 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git apply handling copy/rename patch. + +' +. ./test-lib.sh + +# setup + +cat >test-patch <<\EOF +diff --git a/foo b/bar +similarity index 47% +rename from foo +rename to bar +--- a/foo ++++ b/bar +@@ -1 +1 @@ +-This is foo ++This is bar +EOF + +echo 'This is foo' >foo +chmod +x foo + +test_expect_success setup \ + 'git update-index --add foo' + +test_expect_success apply \ + 'git apply --index --stat --summary --apply test-patch' + +if [ "$(git config --get core.filemode)" = false ] +then + say 'filemode disabled on the filesystem' +else + test_expect_success validate \ + 'test -f bar && ls -l bar | grep "^-..x......"' +fi + +test_expect_success 'apply reverse' \ + 'git apply -R --index --stat --summary --apply test-patch && + test "$(cat foo)" = "This is foo"' + +cat >test-patch <<\EOF +diff --git a/foo b/bar +similarity index 47% +copy from foo +copy to bar +--- a/foo ++++ b/bar +@@ -1 +1 @@ +-This is foo ++This is bar +EOF + +test_expect_success 'apply copy' \ + 'git apply --index --stat --summary --apply test-patch && + test "$(cat bar)" = "This is bar" -a "$(cat foo)" = "This is foo"' + +test_done diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh new file mode 100755 index 0000000000..7da0b4bb8b --- /dev/null +++ b/t/t4103-apply-binary.sh @@ -0,0 +1,119 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git apply handling binary patches + +' +. ./test-lib.sh + +# setup + +cat >file1 <<EOF +A quick brown fox jumps over the lazy dog. +A tiny little penguin runs around in circles. +There is a flag with Linux written on it. +A slow black-and-white panda just sits there, +munching on his bamboo. +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 'stat binary diff -- should not fail.' \ + 'git-checkout master + git apply --stat --summary B.diff' + +test_expect_success 'stat binary diff (copy) -- should not fail.' \ + 'git-checkout master + git apply --stat --summary C.diff' + +test_expect_success 'check binary diff -- should fail.' \ + 'git-checkout master && + test_must_fail git apply --check B.diff' + +test_expect_success 'check binary diff (copy) -- should fail.' \ + 'git-checkout master && + test_must_fail git apply --check C.diff' + +test_expect_success \ + 'check incomplete binary diff with replacement -- should fail.' ' + git-checkout master && + test_must_fail git apply --check --allow-binary-replacement B.diff +' + +test_expect_success \ + 'check incomplete binary diff with replacement (copy) -- should fail.' ' + git-checkout master && + test_must_fail git apply --check --allow-binary-replacement C.diff +' + +test_expect_success 'check binary diff with replacement.' \ + 'git-checkout master + git apply --check --allow-binary-replacement BF.diff' + +test_expect_success 'check binary diff with replacement (copy).' \ + 'git-checkout master + git apply --check --allow-binary-replacement CF.diff' + +# Now we start applying them. + +do_reset () { + rm -f file? && + git-reset --hard && + git-checkout -f master +} + +test_expect_success 'apply binary diff -- should fail.' \ + 'do_reset && + test_must_fail git apply B.diff' + +test_expect_success 'apply binary diff -- should fail.' \ + 'do_reset && + test_must_fail git apply --index B.diff' + +test_expect_success 'apply binary diff (copy) -- should fail.' \ + 'do_reset && + test_must_fail git apply C.diff' + +test_expect_success 'apply binary diff (copy) -- should fail.' \ + 'do_reset && + test_must_fail git apply --index C.diff' + +test_expect_success 'apply binary diff without replacement.' \ + 'do_reset && + git apply BF.diff' + +test_expect_success 'apply binary diff without replacement (copy).' \ + 'do_reset && + git apply CF.diff' + +test_expect_success 'apply binary diff.' \ + 'do_reset && + git apply --allow-binary-replacement --index BF.diff && + test -z "$(git diff --name-status binary)"' + +test_expect_success 'apply binary diff (copy).' \ + 'do_reset && + git apply --allow-binary-replacement --index CF.diff && + test -z "$(git diff --name-status binary)"' + +test_done diff --git a/t/t4104-apply-boundary.sh b/t/t4104-apply-boundary.sh new file mode 100755 index 0000000000..e7e2913de7 --- /dev/null +++ b/t/t4104-apply-boundary.sh @@ -0,0 +1,128 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git apply boundary tests + +' +. ./test-lib.sh + +L="c d e f g h i j k l m n o p q r s t u v w x" + +test_expect_success setup ' + for i in b '"$L"' y + do + echo $i + done >victim && + cat victim >original && + git update-index --add victim && + + : add to the head + for i in a b '"$L"' y + do + echo $i + done >victim && + cat victim >add-a-expect && + git diff victim >add-a-patch.with && + git diff --unified=0 >add-a-patch.without && + + : modify at the head + for i in a '"$L"' y + do + echo $i + done >victim && + cat victim >mod-a-expect && + git diff victim >mod-a-patch.with && + git diff --unified=0 >mod-a-patch.without && + + : remove from the head + for i in '"$L"' y + do + echo $i + done >victim && + cat victim >del-a-expect && + git diff victim >del-a-patch.with + git diff --unified=0 >del-a-patch.without && + + : add to the tail + for i in b '"$L"' y z + do + echo $i + done >victim && + cat victim >add-z-expect && + git diff victim >add-z-patch.with && + git diff --unified=0 >add-z-patch.without && + + : modify at the tail + for i in a '"$L"' y + do + echo $i + done >victim && + cat victim >mod-z-expect && + git diff victim >mod-z-patch.with && + git diff --unified=0 >mod-z-patch.without && + + : remove from the tail + for i in b '"$L"' + do + echo $i + done >victim && + cat victim >del-z-expect && + git diff victim >del-z-patch.with + git diff --unified=0 >del-z-patch.without && + + : done +' + +for with in with without +do + case "$with" in + with) u= ;; + without) u='--unidiff-zero ' ;; + esac + for kind in add-a add-z mod-a mod-z del-a del-z + do + test_expect_success "apply $kind-patch $with context" ' + cat original >victim && + git update-index victim && + git apply --index '"$u$kind-patch.$with"' || { + cat '"$kind-patch.$with"' + (exit 1) + } && + test_cmp '"$kind"'-expect victim + ' + done +done + +for kind in add-a add-z mod-a mod-z del-a del-z +do + rm -f $kind-ng.without + sed -e "s/^diff --git /diff /" \ + -e '/^index /d' \ + <$kind-patch.without >$kind-ng.without + test_expect_success "apply non-git $kind-patch without context" ' + cat original >victim && + git update-index victim && + git apply --unidiff-zero --index '"$kind-ng.without"' || { + cat '"$kind-ng.without"' + (exit 1) + } && + test_cmp '"$kind"'-expect victim + ' +done + +test_expect_success 'two lines' ' + + >file && + git add file && + echo aaa >file && + git diff >patch && + git add file && + echo bbb >file && + git add file && + test_must_fail git apply --check patch + +' + +test_done diff --git a/t/t4105-apply-fuzz.sh b/t/t4105-apply-fuzz.sh new file mode 100755 index 0000000000..3266e39400 --- /dev/null +++ b/t/t4105-apply-fuzz.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +test_description='apply with fuzz and offset' + +. ./test-lib.sh + +dotest () { + name="$1" && shift && + test_expect_success "$name" " + git checkout-index -f -q -u file && + git apply $* && + test_cmp expect file + " +} + +test_expect_success setup ' + + for i in 1 2 3 4 5 6 7 8 9 10 11 12 + do + echo $i + done >file && + git update-index --add file && + for i in 1 2 3 4 5 6 7 a b c d e 8 9 10 11 12 + do + echo $i + done >file && + cat file >expect && + git diff >O0.diff && + + sed -e "s/@@ -5,6 +5,11 @@/@@ -2,6 +2,11 @@/" >O1.diff O0.diff && + sed -e "s/@@ -5,6 +5,11 @@/@@ -7,6 +7,11 @@/" >O2.diff O0.diff && + sed -e "s/@@ -5,6 +5,11 @@/@@ -19,6 +19,11 @@/" >O3.diff O0.diff && + + sed -e "s/^ 5/ S/" >F0.diff O0.diff && + sed -e "s/^ 5/ S/" >F1.diff O1.diff && + sed -e "s/^ 5/ S/" >F2.diff O2.diff && + sed -e "s/^ 5/ S/" >F3.diff O3.diff + +' + +dotest 'unmodified patch' O0.diff + +dotest 'minus offset' O1.diff + +dotest 'plus offset' O2.diff + +dotest 'big offset' O3.diff + +dotest 'fuzz with no offset' -C2 F0.diff + +dotest 'fuzz with minus offset' -C2 F1.diff + +dotest 'fuzz with plus offset' -C2 F2.diff + +dotest 'fuzz with big offset' -C2 F3.diff + +test_done diff --git a/t/t4109-apply-multifrag.sh b/t/t4109-apply-multifrag.sh new file mode 100755 index 0000000000..ac58083fe2 --- /dev/null +++ b/t/t4109-apply-multifrag.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# Copyright (c) 2005 Robert Fitzsimons +# + +test_description='git apply test patches with multiple fragments.' + +. ./test-lib.sh + +cp "$TEST_DIRECTORY/t4109/patch1.patch" . +cp "$TEST_DIRECTORY/t4109/patch2.patch" . +cp "$TEST_DIRECTORY/t4109/patch3.patch" . +cp "$TEST_DIRECTORY/t4109/patch4.patch" . + +test_expect_success 'git apply (1)' ' + git apply patch1.patch patch2.patch && + test_cmp "$TEST_DIRECTORY/t4109/expect-1" main.c +' +rm -f main.c + +test_expect_success 'git apply (2)' ' + git apply patch1.patch patch2.patch patch3.patch && + test_cmp "$TEST_DIRECTORY/t4109/expect-2" main.c +' +rm -f main.c + +test_expect_success 'git apply (3)' ' + git apply patch1.patch patch4.patch && + test_cmp "$TEST_DIRECTORY/t4109/expect-3" main.c +' +mv main.c main.c.git + +test_done + diff --git a/t/t4109/expect-1 b/t/t4109/expect-1 new file mode 100644 index 0000000000..1db5ff1050 --- /dev/null +++ b/t/t4109/expect-1 @@ -0,0 +1,31 @@ +#include <stdlib.h> +#include <stdio.h> + +int func(int num); +void print_int(int num); +void print_ln(); + +int main() { + int i; + + for (i = 0; i < 10; i++) { + print_int(func(i)); + } + + print_ln(); + + return 0; +} + +int func(int num) { + return num * num; +} + +void print_int(int num) { + printf("%d", num); +} + +void print_ln() { + printf("\n"); +} + diff --git a/t/t4109/expect-2 b/t/t4109/expect-2 new file mode 100644 index 0000000000..bc52924112 --- /dev/null +++ b/t/t4109/expect-2 @@ -0,0 +1,23 @@ +#include <stdio.h> + +int func(int num); +void print_int(int num); + +int main() { + int i; + + for (i = 0; i < 10; i++) { + print_int(func(i)); + } + + return 0; +} + +int func(int num) { + return num * num; +} + +void print_int(int num) { + printf("%d", num); +} + diff --git a/t/t4109/expect-3 b/t/t4109/expect-3 new file mode 100644 index 0000000000..cd2a475feb --- /dev/null +++ b/t/t4109/expect-3 @@ -0,0 +1,24 @@ +#include <stdio.h> + +int func(int num); +int func2(int num); + +int main() { + int i; + + for (i = 0; i < 10; i++) { + printf("%d", func(i)); + printf("%d", func3(i)); + } + + return 0; +} + +int func(int num) { + return num * num; +} + +int func2(int num) { + return num * num * num; +} + diff --git a/t/t4109/patch1.patch b/t/t4109/patch1.patch new file mode 100644 index 0000000000..1d411fc3cc --- /dev/null +++ b/t/t4109/patch1.patch @@ -0,0 +1,28 @@ +diff --git a/main.c b/main.c +new file mode 100644 +--- /dev/null ++++ b/main.c +@@ -0,0 +1,23 @@ ++#include <stdio.h> ++ ++int func(int num); ++void print_int(int num); ++ ++int main() { ++ int i; ++ ++ for (i = 0; i < 10; i++) { ++ print_int(func(i)); ++ } ++ ++ return 0; ++} ++ ++int func(int num) { ++ return num * num; ++} ++ ++void print_int(int num) { ++ printf("%d", num); ++} ++ diff --git a/t/t4109/patch2.patch b/t/t4109/patch2.patch new file mode 100644 index 0000000000..8c6b06d536 --- /dev/null +++ b/t/t4109/patch2.patch @@ -0,0 +1,30 @@ +diff --git a/main.c b/main.c +--- a/main.c ++++ b/main.c +@@ -1,7 +1,9 @@ ++#include <stdlib.h> + #include <stdio.h> + + int func(int num); + void print_int(int num); ++void print_ln(); + + int main() { + int i; +@@ -10,6 +12,8 @@ + print_int(func(i)); + } + ++ print_ln(); ++ + return 0; + } + +@@ -21,3 +25,7 @@ + printf("%d", num); + } + ++void print_ln() { ++ printf("\n"); ++} ++ diff --git a/t/t4109/patch3.patch b/t/t4109/patch3.patch new file mode 100644 index 0000000000..d696c55a75 --- /dev/null +++ b/t/t4109/patch3.patch @@ -0,0 +1,31 @@ +cat > patch3.patch <<\EOF +diff --git a/main.c b/main.c +--- a/main.c ++++ b/main.c +@@ -1,9 +1,7 @@ +-#include <stdlib.h> + #include <stdio.h> + + int func(int num); + void print_int(int num); +-void print_ln(); + + int main() { + int i; +@@ -12,8 +10,6 @@ + print_int(func(i)); + } + +- print_ln(); +- + return 0; + } + +@@ -25,7 +21,3 @@ + printf("%d", num); + } + +-void print_ln() { +- printf("\n"); +-} +- diff --git a/t/t4109/patch4.patch b/t/t4109/patch4.patch new file mode 100644 index 0000000000..4b085909b1 --- /dev/null +++ b/t/t4109/patch4.patch @@ -0,0 +1,30 @@ +diff --git a/main.c b/main.c +--- a/main.c ++++ b/main.c +@@ -1,13 +1,14 @@ + #include <stdio.h> + + int func(int num); +-void print_int(int num); ++int func2(int num); + + int main() { + int i; + + for (i = 0; i < 10; i++) { +- print_int(func(i)); ++ printf("%d", func(i)); ++ printf("%d", func3(i)); + } + + return 0; +@@ -17,7 +18,7 @@ + return num * num; + } + +-void print_int(int num) { +- printf("%d", num); ++int func2(int num) { ++ return num * num * num; + } + diff --git a/t/t4110-apply-scan.sh b/t/t4110-apply-scan.sh new file mode 100755 index 0000000000..09f58112e0 --- /dev/null +++ b/t/t4110-apply-scan.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# Copyright (c) 2005 Robert Fitzsimons +# + +test_description='git apply test for patches which require scanning forwards and backwards. + +' +. ./test-lib.sh + +test_expect_success 'git apply scan' ' + git apply \ + "$TEST_DIRECTORY/t4110/patch1.patch" \ + "$TEST_DIRECTORY/t4110/patch2.patch" \ + "$TEST_DIRECTORY/t4110/patch3.patch" \ + "$TEST_DIRECTORY/t4110/patch4.patch" \ + "$TEST_DIRECTORY/t4110/patch5.patch" && + test_cmp new.txt "$TEST_DIRECTORY/t4110/expect" +' + +test_done diff --git a/t/t4110/expect b/t/t4110/expect new file mode 100644 index 0000000000..87cc493ec8 --- /dev/null +++ b/t/t4110/expect @@ -0,0 +1,20 @@ +a1 +a11 +a111 +a1111 +b1 +b11 +b111 +b1111 +b2 +b22 +b222 +b2222 +c1 +c11 +c111 +c1111 +c2 +c22 +c222 +c2222 diff --git a/t/t4110/patch1.patch b/t/t4110/patch1.patch new file mode 100644 index 0000000000..56139080dc --- /dev/null +++ b/t/t4110/patch1.patch @@ -0,0 +1,17 @@ +diff --git a/new.txt b/new.txt +new file mode 100644 +--- /dev/null ++++ b/new.txt +@@ -0,0 +1,12 @@ ++a1 ++a11 ++a111 ++a1111 ++b1 ++b11 ++b111 ++b1111 ++c1 ++c11 ++c111 ++c1111 diff --git a/t/t4110/patch2.patch b/t/t4110/patch2.patch new file mode 100644 index 0000000000..04974247ec --- /dev/null +++ b/t/t4110/patch2.patch @@ -0,0 +1,11 @@ +diff --git a/new.txt b/new.txt +--- a/new.txt ++++ b/new.txt +@@ -1,7 +1,3 @@ +-a1 +-a11 +-a111 +-a1111 + b1 + b11 + b111 diff --git a/t/t4110/patch3.patch b/t/t4110/patch3.patch new file mode 100644 index 0000000000..26bd4427f8 --- /dev/null +++ b/t/t4110/patch3.patch @@ -0,0 +1,14 @@ +diff --git a/new.txt b/new.txt +--- a/new.txt ++++ b/new.txt +@@ -6,6 +6,10 @@ + b11 + b111 + b1111 ++b2 ++b22 ++b222 ++b2222 + c1 + c11 + c111 diff --git a/t/t4110/patch4.patch b/t/t4110/patch4.patch new file mode 100644 index 0000000000..9ffb9c2d7e --- /dev/null +++ b/t/t4110/patch4.patch @@ -0,0 +1,11 @@ +diff --git a/new.txt b/new.txt +--- a/new.txt ++++ b/new.txt +@@ -1,3 +1,7 @@ ++a1 ++a11 ++a111 ++a1111 + b1 + b11 + b111 diff --git a/t/t4110/patch5.patch b/t/t4110/patch5.patch new file mode 100644 index 0000000000..c5ac6914f9 --- /dev/null +++ b/t/t4110/patch5.patch @@ -0,0 +1,11 @@ +diff --git a/new.txt b/new.txt +--- a/new.txt ++++ b/new.txt +@@ -10,3 +10,7 @@ + c11 + c111 + c1111 ++c2 ++c22 ++c222 ++c2222 diff --git a/t/t4112-apply-renames.sh b/t/t4112-apply-renames.sh new file mode 100755 index 0000000000..f9ad183758 --- /dev/null +++ b/t/t4112-apply-renames.sh @@ -0,0 +1,144 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git apply should not get confused with rename/copy. + +' + +. ./test-lib.sh + +# setup + +mkdir -p klibc/arch/x86_64/include/klibc + +cat >klibc/arch/x86_64/include/klibc/archsetjmp.h <<\EOF +/* + * arch/x86_64/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __rbx; + unsigned long __rsp; + unsigned long __rbp; + unsigned long __r12; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; + unsigned long __rip; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ +EOF +cat >klibc/README <<\EOF +This is a simple readme file. +EOF + +cat >patch <<\EOF +diff --git a/klibc/arch/x86_64/include/klibc/archsetjmp.h b/include/arch/cris/klibc/archsetjmp.h +similarity index 76% +copy from klibc/arch/x86_64/include/klibc/archsetjmp.h +copy to include/arch/cris/klibc/archsetjmp.h +--- a/klibc/arch/x86_64/include/klibc/archsetjmp.h ++++ b/include/arch/cris/klibc/archsetjmp.h +@@ -1,21 +1,24 @@ + /* +- * arch/x86_64/include/klibc/archsetjmp.h ++ * arch/cris/include/klibc/archsetjmp.h + */ + + #ifndef _KLIBC_ARCHSETJMP_H + #define _KLIBC_ARCHSETJMP_H + + struct __jmp_buf { +- unsigned long __rbx; +- unsigned long __rsp; +- unsigned long __rbp; +- unsigned long __r12; +- unsigned long __r13; +- unsigned long __r14; +- unsigned long __r15; +- unsigned long __rip; ++ unsigned long __r0; ++ unsigned long __r1; ++ unsigned long __r2; ++ unsigned long __r3; ++ unsigned long __r4; ++ unsigned long __r5; ++ unsigned long __r6; ++ unsigned long __r7; ++ unsigned long __r8; ++ unsigned long __sp; ++ unsigned long __srp; + }; + + typedef struct __jmp_buf jmp_buf[1]; + +-#endif /* _SETJMP_H */ ++#endif /* _KLIBC_ARCHSETJMP_H */ +diff --git a/klibc/arch/x86_64/include/klibc/archsetjmp.h b/include/arch/m32r/klibc/archsetjmp.h +similarity index 66% +rename from klibc/arch/x86_64/include/klibc/archsetjmp.h +rename to include/arch/m32r/klibc/archsetjmp.h +--- a/klibc/arch/x86_64/include/klibc/archsetjmp.h ++++ b/include/arch/m32r/klibc/archsetjmp.h +@@ -1,21 +1,21 @@ + /* +- * arch/x86_64/include/klibc/archsetjmp.h ++ * arch/m32r/include/klibc/archsetjmp.h + */ + + #ifndef _KLIBC_ARCHSETJMP_H + #define _KLIBC_ARCHSETJMP_H + + struct __jmp_buf { +- unsigned long __rbx; +- unsigned long __rsp; +- unsigned long __rbp; ++ unsigned long __r8; ++ unsigned long __r9; ++ unsigned long __r10; ++ unsigned long __r11; + unsigned long __r12; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; +- unsigned long __rip; + }; + + typedef struct __jmp_buf jmp_buf[1]; + +-#endif /* _SETJMP_H */ ++#endif /* _KLIBC_ARCHSETJMP_H */ +diff --git a/klibc/README b/klibc/README +--- a/klibc/README ++++ b/klibc/README +@@ -1,1 +1,4 @@ + This is a simple readme file. ++And we add a few ++lines at the ++end of it. +diff --git a/klibc/README b/klibc/arch/README +copy from klibc/README +copy to klibc/arch/README +--- a/klibc/README ++++ b/klibc/arch/README +@@ -1,1 +1,3 @@ + This is a simple readme file. ++And we copy it to one level down, and ++add a few lines at the end of it. +EOF + +find klibc -type f -print | xargs git update-index --add -- + +test_expect_success 'check rename/copy patch' 'git apply --check patch' + +test_expect_success 'apply rename/copy patch' 'git apply --index patch' + +test_done diff --git a/t/t4113-apply-ending.sh b/t/t4113-apply-ending.sh new file mode 100755 index 0000000000..66fa51591e --- /dev/null +++ b/t/t4113-apply-ending.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# +# Copyright (c) 2006 Catalin Marinas +# + +test_description='git apply trying to add an ending line. + +' +. ./test-lib.sh + +# setup + +cat >test-patch <<\EOF +diff --git a/file b/file +--- a/file ++++ b/file +@@ -1,2 +1,3 @@ + a + b ++c +EOF + +echo 'a' >file +echo 'b' >>file +echo 'c' >>file + +test_expect_success setup \ + 'git update-index --add file' + +# test + +test_expect_success 'apply at the end' \ + 'test_must_fail git apply --index test-patch' + +cat >test-patch <<\EOF +diff a/file b/file +--- a/file ++++ b/file +@@ -1,2 +1,3 @@ ++a + b + c +EOF + +echo >file 'a +b +c' +git update-index file + +test_expect_success 'apply at the beginning' \ + 'test_must_fail git apply --index test-patch' + +test_done diff --git a/t/t4114-apply-typechange.sh b/t/t4114-apply-typechange.sh new file mode 100755 index 0000000000..55334927ab --- /dev/null +++ b/t/t4114-apply-typechange.sh @@ -0,0 +1,105 @@ +#!/bin/sh +# +# Copyright (c) 2006 Eric Wong +# + +test_description='git apply should not get confused with type changes. + +' + +. ./test-lib.sh + +test_expect_success 'setup repository and commits' ' + echo "hello world" > foo && + echo "hi planet" > bar && + git update-index --add foo bar && + git commit -m initial && + git branch initial && + rm -f foo && + ln -s bar foo && + git update-index foo && + git commit -m "foo symlinked to bar" && + git branch foo-symlinked-to-bar && + rm -f foo && + echo "how far is the sun?" > foo && + git update-index foo && + git commit -m "foo back to file" && + git branch foo-back-to-file && + rm -f foo && + git update-index --remove foo && + mkdir foo && + echo "if only I knew" > foo/baz && + git update-index --add foo/baz && + git commit -m "foo becomes a directory" && + git branch "foo-becomes-a-directory" && + echo "hello world" > foo/baz && + git update-index foo/baz && + git commit -m "foo/baz is the original foo" && + git branch foo-baz-renamed-from-foo + ' + +test_expect_success 'file renamed from foo to foo/baz' ' + git checkout -f initial && + git diff-tree -M -p HEAD foo-baz-renamed-from-foo > patch && + git apply --index < patch + ' +test_debug 'cat patch' + + +test_expect_success 'file renamed from foo/baz to foo' ' + git checkout -f foo-baz-renamed-from-foo && + git diff-tree -M -p HEAD initial > patch && + git apply --index < patch + ' +test_debug 'cat patch' + + +test_expect_success 'directory becomes file' ' + git checkout -f foo-becomes-a-directory && + git diff-tree -p HEAD initial > patch && + git apply --index < patch + ' +test_debug 'cat patch' + + +test_expect_success 'file becomes directory' ' + git checkout -f initial && + git diff-tree -p HEAD foo-becomes-a-directory > patch && + git apply --index < patch + ' +test_debug 'cat patch' + + +test_expect_success 'file becomes symlink' ' + git checkout -f initial && + git diff-tree -p HEAD foo-symlinked-to-bar > patch && + git apply --index < patch + ' +test_debug 'cat patch' + + +test_expect_success 'symlink becomes file' ' + git checkout -f foo-symlinked-to-bar && + git diff-tree -p HEAD foo-back-to-file > patch && + git apply --index < patch + ' +test_debug 'cat patch' + + +test_expect_success 'symlink becomes directory' ' + git checkout -f foo-symlinked-to-bar && + git diff-tree -p HEAD foo-becomes-a-directory > patch && + git apply --index < patch + ' +test_debug 'cat patch' + + +test_expect_success 'directory becomes symlink' ' + git checkout -f foo-becomes-a-directory && + git diff-tree -p HEAD foo-symlinked-to-bar > patch && + git apply --index < patch + ' +test_debug 'cat patch' + + +test_done diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh new file mode 100755 index 0000000000..9ace578f17 --- /dev/null +++ b/t/t4115-apply-symlink.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git apply symlinks and partial files + +' + +. ./test-lib.sh + +test_expect_success setup ' + + ln -s path1/path2/path3/path4/path5 link1 && + git add link? && + git commit -m initial && + + git branch side && + + rm -f link? && + + ln -s htap6 link1 && + git update-index link? && + git commit -m second && + + git diff-tree -p HEAD^ HEAD >patch && + git apply --stat --summary patch + +' + +test_expect_success 'apply symlink patch' ' + + git checkout side && + git apply patch && + git diff-files -p >patched && + test_cmp patch patched + +' + +test_expect_success 'apply --index symlink patch' ' + + git checkout -f side && + git apply --index patch && + git diff-index --cached -p HEAD >patched && + test_cmp patch patched + +' + +test_done diff --git a/t/t4116-apply-reverse.sh b/t/t4116-apply-reverse.sh new file mode 100755 index 0000000000..2298ece801 --- /dev/null +++ b/t/t4116-apply-reverse.sh @@ -0,0 +1,91 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git apply in reverse + +' + +. ./test-lib.sh + +test_expect_success setup ' + + for i in a b c d e f g h i j k l m n; do echo $i; done >file1 && + perl -pe "y/ijk/\\000\\001\\002/" <file1 >file2 && + + git add file1 file2 && + git commit -m initial && + git tag initial && + + for i in a b c g h i J K L m o n p q; do echo $i; done >file1 && + perl -pe "y/mon/\\000\\001\\002/" <file1 >file2 && + + git commit -a -m second && + git tag second && + + git diff --binary initial second >patch + +' + +test_expect_success 'apply in forward' ' + + T0=`git rev-parse "second^{tree}"` && + git reset --hard initial && + git apply --index --binary patch && + T1=`git write-tree` && + test "$T0" = "$T1" +' + +test_expect_success 'apply in reverse' ' + + git reset --hard second && + git apply --reverse --binary --index patch && + git diff >diff && + test_cmp /dev/null diff + +' + +test_expect_success 'setup separate repository lacking postimage' ' + + git tar-tree initial initial | $TAR xf - && + ( + cd initial && git init && git add . + ) && + + git tar-tree second second | $TAR xf - && + ( + cd second && git init && git add . + ) + +' + +test_expect_success 'apply in forward without postimage' ' + + T0=`git rev-parse "second^{tree}"` && + ( + cd initial && + git apply --index --binary ../patch && + T1=`git write-tree` && + test "$T0" = "$T1" + ) +' + +test_expect_success 'apply in reverse without postimage' ' + + T0=`git rev-parse "initial^{tree}"` && + ( + cd second && + git apply --index --binary --reverse ../patch && + T1=`git write-tree` && + test "$T0" = "$T1" + ) +' + +test_expect_success 'reversing a whitespace introduction' ' + sed "s/a/a /" < file1 > file1.new && + mv file1.new file1 && + git diff | git apply --reverse --whitespace=error +' + +test_done diff --git a/t/t4117-apply-reject.sh b/t/t4117-apply-reject.sh new file mode 100755 index 0000000000..e9ccd161ee --- /dev/null +++ b/t/t4117-apply-reject.sh @@ -0,0 +1,157 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git apply with rejects + +' + +. ./test-lib.sh + +test_expect_success setup ' + for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 + do + echo $i + done >file1 && + cat file1 >saved.file1 && + git update-index --add file1 && + git commit -m initial && + + for i in 1 2 A B 4 5 6 7 8 9 10 11 12 C 13 14 15 16 17 18 19 20 D 21 + do + echo $i + done >file1 && + git diff >patch.1 && + cat file1 >clean && + + for i in 1 E 2 3 4 5 6 7 8 9 10 11 12 C 13 14 15 16 17 18 19 20 F 21 + do + echo $i + done >expected && + + mv file1 file2 && + git update-index --add --remove file1 file2 && + git diff -M HEAD >patch.2 && + + rm -f file1 file2 && + mv saved.file1 file1 && + git update-index --add --remove file1 file2 && + + for i in 1 E 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 F 21 + do + echo $i + done >file1 && + + cat file1 >saved.file1 +' + +test_expect_success 'apply without --reject should fail' ' + + if git apply patch.1 + then + echo "Eh? Why?" + exit 1 + fi + + test_cmp file1 saved.file1 +' + +test_expect_success 'apply without --reject should fail' ' + + if git apply --verbose patch.1 + then + echo "Eh? Why?" + exit 1 + fi + + test_cmp file1 saved.file1 +' + +test_expect_success 'apply with --reject should fail but update the file' ' + + cat saved.file1 >file1 && + rm -f file1.rej file2.rej && + + if git apply --reject patch.1 + then + echo "succeeds with --reject?" + exit 1 + fi + + test_cmp file1 expected && + + cat file1.rej && + + if test -f file2.rej + then + echo "file2 should not have been touched" + exit 1 + fi +' + +test_expect_success 'apply with --reject should fail but update the file' ' + + cat saved.file1 >file1 && + rm -f file1.rej file2.rej file2 && + + if git apply --reject patch.2 >rejects + then + echo "succeeds with --reject?" + exit 1 + fi + + test -f file1 && { + echo "file1 still exists?" + exit 1 + } + test_cmp file2 expected && + + cat file2.rej && + + if test -f file1.rej + then + echo "file2 should not have been touched" + exit 1 + fi + +' + +test_expect_success 'the same test with --verbose' ' + + cat saved.file1 >file1 && + rm -f file1.rej file2.rej file2 && + + if git apply --reject --verbose patch.2 >rejects + then + echo "succeeds with --reject?" + exit 1 + fi + + test -f file1 && { + echo "file1 still exists?" + exit 1 + } + test_cmp file2 expected && + + cat file2.rej && + + if test -f file1.rej + then + echo "file2 should not have been touched" + exit 1 + fi + +' + +test_expect_success 'apply cleanly with --verbose' ' + + git cat-file -p HEAD:file1 >file1 && + rm -f file?.rej file2 && + + git apply --verbose patch.1 && + + test_cmp file1 clean +' + +test_done diff --git a/t/t4118-apply-empty-context.sh b/t/t4118-apply-empty-context.sh new file mode 100755 index 0000000000..f92e259cc6 --- /dev/null +++ b/t/t4118-apply-empty-context.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='git apply with new style GNU diff with empty context + +' + +. ./test-lib.sh + +test_expect_success setup ' + { + echo; echo; + echo A; echo B; echo C; + echo; + } >file1 && + cat file1 >file1.orig && + { + cat file1 && + echo Q | tr -d "\\012" + } >file2 && + cat file2 >file2.orig + git add file1 file2 && + sed -e "/^B/d" <file1.orig >file1 && + sed -e "/^[BQ]/d" <file2.orig >file2 && + echo Q | tr -d "\\012" >>file2 && + cat file1 >file1.mods && + cat file2 >file2.mods && + git diff | + sed -e "s/^ \$//" >diff.output +' + +test_expect_success 'apply --numstat' ' + + git apply --numstat diff.output >actual && + { + echo "0 1 file1" && + echo "0 1 file2" + } >expect && + test_cmp expect actual + +' + +test_expect_success 'apply --apply' ' + + cat file1.orig >file1 && + cat file2.orig >file2 && + git update-index file1 file2 && + git apply --index diff.output && + test_cmp file1.mods file1 && + test_cmp file2.mods file2 +' + +test_done diff --git a/t/t4119-apply-config.sh b/t/t4119-apply-config.sh new file mode 100755 index 0000000000..3c73a783a7 --- /dev/null +++ b/t/t4119-apply-config.sh @@ -0,0 +1,162 @@ +#!/bin/sh +# +# Copyright (c) 2007 Junio C Hamano +# + +test_description='git apply --whitespace=strip and configuration file. + +' + +. ./test-lib.sh + +test_expect_success setup ' + mkdir sub && + echo A >sub/file1 && + cp sub/file1 saved && + git add sub/file1 && + echo "B " >sub/file1 && + git diff >patch.file +' + +# Also handcraft GNU diff output; note this has trailing whitespace. +tr '_' ' ' >gpatch.file <<\EOF && +--- file1 2007-02-21 01:04:24.000000000 -0800 ++++ file1+ 2007-02-21 01:07:44.000000000 -0800 +@@ -1 +1 @@ +-A ++B_ +EOF + +sed -e 's|file1|sub/&|' gpatch.file >gpatch-sub.file && +sed -e ' + /^--- /s|file1|a/sub/&| + /^+++ /s|file1|b/sub/&| +' gpatch.file >gpatch-ab-sub.file && + +check_result () { + if grep " " "$1" + then + echo "Eh?" + false + elif grep B "$1" + then + echo Happy + else + echo "Huh?" + false + fi +} + +test_expect_success 'apply --whitespace=strip' ' + + rm -f sub/file1 && + cp saved sub/file1 && + git update-index --refresh && + + git apply --whitespace=strip patch.file && + check_result sub/file1 +' + +test_expect_success 'apply --whitespace=strip from config' ' + + rm -f sub/file1 && + cp saved sub/file1 && + git update-index --refresh && + + git config apply.whitespace strip && + git apply patch.file && + check_result sub/file1 +' + +D=`pwd` + +test_expect_success 'apply --whitespace=strip in subdir' ' + + cd "$D" && + git config --unset-all apply.whitespace + rm -f sub/file1 && + cp saved sub/file1 && + git update-index --refresh && + + cd sub && + git apply --whitespace=strip ../patch.file && + check_result file1 +' + +test_expect_success 'apply --whitespace=strip from config in subdir' ' + + cd "$D" && + git config apply.whitespace strip && + rm -f sub/file1 && + cp saved sub/file1 && + git update-index --refresh && + + cd sub && + git apply ../patch.file && + check_result file1 +' + +test_expect_success 'same in subdir but with traditional patch input' ' + + cd "$D" && + git config apply.whitespace strip && + rm -f sub/file1 && + cp saved sub/file1 && + git update-index --refresh && + + cd sub && + git apply ../gpatch.file && + check_result file1 +' + +test_expect_success 'same but with traditional patch input of depth 1' ' + + cd "$D" && + git config apply.whitespace strip && + rm -f sub/file1 && + cp saved sub/file1 && + git update-index --refresh && + + cd sub && + git apply ../gpatch-sub.file && + check_result file1 +' + +test_expect_success 'same but with traditional patch input of depth 2' ' + + cd "$D" && + git config apply.whitespace strip && + rm -f sub/file1 && + cp saved sub/file1 && + git update-index --refresh && + + cd sub && + git apply ../gpatch-ab-sub.file && + check_result file1 +' + +test_expect_success 'same but with traditional patch input of depth 1' ' + + cd "$D" && + git config apply.whitespace strip && + rm -f sub/file1 && + cp saved sub/file1 && + git update-index --refresh && + + git apply -p0 gpatch-sub.file && + check_result sub/file1 +' + +test_expect_success 'same but with traditional patch input of depth 2' ' + + cd "$D" && + git config apply.whitespace strip && + rm -f sub/file1 && + cp saved sub/file1 && + git update-index --refresh && + + git apply gpatch-ab-sub.file && + check_result sub/file1 +' + +test_done diff --git a/t/t4120-apply-popt.sh b/t/t4120-apply-popt.sh new file mode 100755 index 0000000000..83d4ba6798 --- /dev/null +++ b/t/t4120-apply-popt.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Copyright (c) 2007 Shawn O. Pearce +# + +test_description='git apply -p handling.' + +. ./test-lib.sh + +test_expect_success setup ' + mkdir sub && + echo A >sub/file1 && + cp sub/file1 file1 && + git add sub/file1 && + echo B >sub/file1 && + git diff >patch.file && + rm sub/file1 && + rmdir sub +' + +test_expect_success 'apply git diff with -p2' ' + git apply -p2 patch.file +' + +test_done diff --git a/t/t4121-apply-diffs.sh b/t/t4121-apply-diffs.sh new file mode 100755 index 0000000000..aff551a1d7 --- /dev/null +++ b/t/t4121-apply-diffs.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +test_description='git apply for contextually independent diffs' +. ./test-lib.sh + +echo '1 +2 +3 +4 +5 +6 +7 +8' >file + +test_expect_success 'setup' \ + 'git add file && + git commit -q -m 1 && + git checkout -b test && + mv file file.tmp && + echo 0 >file && + cat file.tmp >>file && + rm file.tmp && + git commit -a -q -m 2 && + echo 9 >>file && + git commit -a -q -m 3 && + git checkout master' + +test_expect_success \ + 'check if contextually independent diffs for the same file apply' \ + '( git diff test~2 test~1; git diff test~1 test~0 )| git apply' + +test_done diff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh new file mode 100755 index 0000000000..841773f75f --- /dev/null +++ b/t/t4122-apply-symlink-inside.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +test_description='apply to deeper directory without getting fooled with symlink' +. ./test-lib.sh + +lecho () { + for l_ + do + echo "$l_" + done +} + +test_expect_success setup ' + + mkdir -p arch/i386/boot arch/x86_64 && + lecho 1 2 3 4 5 >arch/i386/boot/Makefile && + ln -s ../i386/boot arch/x86_64/boot && + git add . && + test_tick && + git commit -m initial && + git branch test && + + rm arch/x86_64/boot && + mkdir arch/x86_64/boot && + lecho 2 3 4 5 6 >arch/x86_64/boot/Makefile && + git add . && + test_tick && + git commit -a -m second && + + git format-patch --binary -1 --stdout >test.patch + +' + +test_expect_success apply ' + + git checkout test && + git diff --exit-code test && + git diff --exit-code --cached test && + git apply --index test.patch + +' + +test_expect_success 'check result' ' + + git diff --exit-code master && + git diff --exit-code --cached master && + test_tick && + git commit -m replay && + T1=$(git rev-parse "master^{tree}") && + T2=$(git rev-parse "HEAD^{tree}") && + test "z$T1" = "z$T2" + +' + +test_done diff --git a/t/t4123-apply-shrink.sh b/t/t4123-apply-shrink.sh new file mode 100755 index 0000000000..984157f03b --- /dev/null +++ b/t/t4123-apply-shrink.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +test_description='apply a patch that is larger than the preimage' + +. ./test-lib.sh + +cat >F <<\EOF +1 +2 +3 +4 +5 +6 +7 +8 +999999 +A +B +C +D +E +F +G +H +I +J + +EOF + +test_expect_success setup ' + + git add F && + mv F G && + sed -e "s/1/11/" -e "s/999999/9/" -e "s/H/HH/" <G >F && + git diff >patch && + sed -e "/^\$/d" <G >F && + git add F + +' + +test_expect_success 'apply should fail gracefully' ' + + if git apply --index patch + then + echo Oops, should not have succeeded + false + else + status=$? + echo "Status was $status" + if test -f .git/index.lock + then + echo Oops, should not have crashed + false + fi + fi +' + +test_done diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh new file mode 100755 index 0000000000..85f3da2b98 --- /dev/null +++ b/t/t4124-apply-ws-rule.sh @@ -0,0 +1,151 @@ +#!/bin/sh + +test_description='core.whitespace rules and git-apply' + +. ./test-lib.sh + +prepare_test_file () { + + # A line that has character X is touched iff RULE is in effect: + # X RULE + # ! trailing-space + # @ space-before-tab + # # indent-with-non-tab + sed -e "s/_/ /g" -e "s/>/ /" <<-\EOF + An_SP in an ordinary line>and a HT. + >A HT. + _>A SP and a HT (@). + _>_A SP, a HT and a SP (@). + _______Seven SP. + ________Eight SP (#). + _______>Seven SP and a HT (@). + ________>Eight SP and a HT (@#). + _______>_Seven SP, a HT and a SP (@). + ________>_Eight SP, a HT and a SP (@#). + _______________Fifteen SP (#). + _______________>Fifteen SP and a HT (@#). + ________________Sixteen SP (#). + ________________>Sixteen SP and a HT (@#). + _____a__Five SP, a non WS, two SP. + A line with a (!) trailing SP_ + A line with a (!) trailing HT> + EOF +} + +apply_patch () { + >target && + sed -e "s|\([ab]\)/file|\1/target|" <patch | + git apply "$@" +} + +test_fix () { + + # fix should not barf + apply_patch --whitespace=fix || return 1 + + # find touched lines + diff file target | sed -n -e "s/^> //p" >fixed + + # the changed lines are all expeced to change + fixed_cnt=$(wc -l <fixed) + case "$1" in + '') expect_cnt=$fixed_cnt ;; + ?*) expect_cnt=$(grep "[$1]" <fixed | wc -l) ;; + esac + test $fixed_cnt -eq $expect_cnt || return 1 + + # and we are not missing anything + case "$1" in + '') expect_cnt=0 ;; + ?*) expect_cnt=$(grep "[$1]" <file | wc -l) ;; + esac + test $fixed_cnt -eq $expect_cnt || return 1 + + # Get the patch actually applied + git diff-files -p target >fixed-patch + test -s fixed-patch && return 0 + + # Make sure it is complaint-free + >target + git apply --whitespace=error-all <fixed-patch + +} + +test_expect_success setup ' + + >file && + git add file && + prepare_test_file >file && + git diff-files -p >patch && + >target && + git add target + +' + +test_expect_success 'whitespace=nowarn, default rule' ' + + apply_patch --whitespace=nowarn && + diff file target + +' + +test_expect_success 'whitespace=warn, default rule' ' + + apply_patch --whitespace=warn && + diff file target + +' + +test_expect_success 'whitespace=error-all, default rule' ' + + apply_patch --whitespace=error-all && return 1 + test -s target && return 1 + : happy + +' + +test_expect_success 'whitespace=error-all, no rule' ' + + git config core.whitespace -trailing,-space-before,-indent && + apply_patch --whitespace=error-all && + diff file target + +' + +test_expect_success 'whitespace=error-all, no rule (attribute)' ' + + git config --unset core.whitespace && + echo "target -whitespace" >.gitattributes && + apply_patch --whitespace=error-all && + diff file target + +' + +for t in - '' +do + case "$t" in '') tt='!' ;; *) tt= ;; esac + for s in - '' + do + case "$s" in '') ts='@' ;; *) ts= ;; esac + for i in - '' + do + case "$i" in '') ti='#' ;; *) ti= ;; esac + rule=${t}trailing,${s}space,${i}indent + + rm -f .gitattributes + test_expect_success "rule=$rule" ' + git config core.whitespace "$rule" && + test_fix "$tt$ts$ti" + ' + + test_expect_success "rule=$rule (attributes)" ' + git config --unset core.whitespace && + echo "target whitespace=$rule" >.gitattributes && + test_fix "$tt$ts$ti" + ' + + done + done +done + +test_done diff --git a/t/t4125-apply-ws-fuzz.sh b/t/t4125-apply-ws-fuzz.sh new file mode 100755 index 0000000000..3b471b641b --- /dev/null +++ b/t/t4125-apply-ws-fuzz.sh @@ -0,0 +1,103 @@ +#!/bin/sh + +test_description='applying patch that has broken whitespaces in context' + +. ./test-lib.sh + +test_expect_success setup ' + + >file && + git add file && + + # file-0 is full of whitespace breakages + for l in a bb c d eeee f ggg h + do + echo "$l " + done >file-0 && + + # patch-0 creates a whitespace broken file + cat file-0 >file && + git diff >patch-0 && + git add file && + + # file-1 is still full of whitespace breakages, + # but has one line updated, without fixing any + # whitespaces. + # patch-1 records that change. + sed -e "s/d/D/" file-0 >file-1 && + cat file-1 >file && + git diff >patch-1 && + + # patch-all is the effect of both patch-0 and patch-1 + >file && + git add file && + cat file-1 >file && + git diff >patch-all && + + # patch-2 is the same as patch-1 but is based + # on a version that already has whitespace fixed, + # and does not introduce whitespace breakages. + sed -e "s/ $//" patch-1 >patch-2 && + + # If all whitespace breakages are fixed the contents + # should look like file-fixed + sed -e "s/ $//" file-1 >file-fixed + +' + +test_expect_success nofix ' + + >file && + git add file && + + # Baseline. Applying without fixing any whitespace + # breakages. + git apply --whitespace=nowarn patch-0 && + git apply --whitespace=nowarn patch-1 && + + # The result should obviously match. + test_cmp file-1 file +' + +test_expect_success 'withfix (forward)' ' + + >file && + git add file && + + # The first application will munge the context lines + # the second patch depends on. We should be able to + # adjust and still apply. + git apply --whitespace=fix patch-0 && + git apply --whitespace=fix patch-1 && + + test_cmp file-fixed file +' + +test_expect_success 'withfix (backward)' ' + + >file && + git add file && + + # Now we have a whitespace breakages on our side. + git apply --whitespace=nowarn patch-0 && + + # And somebody sends in a patch based on image + # with whitespace already fixed. + git apply --whitespace=fix patch-2 && + + # The result should accept the whitespace fixed + # postimage. But the line with "h" is beyond context + # horizon and left unfixed. + + sed -e /h/d file-fixed >fixed-head && + sed -e /h/d file >file-head && + test_cmp fixed-head file-head && + + sed -n -e /h/p file-fixed >fixed-tail && + sed -n -e /h/p file >file-tail && + + ! test_cmp fixed-tail file-tail + +' + +test_done diff --git a/t/t4126-apply-empty.sh b/t/t4126-apply-empty.sh new file mode 100755 index 0000000000..ceb6a79fe0 --- /dev/null +++ b/t/t4126-apply-empty.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +test_description='apply empty' + +. ./test-lib.sh + +test_expect_success setup ' + >empty && + git add empty && + test_tick && + git commit -m initial && + for i in a b c d e + do + echo $i + done >empty && + cat empty >expect && + git diff | + sed -e "/^diff --git/d" \ + -e "/^index /d" \ + -e "s|a/empty|empty.orig|" \ + -e "s|b/empty|empty|" >patch0 && + sed -e "s|empty|missing|" patch0 >patch1 && + >empty && + git update-index --refresh +' + +test_expect_success 'apply empty' ' + git reset --hard && + rm -f missing && + git apply patch0 && + test_cmp expect empty +' + +test_expect_success 'apply --index empty' ' + git reset --hard && + rm -f missing && + git apply --index patch0 && + test_cmp expect empty && + git diff --exit-code +' + +test_expect_success 'apply create' ' + git reset --hard && + rm -f missing && + git apply patch1 && + test_cmp expect missing +' + +test_expect_success 'apply --index create' ' + git reset --hard && + rm -f missing && + git apply --index patch1 && + test_cmp expect missing && + git diff --exit-code +' + +test_done diff --git a/t/t4127-apply-same-fn.sh b/t/t4127-apply-same-fn.sh new file mode 100755 index 0000000000..1f859dd908 --- /dev/null +++ b/t/t4127-apply-same-fn.sh @@ -0,0 +1,90 @@ +#!/bin/sh + +test_description='apply same filename' + +. ./test-lib.sh + +modify () { + sed -e "$1" < "$2" > "$2".x && + mv "$2".x "$2" +} + +test_expect_success setup ' + for i in a b c d e f g h i j k l m + do + echo $i + done >same_fn && + cp same_fn other_fn && + git add same_fn other_fn && + git commit -m initial +' +test_expect_success 'apply same filename with independent changes' ' + modify "s/^d/z/" same_fn && + git diff > patch0 && + git add same_fn && + modify "s/^i/y/" same_fn && + git diff >> patch0 && + cp same_fn same_fn2 && + git reset --hard && + git-apply patch0 && + diff same_fn same_fn2 +' + +test_expect_success 'apply same filename with overlapping changes' ' + git reset --hard + modify "s/^d/z/" same_fn && + git diff > patch0 && + git add same_fn && + modify "s/^e/y/" same_fn && + git diff >> patch0 && + cp same_fn same_fn2 && + git reset --hard && + git-apply patch0 && + diff same_fn same_fn2 +' + +test_expect_success 'apply same new filename after rename' ' + git reset --hard + git mv same_fn new_fn + modify "s/^d/z/" new_fn && + git add new_fn && + git diff -M --cached > patch1 && + modify "s/^e/y/" new_fn && + git diff >> patch1 && + cp new_fn new_fn2 && + git reset --hard && + git apply --index patch1 && + diff new_fn new_fn2 +' + +test_expect_success 'apply same old filename after rename -- should fail.' ' + git reset --hard + git mv same_fn new_fn + modify "s/^d/z/" new_fn && + git add new_fn && + git diff -M --cached > patch1 && + git mv new_fn same_fn + modify "s/^e/y/" same_fn && + git diff >> patch1 && + git reset --hard && + test_must_fail git apply patch1 +' + +test_expect_success 'apply A->B (rename), C->A (rename), A->A -- should pass.' ' + git reset --hard + git mv same_fn new_fn + modify "s/^d/z/" new_fn && + git add new_fn && + git diff -M --cached > patch1 && + git commit -m "a rename" && + git mv other_fn same_fn + modify "s/^e/y/" same_fn && + git add same_fn && + git diff -M --cached >> patch1 && + modify "s/^g/x/" same_fn && + git diff >> patch1 && + git reset --hard HEAD^ && + git apply patch1 +' + +test_done diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh new file mode 100755 index 0000000000..2dd0c75f96 --- /dev/null +++ b/t/t4128-apply-root.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +test_description='apply same filename' + +. ./test-lib.sh + +test_expect_success 'setup' ' + + mkdir -p some/sub/dir && + echo Hello > some/sub/dir/file && + git add some/sub/dir/file && + git commit -m initial && + git tag initial + +' + +cat > patch << EOF +diff a/bla/blub/dir/file b/bla/blub/dir/file +--- a/bla/blub/dir/file ++++ b/bla/blub/dir/file +@@ -1,1 +1,1 @@ +-Hello ++Bello +EOF + +test_expect_success 'apply --directory -p (1)' ' + + git apply --directory=some/sub -p3 --index patch && + test Bello = $(git show :some/sub/dir/file) && + test Bello = $(cat some/sub/dir/file) + +' + +test_expect_success 'apply --directory -p (2) ' ' + + git reset --hard initial && + git apply --directory=some/sub/ -p3 --index patch && + test Bello = $(git show :some/sub/dir/file) && + test Bello = $(cat some/sub/dir/file) + +' + +test_done diff --git a/t/t4150-am.sh b/t/t4150-am.sh new file mode 100755 index 0000000000..6e6aaf5936 --- /dev/null +++ b/t/t4150-am.sh @@ -0,0 +1,260 @@ +#!/bin/sh + +test_description='git am running' + +. ./test-lib.sh + +cat >msg <<EOF +second + +Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy +eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam +voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita +kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem +ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod +tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At +vero eos et accusam et justo duo dolores et ea rebum. + + Duis autem vel eum iriure dolor in hendrerit in vulputate velit + esse molestie consequat, vel illum dolore eu feugiat nulla facilisis + at vero eros et accumsan et iusto odio dignissim qui blandit + praesent luptatum zzril delenit augue duis dolore te feugait nulla + facilisi. + + +Lorem ipsum dolor sit amet, +consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut +laoreet dolore magna aliquam erat volutpat. + + git + --- + +++ + +Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit +lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure +dolor in hendrerit in vulputate velit esse molestie consequat, vel illum +dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio +dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te +feugait nulla facilisi. +EOF + +cat >failmail <<EOF +From foo@example.com Fri May 23 10:43:49 2008 +From: foo@example.com +To: bar@example.com +Subject: Re: [RFC/PATCH] git-foo.sh +Date: Fri, 23 May 2008 05:23:42 +0200 + +Sometimes we have to find out that there's nothing left. + +EOF + +cat >pine <<EOF +From MAILER-DAEMON Fri May 23 10:43:49 2008 +Date: 23 May 2008 05:23:42 +0200 +From: Mail System Internal Data <MAILER-DAEMON@example.com> +Subject: DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA +Message-ID: <foo-0001@example.com> + +This text is part of the internal format of your mail folder, and is not +a real message. It is created automatically by the mail system software. +If deleted, important folder data will be lost, and it will be re-created +with the data reset to initial values. + +EOF + +echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected + +test_expect_success setup ' + echo hello >file && + git add file && + test_tick && + git commit -m first && + git tag first && + echo world >>file && + git add file && + test_tick && + git commit -s -F msg && + git tag second && + git format-patch --stdout first >patch1 && + sed -n -e "3,\$p" msg >file && + git add file && + test_tick && + git commit -m third && + git format-patch --stdout first >patch2 && + git checkout -b lorem && + sed -n -e "11,\$p" msg >file && + head -n 9 msg >>file && + test_tick && + git commit -a -m "moved stuff" && + echo goodbye >another && + git add another && + test_tick && + git commit -m "added another file" && + git format-patch --stdout master >lorem-move.patch +' + +# reset time +unset test_tick +test_tick + +test_expect_success 'am applies patch correctly' ' + git checkout first && + test_tick && + git am <patch1 && + ! test -d .git/rebase-apply && + test -z "$(git diff second)" && + test "$(git rev-parse second)" = "$(git rev-parse HEAD)" && + test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)" +' + +GIT_AUTHOR_NAME="Another Thor" +GIT_AUTHOR_EMAIL="a.thor@example.com" +GIT_COMMITTER_NAME="Co M Miter" +GIT_COMMITTER_EMAIL="c.miter@example.com" +export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL + +compare () { + test "$(git cat-file commit "$2" | grep "^$1 ")" = \ + "$(git cat-file commit "$3" | grep "^$1 ")" +} + +test_expect_success 'am changes committer and keeps author' ' + test_tick && + git checkout first && + git am patch2 && + ! test -d .git/rebase-apply && + test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" && + test -z "$(git diff master..HEAD)" && + test -z "$(git diff master^..HEAD^)" && + compare author master HEAD && + compare author master^ HEAD^ && + test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \ + "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)" +' + +test_expect_success 'am --signoff adds Signed-off-by: line' ' + git checkout -b master2 first && + git am --signoff <patch2 && + echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected && + git cat-file commit HEAD^ | grep "Signed-off-by:" >actual && + test_cmp actual expected && + echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected && + git cat-file commit HEAD | grep "Signed-off-by:" >actual && + test_cmp actual expected +' + +test_expect_success 'am stays in branch' ' + test "refs/heads/master2" = "$(git symbolic-ref HEAD)" +' + +test_expect_success 'am --signoff does not add Signed-off-by: line if already there' ' + git format-patch --stdout HEAD^ >patch3 && + sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2," patch3 >patch4 + git checkout HEAD^ && + git am --signoff patch4 && + test "$(git cat-file commit HEAD | grep -c "^Signed-off-by:")" -eq 1 +' + +test_expect_success 'am without --keep removes Re: and [PATCH] stuff' ' + test "$(git rev-parse HEAD)" = "$(git rev-parse master2)" +' + +test_expect_success 'am --keep really keeps the subject' ' + git checkout HEAD^ && + git am --keep patch4 && + ! test -d .git/rebase-apply && + git-cat-file commit HEAD | + grep -q -F "Re: Re: Re: [PATCH 1/5 v2] third" +' + +test_expect_success 'am -3 falls back to 3-way merge' ' + git checkout -b lorem2 master2 && + sed -n -e "3,\$p" msg >file && + head -n 9 msg >>file && + git add file && + test_tick && + git commit -m "copied stuff" && + git am -3 lorem-move.patch && + ! test -d .git/rebase-apply && + test -z "$(git diff lorem)" +' + +test_expect_success 'am pauses on conflict' ' + git checkout lorem2^^ && + test_must_fail git am lorem-move.patch && + test -d .git/rebase-apply +' + +test_expect_success 'am --skip works' ' + git am --skip && + ! test -d .git/rebase-apply && + test -z "$(git diff lorem2^^ -- file)" && + test goodbye = "$(cat another)" +' + +test_expect_success 'am --resolved works' ' + git checkout lorem2^^ && + test_must_fail git am lorem-move.patch && + test -d .git/rebase-apply && + echo resolved >>file && + git add file && + git am --resolved && + ! test -d .git/rebase-apply && + test goodbye = "$(cat another)" +' + +test_expect_success 'am takes patches from a Pine mailbox' ' + git checkout first && + cat pine patch1 | git am && + ! test -d .git/rebase-apply && + test -z "$(git diff master^..HEAD)" +' + +test_expect_success 'am fails on mail without patch' ' + test_must_fail git am <failmail && + rm -r .git/rebase-apply/ +' + +test_expect_success 'am fails on empty patch' ' + echo "---" >>failmail && + test_must_fail git am <failmail && + git am --skip && + ! test -d .git/rebase-apply +' + +test_expect_success 'am works from stdin in subdirectory' ' + rm -fr subdir && + git checkout first && + ( + mkdir -p subdir && + cd subdir && + git am <../patch1 + ) && + test -z "$(git diff second)" +' + +test_expect_success 'am works from file (relative path given) in subdirectory' ' + rm -fr subdir && + git checkout first && + ( + mkdir -p subdir && + cd subdir && + git am ../patch1 + ) && + test -z "$(git diff second)" +' + +test_expect_success 'am works from file (absolute path given) in subdirectory' ' + rm -fr subdir && + git checkout first && + P=$(pwd) && + ( + mkdir -p subdir && + cd subdir && + git am "$P/patch1" + ) && + test -z "$(git diff second)" +' + +test_done diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh new file mode 100755 index 0000000000..7d86cdff64 --- /dev/null +++ b/t/t4151-am-abort.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +test_description='am --abort' + +. ./test-lib.sh + +test_expect_success setup ' + for i in a b c d e f g + do + echo $i + done >file-1 && + cp file-1 file-2 && + test_tick && + git add file-1 file-2 && + git commit -m initial && + git tag initial && + for i in 2 3 4 5 6 + do + echo $i >>file-1 && + echo $i >otherfile-$i && + git add otherfile-$i && + test_tick && + git commit -a -m $i || break + done && + git format-patch initial && + git checkout -b side initial && + echo local change >file-2-expect +' + +for with3 in '' ' -3' +do + test_expect_success "am$with3 stops at a patch that does not apply" ' + + git reset --hard initial && + cp file-2-expect file-2 && + + test_must_fail git am$with3 000[1245]-*.patch && + git log --pretty=tformat:%s >actual && + for i in 3 2 initial + do + echo $i + done >expect && + test_cmp expect actual + ' + + test_expect_success "am$with3 --skip continue after failed am$with3" ' + test_must_fail git-am$with3 --skip >output && + test "$(grep "^Applying" output)" = "Applying: 6" && + test_cmp file-2-expect file-2 && + test ! -f .git/rr-cache/MERGE_RR + ' + + test_expect_success "am --abort goes back after failed am$with3" ' + git-am --abort && + git rev-parse HEAD >actual && + git rev-parse initial >expect && + test_cmp expect actual && + test_cmp file-2-expect file-2 && + git diff-index --exit-code --cached HEAD && + test ! -f .git/rr-cache/MERGE_RR + ' + +done + +test_done diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh new file mode 100755 index 0000000000..b68ab11f29 --- /dev/null +++ b/t/t4200-rerere.sh @@ -0,0 +1,225 @@ +#!/bin/sh +# +# Copyright (c) 2006 Johannes E. Schindelin +# + +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 'nothing recorded without rerere' ' + (rm -rf .git/rr-cache; git config rerere.enabled false) && + test_must_fail git merge first && + ! test -d .git/rr-cache +' + +# activate rerere, old style +test_expect_success 'conflicting merge' ' + git reset --hard && + mkdir .git/rr-cache && + git config --unset rerere.enabled && + test_must_fail git merge first +' + +sha1=$(sed -e 's/ .*//' .git/MERGE_RR) +rr=.git/rr-cache/$sha1 +test_expect_success 'recorded preimage' "grep ^=======$ $rr/preimage" + +test_expect_success 'rerere.enabled works, too' ' + rm -rf .git/rr-cache && + git config rerere.enabled true && + git reset --hard && + test_must_fail git merge first && + grep ^=======$ $rr/preimage +' + +test_expect_success 'no postimage or thisimage yet' \ + "test ! -f $rr/postimage -a ! -f $rr/thisimage" + +test_expect_success 'preimage has right number of lines' ' + + cnt=$(sed -ne "/^<<<<<<</,/^>>>>>>>/p" $rr/preimage | wc -l) && + test $cnt = 13 + +' + +git show first:a1 > a1 + +cat > expect << EOF +--- a/a1 ++++ b/a1 +@@ -1,4 +1,4 @@ +-Some Title ++Some title + ========== + Whether 'tis nobler in the mind to suffer + The slings and arrows of outrageous fortune, +@@ -8,21 +8,11 @@ + The heart-ache and the thousand natural shocks + That flesh is heir to, 'tis a consummation + Devoutly to be wish'd. +-<<<<<<< +-Some Title +-========== +-To die! To sleep; +-======= + 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; +-<<<<<<< +-======= +-* END * +->>>>>>> +EOF +git rerere diff > out + +test_expect_success 'rerere diff' 'test_cmp expect out' + +cat > expect << EOF +a1 +EOF + +git rerere status > out + +test_expect_success 'rerere status' 'test_cmp expect out' + +test_expect_success 'commit succeeds' \ + "git commit -q -a -m 'prefer first over second'" + +test_expect_success 'recorded postimage' "test -f $rr/postimage" + +test_expect_success 'another conflicting merge' ' + git checkout -b third master && + git show second^:a1 | sed "s/To die: t/To die! T/" > a1 && + git commit -q -a -m third && + test_must_fail git pull . first +' + +git show first:a1 | sed 's/To die: t/To die! T/' > expect +test_expect_success 'rerere kicked in' "! grep ^=======$ a1" + +test_expect_success 'rerere prefers first change' 'test_cmp a1 expect' + +rm $rr/postimage +echo "$sha1 a1" | perl -pe 'y/\012/\000/' > .git/MERGE_RR + +test_expect_success 'rerere clear' 'git rerere clear' + +test_expect_success 'clear removed the directory' "test ! -d $rr" + +mkdir $rr +echo Hello > $rr/preimage +echo World > $rr/postimage + +sha2=4000000000000000000000000000000000000000 +rr2=.git/rr-cache/$sha2 +mkdir $rr2 +echo Hello > $rr2/preimage + +almost_15_days_ago=$((60-15*86400)) +just_over_15_days_ago=$((-1-15*86400)) +almost_60_days_ago=$((60-60*86400)) +just_over_60_days_ago=$((-1-60*86400)) + +test-chmtime =$almost_60_days_ago $rr/preimage +test-chmtime =$almost_15_days_ago $rr2/preimage + +test_expect_success 'garbage collection (part1)' 'git rerere gc' + +test_expect_success 'young records still live' \ + "test -f $rr/preimage && test -f $rr2/preimage" + +test-chmtime =$just_over_60_days_ago $rr/preimage +test-chmtime =$just_over_15_days_ago $rr2/preimage + +test_expect_success 'garbage collection (part2)' 'git rerere gc' + +test_expect_success 'old records rest in peace' \ + "test ! -f $rr/preimage && test ! -f $rr2/preimage" + +test_expect_success 'file2 added differently in two branches' ' + git reset --hard && + git checkout -b fourth && + echo Hallo > file2 && + git add file2 && + git commit -m version1 && + git checkout third && + echo Bello > file2 && + git add file2 && + git commit -m version2 && + test_must_fail git merge fourth && + sha1=$(sed -e "s/ .*//" .git/MERGE_RR) && + rr=.git/rr-cache/$sha1 && + echo Cello > file2 && + git add file2 && + git commit -m resolution +' + +test_expect_success 'resolution was recorded properly' ' + git reset --hard HEAD~2 && + git checkout -b fifth && + echo Hallo > file3 && + git add file3 && + git commit -m version1 && + git checkout third && + echo Bello > file3 && + git add file3 && + git commit -m version2 && + git tag version2 && + test_must_fail git merge fifth && + test Cello = "$(cat file3)" && + test 0 != $(git ls-files -u | wc -l) +' + +test_expect_success 'rerere.autoupdate' ' + git config rerere.autoupdate true + git reset --hard && + git checkout version2 && + test_must_fail git merge fifth && + test 0 = $(git ls-files -u | wc -l) + +' + +test_done diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh new file mode 100755 index 0000000000..405b971191 --- /dev/null +++ b/t/t4201-shortlog.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Copyright (c) 2006 Johannes E. Schindelin +# + +test_description='git shortlog +' + +. ./test-lib.sh + +echo 1 > a1 +git add a1 +tree=$(git write-tree) +commit=$( (echo "Test"; echo) | git commit-tree $tree ) +git update-ref HEAD $commit + +echo 2 > a1 +git commit --quiet -m "This is a very, very long first line for the commit message to see if it is wrapped correctly" a1 + +# test if the wrapping is still valid when replacing all i's by treble clefs. +echo 3 > a1 +git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\360\235\204\236')" a1 + +# now fsck up the utf8 +git config i18n.commitencoding non-utf-8 +echo 4 > a1 +git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\370\235\204\236')" a1 + +echo 5 > a1 +git commit --quiet -m "a 12 34 56 78" a1 + +git shortlog -w HEAD > out + +cat > expect << EOF +A U Thor (5): + Test + This is a very, very long first line for the commit message to see if + it is wrapped correctly + Thð„žs ð„žs a very, very long fð„žrst lð„žne for the commð„žt message to see ð„žf + ð„žt ð„žs wrapped correctly + Thø„žs ø„žs a very, very long fø„žrst lø„žne for the commø„žt + message to see ø„žf ø„žt ø„žs wrapped correctly + a 12 34 + 56 78 + +EOF + +test_expect_success 'shortlog wrapping' 'test_cmp expect out' + +git log HEAD > log +GIT_DIR=non-existing git shortlog -w < log > out + +test_expect_success 'shortlog from non-git directory' 'test_cmp expect out' + +test_done diff --git a/t/t4202-log.sh b/t/t4202-log.sh new file mode 100755 index 0000000000..4c8af45f83 --- /dev/null +++ b/t/t4202-log.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +test_description='git log' + +. ./test-lib.sh + +test_expect_success setup ' + + echo one >one && + git add one && + test_tick && + git commit -m initial && + + echo ichi >one && + git add one && + test_tick && + git commit -m second && + + mkdir a && + echo ni >a/two && + git add a/two && + test_tick && + git commit -m third && + + echo san >a/three && + git add a/three && + test_tick && + git commit -m fourth && + + git rm a/three && + test_tick && + git commit -m fifth + +' + +test_expect_success 'diff-filter=A' ' + + actual=$(git log --pretty="format:%s" --diff-filter=A HEAD) && + expect=$(echo fourth ; echo third ; echo initial) && + test "$actual" = "$expect" || { + echo Oops + echo "Actual: $actual" + false + } + +' + +test_expect_success 'diff-filter=M' ' + + actual=$(git log --pretty="format:%s" --diff-filter=M HEAD) && + expect=$(echo second) && + test "$actual" = "$expect" || { + echo Oops + echo "Actual: $actual" + false + } + +' + +test_expect_success 'diff-filter=D' ' + + actual=$(git log --pretty="format:%s" --diff-filter=D HEAD) && + expect=$(echo fifth) && + test "$actual" = "$expect" || { + echo Oops + echo "Actual: $actual" + false + } + +' + + + +test_done + diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh new file mode 100755 index 0000000000..e395ff4e34 --- /dev/null +++ b/t/t5000-tar-tree.sh @@ -0,0 +1,195 @@ +#!/bin/sh +# +# Copyright (C) 2005 Rene Scharfe +# + +test_description='git tar-tree and git get-tar-commit-id test + +This test covers the topics of file contents, commit date handling and +commit id embedding: + + The contents of the repository is compared to the extracted tar + archive. The repository contains simple text files, symlinks and a + binary file (/bin/sh). Only paths shorter than 99 characters are + used. + + git tar-tree applies the commit date to every file in the archive it + creates. The test sets the commit date to a specific value and checks + if the tar archive contains that value. + + When giving git tar-tree a commit id (in contrast to a tree id) it + embeds this commit id into the tar archive as a comment. The test + checks the ability of git get-tar-commit-id to figure it out from the + tar file. + +' + +. ./test-lib.sh +UNZIP=${UNZIP:-unzip} + +SUBSTFORMAT=%H%n + +test_expect_success \ + 'populate workdir' \ + 'mkdir a b c && + echo simple textfile >a/a && + mkdir a/bin && + cp /bin/sh a/bin && + printf "A\$Format:%s\$O" "$SUBSTFORMAT" >a/substfile1 && + printf "A not substituted O" >a/substfile2 && + ln -s a a/l1 && + (p=long_path_to_a_file && cd a && + for depth in 1 2 3 4 5; do mkdir $p && cd $p; done && + echo text >file_with_long_path) && + (cd a && find .) | sort >a.lst' + +test_expect_success \ + 'add ignored file' \ + 'echo ignore me >a/ignored && + echo ignored export-ignore >.gitattributes' + +test_expect_success \ + 'add files to repository' \ + 'find a -type f | xargs git update-index --add && + find a -type l | xargs git update-index --add && + treeid=`git write-tree` && + echo $treeid >treeid && + git update-ref HEAD $(TZ=GMT GIT_COMMITTER_DATE="2005-05-27 22:00:00" \ + git commit-tree $treeid </dev/null)' + +test_expect_success \ + 'remove ignored file' \ + 'rm a/ignored' + +test_expect_success \ + 'git archive' \ + 'git archive HEAD >b.tar' + +test_expect_success \ + 'git tar-tree' \ + 'git tar-tree HEAD >b2.tar' + +test_expect_success \ + 'git archive vs. git tar-tree' \ + 'diff b.tar b2.tar' + +test_expect_success \ + 'validate file modification time' \ + 'mkdir extract && + "$TAR" xf b.tar -C extract a/a && + perl -e '\''print((stat("extract/a/a"))[9], "\n")'\'' >b.mtime && + echo "1117231200" >expected.mtime && + diff expected.mtime b.mtime' + +test_expect_success \ + 'git get-tar-commit-id' \ + 'git get-tar-commit-id <b.tar >b.commitid && + diff .git/$(git symbolic-ref HEAD) b.commitid' + +test_expect_success \ + 'extract tar archive' \ + '(cd b && "$TAR" xf -) <b.tar' + +test_expect_success \ + 'validate filenames' \ + '(cd b/a && find .) | sort >b.lst && + diff a.lst b.lst' + +test_expect_success \ + 'validate file contents' \ + 'diff -r a b/a' + +test_expect_success \ + 'git tar-tree with prefix' \ + 'git tar-tree HEAD prefix >c.tar' + +test_expect_success \ + 'extract tar archive with prefix' \ + '(cd c && "$TAR" xf -) <c.tar' + +test_expect_success \ + 'validate filenames with prefix' \ + '(cd c/prefix/a && find .) | sort >c.lst && + diff a.lst c.lst' + +test_expect_success \ + 'validate file contents with prefix' \ + 'diff -r a c/prefix/a' + +test_expect_success \ + 'create archives with substfiles' \ + 'echo "substfile?" export-subst >a/.gitattributes && + git archive HEAD >f.tar && + git archive --prefix=prefix/ HEAD >g.tar && + rm a/.gitattributes' + +test_expect_success \ + 'extract substfiles' \ + '(mkdir f && cd f && "$TAR" xf -) <f.tar' + +test_expect_success \ + 'validate substfile contents' \ + 'git log --max-count=1 "--pretty=format:A${SUBSTFORMAT}O" HEAD \ + >f/a/substfile1.expected && + diff f/a/substfile1.expected f/a/substfile1 && + diff a/substfile2 f/a/substfile2 +' + +test_expect_success \ + 'extract substfiles from archive with prefix' \ + '(mkdir g && cd g && "$TAR" xf -) <g.tar' + +test_expect_success \ + 'validate substfile contents from archive with prefix' \ + 'git log --max-count=1 "--pretty=format:A${SUBSTFORMAT}O" HEAD \ + >g/prefix/a/substfile1.expected && + diff g/prefix/a/substfile1.expected g/prefix/a/substfile1 && + diff a/substfile2 g/prefix/a/substfile2 +' + +test_expect_success \ + 'git archive --format=zip' \ + 'git archive --format=zip HEAD >d.zip' + +$UNZIP -v >/dev/null 2>&1 +if [ $? -eq 127 ]; then + echo "Skipping ZIP tests, because unzip was not found" + test_done + exit +fi + +test_expect_success \ + 'extract ZIP archive' \ + '(mkdir d && cd d && $UNZIP ../d.zip)' + +test_expect_success \ + 'validate filenames' \ + '(cd d/a && find .) | sort >d.lst && + diff a.lst d.lst' + +test_expect_success \ + 'validate file contents' \ + 'diff -r a d/a' + +test_expect_success \ + 'git archive --format=zip with prefix' \ + 'git archive --format=zip --prefix=prefix/ HEAD >e.zip' + +test_expect_success \ + 'extract ZIP archive with prefix' \ + '(mkdir e && cd e && $UNZIP ../e.zip)' + +test_expect_success \ + 'validate filenames with prefix' \ + '(cd e/prefix/a && find .) | sort >e.lst && + diff a.lst e.lst' + +test_expect_success \ + 'validate file contents with prefix' \ + 'diff -r a e/prefix/a' + +test_expect_success \ + 'git archive --list outside of a git repo' \ + 'GIT_DIR=some/non-existing/directory git archive --list' + +test_done diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh new file mode 100755 index 0000000000..8dfaddda91 --- /dev/null +++ b/t/t5100-mailinfo.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git mailinfo and git mailsplit test' + +. ./test-lib.sh + +test_expect_success 'split sample box' \ + 'git mailsplit -o. ../t5100/sample.mbox >last && + last=`cat last` && + echo total is $last && + test `cat last` = 11' + +for mail in `echo 00*` +do + test_expect_success "mailinfo $mail" \ + "git mailinfo -u msg$mail patch$mail <$mail >info$mail && + echo msg && + diff ../t5100/msg$mail msg$mail && + echo patch && + diff ../t5100/patch$mail patch$mail && + echo info && + diff ../t5100/info$mail info$mail" +done + +test_expect_success 'respect NULs' ' + + git mailsplit -d3 -o. ../t5100/nul-plain && + cmp ../t5100/nul-plain 001 && + (cat 001 | git mailinfo msg patch) && + test 4 = $(wc -l < patch) + +' + +test_expect_success 'Preserve NULs out of MIME encoded message' ' + + git mailsplit -d5 -o. ../t5100/nul-b64.in && + cmp ../t5100/nul-b64.in 00001 && + git mailinfo msg patch <00001 && + cmp ../t5100/nul-b64.expect patch + +' + +test_done diff --git a/t/t5100/0010 b/t/t5100/0010 new file mode 100644 index 0000000000..f5892c9da7 --- /dev/null +++ b/t/t5100/0010 @@ -0,0 +1,35 @@ +From b9704a518e21158433baa2cc2d591fea687967f6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Lukas=20Sandstr=C3=B6m?= <lukass@etek.chalmers.se> +Date: Thu, 10 Jul 2008 23:41:33 +0200 +Subject: Re: discussion that lead to this patch +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[PATCH] git-mailinfo: Fix getting the subject from the body + +"Subject: " isn't in the static array "header", and thus +memcmp("Subject: ", header[i], 7) will never match. + +Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se> +Signed-off-by: Junio C Hamano <gitster@pobox.com> +--- + builtin-mailinfo.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c +index 962aa34..2d1520f 100644 +--- a/builtin-mailinfo.c ++++ b/builtin-mailinfo.c +@@ -334,7 +334,7 @@ static int check_header(char *line, unsigned linesize, char **hdr_data, int over + return 1; + if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) { + for (i = 0; header[i]; i++) { +- if (!memcmp("Subject: ", header[i], 9)) { ++ if (!memcmp("Subject", header[i], 7)) { + if (! handle_header(line, hdr_data[i], 0)) { + return 1; + } +-- +1.5.6.2.455.g1efb2 + diff --git a/t/t5100/info0001 b/t/t5100/info0001 new file mode 100644 index 0000000000..8c052777e0 --- /dev/null +++ b/t/t5100/info0001 @@ -0,0 +1,5 @@ +Author: A U Thor +Email: a.u.thor@example.com +Subject: a commit. +Date: Fri, 9 Jun 2006 00:44:16 -0700 + diff --git a/t/t5100/info0002 b/t/t5100/info0002 new file mode 100644 index 0000000000..49bb0fec85 --- /dev/null +++ b/t/t5100/info0002 @@ -0,0 +1,5 @@ +Author: A U Thor +Email: a.u.thor@example.com +Subject: another patch +Date: Fri, 9 Jun 2006 00:44:16 -0700 + diff --git a/t/t5100/info0003 b/t/t5100/info0003 new file mode 100644 index 0000000000..bd0d1221aa --- /dev/null +++ b/t/t5100/info0003 @@ -0,0 +1,5 @@ +Author: A U Thor +Email: a.u.thor@example.com +Subject: third patch +Date: Fri, 9 Jun 2006 00:44:16 -0700 + diff --git a/t/t5100/info0004 b/t/t5100/info0004 new file mode 100644 index 0000000000..616c3092a2 --- /dev/null +++ b/t/t5100/info0004 @@ -0,0 +1,5 @@ +Author: YOSHIFUJI Hideaki / å‰è—¤è‹±æ˜Ž +Email: yoshfuji@linux-ipv6.org +Subject: GIT: Try all addresses for given remote name +Date: Thu, 21 Jul 2005 09:10:36 -0400 (EDT) + diff --git a/t/t5100/info0005 b/t/t5100/info0005 new file mode 100644 index 0000000000..46a46fc772 --- /dev/null +++ b/t/t5100/info0005 @@ -0,0 +1,5 @@ +Author: David KÃ¥gedal +Email: davidk@lysator.liu.se +Subject: Fixed two bugs in git-cvsimport-script. +Date: Mon, 15 Aug 2005 20:18:25 +0200 + diff --git a/t/t5100/info0006 b/t/t5100/info0006 new file mode 100644 index 0000000000..8c052777e0 --- /dev/null +++ b/t/t5100/info0006 @@ -0,0 +1,5 @@ +Author: A U Thor +Email: a.u.thor@example.com +Subject: a commit. +Date: Fri, 9 Jun 2006 00:44:16 -0700 + diff --git a/t/t5100/info0007 b/t/t5100/info0007 new file mode 100644 index 0000000000..49bb0fec85 --- /dev/null +++ b/t/t5100/info0007 @@ -0,0 +1,5 @@ +Author: A U Thor +Email: a.u.thor@example.com +Subject: another patch +Date: Fri, 9 Jun 2006 00:44:16 -0700 + diff --git a/t/t5100/info0008 b/t/t5100/info0008 new file mode 100644 index 0000000000..e8a2951383 --- /dev/null +++ b/t/t5100/info0008 @@ -0,0 +1,5 @@ +Author: Junio C Hamano +Email: junio@kernel.org +Subject: another patch +Date: Fri, 9 Jun 2006 00:44:16 -0700 + diff --git a/t/t5100/info0009 b/t/t5100/info0009 new file mode 100644 index 0000000000..2a66321c80 --- /dev/null +++ b/t/t5100/info0009 @@ -0,0 +1,5 @@ +Author: F U Bar +Email: f.u.bar@example.com +Subject: updates +Date: Mon, 17 Sep 2001 00:00:00 +0900 + diff --git a/t/t5100/info0010 b/t/t5100/info0010 new file mode 100644 index 0000000000..1791241e46 --- /dev/null +++ b/t/t5100/info0010 @@ -0,0 +1,5 @@ +Author: Lukas Sandström +Email: lukass@etek.chalmers.se +Subject: git-mailinfo: Fix getting the subject from the body +Date: Thu, 10 Jul 2008 23:41:33 +0200 + diff --git a/t/t5100/info0011 b/t/t5100/info0011 new file mode 100644 index 0000000000..da5a605a12 --- /dev/null +++ b/t/t5100/info0011 @@ -0,0 +1,5 @@ +Author: A U Thor +Email: a.u.thor@example.com +Subject: Xyzzy +Date: Fri, 8 Aug 2008 13:08:37 +0200 (CEST) + diff --git a/t/t5100/msg0001 b/t/t5100/msg0001 new file mode 100644 index 0000000000..b275a9a9b2 --- /dev/null +++ b/t/t5100/msg0001 @@ -0,0 +1,2 @@ +Here is a patch from A U Thor. + diff --git a/t/t5100/msg0002 b/t/t5100/msg0002 new file mode 100644 index 0000000000..e2546ec733 --- /dev/null +++ b/t/t5100/msg0002 @@ -0,0 +1,21 @@ +Here is a patch from A U Thor. This addresses the issue raised in the +message: + +From: Nit Picker <nit.picker@example.net> +Subject: foo is too old +Message-Id: <nitpicker.12121212@example.net> + +Hopefully this would fix the problem stated there. + + +I have included an extra blank line above, but it does not have to be +stripped away here, along with the +whitespaces at the end of the above line. They are expected to be squashed +when the message is made into a commit log by stripspace, +Also, there are three blank lines after this paragraph, +two truly blank and another full of spaces in between. + + + +Hope this helps. + diff --git a/t/t5100/msg0003 b/t/t5100/msg0003 new file mode 100644 index 0000000000..1ac68101b1 --- /dev/null +++ b/t/t5100/msg0003 @@ -0,0 +1,9 @@ +Here is a patch from A U Thor. This addresses the issue raised in the +message: + +From: Nit Picker <nit.picker@example.net> +Subject: foo is too old +Message-Id: <nitpicker.12121212@example.net> + +Hopefully this would fix the problem stated there. + diff --git a/t/t5100/msg0004 b/t/t5100/msg0004 new file mode 100644 index 0000000000..6f8ba3b8e0 --- /dev/null +++ b/t/t5100/msg0004 @@ -0,0 +1,7 @@ +Hello. + +Try all addresses for given remote name until it succeeds. +Also supports IPv6. + +Signed-of-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> + diff --git a/t/t5100/msg0005 b/t/t5100/msg0005 new file mode 100644 index 0000000000..dd94cd7b9f --- /dev/null +++ b/t/t5100/msg0005 @@ -0,0 +1,13 @@ +The git-cvsimport-script had a copule of small bugs that prevented me +from importing a big CVS repository. + +The first was that it didn't handle removed files with a multi-digit +primary revision number. + +The second was that it was asking the CVS server for "F" messages, +although they were not handled. + +I also updated the documentation for that script to correspond to +actual flags. + +Signed-off-by: David KÃ¥gedal <davidk@lysator.liu.se> diff --git a/t/t5100/msg0006 b/t/t5100/msg0006 new file mode 100644 index 0000000000..b275a9a9b2 --- /dev/null +++ b/t/t5100/msg0006 @@ -0,0 +1,2 @@ +Here is a patch from A U Thor. + diff --git a/t/t5100/msg0007 b/t/t5100/msg0007 new file mode 100644 index 0000000000..71b23c0236 --- /dev/null +++ b/t/t5100/msg0007 @@ -0,0 +1,2 @@ +Here is an empty patch from A U Thor. + diff --git a/t/t5100/msg0008 b/t/t5100/msg0008 new file mode 100644 index 0000000000..a80ecb97ef --- /dev/null +++ b/t/t5100/msg0008 @@ -0,0 +1,4 @@ +>Here is an empty patch from A U Thor. + +Hey you forgot the patch! + diff --git a/t/t5100/msg0009 b/t/t5100/msg0009 new file mode 100644 index 0000000000..9ffe131489 --- /dev/null +++ b/t/t5100/msg0009 @@ -0,0 +1,2 @@ +This is to fix diff-format documentation. + diff --git a/t/t5100/msg0010 b/t/t5100/msg0010 new file mode 100644 index 0000000000..a96c230092 --- /dev/null +++ b/t/t5100/msg0010 @@ -0,0 +1,5 @@ +"Subject: " isn't in the static array "header", and thus +memcmp("Subject: ", header[i], 7) will never match. + +Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se> +Signed-off-by: Junio C Hamano <gitster@pobox.com> diff --git a/t/t5100/msg0011 b/t/t5100/msg0011 new file mode 100644 index 0000000000..4667f21007 --- /dev/null +++ b/t/t5100/msg0011 @@ -0,0 +1,2 @@ +Here comes a commit log message, and +its second line is here. diff --git a/t/t5100/nul-b64.expect b/t/t5100/nul-b64.expect Binary files differnew file mode 100644 index 0000000000..d7d680f631 --- /dev/null +++ b/t/t5100/nul-b64.expect diff --git a/t/t5100/nul-b64.in b/t/t5100/nul-b64.in new file mode 100644 index 0000000000..16540d961f --- /dev/null +++ b/t/t5100/nul-b64.in @@ -0,0 +1,37 @@ +From 667d8940e719cddee1cfe237cbbe215e20270b09 Mon Sep 17 00:00:00 2001 +From: Junio C Hamano <gitster@pobox.com> +Date: Sun, 25 May 2008 00:38:18 -0700 +Subject: [PATCH] second +Content-Transfer-Encoding: base64 + +LS0tCiBmaWxlIHwgIEJpbiAxMzU3IC0+IDEzNTcgYnl0ZXMKIDEgZmlsZXMgY2hhbmdlZCwg +MCBpbnNlcnRpb25zKCspLCAwIGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL2ZpbGUgYi9m +aWxlCmluZGV4IDc3MzYxZDguLjllMDJiZTYgMTAwNjQ0Ci0tLSBhL2ZpbGUKKysrIGIvZmls +ZQpAQCAtMSwxMiArMSwxMiBAQAogTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNl +Y3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIFN1c3BlbmRpc3NlCiBzaXQgYW1ldCB0dXJwaXMg +ZWdldCBlc3QgY3Vyc3VzIGxhb3JlZXQuIEFsaXF1YW0gbWF1cmlzLiBQcmFlc2VudAotdm9s +dXRwYXQuIFByb2luIGluIHB1cnVzLiBOdWxsYSB1cm5hIHNhcGllbiwgZGFwaWJ1cyBzaXQg +YW1ldCwKK3ZvbHV0cGF0LiBQcm9pbiBpbiBwdXJ1cy4gTnVsbGEgdXJuYSBzYXBpZW4sIGRh +cGkAdXMgc2l0IGFtZXQsCiBoZW5kcmVyaXQgbmVjLCB0ZW1wdXMgZXUsIG1pLiBVdCBwb3J0 +YSwgbGVvIGlkIHRpbmNpZHVudCB1bGxhbWNvcnBlciwKLXZlbGl0IGZlbGlzIHRyaXN0aXF1 +ZSBhbnRlLCBhdCBsb2JvcnRpcyBkaWFtIHBlZGUgdXQgZHVpLiBQcm9pbiBhYwordmVsaXQg +ZmVsaXMgdHJpc3RpcXVlIGFudGUsIGF0IGxvAG9ydGlzIGRpYW0gcGVkZSB1dCBkdWkuIFBy +b2luIGFjCiBsZWN0dXMuIERvbmVjIGF0IG1hc3NhIGFjIGlwc3VtIGhlbmRyZXJpdCBzb2xs +aWNpdHVkaW4uIE5hbSBkaWN0dW0KIG5pc2kgc2VkIG1pLiBEdWlzIHNlZCBhbnRlLiBVdCB2 +aXRhZSBlc3QgdXQgZHVpIHVsdHJpY2llcyBkaWduaXNzaW0uCiAKLUluIHZlbCBvZGlvIGVn +ZXQgbmlzbCBjb252YWxsaXMgdm9sdXRwYXQuIE1vcmJpIHZpdGFlIG5pYmguIE51bGxhbQor +SW4gdmVsIG9kaW8gZWdldCBuaXNsIGNvbnZhbGxpcyB2b2x1dHBhdC4gTW9yAGkgdml0YWUg +bmkAaC4gTnVsbGFtCiBhY2N1bXNhbiwgZG9sb3IgcXVpcyBhbGlxdWFtIHNjZWxlcmlzcXVl +LCBlbGl0IGVuaW0gY29uZGltZW50dW0KIG1hdXJpcywgbm9uIHRyaXN0aXF1ZSBtYXVyaXMg +dHVycGlzIGV0IG1hdXJpcy4gVXQgbm9uIG5pc2wuIE5hbSBkaWFtCiBtaSwgc2VtcGVyIHBv +c3VlcmUsIGVsZWlmZW5kIHV0LCBhdWN0b3IgdmVsLCBlcmF0LiBTZWQgcG9zdWVyZQpAQCAt +MTYsNyArMTYsNyBAQCBzZWQgZXN0LiBFdGlhbSBkaWFtIGZlbGlzLCBmZXJtZW50dW0gZWdl +dCwgYWRpcGlzY2luZyBhdCwgcG9zdWVyZSBpbiwKIGR1aS4gRXRpYW0gbHVjdHVzLgogCiBO +dWxsYSBpZCBhdWd1ZS4gTmFtIGlhY3VsaXMgYWNjdW1zYW4gbmlzaS4gU3VzcGVuZGlzc2Ug +cG90ZW50aS4gTnVuYwotdmFyaXVzIGF1Z3VlIG5lYyBvcmNpLiBVdCBjb25kaW1lbnR1bSBk +b2xvciBzYWdpdHRpcyBuaWJoLiBTdXNwZW5kaXNzZQordmFyaXVzIGF1Z3VlIG5lYyBvcmNp +LiBVdCBjb25kaW1lbnR1bSBkb2xvciBzYWdpdHRpcyBuaQBoLiBTdXNwZW5kaXNzZQogdGVt +cG9yIGxlY3R1cyBzZWQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE51bGxhbSB0ZW1w +b3IgaXBzdW0uIFNlZAogbW9sZXN0aWUgdGVsbHVzLiBQaGFzZWxsdXMgbGlndWxhLiBJbiB2 +ZWhpY3VsYSB1bHRyaWNlcwogbmlzaS4gU3VzcGVuZGlzc2UgZmVsaXMgYXVndWUsIHBlbGxl +bnRlc3F1ZSBhdCwgZGljdHVtIHZpdmVycmEsCi0tIAoxLjUuNS4xLjU0MC5nNTc3ODAKCg== diff --git a/t/t5100/nul-plain b/t/t5100/nul-plain Binary files differnew file mode 100644 index 0000000000..3d40691787 --- /dev/null +++ b/t/t5100/nul-plain diff --git a/t/t5100/patch0001 b/t/t5100/patch0001 new file mode 100644 index 0000000000..8ce155167d --- /dev/null +++ b/t/t5100/patch0001 @@ -0,0 +1,14 @@ +--- + foo | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/foo b/foo +index 9123cdc..918dcf8 100644 +--- a/foo ++++ b/foo +@@ -1 +1 @@ +-Fri Jun 9 00:44:04 PDT 2006 ++Fri Jun 9 00:44:13 PDT 2006 +-- +1.4.0.g6f2b + diff --git a/t/t5100/patch0002 b/t/t5100/patch0002 new file mode 100644 index 0000000000..8ce155167d --- /dev/null +++ b/t/t5100/patch0002 @@ -0,0 +1,14 @@ +--- + foo | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/foo b/foo +index 9123cdc..918dcf8 100644 +--- a/foo ++++ b/foo +@@ -1 +1 @@ +-Fri Jun 9 00:44:04 PDT 2006 ++Fri Jun 9 00:44:13 PDT 2006 +-- +1.4.0.g6f2b + diff --git a/t/t5100/patch0003 b/t/t5100/patch0003 new file mode 100644 index 0000000000..8ce155167d --- /dev/null +++ b/t/t5100/patch0003 @@ -0,0 +1,14 @@ +--- + foo | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/foo b/foo +index 9123cdc..918dcf8 100644 +--- a/foo ++++ b/foo +@@ -1 +1 @@ +-Fri Jun 9 00:44:04 PDT 2006 ++Fri Jun 9 00:44:13 PDT 2006 +-- +1.4.0.g6f2b + diff --git a/t/t5100/patch0004 b/t/t5100/patch0004 new file mode 100644 index 0000000000..196458e44e --- /dev/null +++ b/t/t5100/patch0004 @@ -0,0 +1,93 @@ +diff --git a/connect.c b/connect.c +--- a/connect.c ++++ b/connect.c +@@ -96,42 +96,57 @@ static enum protocol get_protocol(const + die("I don't handle protocol '%s'", name); + } + +-static void lookup_host(const char *host, struct sockaddr *in) +-{ +- struct addrinfo *res; +- int ret; +- +- ret = getaddrinfo(host, NULL, NULL, &res); +- if (ret) +- die("Unable to look up %s (%s)", host, gai_strerror(ret)); +- *in = *res->ai_addr; +- freeaddrinfo(res); +-} ++#define STR_(s) # s ++#define STR(s) STR_(s) + + static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path) + { +- struct sockaddr addr; +- int port = DEFAULT_GIT_PORT, sockfd; +- char *colon; +- +- colon = strchr(host, ':'); +- if (colon) { +- char *end; +- unsigned long n = strtoul(colon+1, &end, 0); +- if (colon[1] && !*end) { +- *colon = 0; +- port = n; ++ int sockfd = -1; ++ char *colon, *end; ++ char *port = STR(DEFAULT_GIT_PORT); ++ struct addrinfo hints, *ai0, *ai; ++ int gai; ++ ++ if (host[0] == '[') { ++ end = strchr(host + 1, ']'); ++ if (end) { ++ *end = 0; ++ end++; ++ host++; ++ } else ++ end = host; ++ } else ++ end = host; ++ colon = strchr(end, ':'); ++ ++ if (colon) ++ port = colon + 1; ++ ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_socktype = SOCK_STREAM; ++ hints.ai_protocol = IPPROTO_TCP; ++ ++ gai = getaddrinfo(host, port, &hints, &ai); ++ if (gai) ++ die("Unable to look up %s (%s)", host, gai_strerror(gai)); ++ ++ for (ai0 = ai; ai; ai = ai->ai_next) { ++ sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); ++ if (sockfd < 0) ++ continue; ++ if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) { ++ close(sockfd); ++ sockfd = -1; ++ continue; + } ++ break; + } + +- lookup_host(host, &addr); +- ((struct sockaddr_in *)&addr)->sin_port = htons(port); ++ freeaddrinfo(ai0); + +- sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_IP); + if (sockfd < 0) + die("unable to create socket (%s)", strerror(errno)); +- if (connect(sockfd, (void *)&addr, sizeof(addr)) < 0) +- die("unable to connect (%s)", strerror(errno)); ++ + fd[0] = sockfd; + fd[1] = sockfd; + packet_write(sockfd, "%s %s\n", prog, path); + +-- +YOSHIFUJI Hideaki @ USAGI Project <yoshfuji@linux-ipv6.org> +GPG-FP : 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA + diff --git a/t/t5100/patch0005 b/t/t5100/patch0005 new file mode 100644 index 0000000000..7d24b24af8 --- /dev/null +++ b/t/t5100/patch0005 @@ -0,0 +1,69 @@ +--- + + Documentation/git-cvsimport-script.txt | 9 ++++++++- + git-cvsimport-script | 4 ++-- + 2 files changed, 10 insertions(+), 3 deletions(-) + +50452f9c0c2df1f04d83a26266ba704b13861632 +diff --git a/Documentation/git-cvsimport-script.txt b/Documentation/git-cvsimport-script.txt +--- a/Documentation/git-cvsimport-script.txt ++++ b/Documentation/git-cvsimport-script.txt +@@ -29,6 +29,10 @@ OPTIONS + currently, only the :local:, :ext: and :pserver: access methods + are supported. + ++-C <target-dir>:: ++ The GIT repository to import to. If the directory doesn't ++ exist, it will be created. Default is the current directory. ++ + -i:: + Import-only: don't perform a checkout after importing. This option + ensures the working directory and cache remain untouched and will +@@ -44,7 +48,7 @@ OPTIONS + + -p <options-for-cvsps>:: + Additional options for cvsps. +- The options '-x' and '-A' are implicit and should not be used here. ++ The options '-u' and '-A' are implicit and should not be used here. + + If you need to pass multiple options, separate them with a comma. + +@@ -57,6 +61,9 @@ OPTIONS + -h:: + Print a short usage message and exit. + ++-z <fuzz>:: ++ Pass the timestamp fuzz factor to cvsps. ++ + OUTPUT + ------ + If '-v' is specified, the script reports what it is doing. +diff --git a/git-cvsimport-script b/git-cvsimport-script +--- a/git-cvsimport-script ++++ b/git-cvsimport-script +@@ -190,7 +190,7 @@ sub conn { + $self->{'socketo'}->write("Root $repo\n"); + + # Trial and error says that this probably is the minimum set +- $self->{'socketo'}->write("Valid-responses ok error Valid-requests Mode M Mbinary E F Checked-in Created Updated Merged Removed\n"); ++ $self->{'socketo'}->write("Valid-responses ok error Valid-requests Mode M Mbinary E Checked-in Created Updated Merged Removed\n"); + + $self->{'socketo'}->write("valid-requests\n"); + $self->{'socketo'}->flush(); +@@ -691,7 +691,7 @@ while(<CVS>) { + unlink($tmpname); + my $mode = pmode($cvs->{'mode'}); + push(@new,[$mode, $sha, $fn]); # may be resurrected! +- } elsif($state == 9 and /^\s+(\S+):\d(?:\.\d+)+->(\d(?:\.\d+)+)\(DEAD\)\s*$/) { ++ } elsif($state == 9 and /^\s+(\S+):\d+(?:\.\d+)+->(\d+(?:\.\d+)+)\(DEAD\)\s*$/) { + my $fn = $1; + $fn =~ s#^/+##; + push(@old,$fn); + +-- +David Kågedal +- +To unsubscribe from this list: send the line "unsubscribe git" in +the body of a message to majordomo@vger.kernel.org +More majordomo info at http://vger.kernel.org/majordomo-info.html + diff --git a/t/t5100/patch0006 b/t/t5100/patch0006 new file mode 100644 index 0000000000..8ce155167d --- /dev/null +++ b/t/t5100/patch0006 @@ -0,0 +1,14 @@ +--- + foo | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/foo b/foo +index 9123cdc..918dcf8 100644 +--- a/foo ++++ b/foo +@@ -1 +1 @@ +-Fri Jun 9 00:44:04 PDT 2006 ++Fri Jun 9 00:44:13 PDT 2006 +-- +1.4.0.g6f2b + diff --git a/t/t5100/patch0007 b/t/t5100/patch0007 new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/t/t5100/patch0007 diff --git a/t/t5100/patch0008 b/t/t5100/patch0008 new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/t/t5100/patch0008 diff --git a/t/t5100/patch0009 b/t/t5100/patch0009 new file mode 100644 index 0000000000..65615c34af --- /dev/null +++ b/t/t5100/patch0009 @@ -0,0 +1,13 @@ +diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt +index b426a14..97756ec 100644 +--- a/Documentation/diff-format.txt ++++ b/Documentation/diff-format.txt +@@ -81,7 +81,7 @@ The "diff" formatting options can be customized via the + environment variable 'GIT_DIFF_OPTS'. For example, if you + prefer context diff: + +- GIT_DIFF_OPTS=-c git-diff-index -p $(cat .git/HEAD) ++ GIT_DIFF_OPTS=-c git-diff-index -p HEAD + + + 2. When the environment variable 'GIT_EXTERNAL_DIFF' is set, the diff --git a/t/t5100/patch0010 b/t/t5100/patch0010 new file mode 100644 index 0000000000..f055481d56 --- /dev/null +++ b/t/t5100/patch0010 @@ -0,0 +1,20 @@ +--- + builtin-mailinfo.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c +index 962aa34..2d1520f 100644 +--- a/builtin-mailinfo.c ++++ b/builtin-mailinfo.c +@@ -334,7 +334,7 @@ static int check_header(char *line, unsigned linesize, char **hdr_data, int over + return 1; + if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) { + for (i = 0; header[i]; i++) { +- if (!memcmp("Subject: ", header[i], 9)) { ++ if (!memcmp("Subject", header[i], 7)) { + if (! handle_header(line, hdr_data[i], 0)) { + return 1; + } +-- +1.5.6.2.455.g1efb2 + diff --git a/t/t5100/patch0011 b/t/t5100/patch0011 new file mode 100644 index 0000000000..8841d3c139 --- /dev/null +++ b/t/t5100/patch0011 @@ -0,0 +1,22 @@ +--- + builtin-mailinfo.c | 4 ++-- + +diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c +index 3e5fe51..aabfe5c 100644 +--- a/builtin-mailinfo.c ++++ b/builtin-mailinfo.c +@@ -758,8 +758,8 @@ static void handle_body(void) + /* process any boundary lines */ + if (*content_top && is_multipart_boundary(&line)) { + /* flush any leftover */ +- if (line.len) +- handle_filter(&line); ++ if (prev.len) ++ handle_filter(&prev); + + if (!handle_boundary()) + goto handle_body_out; +-- +1.6.0.rc2 + + diff --git a/t/t5100/sample.mbox b/t/t5100/sample.mbox new file mode 100644 index 0000000000..d7ca79b1fc --- /dev/null +++ b/t/t5100/sample.mbox @@ -0,0 +1,502 @@ + + + +From nobody Mon Sep 17 00:00:00 2001 +From: A U Thor <a.u.thor@example.com> +Date: Fri, 9 Jun 2006 00:44:16 -0700 +Subject: [PATCH] a commit. + +Here is a patch from A U Thor. + +--- + foo | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/foo b/foo +index 9123cdc..918dcf8 100644 +--- a/foo ++++ b/foo +@@ -1 +1 @@ +-Fri Jun 9 00:44:04 PDT 2006 ++Fri Jun 9 00:44:13 PDT 2006 +-- +1.4.0.g6f2b + +From nobody Mon Sep 17 00:00:00 2001 +From: A U Thor <a.u.thor@example.com> +Date: Fri, 9 Jun 2006 00:44:16 -0700 +Subject: [PATCH] another patch + +Here is a patch from A U Thor. This addresses the issue raised in the +message: + +From: Nit Picker <nit.picker@example.net> +Subject: foo is too old +Message-Id: <nitpicker.12121212@example.net> + +Hopefully this would fix the problem stated there. + + +I have included an extra blank line above, but it does not have to be +stripped away here, along with the +whitespaces at the end of the above line. They are expected to be squashed +when the message is made into a commit log by stripspace, +Also, there are three blank lines after this paragraph, +two truly blank and another full of spaces in between. + + + +Hope this helps. + +--- + foo | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/foo b/foo +index 9123cdc..918dcf8 100644 +--- a/foo ++++ b/foo +@@ -1 +1 @@ +-Fri Jun 9 00:44:04 PDT 2006 ++Fri Jun 9 00:44:13 PDT 2006 +-- +1.4.0.g6f2b + +From nobody Mon Sep 17 00:00:00 2001 +From: Junio C Hamano <junio@kernel.org> +Date: Fri, 9 Jun 2006 00:44:16 -0700 +Subject: re: [PATCH] another patch + +From: A U Thor <a.u.thor@example.com> +Subject: [PATCH] third patch + +Here is a patch from A U Thor. This addresses the issue raised in the +message: + +From: Nit Picker <nit.picker@example.net> +Subject: foo is too old +Message-Id: <nitpicker.12121212@example.net> + +Hopefully this would fix the problem stated there. + +--- + foo | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/foo b/foo +index 9123cdc..918dcf8 100644 +--- a/foo ++++ b/foo +@@ -1 +1 @@ +-Fri Jun 9 00:44:04 PDT 2006 ++Fri Jun 9 00:44:13 PDT 2006 +-- +1.4.0.g6f2b + +From nobody Sat Aug 27 23:07:49 2005 +Path: news.gmane.org!not-for-mail +Message-ID: <20050721.091036.01119516.yoshfuji@linux-ipv6.org> +From: YOSHIFUJI Hideaki / =?iso-2022-jp?B?GyRCNUhGIzFRTEAbKEI=?= + <yoshfuji@linux-ipv6.org> +Newsgroups: gmane.comp.version-control.git +Subject: [PATCH 1/2] GIT: Try all addresses for given remote name +Date: Thu, 21 Jul 2005 09:10:36 -0400 (EDT) +Lines: 99 +Organization: USAGI/WIDE Project +Approved: news@gmane.org +NNTP-Posting-Host: main.gmane.org +Mime-Version: 1.0 +Content-Type: Text/Plain; charset=us-ascii +Content-Transfer-Encoding: 7bit +X-Trace: sea.gmane.org 1121951434 29350 80.91.229.2 (21 Jul 2005 13:10:34 GMT) +X-Complaints-To: usenet@sea.gmane.org +NNTP-Posting-Date: Thu, 21 Jul 2005 13:10:34 +0000 (UTC) + +Hello. + +Try all addresses for given remote name until it succeeds. +Also supports IPv6. + +Signed-of-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> + +diff --git a/connect.c b/connect.c +--- a/connect.c ++++ b/connect.c +@@ -96,42 +96,57 @@ static enum protocol get_protocol(const + die("I don't handle protocol '%s'", name); + } + +-static void lookup_host(const char *host, struct sockaddr *in) +-{ +- struct addrinfo *res; +- int ret; +- +- ret = getaddrinfo(host, NULL, NULL, &res); +- if (ret) +- die("Unable to look up %s (%s)", host, gai_strerror(ret)); +- *in = *res->ai_addr; +- freeaddrinfo(res); +-} ++#define STR_(s) # s ++#define STR(s) STR_(s) + + static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path) + { +- struct sockaddr addr; +- int port = DEFAULT_GIT_PORT, sockfd; +- char *colon; +- +- colon = strchr(host, ':'); +- if (colon) { +- char *end; +- unsigned long n = strtoul(colon+1, &end, 0); +- if (colon[1] && !*end) { +- *colon = 0; +- port = n; ++ int sockfd = -1; ++ char *colon, *end; ++ char *port = STR(DEFAULT_GIT_PORT); ++ struct addrinfo hints, *ai0, *ai; ++ int gai; ++ ++ if (host[0] == '[') { ++ end = strchr(host + 1, ']'); ++ if (end) { ++ *end = 0; ++ end++; ++ host++; ++ } else ++ end = host; ++ } else ++ end = host; ++ colon = strchr(end, ':'); ++ ++ if (colon) ++ port = colon + 1; ++ ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_socktype = SOCK_STREAM; ++ hints.ai_protocol = IPPROTO_TCP; ++ ++ gai = getaddrinfo(host, port, &hints, &ai); ++ if (gai) ++ die("Unable to look up %s (%s)", host, gai_strerror(gai)); ++ ++ for (ai0 = ai; ai; ai = ai->ai_next) { ++ sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); ++ if (sockfd < 0) ++ continue; ++ if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) { ++ close(sockfd); ++ sockfd = -1; ++ continue; + } ++ break; + } + +- lookup_host(host, &addr); +- ((struct sockaddr_in *)&addr)->sin_port = htons(port); ++ freeaddrinfo(ai0); + +- sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_IP); + if (sockfd < 0) + die("unable to create socket (%s)", strerror(errno)); +- if (connect(sockfd, (void *)&addr, sizeof(addr)) < 0) +- die("unable to connect (%s)", strerror(errno)); ++ + fd[0] = sockfd; + fd[1] = sockfd; + packet_write(sockfd, "%s %s\n", prog, path); + +-- +YOSHIFUJI Hideaki @ USAGI Project <yoshfuji@linux-ipv6.org> +GPG-FP : 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA + +From nobody Sat Aug 27 23:07:49 2005 +Path: news.gmane.org!not-for-mail +Message-ID: <u5tacjjdpxq.fsf@lysator.liu.se> +From: =?iso-8859-1?Q?David_K=E5gedal?= <davidk@lysator.liu.se> +Newsgroups: gmane.comp.version-control.git +Subject: [PATCH] Fixed two bugs in git-cvsimport-script. +Date: Mon, 15 Aug 2005 20:18:25 +0200 +Lines: 83 +Approved: news@gmane.org +NNTP-Posting-Host: main.gmane.org +Mime-Version: 1.0 +Content-Type: text/plain; charset=iso-8859-1 +Content-Transfer-Encoding: QUOTED-PRINTABLE +X-Trace: sea.gmane.org 1124130247 31839 80.91.229.2 (15 Aug 2005 18:24:07 GMT) +X-Complaints-To: usenet@sea.gmane.org +NNTP-Posting-Date: Mon, 15 Aug 2005 18:24:07 +0000 (UTC) +Cc: "Junio C. Hamano" <junkio@cox.net> +Original-X-From: git-owner@vger.kernel.org Mon Aug 15 20:24:05 2005 + +The git-cvsimport-script had a copule of small bugs that prevented me +from importing a big CVS repository. + +The first was that it didn't handle removed files with a multi-digit +primary revision number. + +The second was that it was asking the CVS server for "F" messages, +although they were not handled. + +I also updated the documentation for that script to correspond to +actual flags. + +Signed-off-by: David K=E5gedal <davidk@lysator.liu.se> +--- + + Documentation/git-cvsimport-script.txt | 9 ++++++++- + git-cvsimport-script | 4 ++-- + 2 files changed, 10 insertions(+), 3 deletions(-) + +50452f9c0c2df1f04d83a26266ba704b13861632 +diff --git a/Documentation/git-cvsimport-script.txt b/Documentation/git= +-cvsimport-script.txt +--- a/Documentation/git-cvsimport-script.txt ++++ b/Documentation/git-cvsimport-script.txt +@@ -29,6 +29,10 @@ OPTIONS + currently, only the :local:, :ext: and :pserver: access methods=20 + are supported. +=20 ++-C <target-dir>:: ++ The GIT repository to import to. If the directory doesn't ++ exist, it will be created. Default is the current directory. ++ + -i:: + Import-only: don't perform a checkout after importing. This option + ensures the working directory and cache remain untouched and will +@@ -44,7 +48,7 @@ OPTIONS +=20 + -p <options-for-cvsps>:: + Additional options for cvsps. +- The options '-x' and '-A' are implicit and should not be used here. ++ The options '-u' and '-A' are implicit and should not be used here. +=20 + If you need to pass multiple options, separate them with a comma. +=20 +@@ -57,6 +61,9 @@ OPTIONS + -h:: + Print a short usage message and exit. +=20 ++-z <fuzz>:: ++ Pass the timestamp fuzz factor to cvsps. ++ + OUTPUT + ------ + If '-v' is specified, the script reports what it is doing. +diff --git a/git-cvsimport-script b/git-cvsimport-script +--- a/git-cvsimport-script ++++ b/git-cvsimport-script +@@ -190,7 +190,7 @@ sub conn { + $self->{'socketo'}->write("Root $repo\n"); +=20 + # Trial and error says that this probably is the minimum set +- $self->{'socketo'}->write("Valid-responses ok error Valid-requests Mo= +de M Mbinary E F Checked-in Created Updated Merged Removed\n"); ++ $self->{'socketo'}->write("Valid-responses ok error Valid-requests Mo= +de M Mbinary E Checked-in Created Updated Merged Removed\n"); +=20 + $self->{'socketo'}->write("valid-requests\n"); + $self->{'socketo'}->flush(); +@@ -691,7 +691,7 @@ while(<CVS>) { + unlink($tmpname); + my $mode =3D pmode($cvs->{'mode'}); + push(@new,[$mode, $sha, $fn]); # may be resurrected! +- } elsif($state =3D=3D 9 and /^\s+(\S+):\d(?:\.\d+)+->(\d(?:\.\d+)+)\(= +DEAD\)\s*$/) { ++ } elsif($state =3D=3D 9 and /^\s+(\S+):\d+(?:\.\d+)+->(\d+(?:\.\d+)+)= +\(DEAD\)\s*$/) { + my $fn =3D $1; + $fn =3D~ s#^/+##; + push(@old,$fn); + +--=20 +David K=E5gedal +- +To unsubscribe from this list: send the line "unsubscribe git" in +the body of a message to majordomo@vger.kernel.org +More majordomo info at http://vger.kernel.org/majordomo-info.html + +From nobody Mon Sep 17 00:00:00 2001 +From: A U Thor <a.u.thor@example.com> +References: <Pine.LNX.4.640.0001@woody.linux-foundation.org> + <Pine.LNX.4.640.0002@woody.linux-foundation.org> + <Pine.LNX.4.640.0003@woody.linux-foundation.org> + <Pine.LNX.4.640.0004@woody.linux-foundation.org> + <Pine.LNX.4.640.0005@woody.linux-foundation.org> + <Pine.LNX.4.640.0006@woody.linux-foundation.org> + <Pine.LNX.4.640.0007@woody.linux-foundation.org> + <Pine.LNX.4.640.0008@woody.linux-foundation.org> + <Pine.LNX.4.640.0009@woody.linux-foundation.org> + <Pine.LNX.4.640.0010@woody.linux-foundation.org> + <Pine.LNX.4.640.0011@woody.linux-foundation.org> + <Pine.LNX.4.640.0012@woody.linux-foundation.org> + <Pine.LNX.4.640.0013@woody.linux-foundation.org> + <Pine.LNX.4.640.0014@woody.linux-foundation.org> + <Pine.LNX.4.640.0015@woody.linux-foundation.org> + <Pine.LNX.4.640.0016@woody.linux-foundation.org> + <Pine.LNX.4.640.0017@woody.linux-foundation.org> + <Pine.LNX.4.640.0018@woody.linux-foundation.org> + <Pine.LNX.4.640.0019@woody.linux-foundation.org> + <Pine.LNX.4.640.0020@woody.linux-foundation.org> + <Pine.LNX.4.640.0021@woody.linux-foundation.org> + <Pine.LNX.4.640.0022@woody.linux-foundation.org> + <Pine.LNX.4.640.0023@woody.linux-foundation.org> + <Pine.LNX.4.640.0024@woody.linux-foundation.org> + <Pine.LNX.4.640.0025@woody.linux-foundation.org> + <Pine.LNX.4.640.0026@woody.linux-foundation.org> + <Pine.LNX.4.640.0027@woody.linux-foundation.org> + <Pine.LNX.4.640.0028@woody.linux-foundation.org> + <Pine.LNX.4.640.0029@woody.linux-foundation.org> + <Pine.LNX.4.640.0030@woody.linux-foundation.org> + <Pine.LNX.4.640.0031@woody.linux-foundation.org> + <Pine.LNX.4.640.0032@woody.linux-foundation.org> + <Pine.LNX.4.640.0033@woody.linux-foundation.org> + <Pine.LNX.4.640.0034@woody.linux-foundation.org> + <Pine.LNX.4.640.0035@woody.linux-foundation.org> + <Pine.LNX.4.640.0036@woody.linux-foundation.org> + <Pine.LNX.4.640.0037@woody.linux-foundation.org> + <Pine.LNX.4.640.0038@woody.linux-foundation.org> + <Pine.LNX.4.640.0039@woody.linux-foundation.org> + <Pine.LNX.4.640.0040@woody.linux-foundation.org> + <Pine.LNX.4.640.0041@woody.linux-foundation.org> + <Pine.LNX.4.640.0042@woody.linux-foundation.org> + <Pine.LNX.4.640.0043@woody.linux-foundation.org> + <Pine.LNX.4.640.0044@woody.linux-foundation.org> + <Pine.LNX.4.640.0045@woody.linux-foundation.org> + <Pine.LNX.4.640.0046@woody.linux-foundation.org> + <Pine.LNX.4.640.0047@woody.linux-foundation.org> + <Pine.LNX.4.640.0048@woody.linux-foundation.org> + <Pine.LNX.4.640.0049@woody.linux-foundation.org> + <Pine.LNX.4.640.0050@woody.linux-foundation.org> +Date: Fri, 9 Jun 2006 00:44:16 -0700 +Subject: [PATCH] a commit. + +Here is a patch from A U Thor. + +--- + foo | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/foo b/foo +index 9123cdc..918dcf8 100644 +--- a/foo ++++ b/foo +@@ -1 +1 @@ +-Fri Jun 9 00:44:04 PDT 2006 ++Fri Jun 9 00:44:13 PDT 2006 +-- +1.4.0.g6f2b + +From nobody Mon Sep 17 00:00:00 2001 +From: A U Thor <a.u.thor@example.com> +Date: Fri, 9 Jun 2006 00:44:16 -0700 +Subject: [PATCH] another patch + +Here is an empty patch from A U Thor. + +From nobody Mon Sep 17 00:00:00 2001 +From: Junio C Hamano <junio@kernel.org> +Date: Fri, 9 Jun 2006 00:44:16 -0700 +Subject: re: [PATCH] another patch + +From: A U Thor <a.u.thor@example.com> +Subject: [PATCH] another patch +>Here is an empty patch from A U Thor. + +Hey you forgot the patch! + +From nobody Mon Sep 17 00:00:00 2001 +From: A U Thor <a.u.thor@example.com> +Date: Mon, 17 Sep 2001 00:00:00 +0900 +Mime-Version: 1.0 +Content-Type: Text/Plain; charset=us-ascii +Content-Transfer-Encoding: Quoted-Printable + +=0A=0AFrom: F U Bar <f.u.bar@example.com> +Subject: [PATCH] updates=0A=0AThis is to fix diff-format documentation. + +diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt +index b426a14..97756ec 100644 +--- a/Documentation/diff-format.txt ++++ b/Documentation/diff-format.txt +@@ -81,7 +81,7 @@ The "diff" formatting options can be customized via the + environment variable 'GIT_DIFF_OPTS'. For example, if you + prefer context diff: +=20 +- GIT_DIFF_OPTS=3D-c git-diff-index -p $(cat .git/HEAD) ++ GIT_DIFF_OPTS=3D-c git-diff-index -p HEAD +=20 +=20 + 2. When the environment variable 'GIT_EXTERNAL_DIFF' is set, the +From b9704a518e21158433baa2cc2d591fea687967f6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Lukas=20Sandstr=C3=B6m?= <lukass@etek.chalmers.se> +Date: Thu, 10 Jul 2008 23:41:33 +0200 +Subject: Re: discussion that lead to this patch +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[PATCH] git-mailinfo: Fix getting the subject from the body + +"Subject: " isn't in the static array "header", and thus +memcmp("Subject: ", header[i], 7) will never match. + +Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se> +Signed-off-by: Junio C Hamano <gitster@pobox.com> +--- + builtin-mailinfo.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c +index 962aa34..2d1520f 100644 +--- a/builtin-mailinfo.c ++++ b/builtin-mailinfo.c +@@ -334,7 +334,7 @@ static int check_header(char *line, unsigned linesize, char **hdr_data, int over + return 1; + if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) { + for (i = 0; header[i]; i++) { +- if (!memcmp("Subject: ", header[i], 9)) { ++ if (!memcmp("Subject", header[i], 7)) { + if (! handle_header(line, hdr_data[i], 0)) { + return 1; + } +-- +1.5.6.2.455.g1efb2 + +From nobody Fri Aug 8 22:24:03 2008 +Date: Fri, 8 Aug 2008 13:08:37 +0200 (CEST) +From: A U Thor <a.u.thor@example.com> +Subject: [PATCH 3/3 v2] Xyzzy +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="=-=-=" + +--=-=-= +Content-Type: text/plain; charset=iso-8859-15 +Content-Transfer-Encoding: quoted-printable + +Here comes a commit log message, and +its second line is here. +--- + builtin-mailinfo.c | 4 ++-- + +diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c +index 3e5fe51..aabfe5c 100644 +--- a/builtin-mailinfo.c ++++ b/builtin-mailinfo.c +@@ -758,8 +758,8 @@ static void handle_body(void) + /* process any boundary lines */ + if (*content_top && is_multipart_boundary(&line)) { + /* flush any leftover */ +- if (line.len) +- handle_filter(&line); ++ if (prev.len) ++ handle_filter(&prev); +=20 + if (!handle_boundary()) + goto handle_body_out; +--=20 +1.6.0.rc2 + +--=-=-=-- diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh new file mode 100755 index 0000000000..645583f9d7 --- /dev/null +++ b/t/t5300-pack-object.sh @@ -0,0 +1,372 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git-pack-object + +' +. ./test-lib.sh + +TRASH=`pwd` + +test_expect_success \ + 'setup' \ + 'rm -f .git/index* + for i in a b c + do + dd if=/dev/zero bs=4k count=1 | perl -pe "y/\\000/$i/" >$i && + git update-index --add $i || return 1 + done && + cat c >d && echo foo >>d && git update-index --add d && + tree=`git write-tree` && + commit=`git commit-tree $tree </dev/null` && { + echo $tree && + echo $commit && + git ls-tree $tree | sed -e "s/.* \\([0-9a-f]*\\) .*/\\1/" + } >obj-list && { + git diff-tree --root -p $commit && + while read object + do + t=`git cat-file -t $object` && + git cat-file $t $object || return 1 + done <obj-list + } >expect' + +test_expect_success \ + 'pack without delta' \ + 'packname_1=$(git pack-objects --window=0 test-1 <obj-list)' + +rm -fr .git2 +mkdir .git2 + +test_expect_success \ + 'unpack without delta' \ + "GIT_OBJECT_DIRECTORY=.git2/objects && + export GIT_OBJECT_DIRECTORY && + git init && + git unpack-objects -n <test-1-${packname_1}.pack && + git unpack-objects <test-1-${packname_1}.pack" + +unset GIT_OBJECT_DIRECTORY +cd "$TRASH/.git2" + +test_expect_success \ + 'check unpack without delta' \ + '(cd ../.git && find objects -type f -print) | + while read path + do + cmp $path ../.git/$path || { + echo $path differs. + return 1 + } + done' +cd "$TRASH" + +test_expect_success \ + 'pack with REF_DELTA' \ + 'pwd && + packname_2=$(git pack-objects test-2 <obj-list)' + +rm -fr .git2 +mkdir .git2 + +test_expect_success \ + 'unpack with REF_DELTA' \ + 'GIT_OBJECT_DIRECTORY=.git2/objects && + export GIT_OBJECT_DIRECTORY && + git init && + git unpack-objects -n <test-2-${packname_2}.pack && + git unpack-objects <test-2-${packname_2}.pack' + +unset GIT_OBJECT_DIRECTORY +cd "$TRASH/.git2" +test_expect_success \ + 'check unpack with REF_DELTA' \ + '(cd ../.git && find objects -type f -print) | + while read path + do + cmp $path ../.git/$path || { + echo $path differs. + return 1 + } + done' +cd "$TRASH" + +test_expect_success \ + 'pack with OFS_DELTA' \ + 'pwd && + packname_3=$(git pack-objects --delta-base-offset test-3 <obj-list)' + +rm -fr .git2 +mkdir .git2 + +test_expect_success \ + 'unpack with OFS_DELTA' \ + 'GIT_OBJECT_DIRECTORY=.git2/objects && + export GIT_OBJECT_DIRECTORY && + git init && + git unpack-objects -n <test-3-${packname_3}.pack && + git unpack-objects <test-3-${packname_3}.pack' + +unset GIT_OBJECT_DIRECTORY +cd "$TRASH/.git2" +test_expect_success \ + 'check unpack with OFS_DELTA' \ + '(cd ../.git && find objects -type f -print) | + while read path + do + cmp $path ../.git/$path || { + echo $path differs. + return 1 + } + done' +cd "$TRASH" + +test_expect_success 'compare delta flavors' ' + perl -e '\'' + defined($_ = -s $_) or die for @ARGV; + exit 1 if $ARGV[0] <= $ARGV[1]; + '\'' test-2-$packname_2.pack test-3-$packname_3.pack +' + +rm -fr .git2 +mkdir .git2 + +test_expect_success \ + 'use packed objects' \ + 'GIT_OBJECT_DIRECTORY=.git2/objects && + export GIT_OBJECT_DIRECTORY && + git init && + cp test-1-${packname_1}.pack test-1-${packname_1}.idx .git2/objects/pack && { + git diff-tree --root -p $commit && + while read object + do + t=`git cat-file -t $object` && + git cat-file $t $object || return 1 + done <obj-list + } >current && + diff expect current' + +test_expect_success \ + 'use packed deltified (REF_DELTA) objects' \ + 'GIT_OBJECT_DIRECTORY=.git2/objects && + export GIT_OBJECT_DIRECTORY && + rm -f .git2/objects/pack/test-* && + cp test-2-${packname_2}.pack test-2-${packname_2}.idx .git2/objects/pack && { + git diff-tree --root -p $commit && + while read object + do + t=`git cat-file -t $object` && + git cat-file $t $object || return 1 + done <obj-list + } >current && + diff expect current' + +test_expect_success \ + 'use packed deltified (OFS_DELTA) objects' \ + 'GIT_OBJECT_DIRECTORY=.git2/objects && + export GIT_OBJECT_DIRECTORY && + rm -f .git2/objects/pack/test-* && + cp test-3-${packname_3}.pack test-3-${packname_3}.idx .git2/objects/pack && { + git diff-tree --root -p $commit && + while read object + do + t=`git cat-file -t $object` && + git cat-file $t $object || return 1 + done <obj-list + } >current && + diff expect current' + +unset GIT_OBJECT_DIRECTORY + +test_expect_success \ + 'verify pack' \ + 'git verify-pack test-1-${packname_1}.idx \ + test-2-${packname_2}.idx \ + test-3-${packname_3}.idx' + +test_expect_success \ + 'verify-pack catches mismatched .idx and .pack files' \ + 'cat test-1-${packname_1}.idx >test-3.idx && + cat test-2-${packname_2}.pack >test-3.pack && + if git verify-pack test-3.idx + then false + else :; + fi' + +test_expect_success \ + 'verify-pack catches a corrupted pack signature' \ + 'cat test-1-${packname_1}.pack >test-3.pack && + dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=2 && + if git verify-pack test-3.idx + then false + else :; + fi' + +test_expect_success \ + 'verify-pack catches a corrupted pack version' \ + 'cat test-1-${packname_1}.pack >test-3.pack && + dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=7 && + if git verify-pack test-3.idx + then false + else :; + fi' + +test_expect_success \ + 'verify-pack catches a corrupted type/size of the 1st packed object data' \ + 'cat test-1-${packname_1}.pack >test-3.pack && + dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=12 && + if git verify-pack test-3.idx + then false + else :; + fi' + +test_expect_success \ + 'verify-pack catches a corrupted sum of the index file itself' \ + 'l=`wc -c <test-3.idx` && + l=`expr $l - 20` && + cat test-1-${packname_1}.pack >test-3.pack && + dd if=/dev/zero of=test-3.idx count=20 bs=1 conv=notrunc seek=$l && + if git verify-pack test-3.pack + then false + else :; + fi' + +test_expect_success \ + 'build pack index for an existing pack' \ + 'cat test-1-${packname_1}.pack >test-3.pack && + git-index-pack -o tmp.idx test-3.pack && + cmp tmp.idx test-1-${packname_1}.idx && + + git-index-pack test-3.pack && + cmp test-3.idx test-1-${packname_1}.idx && + + cat test-2-${packname_2}.pack >test-3.pack && + git-index-pack -o tmp.idx test-2-${packname_2}.pack && + cmp tmp.idx test-2-${packname_2}.idx && + + git-index-pack test-3.pack && + cmp test-3.idx test-2-${packname_2}.idx && + + cat test-3-${packname_3}.pack >test-3.pack && + git-index-pack -o tmp.idx test-3-${packname_3}.pack && + cmp tmp.idx test-3-${packname_3}.idx && + + git-index-pack test-3.pack && + cmp test-3.idx test-3-${packname_3}.idx && + + :' + +test_expect_success \ + 'fake a SHA1 hash collision' \ + 'test -f .git/objects/c8/2de19312b6c3695c0c18f70709a6c535682a67 && + cp -f .git/objects/9d/235ed07cd19811a6ceb342de82f190e49c9f68 \ + .git/objects/c8/2de19312b6c3695c0c18f70709a6c535682a67' + +test_expect_success \ + 'make sure index-pack detects the SHA1 collision' \ + 'test_must_fail git-index-pack -o bad.idx test-3.pack' + +test_expect_success \ + 'honor pack.packSizeLimit' \ + 'git config pack.packSizeLimit 200 && + packname_4=$(git pack-objects test-4 <obj-list) && + test 3 = $(ls test-4-*.pack | wc -l)' + +test_expect_success 'unpacking with --strict' ' + + git config --unset pack.packsizelimit && + for j in a b c d e f g + do + for i in 0 1 2 3 4 5 6 7 8 9 + do + o=$(echo $j$i | git hash-object -w --stdin) && + echo "100644 $o 0 $j$i" + done + done >LIST && + rm -f .git/index && + git update-index --index-info <LIST && + LIST=$(git write-tree) && + rm -f .git/index && + head -n 10 LIST | git update-index --index-info && + LI=$(git write-tree) && + rm -f .git/index && + tail -n 10 LIST | git update-index --index-info && + ST=$(git write-tree) && + PACK5=$( git rev-list --objects "$LIST" "$LI" "$ST" | \ + git pack-objects test-5 ) && + PACK6=$( ( + echo "$LIST" + echo "$LI" + echo "$ST" + ) | git pack-objects test-6 ) && + test_create_repo test-5 && + ( + cd test-5 && + git unpack-objects --strict <../test-5-$PACK5.pack && + git ls-tree -r $LIST && + git ls-tree -r $LI && + git ls-tree -r $ST + ) && + test_create_repo test-6 && + ( + # tree-only into empty repo -- many unreachables + cd test-6 && + test_must_fail git unpack-objects --strict <../test-6-$PACK6.pack + ) && + ( + # already populated -- no unreachables + cd test-5 && + git unpack-objects --strict <../test-6-$PACK6.pack + ) +' + +test_expect_success 'index-pack with --strict' ' + + for j in a b c d e f g + do + for i in 0 1 2 3 4 5 6 7 8 9 + do + o=$(echo $j$i | git hash-object -w --stdin) && + echo "100644 $o 0 $j$i" + done + done >LIST && + rm -f .git/index && + git update-index --index-info <LIST && + LIST=$(git write-tree) && + rm -f .git/index && + head -n 10 LIST | git update-index --index-info && + LI=$(git write-tree) && + rm -f .git/index && + tail -n 10 LIST | git update-index --index-info && + ST=$(git write-tree) && + PACK5=$( git rev-list --objects "$LIST" "$LI" "$ST" | \ + git pack-objects test-5 ) && + PACK6=$( ( + echo "$LIST" + echo "$LI" + echo "$ST" + ) | git pack-objects test-6 ) && + test_create_repo test-7 && + ( + cd test-7 && + git index-pack --strict --stdin <../test-5-$PACK5.pack && + git ls-tree -r $LIST && + git ls-tree -r $LI && + git ls-tree -r $ST + ) && + test_create_repo test-8 && + ( + # tree-only into empty repo -- many unreachables + cd test-8 && + test_must_fail git index-pack --strict --stdin <../test-6-$PACK6.pack + ) && + ( + # already populated -- no unreachables + cd test-7 && + git index-pack --strict --stdin <../test-6-$PACK6.pack + ) +' + +test_done diff --git a/t/t5301-sliding-window.sh b/t/t5301-sliding-window.sh new file mode 100755 index 0000000000..073ac0c6f9 --- /dev/null +++ b/t/t5301-sliding-window.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# +# Copyright (c) 2006 Shawn Pearce +# + +test_description='mmap sliding window tests' +. ./test-lib.sh + +test_expect_success \ + 'setup' \ + 'rm -f .git/index* + for i in a b c + do + echo $i >$i && + test-genrandom "$i" 32768 >>$i && + git update-index --add $i || return 1 + done && + echo d >d && cat c >>d && git update-index --add d && + tree=`git write-tree` && + commit1=`git commit-tree $tree </dev/null` && + git update-ref HEAD $commit1 && + git-repack -a -d && + test "`git count-objects`" = "0 objects, 0 kilobytes" && + pack1=`ls .git/objects/pack/*.pack` && + test -f "$pack1"' + +test_expect_success \ + 'verify-pack -v, defaults' \ + 'git verify-pack -v "$pack1"' + +test_expect_success \ + 'verify-pack -v, packedGitWindowSize == 1 page' \ + 'git config core.packedGitWindowSize 512 && + git verify-pack -v "$pack1"' + +test_expect_success \ + 'verify-pack -v, packedGit{WindowSize,Limit} == 1 page' \ + 'git config core.packedGitWindowSize 512 && + git config core.packedGitLimit 512 && + git verify-pack -v "$pack1"' + +test_expect_success \ + 'repack -a -d, packedGit{WindowSize,Limit} == 1 page' \ + 'git config core.packedGitWindowSize 512 && + git config core.packedGitLimit 512 && + commit2=`git commit-tree $tree -p $commit1 </dev/null` && + git update-ref HEAD $commit2 && + git-repack -a -d && + test "`git count-objects`" = "0 objects, 0 kilobytes" && + pack2=`ls .git/objects/pack/*.pack` && + test -f "$pack2" + test "$pack1" \!= "$pack2"' + +test_expect_success \ + 'verify-pack -v, defaults' \ + 'git config --unset core.packedGitWindowSize && + git config --unset core.packedGitLimit && + git verify-pack -v "$pack2"' + +test_done diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh new file mode 100755 index 0000000000..0639772ac4 --- /dev/null +++ b/t/t5302-pack-index.sh @@ -0,0 +1,180 @@ +#!/bin/sh +# +# Copyright (c) 2007 Nicolas Pitre +# + +test_description='pack index with 64-bit offsets and object CRC' +. ./test-lib.sh + +test_expect_success \ + 'setup' \ + 'rm -rf .git + git init && + i=1 && + while test $i -le 100 + do + i=`printf '%03i' $i` + echo $i >file_$i && + test-genrandom "$i" 8192 >>file_$i && + git update-index --add file_$i && + i=`expr $i + 1` || return 1 + done && + { echo 101 && test-genrandom 100 8192; } >file_101 && + git update-index --add file_101 && + tree=`git write-tree` && + commit=`git commit-tree $tree </dev/null` && { + echo $tree && + git ls-tree $tree | sed -e "s/.* \\([0-9a-f]*\\) .*/\\1/" + } >obj-list && + git update-ref HEAD $commit' + +test_expect_success \ + 'pack-objects with index version 1' \ + 'pack1=$(git pack-objects --index-version=1 test-1 <obj-list) && + git verify-pack -v "test-1-${pack1}.pack"' + +test_expect_success \ + 'pack-objects with index version 2' \ + 'pack2=$(git pack-objects --index-version=2 test-2 <obj-list) && + git verify-pack -v "test-2-${pack2}.pack"' + +test_expect_success \ + 'both packs should be identical' \ + 'cmp "test-1-${pack1}.pack" "test-2-${pack2}.pack"' + +test_expect_success \ + 'index v1 and index v2 should be different' \ + '! cmp "test-1-${pack1}.idx" "test-2-${pack2}.idx"' + +test_expect_success \ + 'index-pack with index version 1' \ + 'git-index-pack --index-version=1 -o 1.idx "test-1-${pack1}.pack"' + +test_expect_success \ + 'index-pack with index version 2' \ + 'git-index-pack --index-version=2 -o 2.idx "test-1-${pack1}.pack"' + +test_expect_success \ + 'index-pack results should match pack-objects ones' \ + 'cmp "test-1-${pack1}.idx" "1.idx" && + cmp "test-2-${pack2}.idx" "2.idx"' + +test_expect_success \ + 'index v2: force some 64-bit offsets with pack-objects' \ + 'pack3=$(git pack-objects --index-version=2,0x40000 test-3 <obj-list)' + +have_64bits= +if msg=$(git verify-pack -v "test-3-${pack3}.pack" 2>&1) || + ! (echo "$msg" | grep "pack too large .* off_t") +then + have_64bits=t +else + say "skipping tests concerning 64-bit offsets" +fi + +test "$have_64bits" && +test_expect_success \ + 'index v2: verify a pack with some 64-bit offsets' \ + 'git verify-pack -v "test-3-${pack3}.pack"' + +test "$have_64bits" && +test_expect_success \ + '64-bit offsets: should be different from previous index v2 results' \ + '! cmp "test-2-${pack2}.idx" "test-3-${pack3}.idx"' + +test "$have_64bits" && +test_expect_success \ + 'index v2: force some 64-bit offsets with index-pack' \ + 'git-index-pack --index-version=2,0x40000 -o 3.idx "test-1-${pack1}.pack"' + +test "$have_64bits" && +test_expect_success \ + '64-bit offsets: index-pack result should match pack-objects one' \ + 'cmp "test-3-${pack3}.idx" "3.idx"' + +test_expect_success \ + '[index v1] 1) stream pack to repository' \ + 'git-index-pack --index-version=1 --stdin < "test-1-${pack1}.pack" && + git prune-packed && + git count-objects | ( read nr rest && test "$nr" -eq 1 ) && + cmp "test-1-${pack1}.pack" ".git/objects/pack/pack-${pack1}.pack" && + cmp "test-1-${pack1}.idx" ".git/objects/pack/pack-${pack1}.idx"' + +test_expect_success \ + '[index v1] 2) create a stealth corruption in a delta base reference' \ + '# this test assumes a delta smaller than 16 bytes at the end of the pack + git show-index <1.idx | sort -n | sed -ne \$p | ( + read delta_offs delta_sha1 && + git cat-file blob "$delta_sha1" > blob_1 && + chmod +w ".git/objects/pack/pack-${pack1}.pack" && + dd of=".git/objects/pack/pack-${pack1}.pack" seek=$(($delta_offs + 1)) \ + if=".git/objects/pack/pack-${pack1}.idx" skip=$((256 * 4 + 4)) \ + bs=1 count=20 conv=notrunc && + git cat-file blob "$delta_sha1" > blob_2 )' + +test_expect_success \ + '[index v1] 3) corrupted delta happily returned wrong data' \ + '! cmp blob_1 blob_2' + +test_expect_success \ + '[index v1] 4) confirm that the pack is actually corrupted' \ + 'test_must_fail git fsck --full $commit' + +test_expect_success \ + '[index v1] 5) pack-objects happily reuses corrupted data' \ + 'pack4=$(git pack-objects test-4 <obj-list) && + test -f "test-4-${pack1}.pack"' + +test_expect_success \ + '[index v1] 6) newly created pack is BAD !' \ + 'test_must_fail git verify-pack -v "test-4-${pack1}.pack"' + +test_expect_success \ + '[index v2] 1) stream pack to repository' \ + 'rm -f .git/objects/pack/* && + git-index-pack --index-version=2 --stdin < "test-1-${pack1}.pack" && + git prune-packed && + git count-objects | ( read nr rest && test "$nr" -eq 1 ) && + cmp "test-1-${pack1}.pack" ".git/objects/pack/pack-${pack1}.pack" && + cmp "test-2-${pack1}.idx" ".git/objects/pack/pack-${pack1}.idx"' + +test_expect_success \ + '[index v2] 2) create a stealth corruption in a delta base reference' \ + '# this test assumes a delta smaller than 16 bytes at the end of the pack + git show-index <1.idx | sort -n | sed -ne \$p | ( + read delta_offs delta_sha1 delta_crc && + git cat-file blob "$delta_sha1" > blob_3 && + chmod +w ".git/objects/pack/pack-${pack1}.pack" && + dd of=".git/objects/pack/pack-${pack1}.pack" seek=$(($delta_offs + 1)) \ + if=".git/objects/pack/pack-${pack1}.idx" skip=$((8 + 256 * 4)) \ + bs=1 count=20 conv=notrunc && + git cat-file blob "$delta_sha1" > blob_4 )' + +test_expect_success \ + '[index v2] 3) corrupted delta happily returned wrong data' \ + '! cmp blob_3 blob_4' + +test_expect_success \ + '[index v2] 4) confirm that the pack is actually corrupted' \ + 'test_must_fail git fsck --full $commit' + +test_expect_success \ + '[index v2] 5) pack-objects refuses to reuse corrupted data' \ + 'test_must_fail git pack-objects test-5 <obj-list' + +test_expect_success \ + '[index v2] 6) verify-pack detects CRC mismatch' \ + 'rm -f .git/objects/pack/* && + git-index-pack --index-version=2 --stdin < "test-1-${pack1}.pack" && + git verify-pack ".git/objects/pack/pack-${pack1}.pack" && + chmod +w ".git/objects/pack/pack-${pack1}.idx" && + dd if=/dev/zero of=".git/objects/pack/pack-${pack1}.idx" conv=notrunc \ + bs=1 count=4 seek=$((8 + 256 * 4 + `wc -l <obj-list` * 20 + 0)) && + ( while read obj + do git cat-file -p $obj >/dev/null || exit 1 + done <obj-list ) && + err=$(test_must_fail git verify-pack \ + ".git/objects/pack/pack-${pack1}.pack" 2>&1) && + echo "$err" | grep "CRC mismatch"' + +test_done diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh new file mode 100755 index 0000000000..31b20b21d2 --- /dev/null +++ b/t/t5303-pack-corruption-resilience.sh @@ -0,0 +1,194 @@ +#!/bin/sh +# +# Copyright (c) 2008 Nicolas Pitre +# + +test_description='resilience to pack corruptions with redundant objects' +. ./test-lib.sh + +# Note: the test objects are created with knowledge of their pack encoding +# to ensure good code path coverage, and to facilitate direct alteration +# later on. The assumed characteristics are: +# +# 1) blob_2 is a delta with blob_1 for base and blob_3 is a delta with blob2 +# for base, such that blob_3 delta depth is 2; +# +# 2) the bulk of object data is uncompressible so the text part remains +# visible; +# +# 3) object header is always 2 bytes. + +create_test_files() { + test-genrandom "foo" 2000 > file_1 && + test-genrandom "foo" 1800 > file_2 && + test-genrandom "foo" 1800 > file_3 && + echo " base " >> file_1 && + echo " delta1 " >> file_2 && + echo " delta delta2 " >> file_3 && + test-genrandom "bar" 150 >> file_2 && + test-genrandom "baz" 100 >> file_3 +} + +create_new_pack() { + rm -rf .git && + git init && + blob_1=`git hash-object -t blob -w file_1` && + blob_2=`git hash-object -t blob -w file_2` && + blob_3=`git hash-object -t blob -w file_3` && + pack=`printf "$blob_1\n$blob_2\n$blob_3\n" | + git pack-objects $@ .git/objects/pack/pack` && + pack=".git/objects/pack/pack-${pack}" && + git verify-pack -v ${pack}.pack +} + +do_corrupt_object() { + ofs=`git show-index < ${pack}.idx | grep $1 | cut -f1 -d" "` && + ofs=$(($ofs + $2)) && + chmod +w ${pack}.pack && + dd if=/dev/zero of=${pack}.pack count=1 bs=1 conv=notrunc seek=$ofs && + test_must_fail git verify-pack ${pack}.pack +} + +test_expect_success \ + 'initial setup validation' \ + 'create_test_files && + create_new_pack && + git prune-packed && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + 'create corruption in header of first object' \ + 'do_corrupt_object $blob_1 0 && + test_must_fail git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... but having a loose copy allows for full recovery' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_1 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... and loose copy of first delta allows for partial recovery' \ + 'git prune-packed && + test_must_fail git cat-file blob $blob_2 > /dev/null && + mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + test_must_fail git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + 'create corruption in data of first object' \ + 'create_new_pack && + git prune-packed && + chmod +w ${pack}.pack && + perl -i.bak -pe "s/ base /abcdef/" ${pack}.pack && + test_must_fail git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... but having a loose copy allows for full recovery' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_1 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... and loose copy of second object allows for partial recovery' \ + 'git prune-packed && + test_must_fail git cat-file blob $blob_2 > /dev/null && + mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + test_must_fail git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + 'create corruption in header of first delta' \ + 'create_new_pack && + git prune-packed && + do_corrupt_object $blob_2 0 && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... but having a loose copy allows for full recovery' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + 'create corruption in data of first delta' \ + 'create_new_pack && + git prune-packed && + chmod +w ${pack}.pack && + perl -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... but having a loose copy allows for full recovery' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + 'corruption in delta base reference of first delta (OBJ_REF_DELTA)' \ + 'create_new_pack && + git prune-packed && + do_corrupt_object $blob_2 2 && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... but having a loose copy allows for full recovery' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + 'corruption in delta base reference of first delta (OBJ_OFS_DELTA)' \ + 'create_new_pack --delta-base-offset && + git prune-packed && + do_corrupt_object $blob_2 2 && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... and a redundant pack allows for full recovery too' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_1 && + git hash-object -t blob -w file_2 && + printf "$blob_1\n$blob_2\n" | git pack-objects .git/objects/pack/pack && + git prune-packed && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_done diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh new file mode 100755 index 0000000000..771c0a06a4 --- /dev/null +++ b/t/t5304-prune.sh @@ -0,0 +1,115 @@ +#!/bin/sh +# +# Copyright (c) 2008 Johannes E. Schindelin +# + +test_description='prune' +. ./test-lib.sh + +test_expect_success setup ' + + : > file && + git add file && + test_tick && + git commit -m initial && + git gc + +' + +test_expect_success 'prune stale packs' ' + + orig_pack=$(echo .git/objects/pack/*.pack) && + : > .git/objects/tmp_1.pack && + : > .git/objects/tmp_2.pack && + test-chmtime =-86501 .git/objects/tmp_1.pack && + git prune --expire 1.day && + test -f $orig_pack && + test -f .git/objects/tmp_2.pack && + ! test -f .git/objects/tmp_1.pack + +' + +test_expect_success 'prune --expire' ' + + before=$(git count-objects | sed "s/ .*//") && + BLOB=$(echo aleph | git hash-object -w --stdin) && + BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") && + test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && + test -f $BLOB_FILE && + git prune --expire=1.hour.ago && + test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && + test -f $BLOB_FILE && + test-chmtime =-86500 $BLOB_FILE && + git prune --expire 1.day && + test $before = $(git count-objects | sed "s/ .*//") && + ! test -f $BLOB_FILE + +' + +test_expect_success 'gc: implicit prune --expire' ' + + before=$(git count-objects | sed "s/ .*//") && + BLOB=$(echo aleph_0 | git hash-object -w --stdin) && + BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") && + test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && + test -f $BLOB_FILE && + test-chmtime =-$((86400*14-30)) $BLOB_FILE && + git gc && + test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && + test -f $BLOB_FILE && + test-chmtime =-$((86400*14+1)) $BLOB_FILE && + git gc && + test $before = $(git count-objects | sed "s/ .*//") && + ! test -f $BLOB_FILE + +' + +test_expect_success 'gc: refuse to start with invalid gc.pruneExpire' ' + + git config gc.pruneExpire invalid && + test_must_fail git gc + +' + +test_expect_success 'gc: start with ok gc.pruneExpire' ' + + git config gc.pruneExpire 2.days.ago && + git gc + +' + +test_expect_success 'prune: prune nonsense parameters' ' + + test_must_fail git prune garbage && + test_must_fail git prune --- && + test_must_fail git prune --no-such-option + +' + +test_expect_success 'prune: prune unreachable heads' ' + + git config core.logAllRefUpdates false && + mv .git/logs .git/logs.old && + : > file2 && + git add file2 && + git commit -m temporary && + tmp_head=$(git rev-list -1 HEAD) && + git reset HEAD^ && + git prune && + test_must_fail git reset $tmp_head -- + +' + +test_expect_success 'prune: do not prune heads listed as an argument' ' + + : > file2 && + git add file2 && + git commit -m temporary && + tmp_head=$(git rev-list -1 HEAD) && + git reset HEAD^ && + git prune -- $tmp_head && + git reset $tmp_head -- + +' + +test_done diff --git a/t/t5305-include-tag.sh b/t/t5305-include-tag.sh new file mode 100755 index 0000000000..fb471a08c6 --- /dev/null +++ b/t/t5305-include-tag.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +test_description='git-pack-object --include-tag' +. ./test-lib.sh + +TRASH=`pwd` + +test_expect_success setup ' + echo c >d && + git update-index --add d && + tree=`git write-tree` && + commit=`git commit-tree $tree </dev/null` && + echo "object $commit" >sig && + echo "type commit" >>sig && + echo "tag mytag" >>sig && + echo "tagger $(git var GIT_COMMITTER_IDENT)" >>sig && + echo >>sig && + echo "our test tag" >>sig && + tag=`git mktag <sig` && + rm d sig && + git update-ref refs/tags/mytag $tag && { + echo $tree && + echo $commit && + git ls-tree $tree | sed -e "s/.* \\([0-9a-f]*\\) .*/\\1/" + } >obj-list +' + +rm -rf clone.git +test_expect_success 'pack without --include-tag' ' + packname_1=$(git pack-objects \ + --window=0 \ + test-1 <obj-list) +' + +test_expect_success 'unpack objects' ' + ( + GIT_DIR=clone.git && + export GIT_DIR && + git init && + git unpack-objects -n <test-1-${packname_1}.pack && + git unpack-objects <test-1-${packname_1}.pack + ) +' + +test_expect_success 'check unpacked result (have commit, no tag)' ' + git rev-list --objects $commit >list.expect && + ( + GIT_DIR=clone.git && + export GIT_DIR && + test_must_fail git cat-file -e $tag && + git rev-list --objects $commit + ) >list.actual && + test_cmp list.expect list.actual +' + +rm -rf clone.git +test_expect_success 'pack with --include-tag' ' + packname_1=$(git pack-objects \ + --window=0 \ + --include-tag \ + test-2 <obj-list) +' + +test_expect_success 'unpack objects' ' + ( + GIT_DIR=clone.git && + export GIT_DIR && + git init && + git unpack-objects -n <test-2-${packname_1}.pack && + git unpack-objects <test-2-${packname_1}.pack + ) +' + +test_expect_success 'check unpacked result (have commit, have tag)' ' + git rev-list --objects mytag >list.expect && + ( + GIT_DIR=clone.git && + export GIT_DIR && + git rev-list --objects $tag + ) >list.actual && + test_cmp list.expect list.actual +' + +test_done diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh new file mode 100755 index 0000000000..68c2ae688c --- /dev/null +++ b/t/t5400-send-pack.sh @@ -0,0 +1,174 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='See why rewinding head breaks send-pack + +' +. ./test-lib.sh + +cnt=64 +test_expect_success setup ' + test_tick && + mkdir mozart mozart/is && + echo "Commit #0" >mozart/is/pink && + git update-index --add mozart/is/pink && + tree=$(git write-tree) && + commit=$(echo "Commit #0" | git commit-tree $tree) && + zero=$commit && + parent=$zero && + i=0 && + while test $i -le $cnt + do + i=$(($i+1)) && + test_tick && + echo "Commit #$i" >mozart/is/pink && + git update-index --add mozart/is/pink && + tree=$(git write-tree) && + commit=$(echo "Commit #$i" | git commit-tree $tree -p $parent) && + git update-ref refs/tags/commit$i $commit && + parent=$commit || return 1 + done && + git update-ref HEAD "$commit" && + git-clone ./. victim && + cd victim && + git log && + cd .. && + git update-ref HEAD "$zero" && + parent=$zero && + i=0 && + while test $i -le $cnt + do + i=$(($i+1)) && + test_tick && + echo "Rebase #$i" >mozart/is/pink && + git update-index --add mozart/is/pink && + tree=$(git write-tree) && + commit=$(echo "Rebase #$i" | git commit-tree $tree -p $parent) && + git update-ref refs/tags/rebase$i $commit && + parent=$commit || return 1 + done && + git update-ref HEAD "$commit" && + echo Rebase && + git log' + +test_expect_success 'pack the source repository' ' + git repack -a -d && + git prune +' + +test_expect_success 'pack the destination repository' ' + cd victim && + git repack -a -d && + git prune && + cd .. +' + +test_expect_success \ + 'pushing rewound head should not barf but require --force' ' + # should not fail but refuse to update. + if git-send-pack ./victim/.git/ master + then + # now it should fail with Pasky patch + echo >&2 Gaah, it should have failed. + false + else + echo >&2 Thanks, it correctly failed. + true + fi && + if cmp victim/.git/refs/heads/master .git/refs/heads/master + then + # should have been left as it was! + false + else + true + fi && + # this should update + git-send-pack --force ./victim/.git/ master && + cmp victim/.git/refs/heads/master .git/refs/heads/master +' + +test_expect_success \ + 'push can be used to delete a ref' ' + cd victim && + git branch extra master && + cd .. && + test -f victim/.git/refs/heads/extra && + git-send-pack ./victim/.git/ :extra master && + ! test -f victim/.git/refs/heads/extra +' + +unset GIT_CONFIG GIT_CONFIG_LOCAL +HOME=`pwd`/no-such-directory +export HOME ;# this way we force the victim/.git/config to be used. + +test_expect_success \ + 'pushing with --force should be denied with denyNonFastforwards' ' + cd victim && + git config receive.denyNonFastforwards true && + cd .. && + git update-ref refs/heads/master master^ || return 1 + git-send-pack --force ./victim/.git/ master && return 1 + ! test_cmp .git/refs/heads/master victim/.git/refs/heads/master +' + +test_expect_success \ + 'pushing does not include non-head refs' ' + mkdir parent && cd parent && + git-init && touch file && git-add file && git-commit -m add && + cd .. && + git-clone parent child && cd child && git-push --all && + cd ../parent && + git-branch -a >branches && ! grep origin/master branches +' + +rewound_push_setup() { + rm -rf parent child && + mkdir parent && cd parent && + git-init && echo one >file && git-add file && git-commit -m one && + echo two >file && git-commit -a -m two && + cd .. && + git-clone parent child && cd child && git-reset --hard HEAD^ +} + +rewound_push_succeeded() { + cmp ../parent/.git/refs/heads/master .git/refs/heads/master +} + +rewound_push_failed() { + if rewound_push_succeeded + then + false + else + true + fi +} + +test_expect_success \ + 'pushing explicit refspecs respects forcing' ' + rewound_push_setup && + if git-send-pack ../parent/.git refs/heads/master:refs/heads/master + then + false + else + true + fi && rewound_push_failed && + git-send-pack ../parent/.git +refs/heads/master:refs/heads/master && + rewound_push_succeeded +' + +test_expect_success \ + 'pushing wildcard refspecs respects forcing' ' + rewound_push_setup && + if git-send-pack ../parent/.git refs/heads/*:refs/heads/* + then + false + else + true + fi && rewound_push_failed && + git-send-pack ../parent/.git +refs/heads/*:refs/heads/* && + rewound_push_succeeded +' + +test_done diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh new file mode 100755 index 0000000000..ee769d6695 --- /dev/null +++ b/t/t5401-update-hooks.sh @@ -0,0 +1,137 @@ +#!/bin/sh +# +# Copyright (c) 2006 Shawn O. Pearce +# + +test_description='Test the update hook infrastructure.' +. ./test-lib.sh + +test_expect_success setup ' + echo This is a test. >a && + git update-index --add a && + tree0=$(git write-tree) && + commit0=$(echo setup | git commit-tree $tree0) && + echo We hope it works. >a && + git update-index a && + tree1=$(git write-tree) && + commit1=$(echo modify | git commit-tree $tree1 -p $commit0) && + git update-ref refs/heads/master $commit0 && + git update-ref refs/heads/tofail $commit1 && + git-clone ./. victim && + GIT_DIR=victim/.git git update-ref refs/heads/tofail $commit1 && + git update-ref refs/heads/master $commit1 && + git update-ref refs/heads/tofail $commit0 +' + +cat >victim/.git/hooks/pre-receive <<'EOF' +#!/bin/sh +printf %s "$@" >>$GIT_DIR/pre-receive.args +cat - >$GIT_DIR/pre-receive.stdin +echo STDOUT pre-receive +echo STDERR pre-receive >&2 +EOF +chmod u+x victim/.git/hooks/pre-receive + +cat >victim/.git/hooks/update <<'EOF' +#!/bin/sh +echo "$@" >>$GIT_DIR/update.args +read x; printf %s "$x" >$GIT_DIR/update.stdin +echo STDOUT update $1 +echo STDERR update $1 >&2 +test "$1" = refs/heads/master || exit +EOF +chmod u+x victim/.git/hooks/update + +cat >victim/.git/hooks/post-receive <<'EOF' +#!/bin/sh +printf %s "$@" >>$GIT_DIR/post-receive.args +cat - >$GIT_DIR/post-receive.stdin +echo STDOUT post-receive +echo STDERR post-receive >&2 +EOF +chmod u+x victim/.git/hooks/post-receive + +cat >victim/.git/hooks/post-update <<'EOF' +#!/bin/sh +echo "$@" >>$GIT_DIR/post-update.args +read x; printf %s "$x" >$GIT_DIR/post-update.stdin +echo STDOUT post-update +echo STDERR post-update >&2 +EOF +chmod u+x victim/.git/hooks/post-update + +test_expect_success push ' + test_must_fail git-send-pack --force ./victim/.git \ + master tofail >send.out 2>send.err +' + +test_expect_success 'updated as expected' ' + test $(GIT_DIR=victim/.git git rev-parse master) = $commit1 && + test $(GIT_DIR=victim/.git git rev-parse tofail) = $commit1 +' + +test_expect_success 'hooks ran' ' + test -f victim/.git/pre-receive.args && + test -f victim/.git/pre-receive.stdin && + test -f victim/.git/update.args && + test -f victim/.git/update.stdin && + test -f victim/.git/post-receive.args && + test -f victim/.git/post-receive.stdin && + test -f victim/.git/post-update.args && + test -f victim/.git/post-update.stdin +' + +test_expect_success 'pre-receive hook input' ' + (echo $commit0 $commit1 refs/heads/master; + echo $commit1 $commit0 refs/heads/tofail + ) | test_cmp - victim/.git/pre-receive.stdin +' + +test_expect_success 'update hook arguments' ' + (echo refs/heads/master $commit0 $commit1; + echo refs/heads/tofail $commit1 $commit0 + ) | test_cmp - victim/.git/update.args +' + +test_expect_success 'post-receive hook input' ' + echo $commit0 $commit1 refs/heads/master | + test_cmp - victim/.git/post-receive.stdin +' + +test_expect_success 'post-update hook arguments' ' + echo refs/heads/master | + test_cmp - victim/.git/post-update.args +' + +test_expect_success 'all hook stdin is /dev/null' ' + ! test -s victim/.git/update.stdin && + ! test -s victim/.git/post-update.stdin +' + +test_expect_success 'all *-receive hook args are empty' ' + ! test -s victim/.git/pre-receive.args && + ! test -s victim/.git/post-receive.args +' + +test_expect_success 'send-pack produced no output' ' + ! test -s send.out +' + +cat <<EOF >expect +STDOUT pre-receive +STDERR pre-receive +STDOUT update refs/heads/master +STDERR update refs/heads/master +STDOUT update refs/heads/tofail +STDERR update refs/heads/tofail +STDOUT post-receive +STDERR post-receive +STDOUT post-update +STDERR post-update +EOF +test_expect_success 'send-pack stderr contains hook messages' ' + grep ^STD send.err >actual && + test_cmp - actual <expect +' + +test_done diff --git a/t/t5402-post-merge-hook.sh b/t/t5402-post-merge-hook.sh new file mode 100755 index 0000000000..1394047a8d --- /dev/null +++ b/t/t5402-post-merge-hook.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# +# Copyright (c) 2006 Josh England +# + +test_description='Test the post-merge hook.' +. ./test-lib.sh + +test_expect_success setup ' + echo Data for commit0. >a && + git update-index --add a && + tree0=$(git write-tree) && + commit0=$(echo setup | git commit-tree $tree0) && + echo Changed data for commit1. >a && + git update-index a && + tree1=$(git write-tree) && + commit1=$(echo modify | git commit-tree $tree1 -p $commit0) && + git update-ref refs/heads/master $commit0 && + git-clone ./. clone1 && + GIT_DIR=clone1/.git git update-index --add a && + git-clone ./. clone2 && + GIT_DIR=clone2/.git git update-index --add a +' + +for clone in 1 2; do + cat >clone${clone}/.git/hooks/post-merge <<'EOF' +#!/bin/sh +echo $@ >> $GIT_DIR/post-merge.args +EOF + chmod u+x clone${clone}/.git/hooks/post-merge +done + +test_expect_success 'post-merge does not run for up-to-date ' ' + GIT_DIR=clone1/.git git merge $commit0 && + ! test -f clone1/.git/post-merge.args +' + +test_expect_success 'post-merge runs as expected ' ' + GIT_DIR=clone1/.git git merge $commit1 && + test -e clone1/.git/post-merge.args +' + +test_expect_success 'post-merge from normal merge receives the right argument ' ' + grep 0 clone1/.git/post-merge.args +' + +test_expect_success 'post-merge from squash merge runs as expected ' ' + GIT_DIR=clone2/.git git merge --squash $commit1 && + test -e clone2/.git/post-merge.args +' + +test_expect_success 'post-merge from squash merge receives the right argument ' ' + grep 1 clone2/.git/post-merge.args +' + +test_done diff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh new file mode 100755 index 0000000000..823239a251 --- /dev/null +++ b/t/t5403-post-checkout-hook.sh @@ -0,0 +1,74 @@ +#!/bin/sh +# +# Copyright (c) 2006 Josh England +# + +test_description='Test the post-checkout hook.' +. ./test-lib.sh + +test_expect_success setup ' + echo Data for commit0. >a && + echo Data for commit0. >b && + git update-index --add a && + git update-index --add b && + tree0=$(git write-tree) && + commit0=$(echo setup | git commit-tree $tree0) && + git update-ref refs/heads/master $commit0 && + git-clone ./. clone1 && + git-clone ./. clone2 && + GIT_DIR=clone2/.git git branch -a new2 && + echo Data for commit1. >clone2/b && + GIT_DIR=clone2/.git git add clone2/b && + GIT_DIR=clone2/.git git commit -m new2 +' + +for clone in 1 2; do + cat >clone${clone}/.git/hooks/post-checkout <<'EOF' +#!/bin/sh +echo $@ > $GIT_DIR/post-checkout.args +EOF + chmod u+x clone${clone}/.git/hooks/post-checkout +done + +test_expect_success 'post-checkout runs as expected ' ' + GIT_DIR=clone1/.git git checkout master && + test -e clone1/.git/post-checkout.args +' + +test_expect_success 'post-checkout receives the right arguments with HEAD unchanged ' ' + old=$(awk "{print \$1}" clone1/.git/post-checkout.args) && + new=$(awk "{print \$2}" clone1/.git/post-checkout.args) && + flag=$(awk "{print \$3}" clone1/.git/post-checkout.args) && + test $old = $new -a $flag = 1 +' + +test_expect_success 'post-checkout runs as expected ' ' + GIT_DIR=clone1/.git git checkout master && + test -e clone1/.git/post-checkout.args +' + +test_expect_success 'post-checkout args are correct with git checkout -b ' ' + GIT_DIR=clone1/.git git checkout -b new1 && + old=$(awk "{print \$1}" clone1/.git/post-checkout.args) && + new=$(awk "{print \$2}" clone1/.git/post-checkout.args) && + flag=$(awk "{print \$3}" clone1/.git/post-checkout.args) && + test $old = $new -a $flag = 1 +' + +test_expect_success 'post-checkout receives the right args with HEAD changed ' ' + GIT_DIR=clone2/.git git checkout new2 && + old=$(awk "{print \$1}" clone2/.git/post-checkout.args) && + new=$(awk "{print \$2}" clone2/.git/post-checkout.args) && + flag=$(awk "{print \$3}" clone2/.git/post-checkout.args) && + test $old != $new -a $flag = 1 +' + +test_expect_success 'post-checkout receives the right args when not switching branches ' ' + GIT_DIR=clone2/.git git checkout master b && + old=$(awk "{print \$1}" clone2/.git/post-checkout.args) && + new=$(awk "{print \$2}" clone2/.git/post-checkout.args) && + flag=$(awk "{print \$3}" clone2/.git/post-checkout.args) && + test $old = $new -a $flag = 0 +' + +test_done diff --git a/t/t5404-tracking-branches.sh b/t/t5404-tracking-branches.sh new file mode 100755 index 0000000000..c24003565d --- /dev/null +++ b/t/t5404-tracking-branches.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +test_description='tracking branch update checks for git push' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo 1 >file && + git add file && + git commit -m 1 && + git branch b1 && + git branch b2 && + git branch b3 && + git clone . aa && + git checkout b1 && + echo b1 >>file && + git commit -a -m b1 && + git checkout b2 && + echo b2 >>file && + git commit -a -m b2 +' + +test_expect_success 'prepare pushable branches' ' + cd aa && + b1=$(git rev-parse origin/b1) && + b2=$(git rev-parse origin/b2) && + git checkout -b b1 origin/b1 && + echo aa-b1 >>file && + git commit -a -m aa-b1 && + git checkout -b b2 origin/b2 && + echo aa-b2 >>file && + git commit -a -m aa-b2 && + git checkout master && + echo aa-master >>file && + git commit -a -m aa-master +' + +test_expect_success 'mixed-success push returns error' ' + test_must_fail git push +' + +test_expect_success 'check tracking branches updated correctly after push' ' + test "$(git rev-parse origin/master)" = "$(git rev-parse master)" +' + +test_expect_success 'check tracking branches not updated for failed refs' ' + test "$(git rev-parse origin/b1)" = "$b1" && + test "$(git rev-parse origin/b2)" = "$b2" +' + +test_expect_success 'deleted branches have their tracking branches removed' ' + git push origin :b1 && + test "$(git rev-parse origin/b1)" = "origin/b1" +' + +test_expect_success 'already deleted tracking branches ignored' ' + git branch -d -r origin/b3 && + git push origin :b3 >output 2>&1 && + ! grep error output +' + +test_done diff --git a/t/t5405-send-pack-rewind.sh b/t/t5405-send-pack-rewind.sh new file mode 100755 index 0000000000..86abc62271 --- /dev/null +++ b/t/t5405-send-pack-rewind.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +test_description='forced push to replace commit we do not have' + +. ./test-lib.sh + +test_expect_success setup ' + + >file1 && git add file1 && test_tick && + git commit -m Initial && + + mkdir another && ( + cd another && + git init && + git fetch .. master:master + ) && + + >file2 && git add file2 && test_tick && + git commit -m Second + +' + +test_expect_success 'non forced push should die not segfault' ' + + ( + cd another && + git push .. master:master + test $? = 1 + ) + +' + +test_expect_success 'forced push should succeed' ' + + ( + cd another && + git push .. +master:master + ) + +' + +test_done diff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh new file mode 100755 index 0000000000..59e80a5ea2 --- /dev/null +++ b/t/t5406-remote-rejects.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +test_description='remote push rejects are reported by client' + +. ./test-lib.sh + +test_expect_success 'setup' ' + mkdir .git/hooks && + (echo "#!/bin/sh" ; echo "exit 1") >.git/hooks/update && + chmod +x .git/hooks/update && + echo 1 >file && + git add file && + git commit -m 1 && + git clone . child && + cd child && + echo 2 >file && + git commit -a -m 2 +' + +test_expect_success 'push reports error' 'test_must_fail git push 2>stderr' + +test_expect_success 'individual ref reports error' 'grep rejected stderr' + +test_done diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh new file mode 100755 index 0000000000..362cf7e928 --- /dev/null +++ b/t/t5500-fetch-pack.sh @@ -0,0 +1,182 @@ +#!/bin/sh +# +# Copyright (c) 2005 Johannes Schindelin +# + +test_description='Testing multi_ack pack fetching + +' +. ./test-lib.sh + +# Test fetch-pack/upload-pack pair. + +# Some convenience functions + +add () { + name=$1 + text="$@" + branch=`echo $name | sed -e 's/^\(.\).*$/\1/'` + parents="" + + shift + while test $1; do + parents="$parents -p $1" + shift + done + + echo "$text" > test.txt + git update-index --add test.txt + tree=$(git write-tree) + # make sure timestamps are in correct order + sec=$(($sec+1)) + commit=$(echo "$text" | GIT_AUTHOR_DATE=$sec \ + git commit-tree $tree $parents 2>>log2.txt) + eval "$name=$commit; export $name" + echo $commit > .git/refs/heads/$branch + eval ${branch}TIP=$commit +} + +count_objects () { + ls .git/objects/??/* 2>>log2.txt | wc -l | tr -d " " +} + +test_expect_object_count () { + message=$1 + count=$2 + + output="$(count_objects)" + test_expect_success \ + "new object count $message" \ + "test $count = $output" +} + +pull_to_client () { + number=$1 + heads=$2 + count=$3 + no_strict_count_check=$4 + + cd client + test_expect_success "$number pull" \ + "git-fetch-pack -k -v .. $heads" + case "$heads" in *A*) echo $ATIP > .git/refs/heads/A;; esac + case "$heads" in *B*) echo $BTIP > .git/refs/heads/B;; esac + git symbolic-ref HEAD refs/heads/`echo $heads | sed -e 's/^\(.\).*$/\1/'` + + test_expect_success "fsck" 'git fsck --full > fsck.txt 2>&1' + + test_expect_success 'check downloaded results' \ + 'mv .git/objects/pack/pack-* . && + p=`ls -1 pack-*.pack` && + git unpack-objects <$p && + git fsck --full' + + test_expect_success "new object count after $number pull" \ + 'idx=`echo pack-*.idx` && + pack_count=`git show-index <$idx | wc -l` && + test $pack_count = $count' + test -z "$pack_count" && pack_count=0 + if [ -z "$no_strict_count_check" ]; then + test_expect_success "minimal count" "test $count = $pack_count" + else + test $count != $pack_count && \ + echo "WARNING: $pack_count objects transmitted, only $count of which were needed" + fi + rm -f pack-* + cd .. +} + +# Here begins the actual testing + +# A1 - ... - A20 - A21 +# \ +# B1 - B2 - .. - B70 + +# client pulls A20, B1. Then tracks only B. Then pulls A. + +( + mkdir client && + cd client && + git init 2>> log2.txt && + git config transfer.unpacklimit 0 +) + +add A1 + +prev=1; cur=2; while [ $cur -le 10 ]; do + add A$cur $(eval echo \$A$prev) + prev=$cur + cur=$(($cur+1)) +done + +add B1 $A1 + +echo $ATIP > .git/refs/heads/A +echo $BTIP > .git/refs/heads/B +git symbolic-ref HEAD refs/heads/B + +pull_to_client 1st "B A" $((11*3)) + +add A11 $A10 + +prev=1; cur=2; while [ $cur -le 65 ]; do + add B$cur $(eval echo \$B$prev) + prev=$cur + cur=$(($cur+1)) +done + +pull_to_client 2nd "B" $((64*3)) + +pull_to_client 3rd "A" $((1*3)) # old fails + +test_expect_success "clone shallow" 'git-clone --depth 2 "file://$(pwd)/." shallow' + +(cd shallow; git count-objects -v) > count.shallow + +test_expect_success "clone shallow object count" \ + "test \"in-pack: 18\" = \"$(grep in-pack count.shallow)\"" + +count_output () { + sed -e '/^in-pack:/d' -e '/^packs:/d' -e '/: 0$/d' "$1" +} + +test_expect_success "clone shallow object count (part 2)" ' + test -z "$(count_output count.shallow)" +' + +test_expect_success "fsck in shallow repo" \ + "(cd shallow; git fsck --full)" + +#test_done; exit + +add B66 $B65 +add B67 $B66 + +test_expect_success "pull in shallow repo" \ + "(cd shallow; git pull .. B)" + +(cd shallow; git count-objects -v) > count.shallow +test_expect_success "clone shallow object count" \ + "test \"count: 6\" = \"$(grep count count.shallow)\"" + +add B68 $B67 +add B69 $B68 + +test_expect_success "deepening pull in shallow repo" \ + "(cd shallow; git pull --depth 4 .. B)" + +(cd shallow; git count-objects -v) > count.shallow +test_expect_success "clone shallow object count" \ + "test \"count: 12\" = \"$(grep count count.shallow)\"" + +test_expect_success "deepening fetch in shallow repo" \ + "(cd shallow; git fetch --depth 4 .. A:A)" + +(cd shallow; git count-objects -v) > count.shallow +test_expect_success "clone shallow object count" \ + "test \"count: 18\" = \"$(grep count count.shallow)\"" + +test_expect_success "pull in shallow repo with missing merge base" \ + "(cd shallow && test_must_fail git pull --depth 4 .. A)" + +test_done diff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh new file mode 100755 index 0000000000..16eadd6b68 --- /dev/null +++ b/t/t5502-quickfetch.sh @@ -0,0 +1,122 @@ +#!/bin/sh + +test_description='test quickfetch from local' + +. ./test-lib.sh + +test_expect_success setup ' + + test_tick && + echo ichi >file && + git add file && + git commit -m initial && + + cnt=$( ( + git count-objects | sed -e "s/ *objects,.*//" + ) ) && + test $cnt -eq 3 +' + +test_expect_success 'clone without alternate' ' + + ( + mkdir cloned && + cd cloned && + git init-db && + git remote add -f origin .. + ) && + cnt=$( ( + cd cloned && + git count-objects | sed -e "s/ *objects,.*//" + ) ) && + test $cnt -eq 3 +' + +test_expect_success 'further commits in the original' ' + + test_tick && + echo ni >file && + git commit -a -m second && + + cnt=$( ( + git count-objects | sed -e "s/ *objects,.*//" + ) ) && + test $cnt -eq 6 +' + +test_expect_success 'copy commit and tree but not blob by hand' ' + + git rev-list --objects HEAD | + git pack-objects --stdout | + ( + cd cloned && + git unpack-objects + ) && + + cnt=$( ( + cd cloned && + git count-objects | sed -e "s/ *objects,.*//" + ) ) && + test $cnt -eq 6 + + blob=$(git rev-parse HEAD:file | sed -e "s|..|&/|") && + test -f "cloned/.git/objects/$blob" && + rm -f "cloned/.git/objects/$blob" && + + cnt=$( ( + cd cloned && + git count-objects | sed -e "s/ *objects,.*//" + ) ) && + test $cnt -eq 5 + +' + +test_expect_success 'quickfetch should not leave a corrupted repository' ' + + ( + cd cloned && + git fetch + ) && + + cnt=$( ( + cd cloned && + git count-objects | sed -e "s/ *objects,.*//" + ) ) && + test $cnt -eq 6 + +' + +test_expect_success 'quickfetch should not copy from alternate' ' + + ( + mkdir quickclone && + cd quickclone && + git init-db && + (cd ../.git/objects && pwd) >.git/objects/info/alternates && + git remote add origin .. && + git fetch -k -k + ) && + obj_cnt=$( ( + cd quickclone && + git count-objects | sed -e "s/ *objects,.*//" + ) ) && + pck_cnt=$( ( + cd quickclone && + git count-objects -v | sed -n -e "/packs:/{ + s/packs:// + p + q + }" + ) ) && + origin_master=$( ( + cd quickclone && + git rev-parse origin/master + ) ) && + echo "loose objects: $obj_cnt, packfiles: $pck_cnt" && + test $obj_cnt -eq 0 && + test $pck_cnt -eq 0 && + test z$origin_master = z$(git rev-parse master) + +' + +test_done diff --git a/t/t5503-tagfollow.sh b/t/t5503-tagfollow.sh new file mode 100755 index 0000000000..4074e23ffa --- /dev/null +++ b/t/t5503-tagfollow.sh @@ -0,0 +1,150 @@ +#!/bin/sh + +test_description='test automatic tag following' + +. ./test-lib.sh + +# End state of the repository: +# +# T - tag1 S - tag2 +# / / +# L - A ------ O ------ B +# \ \ \ +# \ C - origin/cat \ +# origin/master master + +test_expect_success setup ' + test_tick && + echo ichi >file && + git add file && + git commit -m L && + L=$(git rev-parse --verify HEAD) && + + ( + mkdir cloned && + cd cloned && + git init-db && + git remote add -f origin .. + ) && + + test_tick && + echo A >file && + git add file && + git commit -m A && + A=$(git rev-parse --verify HEAD) +' + +U=UPLOAD_LOG + +cat - <<EOF >expect +#S +want $A +#E +EOF +test_expect_success 'fetch A (new commit : 1 connection)' ' + rm -f $U + ( + cd cloned && + GIT_DEBUG_SEND_PACK=3 git fetch 3>../$U && + test $A = $(git rev-parse --verify origin/master) + ) && + test -s $U && + cut -d" " -f1,2 $U >actual && + test_cmp expect actual +' + +test_expect_success "create tag T on A, create C on branch cat" ' + git tag -a -m tag1 tag1 $A && + T=$(git rev-parse --verify tag1) && + + git checkout -b cat && + echo C >file && + git add file && + git commit -m C && + C=$(git rev-parse --verify HEAD) && + git checkout master +' + +cat - <<EOF >expect +#S +want $C +want $T +#E +EOF +test_expect_success 'fetch C, T (new branch, tag : 1 connection)' ' + rm -f $U + ( + cd cloned && + GIT_DEBUG_SEND_PACK=3 git fetch 3>../$U && + test $C = $(git rev-parse --verify origin/cat) && + test $T = $(git rev-parse --verify tag1) && + test $A = $(git rev-parse --verify tag1^0) + ) && + test -s $U && + cut -d" " -f1,2 $U >actual && + test_cmp expect actual +' + +test_expect_success "create commits O, B, tag S on B" ' + test_tick && + echo O >file && + git add file && + git commit -m O && + + test_tick && + echo B >file && + git add file && + git commit -m B && + B=$(git rev-parse --verify HEAD) && + + git tag -a -m tag2 tag2 $B && + S=$(git rev-parse --verify tag2) +' + +cat - <<EOF >expect +#S +want $B +want $S +#E +EOF +test_expect_success 'fetch B, S (commit and tag : 1 connection)' ' + rm -f $U + ( + cd cloned && + GIT_DEBUG_SEND_PACK=3 git fetch 3>../$U && + test $B = $(git rev-parse --verify origin/master) && + test $B = $(git rev-parse --verify tag2^0) && + test $S = $(git rev-parse --verify tag2) + ) && + test -s $U && + cut -d" " -f1,2 $U >actual && + test_cmp expect actual +' + +cat - <<EOF >expect +#S +want $B +want $S +#E +EOF +test_expect_success 'new clone fetch master and tags' ' + git branch -D cat + rm -f $U + ( + mkdir clone2 && + cd clone2 && + git init && + git remote add origin .. && + GIT_DEBUG_SEND_PACK=3 git fetch 3>../$U && + test $B = $(git rev-parse --verify origin/master) && + test $S = $(git rev-parse --verify tag2) && + test $B = $(git rev-parse --verify tag2^0) && + test $T = $(git rev-parse --verify tag1) && + test $A = $(git rev-parse --verify tag1^0) + ) && + test -s $U && + cut -d" " -f1,2 $U >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh new file mode 100755 index 0000000000..be9ee9326f --- /dev/null +++ b/t/t5505-remote.sh @@ -0,0 +1,327 @@ +#!/bin/sh + +test_description='git remote porcelain-ish' + +. ./test-lib.sh + +setup_repository () { + mkdir "$1" && ( + cd "$1" && + git init && + >file && + git add file && + test_tick && + git commit -m "Initial" && + git checkout -b side && + >elif && + git add elif && + test_tick && + git commit -m "Second" && + git checkout master + ) +} + +tokens_match () { + echo "$1" | tr ' ' '\012' | sort | sed -e '/^$/d' >expect && + echo "$2" | tr ' ' '\012' | sort | sed -e '/^$/d' >actual && + test_cmp expect actual +} + +check_remote_track () { + actual=$(git remote show "$1" | sed -n -e '$p') && + shift && + tokens_match "$*" "$actual" +} + +check_tracking_branch () { + f="" && + r=$(git for-each-ref "--format=%(refname)" | + sed -ne "s|^refs/remotes/$1/||p") && + shift && + tokens_match "$*" "$r" +} + +test_expect_success setup ' + + setup_repository one && + setup_repository two && + ( + cd two && git branch another + ) && + git clone one test + +' + +test_expect_success 'remote information for the origin' ' +( + cd test && + tokens_match origin "$(git remote)" && + check_remote_track origin master side && + check_tracking_branch origin HEAD master side +) +' + +test_expect_success 'add another remote' ' +( + cd test && + git remote add -f second ../two && + tokens_match "origin second" "$(git remote)" && + check_remote_track origin master side && + check_remote_track second master side another && + check_tracking_branch second master side another && + git for-each-ref "--format=%(refname)" refs/remotes | + sed -e "/^refs\/remotes\/origin\//d" \ + -e "/^refs\/remotes\/second\//d" >actual && + >expect && + test_cmp expect actual +) +' + +test_expect_success 'remote forces tracking branches' ' +( + cd test && + case `git config remote.second.fetch` in + +*) true ;; + *) false ;; + esac +) +' + +test_expect_success 'remove remote' ' +( + cd test && + git symbolic-ref refs/remotes/second/HEAD refs/remotes/second/master && + git remote rm second +) +' + +test_expect_success 'remove remote' ' +( + cd test && + tokens_match origin "$(git remote)" && + check_remote_track origin master side && + git for-each-ref "--format=%(refname)" refs/remotes | + sed -e "/^refs\/remotes\/origin\//d" >actual && + >expect && + test_cmp expect actual +) +' + +cat > test/expect << EOF +* remote origin + URL: $(pwd)/one/.git + Remote branch merged with 'git pull' while on branch master + master + New remote branch (next fetch will store in remotes/origin) + master + Tracked remote branches + side master + Local branches pushed with 'git push' + master:upstream +refs/tags/lastbackup +EOF + +test_expect_success 'show' ' + (cd test && + git config --add remote.origin.fetch \ + refs/heads/master:refs/heads/upstream && + git fetch && + git branch -d -r origin/master && + (cd ../one && + echo 1 > file && + test_tick && + git commit -m update file) && + git config remote.origin.push \ + refs/heads/master:refs/heads/upstream && + git config --add remote.origin.push \ + +refs/tags/lastbackup && + git remote show origin > output && + test_cmp expect output) +' + +cat > test/expect << EOF +* remote origin + URL: $(pwd)/one/.git + Remote branch merged with 'git pull' while on branch master + master + Tracked remote branches + master side + Local branches pushed with 'git push' + master:upstream +refs/tags/lastbackup +EOF + +test_expect_success 'show -n' ' + (mv one one.unreachable && + cd test && + git remote show -n origin > output && + mv ../one.unreachable ../one && + test_cmp expect output) +' + +test_expect_success 'prune' ' + (cd one && + git branch -m side side2) && + (cd test && + git fetch origin && + git remote prune origin && + git rev-parse refs/remotes/origin/side2 && + test_must_fail git rev-parse refs/remotes/origin/side) +' + +cat > test/expect << EOF +Pruning origin +URL: $(pwd)/one/.git + * [would prune] origin/side2 +EOF + +test_expect_success 'prune --dry-run' ' + (cd one && + git branch -m side2 side) && + (cd test && + git remote prune --dry-run origin > output && + git rev-parse refs/remotes/origin/side2 && + test_must_fail git rev-parse refs/remotes/origin/side && + (cd ../one && + git branch -m side side2) && + test_cmp expect output) +' + +test_expect_success 'add --mirror && prune' ' + (mkdir mirror && + cd mirror && + git init && + git remote add --mirror -f origin ../one) && + (cd one && + git branch -m side2 side) && + (cd mirror && + git rev-parse --verify refs/heads/side2 && + test_must_fail git rev-parse --verify refs/heads/side && + git fetch origin && + git remote prune origin && + test_must_fail git rev-parse --verify refs/heads/side2 && + git rev-parse --verify refs/heads/side) +' + +test_expect_success 'add alt && prune' ' + (mkdir alttst && + cd alttst && + git init && + git remote add -f origin ../one && + git config remote.alt.url ../one && + git config remote.alt.fetch "+refs/heads/*:refs/remotes/origin/*") && + (cd one && + git branch -m side side2) && + (cd alttst && + git rev-parse --verify refs/remotes/origin/side && + test_must_fail git rev-parse --verify refs/remotes/origin/side2 && + git fetch alt && + git remote prune alt && + test_must_fail git rev-parse --verify refs/remotes/origin/side && + git rev-parse --verify refs/remotes/origin/side2) +' + +cat > one/expect << EOF + apis/master + apis/side + drosophila/another + drosophila/master + drosophila/side +EOF + +test_expect_success 'update' ' + + (cd one && + git remote add drosophila ../two && + git remote add apis ../mirror && + git remote update && + git branch -r > output && + test_cmp expect output) + +' + +cat > one/expect << EOF + drosophila/another + drosophila/master + drosophila/side + manduca/master + manduca/side + megaloprepus/master + megaloprepus/side +EOF + +test_expect_success 'update with arguments' ' + + (cd one && + for b in $(git branch -r) + do + git branch -r -d $b || break + done && + git remote add manduca ../mirror && + git remote add megaloprepus ../mirror && + git config remotes.phobaeticus "drosophila megaloprepus" && + git config remotes.titanus manduca && + git remote update phobaeticus titanus && + git branch -r > output && + test_cmp expect output) + +' + +cat > one/expect << EOF + apis/master + apis/side + manduca/master + manduca/side + megaloprepus/master + megaloprepus/side +EOF + +test_expect_success 'update default' ' + + (cd one && + for b in $(git branch -r) + do + git branch -r -d $b || break + done && + git config remote.drosophila.skipDefaultUpdate true && + git remote update default && + git branch -r > output && + test_cmp expect output) + +' + +cat > one/expect << EOF + drosophila/another + drosophila/master + drosophila/side +EOF + +test_expect_success 'update default (overridden, with funny whitespace)' ' + + (cd one && + for b in $(git branch -r) + do + git branch -r -d $b || break + done && + git config remotes.default "$(printf "\t drosophila \n")" && + git remote update default && + git branch -r > output && + test_cmp expect output) + +' + +test_expect_success '"remote show" does not show symbolic refs' ' + + git clone one three && + (cd three && + git remote show origin > output && + ! grep HEAD < output && + ! grep -i stale < output) + +' + +test_expect_success 'reject adding remote with an invalid name' ' + + test_must_fail git remote add some:url desired-name + +' + +test_done diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh new file mode 100755 index 0000000000..13d1d826c2 --- /dev/null +++ b/t/t5510-fetch.sh @@ -0,0 +1,306 @@ +#!/bin/sh +# Copyright (c) 2006, Junio C Hamano. + +test_description='Per branch config variables affects "git fetch". + +' + +. ./test-lib.sh + +D=`pwd` + +test_expect_success setup ' + echo >file original && + git add file && + git commit -a -m original' + +test_expect_success "clone and setup child repos" ' + git clone . one && + cd one && + echo >file updated by one && + git commit -a -m "updated by one" && + cd .. && + git clone . two && + cd two && + git config branch.master.remote one && + git config remote.one.url ../one/.git/ && + git config remote.one.fetch refs/heads/master:refs/heads/one && + cd .. && + git clone . three && + cd three && + git config branch.master.remote two && + git config branch.master.merge refs/heads/one && + mkdir -p .git/remotes && + { + echo "URL: ../two/.git/" + echo "Pull: refs/heads/master:refs/heads/two" + echo "Pull: refs/heads/one:refs/heads/one" + } >.git/remotes/two && + cd .. && + git clone . bundle && + git clone . seven +' + +test_expect_success "fetch test" ' + cd "$D" && + echo >file updated by origin && + git commit -a -m "updated by origin" && + cd two && + git fetch && + test -f .git/refs/heads/one && + mine=`git rev-parse refs/heads/one` && + his=`cd ../one && git rev-parse refs/heads/master` && + test "z$mine" = "z$his" +' + +test_expect_success "fetch test for-merge" ' + cd "$D" && + cd three && + git fetch && + test -f .git/refs/heads/two && + test -f .git/refs/heads/one && + master_in_two=`cd ../two && git rev-parse master` && + one_in_two=`cd ../two && git rev-parse one` && + { + echo "$master_in_two not-for-merge" + echo "$one_in_two " + } >expected && + cut -f -2 .git/FETCH_HEAD >actual && + diff expected actual' + +test_expect_success 'fetch tags when there is no tags' ' + + cd "$D" && + + mkdir notags && + cd notags && + git init && + + git fetch -t .. + +' + +test_expect_success 'fetch following tags' ' + + cd "$D" && + git tag -a -m 'annotated' anno HEAD && + git tag light HEAD && + + mkdir four && + cd four && + git init && + + git fetch .. :track && + git show-ref --verify refs/tags/anno && + git show-ref --verify refs/tags/light + +' + +test_expect_success 'fetch must not resolve short tag name' ' + + cd "$D" && + + mkdir five && + cd five && + git init && + + test_must_fail git fetch .. anno:five + +' + +test_expect_success 'fetch must not resolve short remote name' ' + + cd "$D" && + git-update-ref refs/remotes/six/HEAD HEAD + + mkdir six && + cd six && + git init && + + test_must_fail git fetch .. six:six + +' + +test_expect_success 'create bundle 1' ' + cd "$D" && + echo >file updated again by origin && + git commit -a -m "tip" && + git bundle create bundle1 master^..master +' + +test_expect_success 'header of bundle looks right' ' + head -n 1 "$D"/bundle1 | grep "^#" && + head -n 2 "$D"/bundle1 | grep "^-[0-9a-f]\{40\} " && + head -n 3 "$D"/bundle1 | grep "^[0-9a-f]\{40\} " && + head -n 4 "$D"/bundle1 | grep "^$" +' + +test_expect_success 'create bundle 2' ' + cd "$D" && + git bundle create bundle2 master~2..master +' + +test_expect_success 'unbundle 1' ' + cd "$D/bundle" && + git checkout -b some-branch && + test_must_fail git fetch "$D/bundle1" master:master +' + +test_expect_success 'bundle 1 has only 3 files ' ' + cd "$D" && + ( + while read x && test -n "$x" + do + :; + done + cat + ) <bundle1 >bundle.pack && + git index-pack bundle.pack && + verify=$(git verify-pack -v bundle.pack) && + test 4 = $(echo "$verify" | wc -l) +' + +test_expect_success 'unbundle 2' ' + cd "$D/bundle" && + git fetch ../bundle2 master:master && + test "tip" = "$(git log -1 --pretty=oneline master | cut -b42-)" +' + +test_expect_success 'bundle does not prerequisite objects' ' + cd "$D" && + touch file2 && + git add file2 && + git commit -m add.file2 file2 && + git bundle create bundle3 -1 HEAD && + ( + while read x && test -n "$x" + do + :; + done + cat + ) <bundle3 >bundle.pack && + git index-pack bundle.pack && + test 4 = $(git verify-pack -v bundle.pack | wc -l) +' + +test_expect_success 'bundle should be able to create a full history' ' + + cd "$D" && + git tag -a -m '1.0' v1.0 master && + git bundle create bundle4 v1.0 + +' + +test "$TEST_RSYNC" && { +test_expect_success 'fetch via rsync' ' + git pack-refs && + mkdir rsynced && + cd rsynced && + git init && + git fetch rsync://127.0.0.1$(pwd)/../.git master:refs/heads/master && + git gc --prune && + test $(git rev-parse master) = $(cd .. && git rev-parse master) && + git fsck --full +' + +test_expect_success 'push via rsync' ' + mkdir ../rsynced2 && + (cd ../rsynced2 && + git init) && + git push rsync://127.0.0.1$(pwd)/../rsynced2/.git master && + cd ../rsynced2 && + git gc --prune && + test $(git rev-parse master) = $(cd .. && git rev-parse master) && + git fsck --full +' + +test_expect_success 'push via rsync' ' + cd .. && + mkdir rsynced3 && + (cd rsynced3 && + git init) && + git push --all rsync://127.0.0.1$(pwd)/rsynced3/.git && + cd rsynced3 && + test $(git rev-parse master) = $(cd .. && git rev-parse master) && + git fsck --full +' +} + +test_expect_success 'fetch with a non-applying branch.<name>.merge' ' + git config branch.master.remote yeti && + git config branch.master.merge refs/heads/bigfoot && + git config remote.blub.url one && + git config remote.blub.fetch "refs/heads/*:refs/remotes/one/*" && + git fetch blub +' + +# the strange name is: a\!'b +test_expect_success 'quoting of a strangely named repo' ' + test_must_fail git fetch "a\\!'\''b" > result 2>&1 && + cat result && + grep "fatal: '\''a\\\\!'\''b'\''" result +' + +test_expect_success 'bundle should record HEAD correctly' ' + + cd "$D" && + git bundle create bundle5 HEAD master && + git bundle list-heads bundle5 >actual && + for h in HEAD refs/heads/master + do + echo "$(git rev-parse --verify $h) $h" + done >expect && + test_cmp expect actual + +' + +test_expect_success 'explicit fetch should not update tracking' ' + + cd "$D" && + git branch -f side && + ( + cd three && + o=$(git rev-parse --verify refs/remotes/origin/master) && + git fetch origin master && + n=$(git rev-parse --verify refs/remotes/origin/master) && + test "$o" = "$n" && + test_must_fail git rev-parse --verify refs/remotes/origin/side + ) +' + +test_expect_success 'explicit pull should not update tracking' ' + + cd "$D" && + git branch -f side && + ( + cd three && + o=$(git rev-parse --verify refs/remotes/origin/master) && + git pull origin master && + n=$(git rev-parse --verify refs/remotes/origin/master) && + test "$o" = "$n" && + test_must_fail git rev-parse --verify refs/remotes/origin/side + ) +' + +test_expect_success 'configured fetch updates tracking' ' + + cd "$D" && + git branch -f side && + ( + cd three && + o=$(git rev-parse --verify refs/remotes/origin/master) && + git fetch origin && + n=$(git rev-parse --verify refs/remotes/origin/master) && + test "$o" != "$n" && + git rev-parse --verify refs/remotes/origin/side + ) +' + +test_expect_success 'pushing nonexistent branch by mistake should not segv' ' + + cd "$D" && + test_must_fail git push seven no:no + +' + +test_done diff --git a/t/t5511-refspec.sh b/t/t5511-refspec.sh new file mode 100755 index 0000000000..22ba380034 --- /dev/null +++ b/t/t5511-refspec.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +test_description='refspec parsing' + +. ./test-lib.sh + +test_refspec () { + + kind=$1 refspec=$2 expect=$3 + git config remote.frotz.url "." && + git config --remove-section remote.frotz && + git config remote.frotz.url "." && + git config "remote.frotz.$kind" "$refspec" && + if test "$expect" != invalid + then + title="$kind $refspec" + test='git ls-remote frotz' + else + title="$kind $refspec (invalid)" + test='test_must_fail git ls-remote frotz' + fi + test_expect_success "$title" "$test" +} + +test_refspec push '' invalid +test_refspec push ':' +test_refspec push '::' invalid +test_refspec push '+:' + +test_refspec fetch '' +test_refspec fetch ':' +test_refspec fetch '::' invalid + +test_refspec push 'refs/heads/*:refs/remotes/frotz/*' +test_refspec push 'refs/heads/*:refs/remotes/frotz' invalid +test_refspec push 'refs/heads:refs/remotes/frotz/*' invalid +test_refspec push 'refs/heads/master:refs/remotes/frotz/xyzzy' + + +# These have invalid LHS, but we do not have a formal "valid sha-1 +# expression syntax checker" so they are not checked with the current +# code. They will be caught downstream anyway, but we may want to +# have tighter check later... + +: test_refspec push 'refs/heads/master::refs/remotes/frotz/xyzzy' invalid +: test_refspec push 'refs/heads/maste :refs/remotes/frotz/xyzzy' invalid + +test_refspec fetch 'refs/heads/*:refs/remotes/frotz/*' +test_refspec fetch 'refs/heads/*:refs/remotes/frotz' invalid +test_refspec fetch 'refs/heads:refs/remotes/frotz/*' invalid +test_refspec fetch 'refs/heads/master:refs/remotes/frotz/xyzzy' +test_refspec fetch 'refs/heads/master::refs/remotes/frotz/xyzzy' invalid +test_refspec fetch 'refs/heads/maste :refs/remotes/frotz/xyzzy' invalid + +test_refspec push 'master~1:refs/remotes/frotz/backup' +test_refspec fetch 'master~1:refs/remotes/frotz/backup' invalid +test_refspec push 'HEAD~4:refs/remotes/frotz/new' +test_refspec fetch 'HEAD~4:refs/remotes/frotz/new' invalid + +test_refspec push 'HEAD' +test_refspec fetch 'HEAD' +test_refspec push 'refs/heads/ nitfol' invalid +test_refspec fetch 'refs/heads/ nitfol' invalid + +test_refspec push 'HEAD:' invalid +test_refspec fetch 'HEAD:' +test_refspec push 'refs/heads/ nitfol:' invalid +test_refspec fetch 'refs/heads/ nitfol:' invalid + +test_refspec push ':refs/remotes/frotz/deleteme' +test_refspec fetch ':refs/remotes/frotz/HEAD-to-me' +test_refspec push ':refs/remotes/frotz/delete me' invalid +test_refspec fetch ':refs/remotes/frotz/HEAD to me' invalid + +test_done diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh new file mode 100755 index 0000000000..1dd8eed5bb --- /dev/null +++ b/t/t5512-ls-remote.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +test_description='git ls-remote' + +. ./test-lib.sh + +test_expect_success setup ' + + >file && + git add file && + test_tick && + git commit -m initial && + git tag mark && + git show-ref --tags -d | sed -e "s/ / /" >expected.tag && + ( + echo "$(git rev-parse HEAD) HEAD" + git show-ref -d | sed -e "s/ / /" + ) >expected.all && + + git remote add self "$(pwd)/.git" + +' + +test_expect_success 'ls-remote --tags .git' ' + + git ls-remote --tags .git >actual && + test_cmp expected.tag actual + +' + +test_expect_success 'ls-remote .git' ' + + git ls-remote .git >actual && + test_cmp expected.all actual + +' + +test_expect_success 'ls-remote --tags self' ' + + git ls-remote --tags self >actual && + test_cmp expected.tag actual + +' + +test_expect_success 'ls-remote self' ' + + git ls-remote self >actual && + test_cmp expected.all actual + +' + +test_done diff --git a/t/t5513-fetch-track.sh b/t/t5513-fetch-track.sh new file mode 100755 index 0000000000..9e7486274b --- /dev/null +++ b/t/t5513-fetch-track.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +test_description='fetch follows remote tracking branches correctly' + +. ./test-lib.sh + +test_expect_success setup ' + >file && + git add . && + test_tick && + git commit -m Initial && + git branch b-0 && + git branch b1 && + git branch b/one && + test_create_repo other && + ( + cd other && + git config remote.origin.url .. && + git config remote.origin.fetch "+refs/heads/b/*:refs/remotes/b/*" + ) +' + +test_expect_success fetch ' + ( + cd other && git fetch origin && + test "$(git for-each-ref --format="%(refname)")" = refs/remotes/b/one + ) +' + +test_done diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh new file mode 100755 index 0000000000..8becbc3f38 --- /dev/null +++ b/t/t5515-fetch-merge-logic.sh @@ -0,0 +1,176 @@ +#!/bin/sh +# +# Copyright (c) 2007 Santi Béjar, based on t4013 by Junio C Hamano +# +# + +test_description='Merge logic in fetch' + +. ./test-lib.sh + +LF=' +' + +test_expect_success setup ' + GIT_AUTHOR_DATE="2006-06-26 00:00:00 +0000" && + GIT_COMMITTER_DATE="2006-06-26 00:00:00 +0000" && + export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && + + echo >file original && + git add file && + git commit -a -m One && + git tag tag-one && + git tag tag-one-tree HEAD^{tree} && + git branch one && + + echo two >> file && + git commit -a -m Two && + git tag -a -m "Tag Two" tag-two && + git branch two && + + echo three >> file && + git commit -a -m Three && + git tag -a -m "Tag Three" tag-three && + git tag -a -m "Tag Three file" tag-three-file HEAD^{tree}:file && + git branch three && + + echo master >> file && + git commit -a -m Master && + git tag -a -m "Tag Master" tag-master && + + git checkout three && + + git clone . cloned && + cd cloned && + git config remote.origin.url ../.git/ && + + git config remote.config-explicit.url ../.git/ && + git config remote.config-explicit.fetch refs/heads/master:remotes/rem/master && + git config --add remote.config-explicit.fetch refs/heads/one:remotes/rem/one && + git config --add remote.config-explicit.fetch two:remotes/rem/two && + git config --add remote.config-explicit.fetch refs/heads/three:remotes/rem/three && + remotes="config-explicit" && + + git config remote.config-glob.url ../.git/ && + git config remote.config-glob.fetch refs/heads/*:refs/remotes/rem/* && + remotes="$remotes config-glob" && + + mkdir -p .git/remotes && + { + echo "URL: ../.git/" + echo "Pull: refs/heads/master:remotes/rem/master" + echo "Pull: refs/heads/one:remotes/rem/one" + echo "Pull: two:remotes/rem/two" + echo "Pull: refs/heads/three:remotes/rem/three" + } >.git/remotes/remote-explicit && + remotes="$remotes remote-explicit" && + + { + echo "URL: ../.git/" + echo "Pull: refs/heads/*:refs/remotes/rem/*" + } >.git/remotes/remote-glob && + remotes="$remotes remote-glob" && + + mkdir -p .git/branches && + echo "../.git" > .git/branches/branches-default && + remotes="$remotes branches-default" && + + echo "../.git#one" > .git/branches/branches-one && + remotes="$remotes branches-one" && + + for remote in $remotes ; do + git config branch.br-$remote.remote $remote && + git config branch.br-$remote-merge.remote $remote && + git config branch.br-$remote-merge.merge refs/heads/three && + git config branch.br-$remote-octopus.remote $remote && + git config branch.br-$remote-octopus.merge refs/heads/one && + git config --add branch.br-$remote-octopus.merge two + done +' + +# Merge logic depends on branch properties and Pull: or .fetch lines +for remote in $remotes ; do + for branch in "" "-merge" "-octopus" ; do +cat <<EOF +br-$remote$branch +br-$remote$branch $remote +EOF + done +done > tests + +# Merge logic does not depend on branch properties, +# but does depend on Pull: or fetch lines. +# Use two branches completely unrelated from the arguments, +# the clone default and one without branch properties +for branch in master br-unconfig ; do + echo $branch + for remote in $remotes ; do + echo $branch $remote + done +done >> tests + +# Merge logic does not depend on branch properties +# neither in the Pull: or .fetch config +for branch in master br-unconfig ; do + cat <<EOF +$branch ../.git +$branch ../.git one +$branch ../.git one two +$branch --tags ../.git +$branch ../.git tag tag-one tag tag-three +$branch ../.git tag tag-one-tree tag tag-three-file +$branch ../.git one tag tag-one tag tag-three-file +EOF +done >> tests + +while read cmd +do + case "$cmd" in + '' | '#'*) continue ;; + esac + test=`echo "$cmd" | sed -e 's|[/ ][/ ]*|_|g'` + cnt=`expr $test_count + 1` + pfx=`printf "%04d" $cnt` + expect_f="../../t5515/fetch.$test" + actual_f="$pfx-fetch.$test" + expect_r="../../t5515/refs.$test" + actual_r="$pfx-refs.$test" + + test_expect_success "$cmd" ' + { + echo "# $cmd" + set x $cmd; shift + git symbolic-ref HEAD refs/heads/$1 ; shift + rm -f .git/FETCH_HEAD + git for-each-ref \ + refs/heads refs/remotes/rem refs/tags | + while read val type refname + do + git update-ref -d "$refname" "$val" + done + git fetch "$@" >/dev/null + cat .git/FETCH_HEAD + } >"$actual_f" && + git show-ref >"$actual_r" && + if test -f "$expect_f" + then + test_cmp "$expect_f" "$actual_f" && + rm -f "$actual_f" + else + # this is to help developing new tests. + cp "$actual_f" "$expect_f" + false + fi && + if test -f "$expect_r" + then + test_cmp "$expect_r" "$actual_r" && + rm -f "$actual_r" + else + # this is to help developing new tests. + cp "$actual_r" "$expect_r" + false + fi + ' +done < tests + +test_done diff --git a/t/t5515/fetch.br-branches-default b/t/t5515/fetch.br-branches-default new file mode 100644 index 0000000000..2e0414f6c3 --- /dev/null +++ b/t/t5515/fetch.br-branches-default @@ -0,0 +1,8 @@ +# br-branches-default +754b754407bf032e9a2f9d5a9ad05ca79a6b228f branch 'master' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-branches-default-merge b/t/t5515/fetch.br-branches-default-merge new file mode 100644 index 0000000000..ca2cc1d1b4 --- /dev/null +++ b/t/t5515/fetch.br-branches-default-merge @@ -0,0 +1,9 @@ +# br-branches-default-merge +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-branches-default-merge_branches-default b/t/t5515/fetch.br-branches-default-merge_branches-default new file mode 100644 index 0000000000..7d947cd80f --- /dev/null +++ b/t/t5515/fetch.br-branches-default-merge_branches-default @@ -0,0 +1,9 @@ +# br-branches-default-merge branches-default +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-branches-default-octopus b/t/t5515/fetch.br-branches-default-octopus new file mode 100644 index 0000000000..ec39c54b7e --- /dev/null +++ b/t/t5515/fetch.br-branches-default-octopus @@ -0,0 +1,10 @@ +# br-branches-default-octopus +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-branches-default-octopus_branches-default b/t/t5515/fetch.br-branches-default-octopus_branches-default new file mode 100644 index 0000000000..6bf42e24b6 --- /dev/null +++ b/t/t5515/fetch.br-branches-default-octopus_branches-default @@ -0,0 +1,10 @@ +# br-branches-default-octopus branches-default +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-branches-default_branches-default b/t/t5515/fetch.br-branches-default_branches-default new file mode 100644 index 0000000000..4a2bf3c95c --- /dev/null +++ b/t/t5515/fetch.br-branches-default_branches-default @@ -0,0 +1,8 @@ +# br-branches-default branches-default +754b754407bf032e9a2f9d5a9ad05ca79a6b228f branch 'master' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-branches-one b/t/t5515/fetch.br-branches-one new file mode 100644 index 0000000000..12ac8d20fb --- /dev/null +++ b/t/t5515/fetch.br-branches-one @@ -0,0 +1,8 @@ +# br-branches-one +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-branches-one-merge b/t/t5515/fetch.br-branches-one-merge new file mode 100644 index 0000000000..b4b3b35ce0 --- /dev/null +++ b/t/t5515/fetch.br-branches-one-merge @@ -0,0 +1,9 @@ +# br-branches-one-merge +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-branches-one-merge_branches-one b/t/t5515/fetch.br-branches-one-merge_branches-one new file mode 100644 index 0000000000..2ecef384eb --- /dev/null +++ b/t/t5515/fetch.br-branches-one-merge_branches-one @@ -0,0 +1,9 @@ +# br-branches-one-merge branches-one +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-branches-one-octopus b/t/t5515/fetch.br-branches-one-octopus new file mode 100644 index 0000000000..96e3029416 --- /dev/null +++ b/t/t5515/fetch.br-branches-one-octopus @@ -0,0 +1,9 @@ +# br-branches-one-octopus +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-branches-one-octopus_branches-one b/t/t5515/fetch.br-branches-one-octopus_branches-one new file mode 100644 index 0000000000..55e0bad621 --- /dev/null +++ b/t/t5515/fetch.br-branches-one-octopus_branches-one @@ -0,0 +1,9 @@ +# br-branches-one-octopus branches-one +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-branches-one_branches-one b/t/t5515/fetch.br-branches-one_branches-one new file mode 100644 index 0000000000..281fa09d48 --- /dev/null +++ b/t/t5515/fetch.br-branches-one_branches-one @@ -0,0 +1,8 @@ +# br-branches-one branches-one +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-config-explicit b/t/t5515/fetch.br-config-explicit new file mode 100644 index 0000000000..e2fa9c8654 --- /dev/null +++ b/t/t5515/fetch.br-config-explicit @@ -0,0 +1,11 @@ +# br-config-explicit +754b754407bf032e9a2f9d5a9ad05ca79a6b228f branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-config-explicit-merge b/t/t5515/fetch.br-config-explicit-merge new file mode 100644 index 0000000000..ec1a7231aa --- /dev/null +++ b/t/t5515/fetch.br-config-explicit-merge @@ -0,0 +1,11 @@ +# br-config-explicit-merge +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-config-explicit-merge_config-explicit b/t/t5515/fetch.br-config-explicit-merge_config-explicit new file mode 100644 index 0000000000..54f689151f --- /dev/null +++ b/t/t5515/fetch.br-config-explicit-merge_config-explicit @@ -0,0 +1,11 @@ +# br-config-explicit-merge config-explicit +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-config-explicit-octopus b/t/t5515/fetch.br-config-explicit-octopus new file mode 100644 index 0000000000..7011dfc181 --- /dev/null +++ b/t/t5515/fetch.br-config-explicit-octopus @@ -0,0 +1,11 @@ +# br-config-explicit-octopus +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-config-explicit-octopus_config-explicit b/t/t5515/fetch.br-config-explicit-octopus_config-explicit new file mode 100644 index 0000000000..bdad51f871 --- /dev/null +++ b/t/t5515/fetch.br-config-explicit-octopus_config-explicit @@ -0,0 +1,11 @@ +# br-config-explicit-octopus config-explicit +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-config-explicit_config-explicit b/t/t5515/fetch.br-config-explicit_config-explicit new file mode 100644 index 0000000000..1b237dde6e --- /dev/null +++ b/t/t5515/fetch.br-config-explicit_config-explicit @@ -0,0 +1,11 @@ +# br-config-explicit config-explicit +754b754407bf032e9a2f9d5a9ad05ca79a6b228f branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-config-glob b/t/t5515/fetch.br-config-glob new file mode 100644 index 0000000000..e75ec2f72b --- /dev/null +++ b/t/t5515/fetch.br-config-glob @@ -0,0 +1,11 @@ +# br-config-glob +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-config-glob-merge b/t/t5515/fetch.br-config-glob-merge new file mode 100644 index 0000000000..ce8f739a0d --- /dev/null +++ b/t/t5515/fetch.br-config-glob-merge @@ -0,0 +1,11 @@ +# br-config-glob-merge +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-config-glob-merge_config-glob b/t/t5515/fetch.br-config-glob-merge_config-glob new file mode 100644 index 0000000000..5817bed8f8 --- /dev/null +++ b/t/t5515/fetch.br-config-glob-merge_config-glob @@ -0,0 +1,11 @@ +# br-config-glob-merge config-glob +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-config-glob-octopus b/t/t5515/fetch.br-config-glob-octopus new file mode 100644 index 0000000000..938e532db2 --- /dev/null +++ b/t/t5515/fetch.br-config-glob-octopus @@ -0,0 +1,11 @@ +# br-config-glob-octopus +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-config-glob-octopus_config-glob b/t/t5515/fetch.br-config-glob-octopus_config-glob new file mode 100644 index 0000000000..c9225bf6ff --- /dev/null +++ b/t/t5515/fetch.br-config-glob-octopus_config-glob @@ -0,0 +1,11 @@ +# br-config-glob-octopus config-glob +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-config-glob_config-glob b/t/t5515/fetch.br-config-glob_config-glob new file mode 100644 index 0000000000..a6c20f92ce --- /dev/null +++ b/t/t5515/fetch.br-config-glob_config-glob @@ -0,0 +1,11 @@ +# br-config-glob config-glob +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-remote-explicit b/t/t5515/fetch.br-remote-explicit new file mode 100644 index 0000000000..83534d2ec8 --- /dev/null +++ b/t/t5515/fetch.br-remote-explicit @@ -0,0 +1,11 @@ +# br-remote-explicit +754b754407bf032e9a2f9d5a9ad05ca79a6b228f branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-remote-explicit-merge b/t/t5515/fetch.br-remote-explicit-merge new file mode 100644 index 0000000000..a9064dd65a --- /dev/null +++ b/t/t5515/fetch.br-remote-explicit-merge @@ -0,0 +1,11 @@ +# br-remote-explicit-merge +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-remote-explicit-merge_remote-explicit b/t/t5515/fetch.br-remote-explicit-merge_remote-explicit new file mode 100644 index 0000000000..732a37e4d3 --- /dev/null +++ b/t/t5515/fetch.br-remote-explicit-merge_remote-explicit @@ -0,0 +1,11 @@ +# br-remote-explicit-merge remote-explicit +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-remote-explicit-octopus b/t/t5515/fetch.br-remote-explicit-octopus new file mode 100644 index 0000000000..ecf020d929 --- /dev/null +++ b/t/t5515/fetch.br-remote-explicit-octopus @@ -0,0 +1,11 @@ +# br-remote-explicit-octopus +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-remote-explicit-octopus_remote-explicit b/t/t5515/fetch.br-remote-explicit-octopus_remote-explicit new file mode 100644 index 0000000000..af77531011 --- /dev/null +++ b/t/t5515/fetch.br-remote-explicit-octopus_remote-explicit @@ -0,0 +1,11 @@ +# br-remote-explicit-octopus remote-explicit +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-remote-explicit_remote-explicit b/t/t5515/fetch.br-remote-explicit_remote-explicit new file mode 100644 index 0000000000..51fae567c8 --- /dev/null +++ b/t/t5515/fetch.br-remote-explicit_remote-explicit @@ -0,0 +1,11 @@ +# br-remote-explicit remote-explicit +754b754407bf032e9a2f9d5a9ad05ca79a6b228f branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-remote-glob b/t/t5515/fetch.br-remote-glob new file mode 100644 index 0000000000..94e6ad31e3 --- /dev/null +++ b/t/t5515/fetch.br-remote-glob @@ -0,0 +1,11 @@ +# br-remote-glob +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-remote-glob-merge b/t/t5515/fetch.br-remote-glob-merge new file mode 100644 index 0000000000..09362e25af --- /dev/null +++ b/t/t5515/fetch.br-remote-glob-merge @@ -0,0 +1,11 @@ +# br-remote-glob-merge +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-remote-glob-merge_remote-glob b/t/t5515/fetch.br-remote-glob-merge_remote-glob new file mode 100644 index 0000000000..e2eabec62e --- /dev/null +++ b/t/t5515/fetch.br-remote-glob-merge_remote-glob @@ -0,0 +1,11 @@ +# br-remote-glob-merge remote-glob +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-remote-glob-octopus b/t/t5515/fetch.br-remote-glob-octopus new file mode 100644 index 0000000000..b08e046195 --- /dev/null +++ b/t/t5515/fetch.br-remote-glob-octopus @@ -0,0 +1,11 @@ +# br-remote-glob-octopus +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-remote-glob-octopus_remote-glob b/t/t5515/fetch.br-remote-glob-octopus_remote-glob new file mode 100644 index 0000000000..d4d547c847 --- /dev/null +++ b/t/t5515/fetch.br-remote-glob-octopus_remote-glob @@ -0,0 +1,11 @@ +# br-remote-glob-octopus remote-glob +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-remote-glob_remote-glob b/t/t5515/fetch.br-remote-glob_remote-glob new file mode 100644 index 0000000000..646dbc8770 --- /dev/null +++ b/t/t5515/fetch.br-remote-glob_remote-glob @@ -0,0 +1,11 @@ +# br-remote-glob remote-glob +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-unconfig b/t/t5515/fetch.br-unconfig new file mode 100644 index 0000000000..65ce6d99e2 --- /dev/null +++ b/t/t5515/fetch.br-unconfig @@ -0,0 +1,11 @@ +# br-unconfig +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-unconfig_--tags_.._.git b/t/t5515/fetch.br-unconfig_--tags_.._.git new file mode 100644 index 0000000000..8258c80868 --- /dev/null +++ b/t/t5515/fetch.br-unconfig_--tags_.._.git @@ -0,0 +1,7 @@ +# br-unconfig --tags ../.git +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-unconfig_.._.git b/t/t5515/fetch.br-unconfig_.._.git new file mode 100644 index 0000000000..284bb1fb61 --- /dev/null +++ b/t/t5515/fetch.br-unconfig_.._.git @@ -0,0 +1,2 @@ +# br-unconfig ../.git +0567da4d5edd2ff4bb292a465ba9e64dcad9536b ../ diff --git a/t/t5515/fetch.br-unconfig_.._.git_one b/t/t5515/fetch.br-unconfig_.._.git_one new file mode 100644 index 0000000000..11eb5a6ef2 --- /dev/null +++ b/t/t5515/fetch.br-unconfig_.._.git_one @@ -0,0 +1,2 @@ +# br-unconfig ../.git one +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ diff --git a/t/t5515/fetch.br-unconfig_.._.git_one_tag_tag-one_tag_tag-three-file b/t/t5515/fetch.br-unconfig_.._.git_one_tag_tag-one_tag_tag-three-file new file mode 100644 index 0000000000..f02bab2fb4 --- /dev/null +++ b/t/t5515/fetch.br-unconfig_.._.git_one_tag_tag-one_tag_tag-three-file @@ -0,0 +1,8 @@ +# br-unconfig ../.git one tag tag-one tag tag-three-file +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 tag 'tag-one' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-unconfig_.._.git_one_two b/t/t5515/fetch.br-unconfig_.._.git_one_two new file mode 100644 index 0000000000..3f1be224b8 --- /dev/null +++ b/t/t5515/fetch.br-unconfig_.._.git_one_two @@ -0,0 +1,3 @@ +# br-unconfig ../.git one two +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ diff --git a/t/t5515/fetch.br-unconfig_.._.git_tag_tag-one-tree_tag_tag-three-file b/t/t5515/fetch.br-unconfig_.._.git_tag_tag-one-tree_tag_tag-three-file new file mode 100644 index 0000000000..85de41109e --- /dev/null +++ b/t/t5515/fetch.br-unconfig_.._.git_tag_tag-one-tree_tag_tag-three-file @@ -0,0 +1,7 @@ +# br-unconfig ../.git tag tag-one-tree tag tag-three-file +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-unconfig_.._.git_tag_tag-one_tag_tag-three b/t/t5515/fetch.br-unconfig_.._.git_tag_tag-one_tag_tag-three new file mode 100644 index 0000000000..0da2337f1b --- /dev/null +++ b/t/t5515/fetch.br-unconfig_.._.git_tag_tag-one_tag_tag-three @@ -0,0 +1,7 @@ +# br-unconfig ../.git tag tag-one tag tag-three +8e32a6d901327a23ef831511badce7bf3bf46689 tag 'tag-one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b tag 'tag-three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-unconfig_branches-default b/t/t5515/fetch.br-unconfig_branches-default new file mode 100644 index 0000000000..fc7041eefc --- /dev/null +++ b/t/t5515/fetch.br-unconfig_branches-default @@ -0,0 +1,8 @@ +# br-unconfig branches-default +754b754407bf032e9a2f9d5a9ad05ca79a6b228f branch 'master' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-unconfig_branches-one b/t/t5515/fetch.br-unconfig_branches-one new file mode 100644 index 0000000000..e94cde745b --- /dev/null +++ b/t/t5515/fetch.br-unconfig_branches-one @@ -0,0 +1,8 @@ +# br-unconfig branches-one +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-unconfig_config-explicit b/t/t5515/fetch.br-unconfig_config-explicit new file mode 100644 index 0000000000..01a283e70d --- /dev/null +++ b/t/t5515/fetch.br-unconfig_config-explicit @@ -0,0 +1,11 @@ +# br-unconfig config-explicit +754b754407bf032e9a2f9d5a9ad05ca79a6b228f branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-unconfig_config-glob b/t/t5515/fetch.br-unconfig_config-glob new file mode 100644 index 0000000000..3a556c5e96 --- /dev/null +++ b/t/t5515/fetch.br-unconfig_config-glob @@ -0,0 +1,11 @@ +# br-unconfig config-glob +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-unconfig_remote-explicit b/t/t5515/fetch.br-unconfig_remote-explicit new file mode 100644 index 0000000000..db216dfa56 --- /dev/null +++ b/t/t5515/fetch.br-unconfig_remote-explicit @@ -0,0 +1,11 @@ +# br-unconfig remote-explicit +754b754407bf032e9a2f9d5a9ad05ca79a6b228f branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.br-unconfig_remote-glob b/t/t5515/fetch.br-unconfig_remote-glob new file mode 100644 index 0000000000..aee65c204d --- /dev/null +++ b/t/t5515/fetch.br-unconfig_remote-glob @@ -0,0 +1,11 @@ +# br-unconfig remote-glob +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.master b/t/t5515/fetch.master new file mode 100644 index 0000000000..950fd078db --- /dev/null +++ b/t/t5515/fetch.master @@ -0,0 +1,11 @@ +# master +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.master_--tags_.._.git b/t/t5515/fetch.master_--tags_.._.git new file mode 100644 index 0000000000..0e59950c7b --- /dev/null +++ b/t/t5515/fetch.master_--tags_.._.git @@ -0,0 +1,7 @@ +# master --tags ../.git +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.master_.._.git b/t/t5515/fetch.master_.._.git new file mode 100644 index 0000000000..66d1aaddae --- /dev/null +++ b/t/t5515/fetch.master_.._.git @@ -0,0 +1,2 @@ +# master ../.git +0567da4d5edd2ff4bb292a465ba9e64dcad9536b ../ diff --git a/t/t5515/fetch.master_.._.git_one b/t/t5515/fetch.master_.._.git_one new file mode 100644 index 0000000000..35deddbd2c --- /dev/null +++ b/t/t5515/fetch.master_.._.git_one @@ -0,0 +1,2 @@ +# master ../.git one +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ diff --git a/t/t5515/fetch.master_.._.git_one_tag_tag-one_tag_tag-three-file b/t/t5515/fetch.master_.._.git_one_tag_tag-one_tag_tag-three-file new file mode 100644 index 0000000000..82868524ca --- /dev/null +++ b/t/t5515/fetch.master_.._.git_one_tag_tag-one_tag_tag-three-file @@ -0,0 +1,8 @@ +# master ../.git one tag tag-one tag tag-three-file +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 tag 'tag-one' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.master_.._.git_one_two b/t/t5515/fetch.master_.._.git_one_two new file mode 100644 index 0000000000..35ec5782c8 --- /dev/null +++ b/t/t5515/fetch.master_.._.git_one_two @@ -0,0 +1,3 @@ +# master ../.git one two +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../ diff --git a/t/t5515/fetch.master_.._.git_tag_tag-one-tree_tag_tag-three-file b/t/t5515/fetch.master_.._.git_tag_tag-one-tree_tag_tag-three-file new file mode 100644 index 0000000000..2e133eff29 --- /dev/null +++ b/t/t5515/fetch.master_.._.git_tag_tag-one-tree_tag_tag-three-file @@ -0,0 +1,7 @@ +# master ../.git tag tag-one-tree tag tag-three-file +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.master_.._.git_tag_tag-one_tag_tag-three b/t/t5515/fetch.master_.._.git_tag_tag-one_tag_tag-three new file mode 100644 index 0000000000..92b18b40cc --- /dev/null +++ b/t/t5515/fetch.master_.._.git_tag_tag-one_tag_tag-three @@ -0,0 +1,7 @@ +# master ../.git tag tag-one tag tag-three +8e32a6d901327a23ef831511badce7bf3bf46689 tag 'tag-one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b tag 'tag-three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.master_branches-default b/t/t5515/fetch.master_branches-default new file mode 100644 index 0000000000..603d6d2331 --- /dev/null +++ b/t/t5515/fetch.master_branches-default @@ -0,0 +1,8 @@ +# master branches-default +754b754407bf032e9a2f9d5a9ad05ca79a6b228f branch 'master' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.master_branches-one b/t/t5515/fetch.master_branches-one new file mode 100644 index 0000000000..fe9bb0b798 --- /dev/null +++ b/t/t5515/fetch.master_branches-one @@ -0,0 +1,8 @@ +# master branches-one +8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.master_config-explicit b/t/t5515/fetch.master_config-explicit new file mode 100644 index 0000000000..4be97c7575 --- /dev/null +++ b/t/t5515/fetch.master_config-explicit @@ -0,0 +1,11 @@ +# master config-explicit +754b754407bf032e9a2f9d5a9ad05ca79a6b228f branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.master_config-glob b/t/t5515/fetch.master_config-glob new file mode 100644 index 0000000000..cb0726ff8d --- /dev/null +++ b/t/t5515/fetch.master_config-glob @@ -0,0 +1,11 @@ +# master config-glob +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.master_remote-explicit b/t/t5515/fetch.master_remote-explicit new file mode 100644 index 0000000000..44a1ca8429 --- /dev/null +++ b/t/t5515/fetch.master_remote-explicit @@ -0,0 +1,11 @@ +# master remote-explicit +754b754407bf032e9a2f9d5a9ad05ca79a6b228f branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/fetch.master_remote-glob b/t/t5515/fetch.master_remote-glob new file mode 100644 index 0000000000..724e8db0a5 --- /dev/null +++ b/t/t5515/fetch.master_remote-glob @@ -0,0 +1,11 @@ +# master remote-glob +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge tag 'tag-master' of ../ +8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ +22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge tag 'tag-three' of ../ +0e3b14047d3ee365f4f2a1b673db059c3972589c not-for-merge tag 'tag-three-file' of ../ +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge tag 'tag-two' of ../ diff --git a/t/t5515/refs.br-branches-default b/t/t5515/refs.br-branches-default new file mode 100644 index 0000000000..21917c1e5d --- /dev/null +++ b/t/t5515/refs.br-branches-default @@ -0,0 +1,12 @@ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/heads/branches-default +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-branches-default-merge b/t/t5515/refs.br-branches-default-merge new file mode 100644 index 0000000000..21917c1e5d --- /dev/null +++ b/t/t5515/refs.br-branches-default-merge @@ -0,0 +1,12 @@ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/heads/branches-default +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-branches-default-merge_branches-default b/t/t5515/refs.br-branches-default-merge_branches-default new file mode 100644 index 0000000000..21917c1e5d --- /dev/null +++ b/t/t5515/refs.br-branches-default-merge_branches-default @@ -0,0 +1,12 @@ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/heads/branches-default +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-branches-default-octopus b/t/t5515/refs.br-branches-default-octopus new file mode 100644 index 0000000000..21917c1e5d --- /dev/null +++ b/t/t5515/refs.br-branches-default-octopus @@ -0,0 +1,12 @@ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/heads/branches-default +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-branches-default-octopus_branches-default b/t/t5515/refs.br-branches-default-octopus_branches-default new file mode 100644 index 0000000000..21917c1e5d --- /dev/null +++ b/t/t5515/refs.br-branches-default-octopus_branches-default @@ -0,0 +1,12 @@ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/heads/branches-default +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-branches-default_branches-default b/t/t5515/refs.br-branches-default_branches-default new file mode 100644 index 0000000000..21917c1e5d --- /dev/null +++ b/t/t5515/refs.br-branches-default_branches-default @@ -0,0 +1,12 @@ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/heads/branches-default +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-branches-one b/t/t5515/refs.br-branches-one new file mode 100644 index 0000000000..8a705a5df2 --- /dev/null +++ b/t/t5515/refs.br-branches-one @@ -0,0 +1,12 @@ +8e32a6d901327a23ef831511badce7bf3bf46689 refs/heads/branches-one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-branches-one-merge b/t/t5515/refs.br-branches-one-merge new file mode 100644 index 0000000000..8a705a5df2 --- /dev/null +++ b/t/t5515/refs.br-branches-one-merge @@ -0,0 +1,12 @@ +8e32a6d901327a23ef831511badce7bf3bf46689 refs/heads/branches-one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-branches-one-merge_branches-one b/t/t5515/refs.br-branches-one-merge_branches-one new file mode 100644 index 0000000000..8a705a5df2 --- /dev/null +++ b/t/t5515/refs.br-branches-one-merge_branches-one @@ -0,0 +1,12 @@ +8e32a6d901327a23ef831511badce7bf3bf46689 refs/heads/branches-one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-branches-one-octopus b/t/t5515/refs.br-branches-one-octopus new file mode 100644 index 0000000000..8a705a5df2 --- /dev/null +++ b/t/t5515/refs.br-branches-one-octopus @@ -0,0 +1,12 @@ +8e32a6d901327a23ef831511badce7bf3bf46689 refs/heads/branches-one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-branches-one-octopus_branches-one b/t/t5515/refs.br-branches-one-octopus_branches-one new file mode 100644 index 0000000000..8a705a5df2 --- /dev/null +++ b/t/t5515/refs.br-branches-one-octopus_branches-one @@ -0,0 +1,12 @@ +8e32a6d901327a23ef831511badce7bf3bf46689 refs/heads/branches-one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-branches-one_branches-one b/t/t5515/refs.br-branches-one_branches-one new file mode 100644 index 0000000000..8a705a5df2 --- /dev/null +++ b/t/t5515/refs.br-branches-one_branches-one @@ -0,0 +1,12 @@ +8e32a6d901327a23ef831511badce7bf3bf46689 refs/heads/branches-one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-config-explicit b/t/t5515/refs.br-config-explicit new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-config-explicit @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-config-explicit-merge b/t/t5515/refs.br-config-explicit-merge new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-config-explicit-merge @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-config-explicit-merge_config-explicit b/t/t5515/refs.br-config-explicit-merge_config-explicit new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-config-explicit-merge_config-explicit @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-config-explicit-octopus b/t/t5515/refs.br-config-explicit-octopus new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-config-explicit-octopus @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-config-explicit-octopus_config-explicit b/t/t5515/refs.br-config-explicit-octopus_config-explicit new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-config-explicit-octopus_config-explicit @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-config-explicit_config-explicit b/t/t5515/refs.br-config-explicit_config-explicit new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-config-explicit_config-explicit @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-config-glob b/t/t5515/refs.br-config-glob new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-config-glob @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-config-glob-merge b/t/t5515/refs.br-config-glob-merge new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-config-glob-merge @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-config-glob-merge_config-glob b/t/t5515/refs.br-config-glob-merge_config-glob new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-config-glob-merge_config-glob @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-config-glob-octopus b/t/t5515/refs.br-config-glob-octopus new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-config-glob-octopus @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-config-glob-octopus_config-glob b/t/t5515/refs.br-config-glob-octopus_config-glob new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-config-glob-octopus_config-glob @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-config-glob_config-glob b/t/t5515/refs.br-config-glob_config-glob new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-config-glob_config-glob @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-remote-explicit b/t/t5515/refs.br-remote-explicit new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-remote-explicit @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-remote-explicit-merge b/t/t5515/refs.br-remote-explicit-merge new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-remote-explicit-merge @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-remote-explicit-merge_remote-explicit b/t/t5515/refs.br-remote-explicit-merge_remote-explicit new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-remote-explicit-merge_remote-explicit @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-remote-explicit-octopus b/t/t5515/refs.br-remote-explicit-octopus new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-remote-explicit-octopus @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-remote-explicit-octopus_remote-explicit b/t/t5515/refs.br-remote-explicit-octopus_remote-explicit new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-remote-explicit-octopus_remote-explicit @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-remote-explicit_remote-explicit b/t/t5515/refs.br-remote-explicit_remote-explicit new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-remote-explicit_remote-explicit @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-remote-glob b/t/t5515/refs.br-remote-glob new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-remote-glob @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-remote-glob-merge b/t/t5515/refs.br-remote-glob-merge new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-remote-glob-merge @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-remote-glob-merge_remote-glob b/t/t5515/refs.br-remote-glob-merge_remote-glob new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-remote-glob-merge_remote-glob @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-remote-glob-octopus b/t/t5515/refs.br-remote-glob-octopus new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-remote-glob-octopus @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-remote-glob-octopus_remote-glob b/t/t5515/refs.br-remote-glob-octopus_remote-glob new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-remote-glob-octopus_remote-glob @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-remote-glob_remote-glob b/t/t5515/refs.br-remote-glob_remote-glob new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-remote-glob_remote-glob @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-unconfig b/t/t5515/refs.br-unconfig new file mode 100644 index 0000000000..13e4ad2e46 --- /dev/null +++ b/t/t5515/refs.br-unconfig @@ -0,0 +1,11 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-unconfig_--tags_.._.git b/t/t5515/refs.br-unconfig_--tags_.._.git new file mode 100644 index 0000000000..13e4ad2e46 --- /dev/null +++ b/t/t5515/refs.br-unconfig_--tags_.._.git @@ -0,0 +1,11 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-unconfig_.._.git b/t/t5515/refs.br-unconfig_.._.git new file mode 100644 index 0000000000..70962eaac1 --- /dev/null +++ b/t/t5515/refs.br-unconfig_.._.git @@ -0,0 +1,5 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two diff --git a/t/t5515/refs.br-unconfig_.._.git_one b/t/t5515/refs.br-unconfig_.._.git_one new file mode 100644 index 0000000000..70962eaac1 --- /dev/null +++ b/t/t5515/refs.br-unconfig_.._.git_one @@ -0,0 +1,5 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two diff --git a/t/t5515/refs.br-unconfig_.._.git_one_tag_tag-one_tag_tag-three-file b/t/t5515/refs.br-unconfig_.._.git_one_tag_tag-one_tag_tag-three-file new file mode 100644 index 0000000000..13e4ad2e46 --- /dev/null +++ b/t/t5515/refs.br-unconfig_.._.git_one_tag_tag-one_tag_tag-three-file @@ -0,0 +1,11 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-unconfig_.._.git_one_two b/t/t5515/refs.br-unconfig_.._.git_one_two new file mode 100644 index 0000000000..70962eaac1 --- /dev/null +++ b/t/t5515/refs.br-unconfig_.._.git_one_two @@ -0,0 +1,5 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two diff --git a/t/t5515/refs.br-unconfig_.._.git_tag_tag-one-tree_tag_tag-three-file b/t/t5515/refs.br-unconfig_.._.git_tag_tag-one-tree_tag_tag-three-file new file mode 100644 index 0000000000..13e4ad2e46 --- /dev/null +++ b/t/t5515/refs.br-unconfig_.._.git_tag_tag-one-tree_tag_tag-three-file @@ -0,0 +1,11 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-unconfig_.._.git_tag_tag-one_tag_tag-three b/t/t5515/refs.br-unconfig_.._.git_tag_tag-one_tag_tag-three new file mode 100644 index 0000000000..13e4ad2e46 --- /dev/null +++ b/t/t5515/refs.br-unconfig_.._.git_tag_tag-one_tag_tag-three @@ -0,0 +1,11 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-unconfig_branches-default b/t/t5515/refs.br-unconfig_branches-default new file mode 100644 index 0000000000..21917c1e5d --- /dev/null +++ b/t/t5515/refs.br-unconfig_branches-default @@ -0,0 +1,12 @@ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/heads/branches-default +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-unconfig_branches-one b/t/t5515/refs.br-unconfig_branches-one new file mode 100644 index 0000000000..8a705a5df2 --- /dev/null +++ b/t/t5515/refs.br-unconfig_branches-one @@ -0,0 +1,12 @@ +8e32a6d901327a23ef831511badce7bf3bf46689 refs/heads/branches-one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-unconfig_config-explicit b/t/t5515/refs.br-unconfig_config-explicit new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-unconfig_config-explicit @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-unconfig_config-glob b/t/t5515/refs.br-unconfig_config-glob new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-unconfig_config-glob @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-unconfig_remote-explicit b/t/t5515/refs.br-unconfig_remote-explicit new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-unconfig_remote-explicit @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.br-unconfig_remote-glob b/t/t5515/refs.br-unconfig_remote-glob new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.br-unconfig_remote-glob @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.master b/t/t5515/refs.master new file mode 100644 index 0000000000..13e4ad2e46 --- /dev/null +++ b/t/t5515/refs.master @@ -0,0 +1,11 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.master_--tags_.._.git b/t/t5515/refs.master_--tags_.._.git new file mode 100644 index 0000000000..13e4ad2e46 --- /dev/null +++ b/t/t5515/refs.master_--tags_.._.git @@ -0,0 +1,11 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.master_.._.git b/t/t5515/refs.master_.._.git new file mode 100644 index 0000000000..70962eaac1 --- /dev/null +++ b/t/t5515/refs.master_.._.git @@ -0,0 +1,5 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two diff --git a/t/t5515/refs.master_.._.git_one b/t/t5515/refs.master_.._.git_one new file mode 100644 index 0000000000..70962eaac1 --- /dev/null +++ b/t/t5515/refs.master_.._.git_one @@ -0,0 +1,5 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two diff --git a/t/t5515/refs.master_.._.git_one_tag_tag-one_tag_tag-three-file b/t/t5515/refs.master_.._.git_one_tag_tag-one_tag_tag-three-file new file mode 100644 index 0000000000..13e4ad2e46 --- /dev/null +++ b/t/t5515/refs.master_.._.git_one_tag_tag-one_tag_tag-three-file @@ -0,0 +1,11 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.master_.._.git_one_two b/t/t5515/refs.master_.._.git_one_two new file mode 100644 index 0000000000..70962eaac1 --- /dev/null +++ b/t/t5515/refs.master_.._.git_one_two @@ -0,0 +1,5 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two diff --git a/t/t5515/refs.master_.._.git_tag_tag-one-tree_tag_tag-three-file b/t/t5515/refs.master_.._.git_tag_tag-one-tree_tag_tag-three-file new file mode 100644 index 0000000000..13e4ad2e46 --- /dev/null +++ b/t/t5515/refs.master_.._.git_tag_tag-one-tree_tag_tag-three-file @@ -0,0 +1,11 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.master_.._.git_tag_tag-one_tag_tag-three b/t/t5515/refs.master_.._.git_tag_tag-one_tag_tag-three new file mode 100644 index 0000000000..13e4ad2e46 --- /dev/null +++ b/t/t5515/refs.master_.._.git_tag_tag-one_tag_tag-three @@ -0,0 +1,11 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.master_branches-default b/t/t5515/refs.master_branches-default new file mode 100644 index 0000000000..21917c1e5d --- /dev/null +++ b/t/t5515/refs.master_branches-default @@ -0,0 +1,12 @@ +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/heads/branches-default +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.master_branches-one b/t/t5515/refs.master_branches-one new file mode 100644 index 0000000000..8a705a5df2 --- /dev/null +++ b/t/t5515/refs.master_branches-one @@ -0,0 +1,12 @@ +8e32a6d901327a23ef831511badce7bf3bf46689 refs/heads/branches-one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.master_config-explicit b/t/t5515/refs.master_config-explicit new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.master_config-explicit @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.master_config-glob b/t/t5515/refs.master_config-glob new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.master_config-glob @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.master_remote-explicit b/t/t5515/refs.master_remote-explicit new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.master_remote-explicit @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5515/refs.master_remote-glob b/t/t5515/refs.master_remote-glob new file mode 100644 index 0000000000..9bbbfd9fc5 --- /dev/null +++ b/t/t5515/refs.master_remote-glob @@ -0,0 +1,15 @@ +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/HEAD +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/origin/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/origin/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/origin/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/origin/two +754b754407bf032e9a2f9d5a9ad05ca79a6b228f refs/remotes/rem/master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/remotes/rem/one +0567da4d5edd2ff4bb292a465ba9e64dcad9536b refs/remotes/rem/three +6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 refs/remotes/rem/two +6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 refs/tags/tag-master +8e32a6d901327a23ef831511badce7bf3bf46689 refs/tags/tag-one +22feea448b023a2d864ef94b013735af34d238ba refs/tags/tag-one-tree +c61a82b60967180544e3c19f819ddbd0c9f89899 refs/tags/tag-three +0e3b14047d3ee365f4f2a1b673db059c3972589c refs/tags/tag-three-file +525b7fb068d59950d185a8779dc957c77eed73ba refs/tags/tag-two diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh new file mode 100755 index 0000000000..f0030ad00e --- /dev/null +++ b/t/t5516-fetch-push.sh @@ -0,0 +1,466 @@ +#!/bin/sh + +test_description='fetching and pushing, with or without wildcard' + +. ./test-lib.sh + +D=`pwd` + +mk_empty () { + rm -fr testrepo && + mkdir testrepo && + ( + cd testrepo && + git init && + mv .git/hooks .git/hooks-disabled + ) +} + +mk_test () { + mk_empty && + ( + for ref in "$@" + do + git push testrepo $the_first_commit:refs/$ref || { + echo "Oops, push refs/$ref failure" + exit 1 + } + done && + cd testrepo && + for ref in "$@" + do + r=$(git show-ref -s --verify refs/$ref) && + test "z$r" = "z$the_first_commit" || { + echo "Oops, refs/$ref is wrong" + exit 1 + } + done && + git fsck --full + ) +} + +check_push_result () { + ( + cd testrepo && + it="$1" && + shift + for ref in "$@" + do + r=$(git show-ref -s --verify refs/$ref) && + test "z$r" = "z$it" || { + echo "Oops, refs/$ref is wrong" + exit 1 + } + done && + git fsck --full + ) +} + +test_expect_success setup ' + + : >path1 && + git add path1 && + test_tick && + git commit -a -m repo && + the_first_commit=$(git show-ref -s --verify refs/heads/master) && + + : >path2 && + git add path2 && + test_tick && + git commit -a -m second && + the_commit=$(git show-ref -s --verify refs/heads/master) + +' + +test_expect_success 'fetch without wildcard' ' + mk_empty && + ( + cd testrepo && + git fetch .. refs/heads/master:refs/remotes/origin/master && + + 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_expect_success 'fetch with wildcard' ' + mk_empty && + ( + cd testrepo && + git config remote.up.url .. && + git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" && + git fetch up && + + 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_expect_success 'fetch with insteadOf' ' + mk_empty && + ( + TRASH=$(pwd)/ && + cd testrepo && + git config "url.$TRASH.insteadOf" trash/ && + git config remote.up.url trash/. && + git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" && + git fetch up && + + 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_expect_success 'push without wildcard' ' + mk_empty && + + git push 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_expect_success 'push with wildcard' ' + mk_empty && + + git push testrepo "refs/heads/*:refs/remotes/origin/*" && + ( + 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_expect_success 'push with insteadOf' ' + mk_empty && + TRASH="$(pwd)/" && + git config "url.$TRASH.insteadOf" trash/ && + git push trash/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_expect_success 'push with matching heads' ' + + mk_test heads/master && + git push testrepo && + check_push_result $the_commit heads/master + +' + +test_expect_success 'push with matching heads on the command line' ' + + mk_test heads/master && + git push testrepo : && + check_push_result $the_commit heads/master + +' + +test_expect_success 'failed (non-fast-forward) push with matching heads' ' + + mk_test heads/master && + git push testrepo : && + git commit --amend -massaged && + test_must_fail git push testrepo && + check_push_result $the_commit heads/master && + git reset --hard $the_commit + +' + +test_expect_success 'push --force with matching heads' ' + + mk_test heads/master && + git push testrepo : && + git commit --amend -massaged && + git push --force testrepo && + ! check_push_result $the_commit heads/master && + git reset --hard $the_commit + +' + +test_expect_success 'push with matching heads and forced update' ' + + mk_test heads/master && + git push testrepo : && + git commit --amend -massaged && + git push testrepo +: && + ! check_push_result $the_commit heads/master && + git reset --hard $the_commit + +' + +test_expect_success 'push with no ambiguity (1)' ' + + mk_test heads/master && + git push testrepo master:master && + check_push_result $the_commit heads/master + +' + +test_expect_success 'push with no ambiguity (2)' ' + + mk_test remotes/origin/master && + git push testrepo master:origin/master && + check_push_result $the_commit remotes/origin/master + +' + +test_expect_success 'push with colon-less refspec, no ambiguity' ' + + mk_test heads/master heads/t/master && + git branch -f t/master master && + git push testrepo master && + check_push_result $the_commit heads/master && + check_push_result $the_first_commit heads/t/master + +' + +test_expect_success 'push with weak ambiguity (1)' ' + + mk_test heads/master remotes/origin/master && + git push testrepo master:master && + check_push_result $the_commit heads/master && + check_push_result $the_first_commit remotes/origin/master + +' + +test_expect_success 'push with weak ambiguity (2)' ' + + mk_test heads/master remotes/origin/master remotes/another/master && + git push testrepo master:master && + check_push_result $the_commit heads/master && + check_push_result $the_first_commit remotes/origin/master remotes/another/master + +' + +test_expect_success 'push with ambiguity' ' + + mk_test heads/frotz tags/frotz && + if git push testrepo master:frotz + then + echo "Oops, should have failed" + false + else + check_push_result $the_first_commit heads/frotz tags/frotz + fi + +' + +test_expect_success 'push with colon-less refspec (1)' ' + + mk_test heads/frotz tags/frotz && + git branch -f frotz master && + git push testrepo frotz && + check_push_result $the_commit heads/frotz && + check_push_result $the_first_commit tags/frotz + +' + +test_expect_success 'push with colon-less refspec (2)' ' + + mk_test heads/frotz tags/frotz && + if git show-ref --verify -q refs/heads/frotz + then + git branch -D frotz + fi && + git tag -f frotz && + git push testrepo frotz && + check_push_result $the_commit tags/frotz && + check_push_result $the_first_commit heads/frotz + +' + +test_expect_success 'push with colon-less refspec (3)' ' + + mk_test && + if git show-ref --verify -q refs/tags/frotz + then + git tag -d frotz + fi && + git branch -f frotz master && + git push testrepo frotz && + check_push_result $the_commit heads/frotz && + test 1 = $( cd testrepo && git show-ref | wc -l ) +' + +test_expect_success 'push with colon-less refspec (4)' ' + + mk_test && + if git show-ref --verify -q refs/heads/frotz + then + git branch -D frotz + fi && + git tag -f frotz && + git push testrepo frotz && + check_push_result $the_commit tags/frotz && + test 1 = $( cd testrepo && git show-ref | wc -l ) + +' + +test_expect_success 'push head with non-existant, incomplete dest' ' + + mk_test && + git push testrepo master:branch && + check_push_result $the_commit heads/branch + +' + +test_expect_success 'push tag with non-existant, incomplete dest' ' + + mk_test && + git tag -f v1.0 && + git push testrepo v1.0:tag && + check_push_result $the_commit tags/tag + +' + +test_expect_success 'push sha1 with non-existant, incomplete dest' ' + + mk_test && + test_must_fail git push testrepo `git rev-parse master`:foo + +' + +test_expect_success 'push ref expression with non-existant, incomplete dest' ' + + mk_test && + test_must_fail git push testrepo master^:branch + +' + +test_expect_success 'push with HEAD' ' + + mk_test heads/master && + git checkout master && + git push testrepo HEAD && + check_push_result $the_commit heads/master + +' + +test_expect_success 'push with HEAD nonexisting at remote' ' + + mk_test heads/master && + git checkout -b local master && + git push testrepo HEAD && + check_push_result $the_commit heads/local +' + +test_expect_success 'push with +HEAD' ' + + mk_test heads/master && + git checkout master && + git branch -D local && + git checkout -b local && + git push testrepo master local && + check_push_result $the_commit heads/master && + check_push_result $the_commit heads/local && + + # Without force rewinding should fail + git reset --hard HEAD^ && + test_must_fail git push testrepo HEAD && + check_push_result $the_commit heads/local && + + # With force rewinding should succeed + git push testrepo +HEAD && + check_push_result $the_first_commit heads/local + +' + +test_expect_success 'push HEAD with non-existant, incomplete dest' ' + + mk_test && + git checkout master && + git push testrepo HEAD:branch && + check_push_result $the_commit heads/branch + +' + +test_expect_success 'push with config remote.*.push = HEAD' ' + + mk_test heads/local && + git checkout master && + git branch -f local $the_commit && + ( + cd testrepo && + git checkout local && + git reset --hard $the_first_commit + ) && + git config remote.there.url testrepo && + git config remote.there.push HEAD && + git config branch.master.remote there && + git push && + check_push_result $the_commit heads/master && + check_push_result $the_first_commit heads/local +' + +# clean up the cruft left with the previous one +git config --remove-section remote.there +git config --remove-section branch.master + +test_expect_success 'push with dry-run' ' + + mk_test heads/master && + (cd testrepo && + old_commit=$(git show-ref -s --verify refs/heads/master)) && + git push --dry-run testrepo && + check_push_result $old_commit heads/master +' + +test_expect_success 'push updates local refs' ' + + rm -rf parent child && + mkdir parent && + (cd parent && git init && + echo one >foo && git add foo && git commit -m one) && + git clone parent child && + (cd child && + echo two >foo && git commit -a -m two && + git push && + test $(git rev-parse master) = $(git rev-parse remotes/origin/master)) + +' + +test_expect_success 'push does not update local refs on failure' ' + + rm -rf parent child && + mkdir parent && + (cd parent && git init && + echo one >foo && git add foo && git commit -m one && + echo exit 1 >.git/hooks/pre-receive && + chmod +x .git/hooks/pre-receive) && + git clone parent child && + (cd child && + echo two >foo && git commit -a -m two && + test_must_fail git push && + test $(git rev-parse master) != \ + $(git rev-parse remotes/origin/master)) + +' + +test_expect_success 'allow deleting an invalid remote ref' ' + + pwd && + rm -f testrepo/.git/objects/??/* && + git push testrepo :refs/heads/master && + (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master) + +' + +test_done diff --git a/t/t5517-push-mirror.sh b/t/t5517-push-mirror.sh new file mode 100755 index 0000000000..ea49dedbf8 --- /dev/null +++ b/t/t5517-push-mirror.sh @@ -0,0 +1,267 @@ +#!/bin/sh + +test_description='pushing to a mirror repository' + +. ./test-lib.sh + +D=`pwd` + +invert () { + if "$@"; then + return 1 + else + return 0 + fi +} + +mk_repo_pair () { + rm -rf master mirror && + mkdir mirror && + ( + cd mirror && + git init + ) && + mkdir master && + ( + cd master && + git init && + git remote add $1 up ../mirror + ) +} + + +# BRANCH tests +test_expect_success 'push mirror creates new branches' ' + + mk_repo_pair && + ( + cd master && + echo one >foo && git add foo && git commit -m one && + git push --mirror up + ) && + master_master=$(cd master && git show-ref -s --verify refs/heads/master) && + mirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) && + test "$master_master" = "$mirror_master" + +' + +test_expect_success 'push mirror updates existing branches' ' + + mk_repo_pair && + ( + cd master && + echo one >foo && git add foo && git commit -m one && + git push --mirror up && + echo two >foo && git add foo && git commit -m two && + git push --mirror up + ) && + master_master=$(cd master && git show-ref -s --verify refs/heads/master) && + mirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) && + test "$master_master" = "$mirror_master" + +' + +test_expect_success 'push mirror force updates existing branches' ' + + mk_repo_pair && + ( + cd master && + echo one >foo && git add foo && git commit -m one && + git push --mirror up && + echo two >foo && git add foo && git commit -m two && + git push --mirror up && + git reset --hard HEAD^ + git push --mirror up + ) && + master_master=$(cd master && git show-ref -s --verify refs/heads/master) && + mirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) && + test "$master_master" = "$mirror_master" + +' + +test_expect_success 'push mirror removes branches' ' + + mk_repo_pair && + ( + cd master && + echo one >foo && git add foo && git commit -m one && + git branch remove master && + git push --mirror up && + git branch -D remove + git push --mirror up + ) && + ( + cd mirror && + invert git show-ref -s --verify refs/heads/remove + ) + +' + +test_expect_success 'push mirror adds, updates and removes branches together' ' + + mk_repo_pair && + ( + cd master && + echo one >foo && git add foo && git commit -m one && + git branch remove master && + git push --mirror up && + git branch -D remove && + git branch add master && + echo two >foo && git add foo && git commit -m two && + git push --mirror up + ) && + master_master=$(cd master && git show-ref -s --verify refs/heads/master) && + master_add=$(cd master && git show-ref -s --verify refs/heads/add) && + mirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) && + mirror_add=$(cd mirror && git show-ref -s --verify refs/heads/add) && + test "$master_master" = "$mirror_master" && + test "$master_add" = "$mirror_add" && + ( + cd mirror && + invert git show-ref -s --verify refs/heads/remove + ) + +' + + +# TAG tests +test_expect_success 'push mirror creates new tags' ' + + mk_repo_pair && + ( + cd master && + echo one >foo && git add foo && git commit -m one && + git tag -f tmaster master && + git push --mirror up + ) && + master_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) && + mirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) && + test "$master_master" = "$mirror_master" + +' + +test_expect_success 'push mirror updates existing tags' ' + + mk_repo_pair && + ( + cd master && + echo one >foo && git add foo && git commit -m one && + git tag -f tmaster master && + git push --mirror up && + echo two >foo && git add foo && git commit -m two && + git tag -f tmaster master && + git push --mirror up + ) && + master_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) && + mirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) && + test "$master_master" = "$mirror_master" + +' + +test_expect_success 'push mirror force updates existing tags' ' + + mk_repo_pair && + ( + cd master && + echo one >foo && git add foo && git commit -m one && + git tag -f tmaster master && + git push --mirror up && + echo two >foo && git add foo && git commit -m two && + git tag -f tmaster master && + git push --mirror up && + git reset --hard HEAD^ + git tag -f tmaster master && + git push --mirror up + ) && + master_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) && + mirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) && + test "$master_master" = "$mirror_master" + +' + +test_expect_success 'push mirror removes tags' ' + + mk_repo_pair && + ( + cd master && + echo one >foo && git add foo && git commit -m one && + git tag -f tremove master && + git push --mirror up && + git tag -d tremove + git push --mirror up + ) && + ( + cd mirror && + invert git show-ref -s --verify refs/tags/tremove + ) + +' + +test_expect_success 'push mirror adds, updates and removes tags together' ' + + mk_repo_pair && + ( + cd master && + echo one >foo && git add foo && git commit -m one && + git tag -f tmaster master && + git tag -f tremove master && + git push --mirror up && + git tag -d tremove && + git tag tadd master && + echo two >foo && git add foo && git commit -m two && + git tag -f tmaster master && + git push --mirror up + ) && + master_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) && + master_add=$(cd master && git show-ref -s --verify refs/tags/tadd) && + mirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) && + mirror_add=$(cd mirror && git show-ref -s --verify refs/tags/tadd) && + test "$master_master" = "$mirror_master" && + test "$master_add" = "$mirror_add" && + ( + cd mirror && + invert git show-ref -s --verify refs/tags/tremove + ) + +' + +test_expect_success 'remote.foo.mirror adds and removes branches' ' + + mk_repo_pair --mirror && + ( + cd master && + echo one >foo && git add foo && git commit -m one && + git branch keep master && + git branch remove master && + git push up && + git branch -D remove + git push up + ) && + ( + cd mirror && + git show-ref -s --verify refs/heads/keep && + invert git show-ref -s --verify refs/heads/remove + ) + +' + +test_expect_success 'remote.foo.mirror=no has no effect' ' + + mk_repo_pair && + ( + cd master && + echo one >foo && git add foo && git commit -m one && + git config --add remote.up.mirror no && + git branch keep master && + git push --mirror up && + git branch -D keep && + git push up + ) && + ( + cd mirror && + git show-ref -s --verify refs/heads/keep + ) + +' + +test_done diff --git a/t/t5518-fetch-exit-status.sh b/t/t5518-fetch-exit-status.sh new file mode 100755 index 0000000000..c6bc65faa0 --- /dev/null +++ b/t/t5518-fetch-exit-status.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# +# Copyright (c) 2008 Dmitry V. Levin +# + +test_description='fetch exit status test' + +. ./test-lib.sh + +test_expect_success setup ' + + >file && + git add file && + git commit -m initial && + + git checkout -b side && + echo side >file && + git commit -a -m side && + + git checkout master && + echo next >file && + git commit -a -m next +' + +test_expect_success 'non fast forward fetch' ' + + test_must_fail git fetch . master:side + +' + +test_expect_success 'forced update' ' + + git fetch . +master:side + +' + +test_done diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh new file mode 100755 index 0000000000..997b2db827 --- /dev/null +++ b/t/t5520-pull.sh @@ -0,0 +1,113 @@ +#!/bin/sh + +test_description='pulling into void' + +. ./test-lib.sh + +D=`pwd` + +test_expect_success setup ' + + echo file >file && + git add file && + git commit -a -m original + +' + +test_expect_success 'pulling into void' ' + mkdir cloned && + cd cloned && + git init && + git pull .. +' + +cd "$D" + +test_expect_success 'checking the results' ' + test -f file && + test -f cloned/file && + diff file cloned/file +' + +test_expect_success 'test . as a remote' ' + + git branch copy master && + git config branch.copy.remote . && + git config branch.copy.merge refs/heads/master && + echo updated >file && + git commit -a -m updated && + git checkout copy && + test `cat file` = file && + git pull && + test `cat file` = updated +' + +test_expect_success 'the default remote . should not break explicit pull' ' + git checkout -b second master^ && + echo modified >file && + git commit -a -m modified && + git checkout copy && + git reset --hard HEAD^ && + test `cat file` = file && + git pull . second && + test `cat file` = modified +' + +test_expect_success '--rebase' ' + git branch to-rebase && + echo modified again > file && + git commit -m file file && + git checkout to-rebase && + echo new > file2 && + git add file2 && + git commit -m "new file" && + git tag before-rebase && + git pull --rebase . copy && + test $(git rev-parse HEAD^) = $(git rev-parse copy) && + test new = $(git show HEAD:file2) +' + +test_expect_success 'branch.to-rebase.rebase' ' + git reset --hard before-rebase && + git config branch.to-rebase.rebase 1 && + git pull . copy && + git config branch.to-rebase.rebase 0 && + test $(git rev-parse HEAD^) = $(git rev-parse copy) && + test new = $(git show HEAD:file2) +' + +test_expect_success '--rebase with rebased upstream' ' + + git remote add -f me . && + git checkout copy && + git reset --hard HEAD^ && + echo conflicting modification > file && + git commit -m conflict file && + git checkout to-rebase && + echo file > file2 && + git commit -m to-rebase file2 && + git pull --rebase me copy && + test "conflicting modification" = "$(cat file)" && + test file = $(cat file2) + +' + +test_expect_success 'pull --rebase dies early with dirty working directory' ' + + git update-ref refs/remotes/me/copy copy^ && + COPY=$(git rev-parse --verify me/copy) && + git rebase --onto $COPY copy && + git config branch.to-rebase.remote me && + git config branch.to-rebase.merge refs/heads/copy && + git config branch.to-rebase.rebase true && + echo dirty >> file && + git add file && + test_must_fail git pull && + test $COPY = $(git rev-parse --verify me/copy) && + git checkout HEAD -- file && + git pull && + test $COPY != $(git rev-parse --verify me/copy) + +' + +test_done diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh new file mode 100755 index 0000000000..1a15817cd5 --- /dev/null +++ b/t/t5530-upload-pack-error.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +test_description='errors in upload-pack' + +. ./test-lib.sh + +D=`pwd` + +corrupt_repo () { + object_sha1=$(git rev-parse "$1") && + ob=$(expr "$object_sha1" : "\(..\)") && + ject=$(expr "$object_sha1" : "..\(..*\)") && + rm -f ".git/objects/$ob/$ject" +} + +test_expect_success 'setup and corrupt repository' ' + + echo file >file && + git add file && + git rev-parse :file && + git commit -a -m original && + test_tick && + echo changed >file && + git commit -a -m changed && + corrupt_repo HEAD:file + +' + +test_expect_success 'fsck fails' ' + test_must_fail git fsck +' + +test_expect_success 'upload-pack fails due to error in pack-objects' ' + + ! echo "0032want $(git rev-parse HEAD) +00000009done +0000" | git-upload-pack . > /dev/null 2> output.err && + grep "pack-objects died" output.err +' + +test_expect_success 'corrupt repo differently' ' + + git hash-object -w file && + corrupt_repo HEAD^^{tree} + +' + +test_expect_success 'fsck fails' ' + test_must_fail git fsck +' +test_expect_success 'upload-pack fails due to error in rev-list' ' + + ! echo "0032want $(git rev-parse HEAD) +00000009done +0000" | git-upload-pack . > /dev/null 2> output.err && + grep "waitpid (async) failed" output.err +' + +test_expect_success 'create empty repository' ' + + mkdir foo && + cd foo && + git init + +' + +test_expect_success 'fetch fails' ' + + test_must_fail git fetch .. master + +' + +test_done diff --git a/t/t5540-http-push.sh b/t/t5540-http-push.sh new file mode 100755 index 0000000000..b0d242e3ed --- /dev/null +++ b/t/t5540-http-push.sh @@ -0,0 +1,81 @@ +#!/bin/sh +# +# Copyright (c) 2008 Clemens Buchacher <drizzd@aon.at> +# + +test_description='test http-push + +This test runs various sanity checks on http-push.' + +. ./test-lib.sh + +ROOT_PATH="$PWD" +LIB_HTTPD_DAV=t + +if git http-push > /dev/null 2>&1 || [ $? -eq 128 ] +then + say "skipping test, USE_CURL_MULTI is not defined" + test_done + exit +fi + +. ../lib-httpd.sh + +if ! start_httpd >&3 2>&4 +then + say "skipping test, web server setup failed" + test_done + exit +fi + +test_expect_success 'setup remote repository' ' + cd "$ROOT_PATH" && + mkdir test_repo && + cd test_repo && + git init && + : >path1 && + git add path1 && + test_tick && + git commit -m initial && + cd - && + git clone --bare test_repo test_repo.git && + cd test_repo.git && + git --bare update-server-info && + mv hooks/post-update.sample hooks/post-update && + cd - && + mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH" +' + +test_expect_success 'clone remote repository' ' + cd "$ROOT_PATH" && + git clone $HTTPD_URL/test_repo.git test_repo_clone +' + +test_expect_failure 'push to remote repository' ' + cd "$ROOT_PATH"/test_repo_clone && + : >path2 && + git add path2 && + test_tick && + git commit -m path2 && + git push && + [ -f "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/refs/heads/master" ] +' + +test_expect_failure 'create and delete remote branch' ' + cd "$ROOT_PATH"/test_repo_clone && + git checkout -b dev && + : >path3 && + git add path3 && + test_tick && + git commit -m dev && + git push origin dev && + git fetch && + git push origin :dev && + git branch -d -r origin/dev && + git fetch && + test_must_fail git show-ref --verify refs/remotes/origin/dev +' + +stop_httpd + +test_done diff --git a/t/t5600-clone-fail-cleanup.sh b/t/t5600-clone-fail-cleanup.sh new file mode 100755 index 0000000000..3c013e2b6a --- /dev/null +++ b/t/t5600-clone-fail-cleanup.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Copyright (C) 2006 Carl D. Worth <cworth@cworth.org> +# + +test_description='test git-clone to cleanup after failure + +This test covers the fact that if git-clone fails, it should remove +the directory it created, to avoid the user having to manually +remove the directory before attempting a clone again.' + +. ./test-lib.sh + +test_expect_success \ + 'clone of non-existent source should fail' \ + 'test_must_fail git-clone foo bar' + +test_expect_success \ + 'failed clone should not leave a directory' \ + '! test -d bar' + +# Need a repo to clone +test_create_repo foo + +# clone doesn't like it if there is no HEAD. Is that a bug? +(cd foo && touch file && git add file && git commit -m 'add file' >/dev/null 2>&1) + +# source repository given to git-clone should be relative to the +# current path not to the target dir +test_expect_success \ + 'clone of non-existent (relative to $PWD) source should fail' \ + 'test_must_fail git-clone ../foo baz' + +test_expect_success \ + 'clone should work now that source exists' \ + 'git-clone foo bar' + +test_expect_success \ + 'successful clone must leave the directory' \ + 'cd bar' + +test_done diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh new file mode 100755 index 0000000000..59c65fef28 --- /dev/null +++ b/t/t5601-clone.sh @@ -0,0 +1,110 @@ +#!/bin/sh + +test_description=clone + +. ./test-lib.sh + +test_expect_success setup ' + + rm -fr .git && + test_create_repo src && + ( + cd src + >file + git add file + git commit -m initial + ) + +' + +test_expect_success 'clone with excess parameters (1)' ' + + rm -fr dst && + test_must_fail git clone -n src dst junk + +' + +test_expect_success 'clone with excess parameters (2)' ' + + rm -fr dst && + test_must_fail git clone -n "file://$(pwd)/src" dst junk + +' + +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_expect_success 'clone does not keep pack' ' + + rm -fr dst && + git clone -n "file://$(pwd)/src" dst && + ! test -f dst/file && + ! (echo dst/.git/objects/pack/pack-* | grep "\.keep") + +' + +test_expect_success 'clone checks out files' ' + + rm -fr dst && + git clone src dst && + test -f dst/file + +' + +test_expect_success 'clone respects GIT_WORK_TREE' ' + + GIT_WORK_TREE=worktree git clone src bare && + test -f bare/config && + test -f worktree/file + +' + +test_expect_success 'clone creates intermediate directories' ' + + git clone src long/path/to/dst && + test -f long/path/to/dst/file + +' + +test_expect_success 'clone creates intermediate directories for bare repo' ' + + git clone --bare src long/path/to/bare/dst && + test -f long/path/to/bare/dst/config + +' + +test_expect_success 'clone --mirror' ' + + git clone --mirror src mirror && + test -f mirror/HEAD && + test ! -f mirror/file && + FETCH="$(cd mirror && git config remote.origin.fetch)" && + test "+refs/*:refs/*" = "$FETCH" && + MIRROR="$(cd mirror && git config --bool remote.origin.mirror)" && + test "$MIRROR" = true + +' + +test_expect_success 'clone --bare names the local repository <name>.git' ' + + git clone --bare src && + test -d src.git + +' + +test_expect_success 'clone --mirror does not repeat tags' ' + + (cd src && + git tag some-tag HEAD) && + git clone --mirror src mirror2 && + (cd mirror2 && + git show-ref 2> clone.err > clone.out) && + test_must_fail grep Duplicate mirror2/clone.err && + grep some-tag mirror2/clone.out + +' + +test_done diff --git a/t/t5602-clone-remote-exec.sh b/t/t5602-clone-remote-exec.sh new file mode 100755 index 0000000000..8367a6845f --- /dev/null +++ b/t/t5602-clone-remote-exec.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +test_description=clone + +. ./test-lib.sh + +test_expect_success setup ' + echo "#!/bin/sh" > not_ssh + echo "echo \"\$*\" > not_ssh_output" >> not_ssh + echo "exit 1" >> not_ssh + chmod +x not_ssh +' + +test_expect_success 'clone calls git-upload-pack unqualified with no -u option' ' + GIT_SSH=./not_ssh git clone localhost:/path/to/repo junk + echo "localhost git-upload-pack '\''/path/to/repo'\''" >expected + test_cmp expected not_ssh_output +' + +test_expect_success 'clone calls specified git-upload-pack with -u option' ' + GIT_SSH=./not_ssh git clone -u /something/bin/git-upload-pack localhost:/path/to/repo junk + echo "localhost /something/bin/git-upload-pack '\''/path/to/repo'\''" >expected + test_cmp expected not_ssh_output +' + +test_done diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh new file mode 100755 index 0000000000..1c10916069 --- /dev/null +++ b/t/t5700-clone-reference.sh @@ -0,0 +1,149 @@ +#!/bin/sh +# +# Copyright (C) 2006 Martin Waitz <tali@admingilde.org> +# + +test_description='test clone --reference' +. ./test-lib.sh + +base_dir=`pwd` + +U=$base_dir/UPLOAD_LOG + +test_expect_success 'preparing first repository' \ +'test_create_repo A && cd A && +echo first > file1 && +git add file1 && +git commit -m initial' + +cd "$base_dir" + +test_expect_success 'preparing second repository' \ +'git clone A B && cd B && +echo second > file2 && +git add file2 && +git commit -m addition && +git repack -a -d && +git prune' + +cd "$base_dir" + +test_expect_success 'cloning with reference (-l -s)' \ +'git clone -l -s --reference B A C' + +cd "$base_dir" + +test_expect_success 'existence of info/alternates' \ +'test `wc -l <C/.git/objects/info/alternates` = 2' + +cd "$base_dir" + +test_expect_success 'pulling from reference' \ +'cd C && +git pull ../B master' + +cd "$base_dir" + +test_expect_success 'that reference gets used' \ +'cd C && +echo "0 objects, 0 kilobytes" > expected && +git count-objects > current && +diff expected current' + +cd "$base_dir" + +rm -f "$U" + +test_expect_success 'cloning with reference (no -l -s)' \ +'GIT_DEBUG_SEND_PACK=3 git clone --reference B "file://$(pwd)/A" D 3>"$U"' + +test_expect_success 'fetched no objects' \ +'! grep "^want" "$U"' + +cd "$base_dir" + +test_expect_success 'existence of info/alternates' \ +'test `wc -l <D/.git/objects/info/alternates` = 1' + +cd "$base_dir" + +test_expect_success 'pulling from reference' \ +'cd D && git pull ../B master' + +cd "$base_dir" + +test_expect_success 'that reference gets used' \ +'cd D && echo "0 objects, 0 kilobytes" > expected && +git count-objects > current && +diff expected current' + +cd "$base_dir" + +test_expect_success 'updating origin' \ +'cd A && +echo third > file3 && +git add file3 && +git commit -m update && +git repack -a -d && +git prune' + +cd "$base_dir" + +test_expect_success 'pulling changes from origin' \ +'cd C && +git pull origin' + +cd "$base_dir" + +# the 2 local objects are commit and tree from the merge +test_expect_success 'that alternate to origin gets used' \ +'cd C && +echo "2 objects" > expected && +git count-objects | cut -d, -f1 > current && +diff expected current' + +cd "$base_dir" + +test_expect_success 'pulling changes from origin' \ +'cd D && +git pull origin' + +cd "$base_dir" + +# the 5 local objects are expected; file3 blob, commit in A to add it +# and its tree, and 2 are our tree and the merge commit. +test_expect_success 'check objects expected to exist locally' \ +'cd D && +echo "5 objects" > expected && +git count-objects | cut -d, -f1 > current && +diff expected current' + +cd "$base_dir" + +test_expect_success 'preparing alternate repository #1' \ +'test_create_repo F && cd F && +echo first > file1 && +git add file1 && +git commit -m initial' + +cd "$base_dir" + +test_expect_success 'cloning alternate repo #2 and adding changes to repo #1' \ +'git clone F G && cd F && +echo second > file2 && +git add file2 && +git commit -m addition' + +cd "$base_dir" + +test_expect_success 'cloning alternate repo #1, using #2 as reference' \ +'git clone --reference G F H' + +cd "$base_dir" + +test_expect_success 'cloning with reference being subset of source (-l -s)' \ +'git clone -l -s --reference A B E' + +cd "$base_dir" + +test_done diff --git a/t/t5701-clone-local.sh b/t/t5701-clone-local.sh new file mode 100755 index 0000000000..8dfaaa456e --- /dev/null +++ b/t/t5701-clone-local.sh @@ -0,0 +1,119 @@ +#!/bin/sh + +test_description='test local clone' +. ./test-lib.sh + +D=`pwd` + +test_expect_success 'preparing origin repository' ' + : >file && git add . && git commit -m1 && + git clone --bare . a.git && + git clone --bare . x && + test "$(GIT_CONFIG=a.git/config git config --bool core.bare)" = true && + test "$(GIT_CONFIG=x/config git config --bool core.bare)" = true + git bundle create b1.bundle --all HEAD && + git bundle create b2.bundle --all && + mkdir dir && + cp b1.bundle dir/b3 + cp b1.bundle b4 +' + +test_expect_success 'local clone without .git suffix' ' + cd "$D" && + git clone -l -s a b && + cd b && + test "$(GIT_CONFIG=.git/config git config --bool core.bare)" = false && + git fetch +' + +test_expect_success 'local clone with .git suffix' ' + cd "$D" && + git clone -l -s a.git c && + cd c && + git fetch +' + +test_expect_success 'local clone from x' ' + cd "$D" && + git clone -l -s x y && + cd y && + git fetch +' + +test_expect_success 'local clone from x.git that does not exist' ' + cd "$D" && + if git clone -l -s x.git z + then + echo "Oops, should have failed" + false + else + echo happy + fi +' + +test_expect_success 'With -no-hardlinks, local will make a copy' ' + cd "$D" && + git clone --bare --no-hardlinks x w && + cd w && + linked=$(find objects -type f ! -links 1 | wc -l) && + test 0 = $linked +' + +test_expect_success 'Even without -l, local will make a hardlink' ' + cd "$D" && + rm -fr w && + git clone -l --bare x w && + cd w && + copied=$(find objects -type f -links 1 | wc -l) && + test 0 = $copied +' + +test_expect_success 'local clone of repo with nonexistent ref in HEAD' ' + cd "$D" && + echo "ref: refs/heads/nonexistent" > a.git/HEAD && + git clone a d && + cd d && + git fetch && + test ! -e .git/refs/remotes/origin/HEAD' + +test_expect_success 'bundle clone without .bundle suffix' ' + cd "$D" && + git clone dir/b3 && + cd b3 && + git fetch +' + +test_expect_success 'bundle clone with .bundle suffix' ' + cd "$D" && + git clone b1.bundle && + cd b1 && + git fetch +' + +test_expect_success 'bundle clone from b4' ' + cd "$D" && + git clone b4 bdl && + cd bdl && + git fetch +' + +test_expect_success 'bundle clone from b4.bundle that does not exist' ' + cd "$D" && + if git clone b4.bundle bb + then + echo "Oops, should have failed" + false + else + echo happy + fi +' + +test_expect_success 'bundle clone with nonexistent HEAD' ' + cd "$D" && + git clone b2.bundle b2 && + cd b2 && + git fetch + test ! -e .git/refs/heads/master +' + +test_done diff --git a/t/t5702-clone-options.sh b/t/t5702-clone-options.sh new file mode 100755 index 0000000000..328e4d9a33 --- /dev/null +++ b/t/t5702-clone-options.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +test_description='basic clone options' +. ./test-lib.sh + +test_expect_success 'setup' ' + + mkdir parent && + (cd parent && git init && + echo one >file && git add file && + git commit -m one) + +' + +test_expect_success 'clone -o' ' + + git clone -o foo parent clone-o && + (cd clone-o && git rev-parse --verify refs/remotes/foo/master) + +' + +test_done diff --git a/t/t5710-info-alternate.sh b/t/t5710-info-alternate.sh new file mode 100755 index 0000000000..ef7127c1b3 --- /dev/null +++ b/t/t5710-info-alternate.sh @@ -0,0 +1,112 @@ +#!/bin/sh +# +# Copyright (C) 2006 Martin Waitz <tali@admingilde.org> +# + +test_description='test transitive info/alternate entries' +. ./test-lib.sh + +# test that a file is not reachable in the current repository +# but that it is after creating a info/alternate entry +reachable_via() { + alternate="$1" + file="$2" + if git cat-file -e "HEAD:$file"; then return 1; fi + echo "$alternate" >> .git/objects/info/alternate + git cat-file -e "HEAD:$file" +} + +test_valid_repo() { + git fsck --full > fsck.log && + test `wc -l < fsck.log` = 0 +} + +base_dir=`pwd` + +test_expect_success 'preparing first repository' \ +'test_create_repo A && cd A && +echo "Hello World" > file1 && +git add file1 && +git commit -m "Initial commit" file1 && +git repack -a -d && +git prune' + +cd "$base_dir" + +test_expect_success 'preparing second repository' \ +'git clone -l -s A B && cd B && +echo "foo bar" > file2 && +git add file2 && +git commit -m "next commit" file2 && +git repack -a -d -l && +git prune' + +cd "$base_dir" + +test_expect_success 'preparing third repository' \ +'git clone -l -s B C && cd C && +echo "Goodbye, cruel world" > file3 && +git add file3 && +git commit -m "one more" file3 && +git repack -a -d -l && +git prune' + +cd "$base_dir" + +test_expect_success 'creating too deep nesting' \ +'git clone -l -s C D && +git clone -l -s D E && +git clone -l -s E F && +git clone -l -s F G && +git clone -l -s G H' + +test_expect_success 'invalidity of deepest repository' \ +'cd H && { + test_valid_repo + test $? -ne 0 +}' + +cd "$base_dir" + +test_expect_success 'validity of third repository' \ +'cd C && +test_valid_repo' + +cd "$base_dir" + +test_expect_success 'validity of fourth repository' \ +'cd D && +test_valid_repo' + +cd "$base_dir" + +test_expect_success 'breaking of loops' \ +'echo "$base_dir"/B/.git/objects >> "$base_dir"/A/.git/objects/info/alternates&& +cd C && +test_valid_repo' + +cd "$base_dir" + +test_expect_success 'that info/alternates is necessary' \ +'cd C && +rm -f .git/objects/info/alternates && +! (test_valid_repo)' + +cd "$base_dir" + +test_expect_success 'that relative alternate is possible for current dir' \ +'cd C && +echo "../../../B/.git/objects" > .git/objects/info/alternates && +test_valid_repo' + +cd "$base_dir" + +test_expect_success \ + 'that relative alternate is only possible for current dir' ' + cd D && + ! (test_valid_repo) +' + +cd "$base_dir" + +test_done diff --git a/t/t6000lib.sh b/t/t6000lib.sh new file mode 100755 index 0000000000..f55627b641 --- /dev/null +++ b/t/t6000lib.sh @@ -0,0 +1,125 @@ +[ -d .git/refs/tags ] || mkdir -p .git/refs/tags + +:> sed.script + +# Answer the sha1 has associated with the tag. The tag must exist in .git or .git/refs/tags +tag() +{ + _tag=$1 + [ -f .git/refs/tags/$_tag ] || error "tag: \"$_tag\" does not exist" + cat .git/refs/tags/$_tag +} + +# Generate a commit using the text specified to make it unique and the tree +# named by the tag specified. +unique_commit() +{ + _text=$1 + _tree=$2 + shift 2 + echo $_text | git commit-tree $(tag $_tree) "$@" +} + +# Save the output of a command into the tag specified. Prepend +# a substitution script for the tag onto the front of sed.script +save_tag() +{ + _tag=$1 + [ -n "$_tag" ] || error "usage: save_tag tag commit-args ..." + shift 1 + "$@" >.git/refs/tags/$_tag + + echo "s/$(tag $_tag)/$_tag/g" > sed.script.tmp + cat sed.script >> sed.script.tmp + rm sed.script + mv sed.script.tmp sed.script +} + +# Replace unhelpful sha1 hashses with their symbolic equivalents +entag() +{ + sed -f sed.script +} + +# Execute a command after first saving, then setting the GIT_AUTHOR_EMAIL +# tag to a specified value. Restore the original value on return. +as_author() +{ + _author=$1 + shift 1 + _save=$GIT_AUTHOR_EMAIL + + GIT_AUTHOR_EMAIL="$_author" + export GIT_AUTHOR_EMAIL + "$@" + if test -z "$_save" + then + unset GIT_AUTHOR_EMAIL + else + GIT_AUTHOR_EMAIL="$_save" + export GIT_AUTHOR_EMAIL + fi +} + +commit_date() +{ + _commit=$1 + git cat-file commit $_commit | sed -n "s/^committer .*> \([0-9]*\) .*/\1/p" +} + +on_committer_date() +{ + _date=$1 + shift 1 + GIT_COMMITTER_DATE="$_date" + export GIT_COMMITTER_DATE + "$@" + unset GIT_COMMITTER_DATE +} + +# Execute a command and suppress any error output. +hide_error() +{ + "$@" 2>/dev/null +} + +check_output() +{ + _name=$1 + shift 1 + if eval "$*" | entag > $_name.actual + then + diff $_name.expected $_name.actual + else + return 1; + fi +} + +# Turn a reasonable test description into a reasonable test name. +# All alphanums translated into -'s which are then compressed and stripped +# from front and back. +name_from_description() +{ + perl -pe ' + s/[^A-Za-z0-9.]/-/g; + s/-+/-/g; + s/-$//; + s/^-//; + y/A-Z/a-z/; + ' +} + + +# Execute the test described by the first argument, by eval'ing +# command line specified in the 2nd argument. Check the status code +# is zero and that the output matches the stream read from +# stdin. +test_output_expect_success() +{ + _description=$1 + _test=$2 + [ $# -eq 2 ] || error "usage: test_output_expect_success description test <<EOF ... EOF" + _name=$(echo $_description | name_from_description) + cat > $_name.expected + test_expect_success "$_description" "check_output $_name \"$_test\"" +} diff --git a/t/t6001-rev-list-graft.sh b/t/t6001-rev-list-graft.sh new file mode 100755 index 0000000000..b2131cdacd --- /dev/null +++ b/t/t6001-rev-list-graft.sh @@ -0,0 +1,113 @@ +#!/bin/sh + +test_description='Revision traversal vs grafts and path limiter' + +. ./test-lib.sh + +test_expect_success setup ' + mkdir subdir && + echo >fileA fileA && + echo >subdir/fileB fileB && + git add fileA subdir/fileB && + git commit -a -m "Initial in one history." && + A0=`git rev-parse --verify HEAD` && + + echo >fileA fileA modified && + git commit -a -m "Second in one history." && + A1=`git rev-parse --verify HEAD` && + + echo >subdir/fileB fileB modified && + git commit -a -m "Third in one history." && + A2=`git rev-parse --verify HEAD` && + + rm -f .git/refs/heads/master .git/index && + + echo >fileA fileA again && + echo >subdir/fileB fileB again && + git add fileA subdir/fileB && + git commit -a -m "Initial in alternate history." && + B0=`git rev-parse --verify HEAD` && + + echo >fileA fileA modified in alternate history && + git commit -a -m "Second in alternate history." && + B1=`git rev-parse --verify HEAD` && + + echo >subdir/fileB fileB modified in alternate history && + git commit -a -m "Third in alternate history." && + B2=`git rev-parse --verify HEAD` && + : done +' + +check () { + type=$1 + shift + + arg= + which=arg + rm -f test.expect + for a + do + if test "z$a" = z-- + then + which=expect + child= + continue + fi + if test "$which" = arg + then + arg="$arg$a " + continue + fi + if test "$type" = basic + then + echo "$a" + else + if test "z$child" != z + then + echo "$child $a" + fi + child="$a" + fi + done >test.expect + if test "$type" != basic && test "z$child" != z + then + echo >>test.expect $child + fi + if test $type = basic + then + git rev-list $arg >test.actual + elif test $type = parents + then + git rev-list --parents $arg >test.actual + elif test $type = parents-raw + then + git rev-list --parents --pretty=raw $arg | + sed -n -e 's/^commit //p' >test.actual + fi + diff test.expect test.actual +} + +for type in basic parents parents-raw +do + test_expect_success 'without grafts' " + rm -f .git/info/grafts + check $type $B2 -- $B2 $B1 $B0 + " + + test_expect_success 'with grafts' " + echo '$B0 $A2' >.git/info/grafts + check $type $B2 -- $B2 $B1 $B0 $A2 $A1 $A0 + " + + test_expect_success 'without grafts, with pathlimit' " + rm -f .git/info/grafts + check $type $B2 subdir -- $B2 $B0 + " + + test_expect_success 'with grafts, with pathlimit' " + echo '$B0 $A2' >.git/info/grafts + check $type $B2 subdir -- $B2 $B0 $A2 $A0 + " + +done +test_done diff --git a/t/t6002-rev-list-bisect.sh b/t/t6002-rev-list-bisect.sh new file mode 100755 index 0000000000..8f5de097ec --- /dev/null +++ b/t/t6002-rev-list-bisect.sh @@ -0,0 +1,238 @@ +#!/bin/sh +# +# Copyright (c) 2005 Jon Seymour +# +test_description='Tests git rev-list --bisect functionality' + +. ./test-lib.sh +. ../t6000lib.sh # t6xxx specific functions + +# usage: test_bisection max-diff bisect-option head ^prune... +# +# e.g. test_bisection 1 --bisect l1 ^l0 +# +test_bisection_diff() +{ + _max_diff=$1 + _bisect_option=$2 + shift 2 + _bisection=$(git rev-list $_bisect_option "$@") + _list_size=$(git rev-list "$@" | wc -l) + _head=$1 + shift 1 + _bisection_size=$(git rev-list $_bisection "$@" | wc -l) + [ -n "$_list_size" -a -n "$_bisection_size" ] || + error "test_bisection_diff failed" + + # Test if bisection size is close to half of list size within + # tolerance. + # + _bisect_err=`expr $_list_size - $_bisection_size \* 2` + test "$_bisect_err" -lt 0 && _bisect_err=`expr 0 - $_bisect_err` + _bisect_err=`expr $_bisect_err / 2` ; # floor + + test_expect_success \ + "bisection diff $_bisect_option $_head $* <= $_max_diff" \ + 'test $_bisect_err -le $_max_diff' +} + +date >path0 +git update-index --add path0 +save_tag tree git write-tree +on_committer_date "1971-08-16 00:00:00" hide_error save_tag root unique_commit root tree +on_committer_date "1971-08-16 00:00:01" save_tag l0 unique_commit l0 tree -p root +on_committer_date "1971-08-16 00:00:02" save_tag l1 unique_commit l1 tree -p l0 +on_committer_date "1971-08-16 00:00:03" save_tag l2 unique_commit l2 tree -p l1 +on_committer_date "1971-08-16 00:00:04" save_tag a0 unique_commit a0 tree -p l2 +on_committer_date "1971-08-16 00:00:05" save_tag a1 unique_commit a1 tree -p a0 +on_committer_date "1971-08-16 00:00:06" save_tag b1 unique_commit b1 tree -p a0 +on_committer_date "1971-08-16 00:00:07" save_tag c1 unique_commit c1 tree -p b1 +on_committer_date "1971-08-16 00:00:08" save_tag b2 unique_commit b2 tree -p b1 +on_committer_date "1971-08-16 00:00:09" save_tag b3 unique_commit b2 tree -p b2 +on_committer_date "1971-08-16 00:00:10" save_tag c2 unique_commit c2 tree -p c1 -p b2 +on_committer_date "1971-08-16 00:00:11" save_tag c3 unique_commit c3 tree -p c2 +on_committer_date "1971-08-16 00:00:12" save_tag a2 unique_commit a2 tree -p a1 +on_committer_date "1971-08-16 00:00:13" save_tag a3 unique_commit a3 tree -p a2 +on_committer_date "1971-08-16 00:00:14" save_tag b4 unique_commit b4 tree -p b3 -p a3 +on_committer_date "1971-08-16 00:00:15" save_tag a4 unique_commit a4 tree -p a3 -p b4 -p c3 +on_committer_date "1971-08-16 00:00:16" save_tag l3 unique_commit l3 tree -p a4 +on_committer_date "1971-08-16 00:00:17" save_tag l4 unique_commit l4 tree -p l3 +on_committer_date "1971-08-16 00:00:18" save_tag l5 unique_commit l5 tree -p l4 +git update-ref HEAD $(tag l5) + + +# E +# / \ +# e1 | +# | | +# e2 | +# | | +# e3 | +# | | +# e4 | +# | | +# | f1 +# | | +# | f2 +# | | +# | f3 +# | | +# | f4 +# | | +# e5 | +# | | +# e6 | +# | | +# e7 | +# | | +# e8 | +# \ / +# F + + +on_committer_date "1971-08-16 00:00:00" hide_error save_tag F unique_commit F tree +on_committer_date "1971-08-16 00:00:01" save_tag e8 unique_commit e8 tree -p F +on_committer_date "1971-08-16 00:00:02" save_tag e7 unique_commit e7 tree -p e8 +on_committer_date "1971-08-16 00:00:03" save_tag e6 unique_commit e6 tree -p e7 +on_committer_date "1971-08-16 00:00:04" save_tag e5 unique_commit e5 tree -p e6 +on_committer_date "1971-08-16 00:00:05" save_tag f4 unique_commit f4 tree -p F +on_committer_date "1971-08-16 00:00:06" save_tag f3 unique_commit f3 tree -p f4 +on_committer_date "1971-08-16 00:00:07" save_tag f2 unique_commit f2 tree -p f3 +on_committer_date "1971-08-16 00:00:08" save_tag f1 unique_commit f1 tree -p f2 +on_committer_date "1971-08-16 00:00:09" save_tag e4 unique_commit e4 tree -p e5 +on_committer_date "1971-08-16 00:00:10" save_tag e3 unique_commit e3 tree -p e4 +on_committer_date "1971-08-16 00:00:11" save_tag e2 unique_commit e2 tree -p e3 +on_committer_date "1971-08-16 00:00:12" save_tag e1 unique_commit e1 tree -p e2 +on_committer_date "1971-08-16 00:00:13" save_tag E unique_commit E tree -p e1 -p f1 + +on_committer_date "1971-08-16 00:00:00" hide_error save_tag U unique_commit U tree +on_committer_date "1971-08-16 00:00:01" save_tag u0 unique_commit u0 tree -p U +on_committer_date "1971-08-16 00:00:01" save_tag u1 unique_commit u1 tree -p u0 +on_committer_date "1971-08-16 00:00:02" save_tag u2 unique_commit u2 tree -p u0 +on_committer_date "1971-08-16 00:00:03" save_tag u3 unique_commit u3 tree -p u0 +on_committer_date "1971-08-16 00:00:04" save_tag u4 unique_commit u4 tree -p u0 +on_committer_date "1971-08-16 00:00:05" save_tag u5 unique_commit u5 tree -p u0 +on_committer_date "1971-08-16 00:00:06" save_tag V unique_commit V tree -p u1 -p u2 -p u3 -p u4 -p u5 + +test_sequence() +{ + _bisect_option=$1 + + test_bisection_diff 0 $_bisect_option l0 ^root + test_bisection_diff 0 $_bisect_option l1 ^root + test_bisection_diff 0 $_bisect_option l2 ^root + test_bisection_diff 0 $_bisect_option a0 ^root + test_bisection_diff 0 $_bisect_option a1 ^root + test_bisection_diff 0 $_bisect_option a2 ^root + test_bisection_diff 0 $_bisect_option a3 ^root + test_bisection_diff 0 $_bisect_option b1 ^root + test_bisection_diff 0 $_bisect_option b2 ^root + test_bisection_diff 0 $_bisect_option b3 ^root + test_bisection_diff 0 $_bisect_option c1 ^root + test_bisection_diff 0 $_bisect_option c2 ^root + test_bisection_diff 0 $_bisect_option c3 ^root + test_bisection_diff 0 $_bisect_option E ^F + test_bisection_diff 0 $_bisect_option e1 ^F + test_bisection_diff 0 $_bisect_option e2 ^F + test_bisection_diff 0 $_bisect_option e3 ^F + test_bisection_diff 0 $_bisect_option e4 ^F + test_bisection_diff 0 $_bisect_option e5 ^F + test_bisection_diff 0 $_bisect_option e6 ^F + test_bisection_diff 0 $_bisect_option e7 ^F + test_bisection_diff 0 $_bisect_option f1 ^F + test_bisection_diff 0 $_bisect_option f2 ^F + test_bisection_diff 0 $_bisect_option f3 ^F + test_bisection_diff 0 $_bisect_option f4 ^F + test_bisection_diff 0 $_bisect_option E ^F + + test_bisection_diff 1 $_bisect_option V ^U + test_bisection_diff 0 $_bisect_option V ^U ^u1 ^u2 ^u3 + test_bisection_diff 0 $_bisect_option u1 ^U + test_bisection_diff 0 $_bisect_option u2 ^U + test_bisection_diff 0 $_bisect_option u3 ^U + test_bisection_diff 0 $_bisect_option u4 ^U + test_bisection_diff 0 $_bisect_option u5 ^U + +# +# the following illustrates Linus' binary bug blatt idea. +# +# assume the bug is actually at l3, but you don't know that - all you know is that l3 is broken +# and it wasn't broken before +# +# keep bisecting the list, advancing the "bad" head and accumulating "good" heads until +# the bisection point is the head - this is the bad point. +# + +test_output_expect_success "$_bisect_option l5 ^root" 'git rev-list $_bisect_option l5 ^root' <<EOF +c3 +EOF + +test_output_expect_success "$_bisect_option l5 ^root ^c3" 'git rev-list $_bisect_option l5 ^root ^c3' <<EOF +b4 +EOF + +test_output_expect_success "$_bisect_option l5 ^root ^c3 ^b4" 'git rev-list $_bisect_option l5 ^c3 ^b4' <<EOF +l3 +EOF + +test_output_expect_success "$_bisect_option l3 ^root ^c3 ^b4" 'git rev-list $_bisect_option l3 ^root ^c3 ^b4' <<EOF +a4 +EOF + +test_output_expect_success "$_bisect_option l5 ^b3 ^a3 ^b4 ^a4" 'git rev-list $_bisect_option l3 ^b3 ^a3 ^a4' <<EOF +l3 +EOF + +# +# if l3 is bad, then l4 is bad too - so advance the bad pointer by making b4 the known bad head +# + +test_output_expect_success "$_bisect_option l4 ^a2 ^a3 ^b ^a4" 'git rev-list $_bisect_option l4 ^a2 ^a3 ^a4' <<EOF +l3 +EOF + +test_output_expect_success "$_bisect_option l3 ^a2 ^a3 ^b ^a4" 'git rev-list $_bisect_option l3 ^a2 ^a3 ^a4' <<EOF +l3 +EOF + +# found! + +# +# as another example, let's consider a4 to be the bad head, in which case +# + +test_output_expect_success "$_bisect_option a4 ^a2 ^a3 ^b4" 'git rev-list $_bisect_option a4 ^a2 ^a3 ^b4' <<EOF +c2 +EOF + +test_output_expect_success "$_bisect_option a4 ^a2 ^a3 ^b4 ^c2" 'git rev-list $_bisect_option a4 ^a2 ^a3 ^b4 ^c2' <<EOF +c3 +EOF + +test_output_expect_success "$_bisect_option a4 ^a2 ^a3 ^b4 ^c2 ^c3" 'git rev-list $_bisect_option a4 ^a2 ^a3 ^b4 ^c2 ^c3' <<EOF +a4 +EOF + +# found! + +# +# or consider c3 to be the bad head +# + +test_output_expect_success "$_bisect_option a4 ^a2 ^a3 ^b4" 'git rev-list $_bisect_option a4 ^a2 ^a3 ^b4' <<EOF +c2 +EOF + +test_output_expect_success "$_bisect_option c3 ^a2 ^a3 ^b4 ^c2" 'git rev-list $_bisect_option c3 ^a2 ^a3 ^b4 ^c2' <<EOF +c3 +EOF + +# found! + +} + +test_sequence "--bisect" + +# +# +test_done diff --git a/t/t6003-rev-list-topo-order.sh b/t/t6003-rev-list-topo-order.sh new file mode 100755 index 0000000000..5daa0be8cc --- /dev/null +++ b/t/t6003-rev-list-topo-order.sh @@ -0,0 +1,408 @@ +#!/bin/sh +# +# Copyright (c) 2005 Jon Seymour +# + +test_description='Tests git rev-list --topo-order functionality' + +. ./test-lib.sh +. ../t6000lib.sh # t6xxx specific functions + +list_duplicates() +{ + "$@" | sort | uniq -d +} + +date >path0 +git update-index --add path0 +save_tag tree git write-tree +on_committer_date "1971-08-16 00:00:00" hide_error save_tag root unique_commit root tree +on_committer_date "1971-08-16 00:00:01" save_tag l0 unique_commit l0 tree -p root +on_committer_date "1971-08-16 00:00:02" save_tag l1 unique_commit l1 tree -p l0 +on_committer_date "1971-08-16 00:00:03" save_tag l2 unique_commit l2 tree -p l1 +on_committer_date "1971-08-16 00:00:04" save_tag a0 unique_commit a0 tree -p l2 +on_committer_date "1971-08-16 00:00:05" save_tag a1 unique_commit a1 tree -p a0 +on_committer_date "1971-08-16 00:00:06" save_tag b1 unique_commit b1 tree -p a0 +on_committer_date "1971-08-16 00:00:07" save_tag c1 unique_commit c1 tree -p b1 +on_committer_date "1971-08-16 00:00:08" as_author foobar@example.com save_tag b2 unique_commit b2 tree -p b1 +on_committer_date "1971-08-16 00:00:09" save_tag b3 unique_commit b3 tree -p b2 +on_committer_date "1971-08-16 00:00:10" save_tag c2 unique_commit c2 tree -p c1 -p b2 +on_committer_date "1971-08-16 00:00:11" save_tag c3 unique_commit c3 tree -p c2 +on_committer_date "1971-08-16 00:00:12" save_tag a2 unique_commit a2 tree -p a1 +on_committer_date "1971-08-16 00:00:13" save_tag a3 unique_commit a3 tree -p a2 +on_committer_date "1971-08-16 00:00:14" save_tag b4 unique_commit b4 tree -p b3 -p a3 +on_committer_date "1971-08-16 00:00:15" save_tag a4 unique_commit a4 tree -p a3 -p b4 -p c3 +on_committer_date "1971-08-16 00:00:16" save_tag l3 unique_commit l3 tree -p a4 +on_committer_date "1971-08-16 00:00:17" save_tag l4 unique_commit l4 tree -p l3 +on_committer_date "1971-08-16 00:00:18" save_tag l5 unique_commit l5 tree -p l4 +on_committer_date "1971-08-16 00:00:19" save_tag m1 unique_commit m1 tree -p a4 -p c3 +on_committer_date "1971-08-16 00:00:20" save_tag m2 unique_commit m2 tree -p c3 -p a4 +on_committer_date "1971-08-16 00:00:21" hide_error save_tag alt_root unique_commit alt_root tree +on_committer_date "1971-08-16 00:00:22" save_tag r0 unique_commit r0 tree -p alt_root +on_committer_date "1971-08-16 00:00:23" save_tag r1 unique_commit r1 tree -p r0 +on_committer_date "1971-08-16 00:00:24" save_tag l5r1 unique_commit l5r1 tree -p l5 -p r1 +on_committer_date "1971-08-16 00:00:25" save_tag r1l5 unique_commit r1l5 tree -p r1 -p l5 + + +# +# note: as of 20/6, it isn't possible to create duplicate parents, so this +# can't be tested. +# +#on_committer_date "1971-08-16 00:00:20" save_tag m3 unique_commit m3 tree -p c3 -p a4 -p c3 +hide_error save_tag e1 as_author e@example.com unique_commit e1 tree +save_tag e2 as_author e@example.com unique_commit e2 tree -p e1 +save_tag f1 as_author f@example.com unique_commit f1 tree -p e1 +save_tag e3 as_author e@example.com unique_commit e3 tree -p e2 +save_tag f2 as_author f@example.com unique_commit f2 tree -p f1 +save_tag e4 as_author e@example.com unique_commit e4 tree -p e3 -p f2 +save_tag e5 as_author e@example.com unique_commit e5 tree -p e4 +save_tag f3 as_author f@example.com unique_commit f3 tree -p f2 +save_tag f4 as_author f@example.com unique_commit f4 tree -p f3 +save_tag e6 as_author e@example.com unique_commit e6 tree -p e5 -p f4 +save_tag f5 as_author f@example.com unique_commit f5 tree -p f4 +save_tag f6 as_author f@example.com unique_commit f6 tree -p f5 -p e6 +save_tag e7 as_author e@example.com unique_commit e7 tree -p e6 +save_tag e8 as_author e@example.com unique_commit e8 tree -p e7 +save_tag e9 as_author e@example.com unique_commit e9 tree -p e8 +save_tag f7 as_author f@example.com unique_commit f7 tree -p f6 +save_tag f8 as_author f@example.com unique_commit f8 tree -p f7 +save_tag f9 as_author f@example.com unique_commit f9 tree -p f8 +save_tag e10 as_author e@example.com unique_commit e1 tree -p e9 -p f8 + +hide_error save_tag g0 unique_commit g0 tree +save_tag g1 unique_commit g1 tree -p g0 +save_tag h1 unique_commit g2 tree -p g0 +save_tag g2 unique_commit g3 tree -p g1 -p h1 +save_tag h2 unique_commit g4 tree -p g2 +save_tag g3 unique_commit g5 tree -p g2 +save_tag g4 unique_commit g6 tree -p g3 -p h2 + +git update-ref HEAD $(tag l5) + +test_output_expect_success 'rev-list has correct number of entries' 'git rev-list HEAD | wc -l | tr -d \" \"' <<EOF +19 +EOF + +test_output_expect_success 'simple topo order' 'git rev-list --topo-order HEAD' <<EOF +l5 +l4 +l3 +a4 +c3 +c2 +c1 +b4 +a3 +a2 +a1 +b3 +b2 +b1 +a0 +l2 +l1 +l0 +root +EOF + +test_output_expect_success 'two diamonds topo order (g6)' 'git rev-list --topo-order g4' <<EOF +g4 +h2 +g3 +g2 +h1 +g1 +g0 +EOF + +test_output_expect_success 'multiple heads' 'git rev-list --topo-order a3 b3 c3' <<EOF +a3 +a2 +a1 +c3 +c2 +c1 +b3 +b2 +b1 +a0 +l2 +l1 +l0 +root +EOF + +test_output_expect_success 'multiple heads, prune at a1' 'git rev-list --topo-order a3 b3 c3 ^a1' <<EOF +a3 +a2 +c3 +c2 +c1 +b3 +b2 +b1 +EOF + +test_output_expect_success 'multiple heads, prune at l1' 'git rev-list --topo-order a3 b3 c3 ^l1' <<EOF +a3 +a2 +a1 +c3 +c2 +c1 +b3 +b2 +b1 +a0 +l2 +EOF + +test_output_expect_success 'cross-epoch, head at l5, prune at l1' 'git rev-list --topo-order l5 ^l1' <<EOF +l5 +l4 +l3 +a4 +c3 +c2 +c1 +b4 +a3 +a2 +a1 +b3 +b2 +b1 +a0 +l2 +EOF + +test_output_expect_success 'duplicated head arguments' 'git rev-list --topo-order l5 l5 ^l1' <<EOF +l5 +l4 +l3 +a4 +c3 +c2 +c1 +b4 +a3 +a2 +a1 +b3 +b2 +b1 +a0 +l2 +EOF + +test_output_expect_success 'prune near topo' 'git rev-list --topo-order a4 ^c3' <<EOF +a4 +b4 +a3 +a2 +a1 +b3 +EOF + +test_output_expect_success "head has no parent" 'git rev-list --topo-order root' <<EOF +root +EOF + +test_output_expect_success "two nodes - one head, one base" 'git rev-list --topo-order l0' <<EOF +l0 +root +EOF + +test_output_expect_success "three nodes one head, one internal, one base" 'git rev-list --topo-order l1' <<EOF +l1 +l0 +root +EOF + +test_output_expect_success "linear prune l2 ^root" 'git rev-list --topo-order l2 ^root' <<EOF +l2 +l1 +l0 +EOF + +test_output_expect_success "linear prune l2 ^l0" 'git rev-list --topo-order l2 ^l0' <<EOF +l2 +l1 +EOF + +test_output_expect_success "linear prune l2 ^l1" 'git rev-list --topo-order l2 ^l1' <<EOF +l2 +EOF + +test_output_expect_success "linear prune l5 ^a4" 'git rev-list --topo-order l5 ^a4' <<EOF +l5 +l4 +l3 +EOF + +test_output_expect_success "linear prune l5 ^l3" 'git rev-list --topo-order l5 ^l3' <<EOF +l5 +l4 +EOF + +test_output_expect_success "linear prune l5 ^l4" 'git rev-list --topo-order l5 ^l4' <<EOF +l5 +EOF + +test_output_expect_success "max-count 10 - topo order" 'git rev-list --topo-order --max-count=10 l5' <<EOF +l5 +l4 +l3 +a4 +c3 +c2 +c1 +b4 +a3 +a2 +EOF + +test_output_expect_success "max-count 10 - non topo order" 'git rev-list --max-count=10 l5' <<EOF +l5 +l4 +l3 +a4 +b4 +a3 +a2 +c3 +c2 +b3 +EOF + +test_output_expect_success '--max-age=c3, no --topo-order' "git rev-list --max-age=$(commit_date c3) l5" <<EOF +l5 +l4 +l3 +a4 +b4 +a3 +a2 +c3 +EOF + +# +# this test fails on --topo-order - a fix is required +# +#test_output_expect_success '--max-age=c3, --topo-order' "git rev-list --topo-order --max-age=$(commit_date c3) l5" <<EOF +#l5 +#l4 +#l3 +#a4 +#c3 +#b4 +#a3 +#a2 +#EOF + +test_output_expect_success 'one specified head reachable from another a4, c3, --topo-order' "list_duplicates git rev-list --topo-order a4 c3" <<EOF +EOF + +test_output_expect_success 'one specified head reachable from another c3, a4, --topo-order' "list_duplicates git rev-list --topo-order c3 a4" <<EOF +EOF + +test_output_expect_success 'one specified head reachable from another a4, c3, no --topo-order' "list_duplicates git rev-list a4 c3" <<EOF +EOF + +test_output_expect_success 'one specified head reachable from another c3, a4, no --topo-order' "list_duplicates git rev-list c3 a4" <<EOF +EOF + +test_output_expect_success 'graph with c3 and a4 parents of head' "list_duplicates git rev-list m1" <<EOF +EOF + +test_output_expect_success 'graph with a4 and c3 parents of head' "list_duplicates git rev-list m2" <<EOF +EOF + +test_expect_success "head ^head --topo-order" 'git rev-list --topo-order a3 ^a3' <<EOF +EOF + +test_expect_success "head ^head no --topo-order" 'git rev-list a3 ^a3' <<EOF +EOF + +test_output_expect_success 'simple topo order (l5r1)' 'git rev-list --topo-order l5r1' <<EOF +l5r1 +r1 +r0 +alt_root +l5 +l4 +l3 +a4 +c3 +c2 +c1 +b4 +a3 +a2 +a1 +b3 +b2 +b1 +a0 +l2 +l1 +l0 +root +EOF + +test_output_expect_success 'simple topo order (r1l5)' 'git rev-list --topo-order r1l5' <<EOF +r1l5 +l5 +l4 +l3 +a4 +c3 +c2 +c1 +b4 +a3 +a2 +a1 +b3 +b2 +b1 +a0 +l2 +l1 +l0 +root +r1 +r0 +alt_root +EOF + +test_output_expect_success "don't print things unreachable from one branch" "git rev-list a3 ^b3 --topo-order" <<EOF +a3 +a2 +a1 +EOF + +test_output_expect_success "--topo-order a4 l3" "git rev-list --topo-order a4 l3" <<EOF +l3 +a4 +c3 +c2 +c1 +b4 +a3 +a2 +a1 +b3 +b2 +b1 +a0 +l2 +l1 +l0 +root +EOF + +# +# + +test_done diff --git a/t/t6004-rev-list-path-optim.sh b/t/t6004-rev-list-path-optim.sh new file mode 100755 index 0000000000..5dabf1c5e3 --- /dev/null +++ b/t/t6004-rev-list-path-optim.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +test_description='git rev-list trivial path optimization test' + +. ./test-lib.sh + +test_expect_success setup ' +echo Hello > a && +git add a && +git commit -m "Initial commit" a && +initial=$(git rev-parse --verify HEAD) +' + +test_expect_success path-optimization ' + commit=$(echo "Unchanged tree" | git commit-tree "HEAD^{tree}" -p HEAD) && + test $(git rev-list $commit | wc -l) = 2 && + test $(git rev-list $commit -- . | wc -l) = 1 +' + +test_expect_success 'further setup' ' + git checkout -b side && + echo Irrelevant >c && + git add c && + git commit -m "Side makes an irrelevant commit" && + echo "More Irrelevancy" >c && + git add c && + git commit -m "Side makes another irrelevant commit" && + echo Bye >a && + git add a && + git commit -m "Side touches a" && + side=$(git rev-parse --verify HEAD) && + echo "Yet more Irrelevancy" >c && + git add c && + git commit -m "Side makes yet another irrelevant commit" && + git checkout master && + echo Another >b && + git add b && + git commit -m "Master touches b" && + git merge side && + echo Touched >b && + git add b && + git commit -m "Master touches b again" +' + +test_expect_success 'path optimization 2' ' + ( echo "$side"; echo "$initial" ) >expected && + git rev-list HEAD -- a >actual && + test_cmp expected actual +' + +test_done diff --git a/t/t6005-rev-list-count.sh b/t/t6005-rev-list-count.sh new file mode 100755 index 0000000000..0b64822bf6 --- /dev/null +++ b/t/t6005-rev-list-count.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +test_description='git rev-list --max-count and --skip test' + +. ./test-lib.sh + +test_expect_success 'setup' ' + for n in 1 2 3 4 5 ; do \ + echo $n > a ; \ + git add a ; \ + git commit -m "$n" ; \ + done +' + +test_expect_success 'no options' ' + test $(git rev-list HEAD | wc -l) = 5 +' + +test_expect_success '--max-count' ' + test $(git rev-list HEAD --max-count=0 | wc -l) = 0 && + test $(git rev-list HEAD --max-count=3 | wc -l) = 3 && + test $(git rev-list HEAD --max-count=5 | wc -l) = 5 && + test $(git rev-list HEAD --max-count=10 | wc -l) = 5 +' + +test_expect_success '--max-count all forms' ' + test $(git rev-list HEAD --max-count=1 | wc -l) = 1 && + test $(git rev-list HEAD -1 | wc -l) = 1 && + test $(git rev-list HEAD -n1 | wc -l) = 1 && + test $(git rev-list HEAD -n 1 | wc -l) = 1 +' + +test_expect_success '--skip' ' + test $(git rev-list HEAD --skip=0 | wc -l) = 5 && + test $(git rev-list HEAD --skip=3 | wc -l) = 2 && + test $(git rev-list HEAD --skip=5 | wc -l) = 0 && + test $(git rev-list HEAD --skip=10 | wc -l) = 0 +' + +test_expect_success '--skip --max-count' ' + test $(git rev-list HEAD --skip=0 --max-count=0 | wc -l) = 0 && + test $(git rev-list HEAD --skip=0 --max-count=10 | wc -l) = 5 && + test $(git rev-list HEAD --skip=3 --max-count=0 | wc -l) = 0 && + test $(git rev-list HEAD --skip=3 --max-count=1 | wc -l) = 1 && + test $(git rev-list HEAD --skip=3 --max-count=2 | wc -l) = 2 && + test $(git rev-list HEAD --skip=3 --max-count=10 | wc -l) = 2 && + test $(git rev-list HEAD --skip=5 --max-count=10 | wc -l) = 0 && + test $(git rev-list HEAD --skip=10 --max-count=10 | wc -l) = 0 +' + +test_done diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh new file mode 100755 index 0000000000..9176484db2 --- /dev/null +++ b/t/t6006-rev-list-format.sh @@ -0,0 +1,152 @@ +#!/bin/sh + +test_description='git rev-list --pretty=format test' + +. ./test-lib.sh + +test_tick +test_expect_success 'setup' ' +touch foo && git add foo && git-commit -m "added foo" && + echo changed >foo && git-commit -a -m "changed foo" +' + +# usage: test_format name format_string <expected_output +test_format() { + cat >expect.$1 + test_expect_success "format $1" " +git rev-list --pretty=format:$2 master >output.$1 && +test_cmp expect.$1 output.$1 +" +} + +test_format hash %H%n%h <<'EOF' +commit 131a310eb913d107dd3c09a65d1651175898735d +131a310eb913d107dd3c09a65d1651175898735d +131a310 +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +86c75cf +EOF + +test_format tree %T%n%t <<'EOF' +commit 131a310eb913d107dd3c09a65d1651175898735d +fe722612f26da5064c32ca3843aa154bdb0b08a0 +fe72261 +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +4d5fcadc293a348e88f777dc0920f11e7d71441c +4d5fcad +EOF + +test_format parents %P%n%p <<'EOF' +commit 131a310eb913d107dd3c09a65d1651175898735d +86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +86c75cf +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 + + +EOF + +# we don't test relative here +test_format author %an%n%ae%n%ad%n%aD%n%at <<'EOF' +commit 131a310eb913d107dd3c09a65d1651175898735d +A U Thor +author@example.com +Thu Apr 7 15:13:13 2005 -0700 +Thu, 7 Apr 2005 15:13:13 -0700 +1112911993 +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +A U Thor +author@example.com +Thu Apr 7 15:13:13 2005 -0700 +Thu, 7 Apr 2005 15:13:13 -0700 +1112911993 +EOF + +test_format committer %cn%n%ce%n%cd%n%cD%n%ct <<'EOF' +commit 131a310eb913d107dd3c09a65d1651175898735d +C O Mitter +committer@example.com +Thu Apr 7 15:13:13 2005 -0700 +Thu, 7 Apr 2005 15:13:13 -0700 +1112911993 +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +C O Mitter +committer@example.com +Thu Apr 7 15:13:13 2005 -0700 +Thu, 7 Apr 2005 15:13:13 -0700 +1112911993 +EOF + +test_format encoding %e <<'EOF' +commit 131a310eb913d107dd3c09a65d1651175898735d +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +EOF + +test_format subject %s <<'EOF' +commit 131a310eb913d107dd3c09a65d1651175898735d +changed foo +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +added foo +EOF + +test_format body %b <<'EOF' +commit 131a310eb913d107dd3c09a65d1651175898735d +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +EOF + +test_format colors %Credfoo%Cgreenbar%Cbluebaz%Cresetxyzzy <<'EOF' +commit 131a310eb913d107dd3c09a65d1651175898735d +[31mfoo[32mbar[34mbaz[mxyzzy +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +[31mfoo[32mbar[34mbaz[mxyzzy +EOF + +cat >commit-msg <<'EOF' +Test printing of complex bodies + +This commit message is much longer than the others, +and it will be encoded in iso8859-1. We should therefore +include an iso8859 character: ¡bueno! +EOF +test_expect_success 'setup complex body' ' +git config i18n.commitencoding iso8859-1 && + echo change2 >foo && git-commit -a -F commit-msg +' + +test_format complex-encoding %e <<'EOF' +commit f58db70b055c5718631e5c61528b28b12090cdea +iso8859-1 +commit 131a310eb913d107dd3c09a65d1651175898735d +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +EOF + +test_format complex-subject %s <<'EOF' +commit f58db70b055c5718631e5c61528b28b12090cdea +Test printing of complex bodies +commit 131a310eb913d107dd3c09a65d1651175898735d +changed foo +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +added foo +EOF + +test_format complex-body %b <<'EOF' +commit f58db70b055c5718631e5c61528b28b12090cdea +This commit message is much longer than the others, +and it will be encoded in iso8859-1. We should therefore +include an iso8859 character: ¡bueno! + +commit 131a310eb913d107dd3c09a65d1651175898735d +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +EOF + +test_expect_success 'empty email' ' + test_tick && + C=$(GIT_AUTHOR_EMAIL= git commit-tree HEAD^{tree} </dev/null) && + A=$(git show --pretty=format:%an,%ae,%ad%n -s $C) && + test "$A" = "A U Thor,,Thu Apr 7 15:14:13 2005 -0700" || { + echo "Eh? $A" >failure + false + } +' + +test_done diff --git a/t/t6007-rev-list-cherry-pick-file.sh b/t/t6007-rev-list-cherry-pick-file.sh new file mode 100755 index 0000000000..4b8611ce20 --- /dev/null +++ b/t/t6007-rev-list-cherry-pick-file.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +test_description='test git rev-list --cherry-pick -- file' + +. ./test-lib.sh + +# A---B +# \ +# \ +# C +# +# B changes a file foo.c, adding a line of text. C changes foo.c as +# well as bar.c, but the change in foo.c was identical to change B. + +test_expect_success setup ' + echo Hallo > foo && + git add foo && + test_tick && + git commit -m "A" && + git tag A && + git checkout -b branch && + echo Bello > foo && + echo Cello > bar && + git add foo bar && + test_tick && + git commit -m "C" && + git tag C && + git checkout master && + git checkout branch foo && + test_tick && + git commit -m "B" && + git tag B +' + +test_expect_success '--cherry-pick foo comes up empty' ' + test -z "$(git rev-list --left-right --cherry-pick B...C -- foo)" +' + +test_expect_success '--cherry-pick bar does not come up empty' ' + ! test -z "$(git rev-list --left-right --cherry-pick B...C -- bar)" +' + +test_expect_success '--cherry-pick with independent, but identical branches' ' + git symbolic-ref HEAD refs/heads/independent && + rm .git/index && + echo Hallo > foo && + git add foo && + test_tick && + git commit -m "independent" && + echo Bello > foo && + test_tick && + git commit -m "independent, too" foo && + test -z "$(git rev-list --left-right --cherry-pick \ + HEAD...master -- foo)" +' + +test_done diff --git a/t/t6008-rev-list-submodule.sh b/t/t6008-rev-list-submodule.sh new file mode 100755 index 0000000000..c4af9ca0a7 --- /dev/null +++ b/t/t6008-rev-list-submodule.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes E. Schindelin +# + +test_description='git rev-list involving submodules that this repo has' + +. ./test-lib.sh + +test_expect_success 'setup' ' + : > file && + git add file && + test_tick && + git commit -m initial && + echo 1 > file && + test_tick && + git commit -m second file && + echo 2 > file && + test_tick && + git commit -m third file && + + rm .git/index && + + : > super-file && + git add super-file && + git submodule add "$(pwd)" sub && + git symbolic-ref HEAD refs/heads/super && + test_tick && + git commit -m super-initial && + echo 1 > super-file && + test_tick && + git commit -m super-first super-file && + echo 2 > super-file && + test_tick && + git commit -m super-second super-file +' + +test_expect_success "Ilari's test" ' + git rev-list --objects super master ^super^ +' + +test_done diff --git a/t/t6009-rev-list-parent.sh b/t/t6009-rev-list-parent.sh new file mode 100755 index 0000000000..c8a96a9a99 --- /dev/null +++ b/t/t6009-rev-list-parent.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +test_description='properly cull all ancestors' + +. ./test-lib.sh + +commit () { + test_tick && + echo $1 >file && + git commit -a -m $1 && + git tag $1 +} + +test_expect_success setup ' + + touch file && + git add file && + + commit one && + + test_tick=$(($test_tick - 2400)) + + commit two && + commit three && + commit four && + + git log --pretty=oneline --abbrev-commit +' + +test_expect_success 'one is ancestor of others and should not be shown' ' + + git rev-list one --not four >result && + >expect && + test_cmp expect result + +' + +test_done diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh new file mode 100755 index 0000000000..b6e57b2426 --- /dev/null +++ b/t/t6010-merge-base.sh @@ -0,0 +1,111 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='Merge base computation. +' + +. ./test-lib.sh + +T=$(git write-tree) + +M=1130000000 +Z=+0000 + +GIT_COMMITTER_EMAIL=git@comm.iter.xz +GIT_COMMITTER_NAME='C O Mmiter' +GIT_AUTHOR_NAME='A U Thor' +GIT_AUTHOR_EMAIL=git@au.thor.xz +export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL + +doit() { + OFFSET=$1; shift + NAME=$1; shift + PARENTS= + for P + do + PARENTS="${PARENTS}-p $P " + done + GIT_COMMITTER_DATE="$(($M + $OFFSET)) $Z" + GIT_AUTHOR_DATE=$GIT_COMMITTER_DATE + export GIT_COMMITTER_DATE GIT_AUTHOR_DATE + commit=$(echo $NAME | git commit-tree $T $PARENTS) + echo $commit >.git/refs/tags/$NAME + echo $commit +} + +# E---D---C---B---A +# \'-_ \ \ +# \ `---------G \ +# \ \ +# F----------------H + +# Setup... +E=$(doit 5 E) +D=$(doit 4 D $E) +F=$(doit 6 F $E) +C=$(doit 3 C $D) +B=$(doit 2 B $C) +A=$(doit 1 A $B) +G=$(doit 7 G $B $E) +H=$(doit 8 H $A $F) + +test_expect_success 'compute merge-base (single)' \ + 'MB=$(git merge-base G H) && + expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/B"' + +test_expect_success 'compute merge-base (all)' \ + 'MB=$(git merge-base --all G H) && + expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/B"' + +test_expect_success 'compute merge-base with show-branch' \ + 'MB=$(git show-branch --merge-base G H) && + expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/B"' + +# Setup for second test to demonstrate that relying on timestamps in a +# distributed SCM to provide a _consistent_ partial ordering of commits +# leads to insanity. +# +# Relative +# Structure timestamps +# +# PL PR +4 +4 +# / \/ \ / \/ \ +# L2 C2 R2 +3 -1 +3 +# | | | | | | +# L1 C1 R1 +2 -2 +2 +# | | | | | | +# L0 C0 R0 +1 -3 +1 +# \ | / \ | / +# S 0 +# +# The left and right chains of commits can be of any length and complexity as +# long as all of the timestamps are greater than that of S. + +S=$(doit 0 S) + +C0=$(doit -3 C0 $S) +C1=$(doit -2 C1 $C0) +C2=$(doit -1 C2 $C1) + +L0=$(doit 1 L0 $S) +L1=$(doit 2 L1 $L0) +L2=$(doit 3 L2 $L1) + +R0=$(doit 1 R0 $S) +R1=$(doit 2 R1 $R0) +R2=$(doit 3 R2 $R1) + +PL=$(doit 4 PL $L2 $C2) +PR=$(doit 4 PR $C2 $R2) + +test_expect_success 'compute merge-base (single)' \ + 'MB=$(git merge-base PL PR) && + expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/C2"' + +test_expect_success 'compute merge-base (all)' \ + 'MB=$(git merge-base --all PL PR) && + expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/C2"' + +test_done diff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh new file mode 100755 index 0000000000..e51eb41f4b --- /dev/null +++ b/t/t6011-rev-list-with-bad-commit.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +test_description='git rev-list should notice bad commits' + +. ./test-lib.sh + +# Note: +# - compression level is set to zero to make "corruptions" easier to perform +# - reflog is disabled to avoid extra references which would twart the test + +test_expect_success 'setup' \ + ' + git init && + git config core.compression 0 && + git config core.logallrefupdates false && + echo "foo" > foo && + git add foo && + git commit -m "first commit" && + echo "bar" > bar && + git add bar && + git commit -m "second commit" && + echo "baz" > baz && + git add baz && + git commit -m "third commit" && + echo "foo again" >> foo && + git add foo && + git commit -m "fourth commit" && + git repack -a -f -d + ' + +test_expect_success 'verify number of revisions' \ + ' + revs=$(git rev-list --all | wc -l) && + test $revs -eq 4 && + first_commit=$(git rev-parse HEAD~3) + ' + +test_expect_success 'corrupt second commit object' \ + ' + perl -i.bak -pe "s/second commit/socond commit/" .git/objects/pack/*.pack && + test_must_fail git fsck --full + ' + +test_expect_success 'rev-list should fail' \ + ' + test_must_fail git rev-list --all > /dev/null + ' + +test_expect_success 'git repack _MUST_ fail' \ + ' + test_must_fail git repack -a -f -d + ' + +test_expect_success 'first commit is still available' \ + ' + git log $first_commit + ' + +test_done + diff --git a/t/t6020-merge-df.sh b/t/t6020-merge-df.sh new file mode 100755 index 0000000000..a19d49de28 --- /dev/null +++ b/t/t6020-merge-df.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Copyright (c) 2005 Fredrik Kuivinen +# + +test_description='Test merge with directory/file conflicts' +. ./test-lib.sh + +test_expect_success 'prepare repository' \ +'echo "Hello" > init && +git add init && +git commit -m "Initial commit" && +git branch B && +mkdir dir && +echo "foo" > dir/foo && +git add dir/foo && +git commit -m "File: dir/foo" && +git checkout B && +echo "file dir" > dir && +git add dir && +git commit -m "File: dir"' + +test_expect_code 1 'Merge with d/f conflicts' 'git merge "merge msg" B master' + +test_done diff --git a/t/t6021-merge-criss-cross.sh b/t/t6021-merge-criss-cross.sh new file mode 100755 index 0000000000..331b9b07d4 --- /dev/null +++ b/t/t6021-merge-criss-cross.sh @@ -0,0 +1,96 @@ +#!/bin/sh +# +# Copyright (c) 2005 Fredrik Kuivinen +# + +# See http://marc.theaimsgroup.com/?l=git&m=111463358500362&w=2 for a +# nice description of what this is about. + + +test_description='Test criss-cross merge' +. ./test-lib.sh + +test_expect_success 'prepare repository' \ +'echo "1 +2 +3 +4 +5 +6 +7 +8 +9" > file && +git add file && +git commit -m "Initial commit" file && +git branch A && +git branch B && +git checkout A && +echo "1 +2 +3 +4 +5 +6 +7 +8 changed in B8, branch A +9" > file && +git commit -m "B8" file && +git checkout B && +echo "1 +2 +3 changed in C3, branch B +4 +5 +6 +7 +8 +9 +" > file && +git commit -m "C3" file && +git branch C3 && +git merge "pre E3 merge" B A && +echo "1 +2 +3 changed in E3, branch B. New file size +4 +5 +6 +7 +8 changed in B8, branch A +9 +" > file && +git commit -m "E3" file && +git checkout A && +git merge "pre D8 merge" A C3 && +echo "1 +2 +3 changed in C3, branch B +4 +5 +6 +7 +8 changed in D8, branch A. New file size 2 +9" > file && +git commit -m D8 file' + +test_expect_success 'Criss-cross merge' 'git merge "final merge" A B' + +cat > file-expect <<EOF +1 +2 +3 changed in E3, branch B. New file size +4 +5 +6 +7 +8 changed in D8, branch A. New file size 2 +9 +EOF + +test_expect_success 'Criss-cross merge result' 'cmp file file-expect' + +test_expect_success 'Criss-cross merge fails (-s resolve)' \ +'git reset --hard A^ && +test_must_fail git merge -s resolve -m "final merge" B' + +test_done diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh new file mode 100755 index 0000000000..e3f7ae8120 --- /dev/null +++ b/t/t6022-merge-rename.sh @@ -0,0 +1,344 @@ +#!/bin/sh + +test_description='Merge-recursive merging renames' +. ./test-lib.sh + +test_expect_success setup \ +' +cat >A <<\EOF && +a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +c cccccccccccccccccccccccccccccccccccccccccccccccc +d dddddddddddddddddddddddddddddddddddddddddddddddd +e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee +f ffffffffffffffffffffffffffffffffffffffffffffffff +g gggggggggggggggggggggggggggggggggggggggggggggggg +h hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh +i iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii +j jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj +k kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk +l llllllllllllllllllllllllllllllllllllllllllllllll +m mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm +n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn +o oooooooooooooooooooooooooooooooooooooooooooooooo +EOF + +cat >M <<\EOF && +A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB +C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD +E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +G GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG +H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH +I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII +J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ +K KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK +L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL +M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM +N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +O OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO +EOF + +git add A M && +git commit -m "initial has A and M" && +git branch white && +git branch red && +git branch blue && +git branch yellow && +git branch change && +git branch change+rename && + +sed -e "/^g /s/.*/g : master changes a line/" <A >A+ && +mv A+ A && +git commit -a -m "master updates A" && + +git checkout yellow && +rm -f M && +git commit -a -m "yellow removes M" && + +git checkout white && +sed -e "/^g /s/.*/g : white changes a line/" <A >B && +sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N && +rm -f A M && +git update-index --add --remove A B M N && +git commit -m "white renames A->B, M->N" && + +git checkout red && +sed -e "/^g /s/.*/g : red changes a line/" <A >B && +sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N && +rm -f A M && +git update-index --add --remove A B M N && +git commit -m "red renames A->B, M->N" && + +git checkout blue && +sed -e "/^g /s/.*/g : blue changes a line/" <A >C && +sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N && +rm -f A M && +git update-index --add --remove A C M N && +git commit -m "blue renames A->C, M->N" && + +git checkout change && +sed -e "/^g /s/.*/g : changed line/" <A >A+ && +mv A+ A && +git commit -q -a -m "changed" && + +git checkout change+rename && +sed -e "/^g /s/.*/g : changed line/" <A >B && +rm A && +git update-index --add B && +git commit -q -a -m "changed and renamed" && + +git checkout master' + +test_expect_success 'pull renaming branch into unrenaming one' \ +' + git show-branch + git pull . white && { + echo "BAD: should have conflicted" + return 1 + } + git ls-files -s + test "$(git ls-files -u B | wc -l)" -eq 3 || { + echo "BAD: should have left stages for B" + return 1 + } + test "$(git ls-files -s N | wc -l)" -eq 1 || { + echo "BAD: should have merged N" + return 1 + } + sed -ne "/^g/{ + p + q + }" B | grep master || { + echo "BAD: should have listed our change first" + return 1 + } + test "$(git diff white N | wc -l)" -eq 0 || { + echo "BAD: should have taken colored branch" + return 1 + } +' + +test_expect_success 'pull renaming branch into another renaming one' \ +' + rm -f B + git reset --hard + git checkout red + git pull . white && { + echo "BAD: should have conflicted" + return 1 + } + test "$(git ls-files -u B | wc -l)" -eq 3 || { + echo "BAD: should have left stages" + return 1 + } + test "$(git ls-files -s N | wc -l)" -eq 1 || { + echo "BAD: should have merged N" + return 1 + } + sed -ne "/^g/{ + p + q + }" B | grep red || { + echo "BAD: should have listed our change first" + return 1 + } + test "$(git diff white N | wc -l)" -eq 0 || { + echo "BAD: should have taken colored branch" + return 1 + } +' + +test_expect_success 'pull unrenaming branch into renaming one' \ +' + git reset --hard + git show-branch + git pull . master && { + echo "BAD: should have conflicted" + return 1 + } + test "$(git ls-files -u B | wc -l)" -eq 3 || { + echo "BAD: should have left stages" + return 1 + } + test "$(git ls-files -s N | wc -l)" -eq 1 || { + echo "BAD: should have merged N" + return 1 + } + sed -ne "/^g/{ + p + q + }" B | grep red || { + echo "BAD: should have listed our change first" + return 1 + } + test "$(git diff white N | wc -l)" -eq 0 || { + echo "BAD: should have taken colored branch" + return 1 + } +' + +test_expect_success 'pull conflicting renames' \ +' + git reset --hard + git show-branch + git pull . blue && { + echo "BAD: should have conflicted" + return 1 + } + test "$(git ls-files -u A | wc -l)" -eq 1 || { + echo "BAD: should have left a stage" + return 1 + } + test "$(git ls-files -u B | wc -l)" -eq 1 || { + echo "BAD: should have left a stage" + return 1 + } + test "$(git ls-files -u C | wc -l)" -eq 1 || { + echo "BAD: should have left a stage" + return 1 + } + test "$(git ls-files -s N | wc -l)" -eq 1 || { + echo "BAD: should have merged N" + return 1 + } + sed -ne "/^g/{ + p + q + }" B | grep red || { + echo "BAD: should have listed our change first" + return 1 + } + test "$(git diff white N | wc -l)" -eq 0 || { + echo "BAD: should have taken colored branch" + return 1 + } +' + +test_expect_success 'interference with untracked working tree file' ' + + git reset --hard + git show-branch + echo >A this file should not matter + git pull . white && { + echo "BAD: should have conflicted" + return 1 + } + test -f A || { + echo "BAD: should have left A intact" + return 1 + } +' + +test_expect_success 'interference with untracked working tree file' ' + + git reset --hard + git checkout white + git show-branch + rm -f A + echo >A this file should not matter + git pull . red && { + echo "BAD: should have conflicted" + return 1 + } + test -f A || { + echo "BAD: should have left A intact" + return 1 + } +' + +test_expect_success 'interference with untracked working tree file' ' + + git reset --hard + rm -f A M + git checkout -f master + git tag -f anchor + git show-branch + git pull . yellow || { + echo "BAD: should have cleanly merged" + return 1 + } + test -f M && { + echo "BAD: should have removed M" + return 1 + } + git reset --hard anchor +' + +test_expect_success 'updated working tree file should prevent the merge' ' + + git reset --hard + rm -f A M + git checkout -f master + git tag -f anchor + git show-branch + echo >>M one line addition + cat M >M.saved + git pull . yellow && { + echo "BAD: should have complained" + return 1 + } + diff M M.saved || { + echo "BAD: should have left M intact" + return 1 + } + rm -f M.saved +' + +test_expect_success 'updated working tree file should prevent the merge' ' + + git reset --hard + rm -f A M + git checkout -f master + git tag -f anchor + git show-branch + echo >>M one line addition + cat M >M.saved + git update-index M + git pull . yellow && { + echo "BAD: should have complained" + return 1 + } + diff M M.saved || { + echo "BAD: should have left M intact" + return 1 + } + rm -f M.saved +' + +test_expect_success 'interference with untracked working tree file' ' + + git reset --hard + rm -f A M + git checkout -f yellow + git tag -f anchor + git show-branch + echo >M this file should not matter + git pull . master || { + echo "BAD: should have cleanly merged" + return 1 + } + test -f M || { + echo "BAD: should have left M intact" + return 1 + } + git ls-files -s | grep M && { + echo "BAD: M must be untracked in the result" + return 1 + } + git reset --hard anchor +' + +test_expect_success 'merge of identical changes in a renamed file' ' + rm -f A M N + git reset --hard && + git checkout change+rename && + GIT_MERGE_VERBOSITY=3 git merge change | grep "^Skipped B" && + git reset --hard HEAD^ && + git checkout change && + GIT_MERGE_VERBOSITY=3 git merge change+rename | grep "^Skipped B" +' + +test_done diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh new file mode 100755 index 0000000000..f674c48cab --- /dev/null +++ b/t/t6023-merge-file.sh @@ -0,0 +1,164 @@ +#!/bin/sh + +test_description='RCS merge replacement: merge-file' +. ./test-lib.sh + +cat > orig.txt << EOF +Dominus regit me, +et nihil mihi deerit. +In loco pascuae ibi me collocavit, +super aquam refectionis educavit me; +animam meam convertit, +deduxit me super semitas jusitiae, +propter nomen suum. +EOF + +cat > new1.txt << EOF +Dominus regit me, +et nihil mihi deerit. +In loco pascuae ibi me collocavit, +super aquam refectionis educavit me; +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 + +cat > new2.txt << EOF +Dominus regit me, et nihil mihi deerit. +In loco pascuae ibi me collocavit, +super aquam refectionis educavit me; +animam meam convertit, +deduxit me super semitas jusitiae, +propter nomen suum. +EOF + +cat > new3.txt << EOF +DOMINUS regit me, +et nihil mihi deerit. +In loco pascuae ibi me collocavit, +super aquam refectionis educavit me; +animam meam convertit, +deduxit me super semitas jusitiae, +propter nomen suum. +EOF + +cat > new4.txt << EOF +Dominus regit me, et nihil mihi deerit. +In loco pascuae ibi me collocavit, +super aquam refectionis educavit me; +animam meam convertit, +deduxit me super semitas jusitiae, +EOF +printf "propter nomen suum." >> new4.txt + +cp new1.txt test.txt +test_expect_success "merge without conflict" \ + "git merge-file 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" + +test_expect_success "merge result added missing LF" \ + "test_cmp test.txt test2.txt" + +cp test.txt backup.txt +test_expect_success "merge with conflicts" \ + "test_must_fail git merge-file test.txt orig.txt new3.txt" + +cat > expect.txt << EOF +<<<<<<< test.txt +Dominus regit me, et nihil mihi deerit. +======= +DOMINUS regit me, +et nihil mihi deerit. +>>>>>>> new3.txt +In loco pascuae ibi me collocavit, +super aquam refectionis educavit me; +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 "expected conflict markers" "test_cmp test.txt expect.txt" + +cp backup.txt test.txt +test_expect_success "merge with conflicts, using -L" \ + "test_must_fail git merge-file -L 1 -L 2 test.txt orig.txt new3.txt" + +cat > expect.txt << EOF +<<<<<<< 1 +Dominus regit me, et nihil mihi deerit. +======= +DOMINUS regit me, +et nihil mihi deerit. +>>>>>>> new3.txt +In loco pascuae ibi me collocavit, +super aquam refectionis educavit me; +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 "expected conflict markers, with -L" \ + "test_cmp test.txt expect.txt" + +sed "s/ tu / TU /" < new1.txt > new5.txt +test_expect_success "conflict in removed tail" \ + "test_must_fail git merge-file -p orig.txt new1.txt new5.txt > out" + +cat > expect << EOF +Dominus regit me, +et nihil mihi deerit. +In loco pascuae ibi me collocavit, +super aquam refectionis educavit me; +animam meam convertit, +deduxit me super semitas jusitiae, +propter nomen suum. +<<<<<<< orig.txt +======= +Nam et si ambulavero in medio umbrae mortis, +non timebo mala, quoniam TU mecum es: +virga tua et baculus tuus ipsa me consolata sunt. +>>>>>>> new5.txt +EOF + +test_expect_success "expected conflict markers" "test_cmp expect out" + +test_expect_success 'binary files cannot be merged' ' + test_must_fail git merge-file -p \ + orig.txt ../test4012.png new1.txt 2> merge.err && + grep "Cannot merge binary files" merge.err +' + +sed -e "s/deerit.$/deerit;/" -e "s/me;$/me./" < new5.txt > new6.txt +sed -e "s/deerit.$/deerit,/" -e "s/me;$/me,/" < new5.txt > new7.txt + +test_expect_success 'MERGE_ZEALOUS simplifies non-conflicts' ' + + test_must_fail git merge-file -p new6.txt new5.txt new7.txt > output && + test 1 = $(grep ======= < output | wc -l) + +' + +sed -e 's/deerit./&\n\n\n\n/' -e "s/locavit,/locavit;/" < new6.txt > new8.txt +sed -e 's/deerit./&\n\n\n\n/' -e "s/locavit,/locavit --/" < new7.txt > new9.txt + +test_expect_success 'ZEALOUS_ALNUM' ' + + test_must_fail git merge-file -p \ + new8.txt new5.txt new9.txt > merge.out && + test 1 = $(grep ======= < merge.out | wc -l) + +' + +test_done diff --git a/t/t6023-merge-rename-nocruft.sh b/t/t6023-merge-rename-nocruft.sh new file mode 100755 index 0000000000..65be95fbaa --- /dev/null +++ b/t/t6023-merge-rename-nocruft.sh @@ -0,0 +1,139 @@ +#!/bin/sh + +test_description='Merge-recursive merging renames' +. ./test-lib.sh + +test_expect_success setup \ +' +cat >A <<\EOF && +a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +c cccccccccccccccccccccccccccccccccccccccccccccccc +d dddddddddddddddddddddddddddddddddddddddddddddddd +e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee +f ffffffffffffffffffffffffffffffffffffffffffffffff +g gggggggggggggggggggggggggggggggggggggggggggggggg +h hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh +i iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii +j jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj +k kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk +l llllllllllllllllllllllllllllllllllllllllllllllll +m mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm +n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn +o oooooooooooooooooooooooooooooooooooooooooooooooo +EOF + +cat >M <<\EOF && +A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB +C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD +E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +G GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG +H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH +I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII +J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ +K KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK +L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL +M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM +N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +O OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO +EOF + +git add A M && +git commit -m "initial has A and M" && +git branch white && +git branch red && +git branch blue && + +git checkout white && +sed -e "/^g /s/.*/g : white changes a line/" <A >B && +sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N && +rm -f A M && +git update-index --add --remove A B M N && +git commit -m "white renames A->B, M->N" && + +git checkout red && +echo created by red >R && +git update-index --add R && +git commit -m "red creates R" && + +git checkout blue && +sed -e "/^o /s/.*/g : blue changes a line/" <A >B && +rm -f A && +mv B A && +git update-index A && +git commit -m "blue modify A" && + +git checkout master' + +# This test broke in 65ac6e9c3f47807cb603af07a6a9e1a43bc119ae +test_expect_success 'merge white into red (A->B,M->N)' \ +' + git checkout -b red-white red && + git merge white && + git write-tree >/dev/null || { + echo "BAD: merge did not complete" + return 1 + } + + test -f B || { + echo "BAD: B does not exist in working directory" + return 1 + } + test -f N || { + echo "BAD: N does not exist in working directory" + return 1 + } + test -f R || { + echo "BAD: R does not exist in working directory" + return 1 + } + + test -f A && { + echo "BAD: A still exists in working directory" + return 1 + } + test -f M && { + echo "BAD: M still exists in working directory" + return 1 + } + return 0 +' + +# This test broke in 8371234ecaaf6e14fe3f2082a855eff1bbd79ae9 +test_expect_success 'merge blue into white (A->B, mod A, A untracked)' \ +' + git checkout -b white-blue white && + echo dirty >A && + git merge blue && + git write-tree >/dev/null || { + echo "BAD: merge did not complete" + return 1 + } + + test -f A || { + echo "BAD: A does not exist in working directory" + return 1 + } + test `cat A` = dirty || { + echo "BAD: A content is wrong" + return 1 + } + test -f B || { + echo "BAD: B does not exist in working directory" + return 1 + } + test -f N || { + echo "BAD: N does not exist in working directory" + return 1 + } + test -f M && { + echo "BAD: M still exists in working directory" + return 1 + } + return 0 +' + +test_done diff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh new file mode 100755 index 0000000000..802d0d06eb --- /dev/null +++ b/t/t6024-recursive-merge.sh @@ -0,0 +1,100 @@ +#!/bin/sh + +test_description='Test merge without common ancestors' +. ./test-lib.sh + +# This scenario is based on a real-world repository of Shawn Pearce. + +# 1 - A - D - F +# \ X / +# B X +# X \ +# 2 - C - E - G + +GIT_COMMITTER_DATE="2006-12-12 23:28:00 +0100" +export GIT_COMMITTER_DATE + +test_expect_success "setup tests" ' +echo 1 > a1 && +git add a1 && +GIT_AUTHOR_DATE="2006-12-12 23:00:00" git commit -m 1 a1 && + +git checkout -b A master && +echo A > a1 && +GIT_AUTHOR_DATE="2006-12-12 23:00:01" git commit -m A a1 && + +git checkout -b B master && +echo B > a1 && +GIT_AUTHOR_DATE="2006-12-12 23:00:02" git commit -m B a1 && + +git checkout -b D A && +git rev-parse B > .git/MERGE_HEAD && +echo D > a1 && +git update-index a1 && +GIT_AUTHOR_DATE="2006-12-12 23:00:03" git commit -m D && + +git symbolic-ref HEAD refs/heads/other && +echo 2 > a1 && +GIT_AUTHOR_DATE="2006-12-12 23:00:04" git commit -m 2 a1 && + +git checkout -b C && +echo C > a1 && +GIT_AUTHOR_DATE="2006-12-12 23:00:05" git commit -m C a1 && + +git checkout -b E C && +git rev-parse B > .git/MERGE_HEAD && +echo E > a1 && +git update-index a1 && +GIT_AUTHOR_DATE="2006-12-12 23:00:06" git commit -m E && + +git checkout -b G E && +git rev-parse A > .git/MERGE_HEAD && +echo G > a1 && +git update-index a1 && +GIT_AUTHOR_DATE="2006-12-12 23:00:07" git commit -m G && + +git checkout -b F D && +git rev-parse C > .git/MERGE_HEAD && +echo F > a1 && +git update-index a1 && +GIT_AUTHOR_DATE="2006-12-12 23:00:08" git commit -m F +' + +test_expect_success "combined merge conflicts" " + test_must_fail git merge -m final G +" + +cat > expect << EOF +<<<<<<< HEAD:a1 +F +======= +G +>>>>>>> G:a1 +EOF + +test_expect_success "result contains a conflict" "test_cmp expect a1" + +git ls-files --stage > out +cat > expect << EOF +100644 da056ce14a2241509897fa68bb2b3b6e6194ef9e 1 a1 +100644 cf84443e49e1b366fac938711ddf4be2d4d1d9e9 2 a1 +100644 fd7923529855d0b274795ae3349c5e0438333979 3 a1 +EOF + +test_expect_success "virtual trees were processed" "test_cmp expect out" + +test_expect_success 'refuse to merge binary files' ' + git reset --hard && + printf "\0" > binary-file && + git add binary-file && + git commit -m binary && + git checkout G && + printf "\0\0" > binary-file && + git add binary-file && + git commit -m binary2 && + test_must_fail git merge F > merge.out 2> merge.err && + grep "Cannot merge binary files: HEAD:binary-file vs. F:binary-file" \ + merge.err +' + +test_done diff --git a/t/t6025-merge-symlinks.sh b/t/t6025-merge-symlinks.sh new file mode 100755 index 0000000000..fc58456a11 --- /dev/null +++ b/t/t6025-merge-symlinks.sh @@ -0,0 +1,61 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes Sixt +# + +test_description='merging symlinks on filesystem w/o symlink support. + +This tests that git-merge-recursive writes merge results as plain files +if core.symlinks is false.' + +. ./test-lib.sh + +test_expect_success \ +'setup' ' +git config core.symlinks false && +> file && +git add file && +git-commit -m initial && +git branch b-symlink && +git branch b-file && +l=$(echo -n file | git-hash-object -t blob -w --stdin) && +echo "120000 $l symlink" | git update-index --index-info && +git-commit -m master && +git-checkout b-symlink && +l=$(echo -n file-different | git-hash-object -t blob -w --stdin) && +echo "120000 $l symlink" | git update-index --index-info && +git-commit -m b-symlink && +git-checkout b-file && +echo plain-file > symlink && +git add symlink && +git-commit -m b-file' + +test_expect_success \ +'merge master into b-symlink, which has a different symbolic link' ' +git-checkout b-symlink && +test_must_fail git-merge master' + +test_expect_success \ +'the merge result must be a file' ' +test -f symlink' + +test_expect_success \ +'merge master into b-file, which has a file instead of a symbolic link' ' +git-reset --hard && git-checkout b-file && +test_must_fail git-merge master' + +test_expect_success \ +'the merge result must be a file' ' +test -f symlink' + +test_expect_success \ +'merge b-file, which has a file instead of a symbolic link, into master' ' +git-reset --hard && +git-checkout master && +test_must_fail git-merge b-file' + +test_expect_success \ +'the merge result must be a file' ' +test -f symlink' + +test_done diff --git a/t/t6026-merge-attr.sh b/t/t6026-merge-attr.sh new file mode 100755 index 0000000000..56fc341768 --- /dev/null +++ b/t/t6026-merge-attr.sh @@ -0,0 +1,145 @@ +#!/bin/sh +# +# Copyright (c) 2007 Junio C Hamano +# + +test_description='per path merge controlled by merge attribute' + +. ./test-lib.sh + +test_expect_success setup ' + + for f in text binary union + do + echo Initial >$f && git add $f || break + done && + test_tick && + git commit -m Initial && + + git branch side && + for f in text binary union + do + echo Master >>$f && git add $f || break + done && + test_tick && + git commit -m Master && + + git checkout side && + for f in text binary union + do + echo Side >>$f && git add $f || break + done && + test_tick && + git commit -m Side && + + git tag anchor +' + +test_expect_success merge ' + + { + echo "binary -merge" + echo "union merge=union" + } >.gitattributes && + + if git merge master + then + echo Gaah, should have conflicted + false + else + echo Ok, conflicted. + fi +' + +test_expect_success 'check merge result in index' ' + + git ls-files -u | grep binary && + git ls-files -u | grep text && + ! (git ls-files -u | grep union) + +' + +test_expect_success 'check merge result in working tree' ' + + git cat-file -p HEAD:binary >binary-orig && + grep "<<<<<<<" text && + cmp binary-orig binary && + ! grep "<<<<<<<" union && + grep Master union && + grep Side union + +' + +cat >./custom-merge <<\EOF +#!/bin/sh + +orig="$1" ours="$2" theirs="$3" exit="$4" +( + echo "orig is $orig" + echo "ours is $ours" + echo "theirs is $theirs" + echo "=== orig ===" + cat "$orig" + echo "=== ours ===" + cat "$ours" + echo "=== theirs ===" + cat "$theirs" +) >"$ours+" +cat "$ours+" >"$ours" +rm -f "$ours+" +exit "$exit" +EOF +chmod +x ./custom-merge + +test_expect_success 'custom merge backend' ' + + echo "* merge=union" >.gitattributes && + echo "text merge=custom" >>.gitattributes && + + git reset --hard anchor && + git config --replace-all \ + merge.custom.driver "./custom-merge %O %A %B 0" && + git config --replace-all \ + merge.custom.name "custom merge driver for testing" && + + git merge master && + + cmp binary union && + sed -e 1,3d text >check-1 && + o=$(git-unpack-file master^:text) && + a=$(git-unpack-file side^:text) && + b=$(git-unpack-file master:text) && + sh -c "./custom-merge $o $a $b 0" && + sed -e 1,3d $a >check-2 && + cmp check-1 check-2 && + rm -f $o $a $b +' + +test_expect_success 'custom merge backend' ' + + git reset --hard anchor && + git config --replace-all \ + merge.custom.driver "./custom-merge %O %A %B 1" && + git config --replace-all \ + merge.custom.name "custom merge driver for testing" && + + if git merge master + then + echo "Eh? should have conflicted" + false + else + echo "Ok, conflicted" + fi && + + cmp binary union && + sed -e 1,3d text >check-1 && + o=$(git-unpack-file master^:text) && + a=$(git-unpack-file anchor:text) && + b=$(git-unpack-file master:text) && + sh -c "./custom-merge $o $a $b 0" && + sed -e 1,3d $a >check-2 && + cmp check-1 check-2 && + rm -f $o $a $b +' + +test_done diff --git a/t/t6027-merge-binary.sh b/t/t6027-merge-binary.sh new file mode 100755 index 0000000000..92ca1f0f8c --- /dev/null +++ b/t/t6027-merge-binary.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +test_description='ask merge-recursive to merge binary files' + +. ./test-lib.sh + +test_expect_success setup ' + + cat ../test4012.png >m && + git add m && + git ls-files -s | sed -e "s/ 0 / 1 /" >E1 && + test_tick && + git commit -m "initial" && + + git branch side && + echo frotz >a && + git add a && + echo nitfol >>m && + git add a m && + git ls-files -s a >E0 && + git ls-files -s m | sed -e "s/ 0 / 3 /" >E3 && + test_tick && + git commit -m "master adds some" && + + git checkout side && + echo rezrov >>m && + git add m && + git ls-files -s m | sed -e "s/ 0 / 2 /" >E2 && + test_tick && + git commit -m "side modifies" && + + git tag anchor && + + cat E0 E1 E2 E3 >expect +' + +test_expect_success resolve ' + + rm -f a* m* && + git reset --hard anchor && + + if git merge -s resolve master + then + echo Oops, should not have succeeded + false + else + git ls-files -s >current + test_cmp current expect + fi +' + +test_expect_success recursive ' + + rm -f a* m* && + git reset --hard anchor && + + if git merge -s recursive master + then + echo Oops, should not have succeeded + false + else + git ls-files -s >current + test_cmp current expect + fi +' + +test_done diff --git a/t/t6028-merge-up-to-date.sh b/t/t6028-merge-up-to-date.sh new file mode 100755 index 0000000000..f8f3e3ff2c --- /dev/null +++ b/t/t6028-merge-up-to-date.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +test_description='merge fast forward and up to date' + +. ./test-lib.sh + +test_expect_success setup ' + >file && + git add file && + test_tick && + git commit -m initial && + git tag c0 && + + echo second >file && + git add file && + test_tick && + git commit -m second && + git tag c1 && + git branch test +' + +test_expect_success 'merge -s recursive up-to-date' ' + + git reset --hard c1 && + test_tick && + git merge -s recursive c0 && + expect=$(git rev-parse c1) && + current=$(git rev-parse HEAD) && + test "$expect" = "$current" + +' + +test_expect_success 'merge -s recursive fast-forward' ' + + git reset --hard c0 && + test_tick && + git merge -s recursive c1 && + expect=$(git rev-parse c1) && + current=$(git rev-parse HEAD) && + test "$expect" = "$current" + +' + +test_expect_success 'merge -s ours up-to-date' ' + + git reset --hard c1 && + test_tick && + git merge -s ours c0 && + expect=$(git rev-parse c1) && + current=$(git rev-parse HEAD) && + test "$expect" = "$current" + +' + +test_expect_success 'merge -s ours fast-forward' ' + + git reset --hard c0 && + test_tick && + git merge -s ours c1 && + expect=$(git rev-parse c0^{tree}) && + current=$(git rev-parse HEAD^{tree}) && + test "$expect" = "$current" + +' + +test_expect_success 'merge -s subtree up-to-date' ' + + git reset --hard c1 && + test_tick && + git merge -s subtree c0 && + expect=$(git rev-parse c1) && + current=$(git rev-parse HEAD) && + test "$expect" = "$current" + +' + +test_done diff --git a/t/t6029-merge-subtree.sh b/t/t6029-merge-subtree.sh new file mode 100755 index 0000000000..5bbfa44e8d --- /dev/null +++ b/t/t6029-merge-subtree.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +test_description='subtree merge strategy' + +. ./test-lib.sh + +test_expect_success setup ' + + s="1 2 3 4 5 6 7 8" + for i in $s; do echo $i; done >hello && + git add hello && + git commit -m initial && + git checkout -b side && + echo >>hello world && + git add hello && + git commit -m second && + git checkout master && + for i in mundo $s; do echo $i; done >hello && + git add hello && + git commit -m master + +' + +test_expect_success 'subtree available and works like recursive' ' + + git merge -s subtree side && + for i in mundo $s world; do echo $i; done >expect && + test_cmp expect hello + +' + +test_expect_success 'setup' ' + mkdir git-gui && + cd git-gui && + git init && + echo git-gui > git-gui.sh && + o1=$(git hash-object git-gui.sh) && + git add git-gui.sh && + git commit -m "initial git-gui" && + cd .. && + mkdir git && + cd git && + git init && + echo git >git.c && + o2=$(git hash-object git.c) && + git add git.c && + git commit -m "initial git" +' + +test_expect_success 'initial merge' ' + git remote add -f gui ../git-gui && + git merge -s ours --no-commit gui/master && + git read-tree --prefix=git-gui/ -u gui/master && + git commit -m "Merge git-gui as our subdirectory" && + git ls-files -s >actual && + ( + echo "100644 $o1 0 git-gui/git-gui.sh" + echo "100644 $o2 0 git.c" + ) >expected && + test_cmp expected actual +' + +test_expect_success 'merge update' ' + cd ../git-gui && + echo git-gui2 > git-gui.sh && + o3=$(git hash-object git-gui.sh) && + git add git-gui.sh && + git commit -m "update git-gui" && + cd ../git && + git pull -s subtree gui master && + git ls-files -s >actual && + ( + echo "100644 $o3 0 git-gui/git-gui.sh" + echo "100644 $o2 0 git.c" + ) >expected && + test_cmp expected actual +' + +test_done diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh new file mode 100755 index 0000000000..244fda62a5 --- /dev/null +++ b/t/t6030-bisect-porcelain.sh @@ -0,0 +1,355 @@ +#!/bin/sh +# +# Copyright (c) 2007 Christian Couder +# +test_description='Tests git-bisect functionality' + +exec </dev/null + +. ./test-lib.sh + +add_line_into_file() +{ + _line=$1 + _file=$2 + + if [ -f "$_file" ]; then + echo "$_line" >> $_file || return $? + MSG="Add <$_line> into <$_file>." + else + echo "$_line" > $_file || return $? + git add $_file || return $? + MSG="Create file <$_file> with <$_line> inside." + fi + + test_tick + git-commit --quiet -m "$MSG" $_file +} + +HASH1= +HASH2= +HASH3= +HASH4= + +test_expect_success 'set up basic repo with 1 file (hello) and 4 commits' ' + add_line_into_file "1: Hello World" hello && + HASH1=$(git rev-parse --verify HEAD) && + add_line_into_file "2: A new day for git" hello && + HASH2=$(git rev-parse --verify HEAD) && + add_line_into_file "3: Another new day for git" hello && + HASH3=$(git rev-parse --verify HEAD) && + add_line_into_file "4: Ciao for now" hello && + HASH4=$(git rev-parse --verify HEAD) +' + +test_expect_success 'bisect starts with only one bad' ' + git bisect reset && + git bisect start && + git bisect bad $HASH4 && + git bisect next +' + +test_expect_success 'bisect does not start with only one good' ' + git bisect reset && + git bisect start && + git bisect good $HASH1 || return 1 + + if git bisect next + then + echo Oops, should have failed. + false + else + : + fi +' + +test_expect_success 'bisect start with one bad and good' ' + git bisect reset && + git bisect start && + git bisect good $HASH1 && + git bisect bad $HASH4 && + git bisect next +' + +test_expect_success 'bisect fails if given any junk instead of revs' ' + git bisect reset && + test_must_fail git bisect start foo $HASH1 -- && + test_must_fail git bisect start $HASH4 $HASH1 bar -- && + test -z "$(git for-each-ref "refs/bisect/*")" && + test -z "$(ls .git/BISECT_* 2>/dev/null)" && + git bisect start && + test_must_fail git bisect good foo $HASH1 && + test_must_fail git bisect good $HASH1 bar && + test_must_fail git bisect bad frotz && + test_must_fail git bisect bad $HASH3 $HASH4 && + test_must_fail git bisect skip bar $HASH3 && + test_must_fail git bisect skip $HASH1 foo && + test -z "$(git for-each-ref "refs/bisect/*")" && + git bisect good $HASH1 && + git bisect bad $HASH4 +' + +test_expect_success 'bisect reset: back in the master branch' ' + git bisect reset && + echo "* master" > branch.expect && + git branch > branch.output && + cmp branch.expect branch.output +' + +test_expect_success 'bisect reset: back in another branch' ' + git checkout -b other && + git bisect start && + git bisect good $HASH1 && + git bisect bad $HASH3 && + git bisect reset && + echo " master" > branch.expect && + echo "* other" >> branch.expect && + git branch > branch.output && + cmp branch.expect branch.output +' + +test_expect_success 'bisect reset when not bisecting' ' + git bisect reset && + git branch > branch.output && + cmp branch.expect branch.output +' + +test_expect_success 'bisect reset removes packed refs' ' + git bisect reset && + git bisect start && + git bisect good $HASH1 && + git bisect bad $HASH3 && + git pack-refs --all --prune && + git bisect next && + git bisect reset && + test -z "$(git for-each-ref "refs/bisect/*")" && + test -z "$(git for-each-ref "refs/heads/bisect")" +' + +test_expect_success 'bisect start: back in good branch' ' + git branch > branch.output && + grep "* other" branch.output > /dev/null && + git bisect start $HASH4 $HASH1 -- && + git bisect good && + git bisect start $HASH4 $HASH1 -- && + git bisect bad && + git bisect reset && + git branch > branch.output && + grep "* other" branch.output > /dev/null +' + +test_expect_success 'bisect start: no ".git/BISECT_START" if junk rev' ' + git bisect start $HASH4 $HASH1 -- && + git bisect good && + test_must_fail git bisect start $HASH4 foo -- && + git branch > branch.output && + grep "* other" branch.output > /dev/null && + test_must_fail test -e .git/BISECT_START +' + +test_expect_success 'bisect start: no ".git/BISECT_START" if mistaken rev' ' + git bisect start $HASH4 $HASH1 -- && + git bisect good && + test_must_fail git bisect start $HASH1 $HASH4 -- && + git branch > branch.output && + grep "* other" branch.output > /dev/null && + test_must_fail test -e .git/BISECT_START +' + +test_expect_success 'bisect start: no ".git/BISECT_START" if checkout error' ' + echo "temp stuff" > hello && + test_must_fail git bisect start $HASH4 $HASH1 -- && + git branch && + git branch > branch.output && + grep "* other" branch.output > /dev/null && + test_must_fail test -e .git/BISECT_START && + test -z "$(git for-each-ref "refs/bisect/*")" && + git checkout HEAD hello +' + +# $HASH1 is good, $HASH4 is bad, we skip $HASH3 +# but $HASH2 is bad, +# so we should find $HASH2 as the first bad commit +test_expect_success 'bisect skip: successfull result' ' + git bisect reset && + 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 && + git bisect reset +' + +# $HASH1 is good, $HASH4 is bad, we skip $HASH3 and $HASH2 +# so we should not be able to tell the first bad commit +# among $HASH2, $HASH3 and $HASH4 +test_expect_success 'bisect skip: cannot tell between 3 commits' ' + git bisect start $HASH4 $HASH1 && + git bisect skip || return 1 + + if git bisect skip > my_bisect_log.txt + then + echo Oops, should have failed. + false + else + test $? -eq 2 && + grep "first bad commit could be any of" my_bisect_log.txt && + ! grep $HASH1 my_bisect_log.txt && + grep $HASH2 my_bisect_log.txt && + grep $HASH3 my_bisect_log.txt && + grep $HASH4 my_bisect_log.txt && + git bisect reset + fi +' + +# $HASH1 is good, $HASH4 is bad, we skip $HASH3 +# but $HASH2 is good, +# so we should not be able to tell the first bad commit +# among $HASH3 and $HASH4 +test_expect_success 'bisect skip: cannot tell between 2 commits' ' + git bisect start $HASH4 $HASH1 && + git bisect skip || return 1 + + if git bisect good > my_bisect_log.txt + then + echo Oops, should have failed. + false + else + test $? -eq 2 && + grep "first bad commit could be any of" my_bisect_log.txt && + ! grep $HASH1 my_bisect_log.txt && + ! grep $HASH2 my_bisect_log.txt && + grep $HASH3 my_bisect_log.txt && + grep $HASH4 my_bisect_log.txt && + git bisect reset + fi +' + +# We want to automatically find the commit that +# introduced "Another" into hello. +test_expect_success \ + '"git bisect run" simple case' \ + 'echo "#"\!"/bin/sh" > test_script.sh && + echo "grep Another hello > /dev/null" >> test_script.sh && + echo "test \$? -ne 0" >> test_script.sh && + chmod +x test_script.sh && + git bisect start && + 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 && + git bisect reset' + +# We want to automatically find the commit that +# introduced "Ciao" into hello. +test_expect_success \ + '"git bisect run" with more complex "git bisect start"' \ + 'echo "#"\!"/bin/sh" > test_script.sh && + echo "grep Ciao hello > /dev/null" >> test_script.sh && + echo "test \$? -ne 0" >> test_script.sh && + 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 && + git bisect reset' + +# $HASH1 is good, $HASH5 is bad, we skip $HASH3 +# but $HASH4 is good, +# so we should find $HASH5 as the first bad commit +HASH5= +test_expect_success 'bisect skip: add line and then a new test' ' + add_line_into_file "5: Another new line." hello && + HASH5=$(git rev-parse --verify HEAD) && + 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 && + 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 && + git bisect reset +' + +HASH6= +test_expect_success 'bisect run & skip: cannot tell between 2' ' + add_line_into_file "6: Yet a line." hello && + HASH6=$(git rev-parse --verify HEAD) && + echo "#"\!"/bin/sh" > test_script.sh && + echo "sed -ne \\\$p hello | grep Ciao > /dev/null && exit 125" >> test_script.sh && + echo "grep line hello > /dev/null" >> test_script.sh && + echo "test \$? -ne 0" >> test_script.sh && + chmod +x test_script.sh && + git bisect start $HASH6 $HASH1 && + if git bisect run ./test_script.sh > my_bisect_log.txt + then + echo Oops, should have failed. + false + else + test $? -eq 2 && + grep "first bad commit could be any of" my_bisect_log.txt && + ! grep $HASH3 my_bisect_log.txt && + ! grep $HASH6 my_bisect_log.txt && + grep $HASH4 my_bisect_log.txt && + grep $HASH5 my_bisect_log.txt + fi +' + +HASH7= +test_expect_success 'bisect run & skip: find first bad' ' + git bisect reset && + add_line_into_file "7: Should be the last line." hello && + HASH7=$(git rev-parse --verify HEAD) && + echo "#"\!"/bin/sh" > test_script.sh && + echo "sed -ne \\\$p hello | grep Ciao > /dev/null && exit 125" >> test_script.sh && + echo "sed -ne \\\$p hello | grep day > /dev/null && exit 125" >> test_script.sh && + echo "grep Yet hello > /dev/null" >> test_script.sh && + echo "test \$? -ne 0" >> test_script.sh && + 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 +' + +test_expect_success 'bisect starting with a detached HEAD' ' + + git bisect reset && + git checkout master^ && + HEAD=$(git rev-parse --verify HEAD) && + git bisect start && + test $HEAD = $(cat .git/BISECT_START) && + git bisect reset && + test $HEAD = $(git rev-parse --verify HEAD) +' + +test_expect_success 'bisect errors out if bad and good are mistaken' ' + git bisect reset && + test_must_fail git bisect start $HASH2 $HASH4 2> rev_list_error && + grep "mistake good and bad" rev_list_error && + git bisect reset +' + +test_expect_success 'bisect does not create a "bisect" branch' ' + git bisect reset && + git bisect start $HASH7 $HASH1 && + git branch bisect && + rev_hash4=$(git rev-parse --verify HEAD) && + test "$rev_hash4" = "$HASH4" && + git branch -D bisect && + git bisect good && + git branch bisect && + 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 && + git bisect reset && + rev_hash6=$(git rev-parse --verify bisect) && + test "$rev_hash6" = "$HASH6" && + git branch -D bisect +' + +# +# +test_done diff --git a/t/t6031-merge-recursive.sh b/t/t6031-merge-recursive.sh new file mode 100755 index 0000000000..8073e0c3ef --- /dev/null +++ b/t/t6031-merge-recursive.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +test_description='merge-recursive: handle file mode' +. ./test-lib.sh + +# Note that we follow "chmod +x F" with "update-index --chmod=+x F" to +# help filesystems that do not have the executable bit. + +test_expect_success 'mode change in one branch: keep changed version' ' + : >file1 && + git add file1 && + git commit -m initial && + git checkout -b a1 master && + : >dummy && + git add dummy && + git commit -m a && + git checkout -b b1 master && + chmod +x file1 && + git update-index --chmod=+x file1 && + git commit -m b1 && + git checkout a1 && + git merge-recursive master -- a1 b1 && + test -x file1 +' + +test_expect_success 'mode change in both branches: expect conflict' ' + git reset --hard HEAD && + git checkout -b a2 master && + : >file2 && + H=$(git hash-object file2) && + chmod +x file2 && + git update-index --add --chmod=+x file2 && + git commit -m a2 && + git checkout -b b2 master && + : >file2 && + git add file2 && + git commit -m b2 && + git checkout a2 && + ( + git merge-recursive master -- a2 b2 + test $? = 1 + ) && + git ls-files -u >actual && + ( + echo "100755 $H 2 file2" + echo "100644 $H 3 file2" + ) >expect && + test_cmp actual expect && + test -x file2 +' + +test_done diff --git a/t/t6032-merge-large-rename.sh b/t/t6032-merge-large-rename.sh new file mode 100755 index 0000000000..eac5ebac24 --- /dev/null +++ b/t/t6032-merge-large-rename.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +test_description='merging with large rename matrix' +. ./test-lib.sh + +count() { + i=1 + while test $i -le $1; do + echo $i + i=$(($i + 1)) + done +} + +test_expect_success 'setup (initial)' ' + touch file && + git add . && + git commit -m initial && + git tag initial +' + +make_text() { + echo $1: $2 + for i in `count 20`; do + echo $1: $i + done + echo $1: $3 +} + +test_rename() { + test_expect_success "rename ($1, $2)" ' + n='$1' + expect='$2' + git checkout -f master && + git branch -D test$n || true && + git reset --hard initial && + for i in $(count $n); do + make_text $i initial initial >$i + done && + git add . && + git commit -m add=$n && + for i in $(count $n); do + make_text $i changed initial >$i + done && + git commit -a -m change=$n && + git checkout -b test$n HEAD^ && + for i in $(count $n); do + git rm $i + make_text $i initial changed >$i.moved + done && + git add . && + git commit -m change+rename=$n && + case "$expect" in + ok) git merge master ;; + *) test_must_fail git merge master ;; + esac + ' +} + +test_rename 5 ok + +test_expect_success 'set diff.renamelimit to 4' ' + git config diff.renamelimit 4 +' +test_rename 4 ok +test_rename 5 fail + +test_expect_success 'set merge.renamelimit to 5' ' + git config merge.renamelimit 5 +' +test_rename 5 ok +test_rename 6 fail + +test_done diff --git a/t/t6033-merge-crlf.sh b/t/t6033-merge-crlf.sh new file mode 100755 index 0000000000..75d9602de4 --- /dev/null +++ b/t/t6033-merge-crlf.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +append_cr () { + sed -e 's/$/Q/' | tr Q '\015' +} + +remove_cr () { + tr '\015' Q | sed -e 's/Q$//' +} + +test_description='merge conflict in crlf repo + + b---M + / / + initial---a + +' + +. ./test-lib.sh + +test_expect_success setup ' + git config core.autocrlf true && + echo foo | append_cr >file && + git add file && + git commit -m "Initial" && + git tag initial && + git branch side && + echo line from a | append_cr >file && + git commit -m "add line from a" file && + git tag a && + git checkout side && + echo line from b | append_cr >file && + git commit -m "add line from b" file && + git tag b && + git checkout master +' + +test_expect_success 'Check "ours" is CRLF' ' + git reset --hard initial && + git merge side -s ours && + cat file | remove_cr | append_cr >file.temp && + test_cmp file file.temp +' + +test_expect_success 'Check that conflict file is CRLF' ' + git reset --hard a && + test_must_fail git merge side && + cat file | remove_cr | append_cr >file.temp && + test_cmp file file.temp +' + +test_done diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh new file mode 100755 index 0000000000..aac212e936 --- /dev/null +++ b/t/t6040-tracking-info.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +test_description='remote tracking stats' + +. ./test-lib.sh + +advance () { + echo "$1" >"$1" && + git add "$1" && + test_tick && + git commit -m "$1" +} + +test_expect_success setup ' + for i in a b c; + do + advance $i || break + done && + git clone . test && + ( + cd test && + git checkout -b b1 origin && + git reset --hard HEAD^ && + advance d && + git checkout -b b2 origin && + git reset --hard b1 && + git checkout -b b3 origin && + git reset --hard HEAD^ && + git checkout -b b4 origin && + advance e && + advance f + ) +' + +script='s/^..\(b.\)[ 0-9a-f]*\[\([^]]*\)\].*/\1 \2/p' +cat >expect <<\EOF +b1 ahead 1, behind 1 +b2 ahead 1, behind 1 +b3 behind 1 +b4 ahead 2 +EOF + +test_expect_success 'branch -v' ' + ( + cd test && + git branch -v + ) | + sed -n -e "$script" >actual && + test_cmp expect actual +' + +test_expect_success 'checkout' ' + ( + cd test && git checkout b1 + ) >actual && + grep -e "have 1 and 1 different" actual +' + +test_expect_success 'status' ' + ( + cd test && + git checkout b1 >/dev/null && + # reports nothing to commit + test_must_fail git status + ) >actual && + grep -e "have 1 and 1 different" actual +' + + +test_done diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh new file mode 100755 index 0000000000..919552a2fc --- /dev/null +++ b/t/t6101-rev-parse-parents.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# +# Copyright (c) 2005 Johannes Schindelin +# + +test_description='Test git rev-parse with different parent options' + +. ./test-lib.sh +. ../t6000lib.sh # t6xxx specific functions + +date >path0 +git update-index --add path0 +save_tag tree git write-tree +hide_error save_tag start unique_commit "start" tree +save_tag second unique_commit "second" tree -p start +hide_error save_tag start2 unique_commit "start2" tree +save_tag two_parents unique_commit "next" tree -p second -p start2 +save_tag final unique_commit "final" tree -p two_parents + +test_expect_success 'start is valid' 'git rev-parse start | grep "^[0-9a-f]\{40\}$"' +test_expect_success 'start^0' "test $(cat .git/refs/tags/start) = $(git rev-parse start^0)" +test_expect_success 'start^1 not valid' "if git rev-parse --verify start^1; then false; else :; fi" +test_expect_success 'second^1 = second^' "test $(git rev-parse second^1) = $(git rev-parse second^)" +test_expect_success 'final^1^1^1' "test $(git rev-parse start) = $(git rev-parse final^1^1^1)" +test_expect_success 'final^1^1^1 = final^^^' "test $(git rev-parse final^1^1^1) = $(git rev-parse final^^^)" +test_expect_success 'final^1^2' "test $(git rev-parse start2) = $(git rev-parse final^1^2)" +test_expect_success 'final^1^2 != final^1^1' "test $(git rev-parse final^1^2) != $(git rev-parse final^1^1)" +test_expect_success 'final^1^3 not valid' "if git rev-parse --verify final^1^3; then false; else :; fi" +test_expect_success '--verify start2^1' 'test_must_fail git rev-parse --verify start2^1' +test_expect_success '--verify start2^0' 'git rev-parse --verify start2^0' +test_expect_success 'final^1^@ = final^1^1 final^1^2' "test \"$(git rev-parse final^1^@)\" = \"$(git rev-parse final^1^1 final^1^2)\"" +test_expect_success 'final^1^! = final^1 ^final^1^1 ^final^1^2' "test \"$(git rev-parse final^1^\!)\" = \"$(git rev-parse final^1 ^final^1^1 ^final^1^2)\"" + +test_expect_success 'repack for next test' 'git repack -a -d' +test_expect_success 'short SHA-1 works' ' + start=`git rev-parse --verify start` && + echo $start && + abbrv=`echo $start | sed s/.\$//` && + echo $abbrv && + abbrv=`git rev-parse --verify $abbrv` && + echo $abbrv && + test $start = $abbrv' + +test_done diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh new file mode 100755 index 0000000000..2fb672c3b4 --- /dev/null +++ b/t/t6120-describe.sh @@ -0,0 +1,144 @@ +#!/bin/sh + +test_description='test describe + + B + .--------------o----o----o----x + / / / + o----o----o----o----o----. / + \ A c / + .------------o---o---o + D e +' +. ./test-lib.sh + +check_describe () { + expect="$1" + shift + R=$(git describe "$@" 2>err.actual) + S=$? + cat err.actual >&3 + test_expect_success "describe $*" ' + test $S = 0 && + case "$R" in + $expect) echo happy ;; + *) echo "Oops - $R is not $expect"; + false ;; + esac + ' +} + +test_expect_success setup ' + + test_tick && + echo one >file && git add file && git-commit -m initial && + one=$(git rev-parse HEAD) && + + test_tick && + echo two >file && git add file && git-commit -m second && + two=$(git rev-parse HEAD) && + + test_tick && + echo three >file && git add file && git-commit -m third && + + test_tick && + echo A >file && git add file && git-commit -m A && + test_tick && + git-tag -a -m A A && + + test_tick && + echo c >file && git add file && git-commit -m c && + test_tick && + git-tag c && + + git reset --hard $two && + test_tick && + echo B >side && git add side && git-commit -m B && + test_tick && + git-tag -a -m B B && + + test_tick && + git-merge -m Merged c && + merged=$(git rev-parse HEAD) && + + git reset --hard $two && + test_tick && + echo D >another && git add another && git-commit -m D && + test_tick && + git-tag -a -m D D && + + test_tick && + echo DD >another && git commit -a -m another && + + test_tick && + git-tag e && + + test_tick && + echo DDD >another && git commit -a -m "yet another" && + + test_tick && + git-merge -m Merged $merged && + + test_tick && + echo X >file && echo X >side && git add file side && + git-commit -m x + +' + +check_describe A-* HEAD +check_describe A-* HEAD^ +check_describe D-* HEAD^^ +check_describe A-* HEAD^^2 +check_describe B HEAD^^2^ + +check_describe A-* --tags HEAD +check_describe A-* --tags HEAD^ +check_describe D-* --tags HEAD^^ +check_describe A-* --tags HEAD^^2 +check_describe B --tags HEAD^^2^ + +check_describe B-0-* --long HEAD^^2^ +check_describe A-3-* --long HEAD^^2 + +test_expect_success 'rename tag A to Q locally' ' + mv .git/refs/tags/A .git/refs/tags/Q +' +cat - >err.expect <<EOF +warning: tag 'A' is really 'Q' here +EOF +check_describe A-* HEAD +test_expect_success 'warning was displayed for Q' ' + test_cmp err.expect err.actual +' +test_expect_success 'rename tag Q back to A' ' + mv .git/refs/tags/Q .git/refs/tags/A +' + +test_expect_success 'pack tag refs' 'git pack-refs' +check_describe A-* HEAD + +test_expect_success 'set-up matching pattern tests' ' + git tag -a -m test-annotated test-annotated && + echo >>file && + test_tick && + git commit -a -m "one more" && + git tag test1-lightweight && + echo >>file && + test_tick && + git commit -a -m "yet another" && + git tag test2-lightweight && + echo >>file && + test_tick && + git commit -a -m "even more" + +' + +check_describe "test-annotated-*" --match="test-*" + +check_describe "test1-lightweight-*" --tags --match="test1-*" + +check_describe "test2-lightweight-*" --tags --match="test2-*" + +check_describe "test2-lightweight-*" --long --tags --match="test2-*" HEAD^ + +test_done diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh new file mode 100755 index 0000000000..bc74349416 --- /dev/null +++ b/t/t6200-fmt-merge-msg.sh @@ -0,0 +1,211 @@ +#!/bin/sh +# +# Copyright (c) 2006, Junio C Hamano +# + +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 && + git commit -m "Initial" && + + echo uno >one && + echo dos >two && + git add two && + setdate && + git commit -a -m "Second" && + + git checkout -b left && + + echo $datestamp >one && + setdate && + git commit -a -m "Common #1" && + + echo $datestamp >one && + setdate && + git commit -a -m "Common #2" && + + git branch right && + + echo $datestamp >two && + setdate && + git commit -a -m "Left #3" && + + echo $datestamp >two && + setdate && + git commit -a -m "Left #4" && + + echo $datestamp >two && + setdate && + git commit -a -m "Left #5" && + + git checkout right && + + echo $datestamp >three && + git add three && + setdate && + git commit -a -m "Right #3" && + + echo $datestamp >three && + setdate && + git commit -a -m "Right #4" && + + echo $datestamp >three && + setdate && + git commit -a -m "Right #5" && + + git show-branch +' + +cat >expected <<\EOF +Merge branch 'left' +EOF + +test_expect_success 'merge-msg test #1' ' + + git checkout master && + git fetch . left && + + git fmt-merge-msg <.git/FETCH_HEAD >actual && + test_cmp expected actual +' + +cat >expected <<EOF +Merge branch 'left' of ../$test +EOF + +test_expect_success 'merge-msg test #2' ' + + git checkout master && + git fetch ../"$test" left && + + git fmt-merge-msg <.git/FETCH_HEAD >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +Merge branch 'left' + +* left: + Left #5 + Left #4 + Left #3 + Common #2 + Common #1 +EOF + +test_expect_success 'merge-msg test #3-1' ' + + git config --unset-all merge.log + git config --unset-all merge.summary + git config merge.log true && + + git checkout master && + setdate && + git fetch . left && + + git fmt-merge-msg <.git/FETCH_HEAD >actual && + test_cmp expected actual +' + +test_expect_success 'merge-msg test #3-2' ' + + git config --unset-all merge.log + git config --unset-all merge.summary + git config merge.summary true && + + git checkout master && + setdate && + git fetch . left && + + git fmt-merge-msg <.git/FETCH_HEAD >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +Merge branches 'left' and 'right' + +* left: + Left #5 + Left #4 + Left #3 + Common #2 + Common #1 + +* right: + Right #5 + Right #4 + Right #3 + Common #2 + Common #1 +EOF + +test_expect_success 'merge-msg test #4-1' ' + + git config --unset-all merge.log + git config --unset-all merge.summary + git config merge.log true && + + git checkout master && + setdate && + git fetch . left right && + + git fmt-merge-msg <.git/FETCH_HEAD >actual && + test_cmp expected actual +' + +test_expect_success 'merge-msg test #4-2' ' + + git config --unset-all merge.log + git config --unset-all merge.summary + git config merge.summary true && + + git checkout master && + setdate && + git fetch . left right && + + git fmt-merge-msg <.git/FETCH_HEAD >actual && + test_cmp expected actual +' + +test_expect_success 'merge-msg test #5-1' ' + + git config --unset-all merge.log + git config --unset-all merge.summary + git config merge.log yes && + + git checkout master && + setdate && + git fetch . left right && + + git fmt-merge-msg <.git/FETCH_HEAD >actual && + test_cmp expected actual +' + +test_expect_success 'merge-msg test #5-2' ' + + git config --unset-all merge.log + git config --unset-all merge.summary + git config merge.summary yes && + + git checkout master && + setdate && + git fetch . left right && + + git fmt-merge-msg <.git/FETCH_HEAD >actual && + test_cmp expected actual +' + +test_done diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh new file mode 100755 index 0000000000..a3c8941c72 --- /dev/null +++ b/t/t6300-for-each-ref.sh @@ -0,0 +1,265 @@ +#!/bin/sh +# +# Copyright (c) 2007 Andy Parkins +# + +test_description='for-each-ref test' + +. ./test-lib.sh + +# Mon Jul 3 15:18:43 2006 +0000 +datestamp=1151939923 +setdate_and_increment () { + GIT_COMMITTER_DATE="$datestamp +0200" + datestamp=$(expr "$datestamp" + 1) + GIT_AUTHOR_DATE="$datestamp +0200" + datestamp=$(expr "$datestamp" + 1) + export GIT_COMMITTER_DATE GIT_AUTHOR_DATE +} + +test_expect_success 'Create sample commit with known timestamp' ' + setdate_and_increment && + echo "Using $datestamp" > one && + git add one && + git commit -m "Initial" && + setdate_and_increment && + git tag -a -m "Tagging at $datestamp" testtag +' + +test_atom() { + case "$1" in + head) ref=refs/heads/master ;; + tag) ref=refs/tags/testtag ;; + esac + printf '%s\n' "$3" >expected + test_expect_${4:-success} "basic atom: $1 $2" " + git for-each-ref --format='%($2)' $ref >actual && + test_cmp expected actual + " +} + +test_atom head refname refs/heads/master +test_atom head objecttype commit +test_atom head objectsize 171 +test_atom head objectname 67a36f10722846e891fbada1ba48ed035de75581 +test_atom head tree 0e51c00fcb93dffc755546f27593d511e1bdb46f +test_atom head parent '' +test_atom head numparent 0 +test_atom head object '' +test_atom head type '' +test_atom head author 'A U Thor <author@example.com> 1151939924 +0200' +test_atom head authorname 'A U Thor' +test_atom head authoremail '<author@example.com>' +test_atom head authordate 'Mon Jul 3 17:18:44 2006 +0200' +test_atom head committer 'C O Mitter <committer@example.com> 1151939923 +0200' +test_atom head committername 'C O Mitter' +test_atom head committeremail '<committer@example.com>' +test_atom head committerdate 'Mon Jul 3 17:18:43 2006 +0200' +test_atom head tag '' +test_atom head tagger '' +test_atom head taggername '' +test_atom head taggeremail '' +test_atom head taggerdate '' +test_atom head creator 'C O Mitter <committer@example.com> 1151939923 +0200' +test_atom head creatordate 'Mon Jul 3 17:18:43 2006 +0200' +test_atom head subject 'Initial' +test_atom head body '' +test_atom head contents 'Initial +' + +test_atom tag refname refs/tags/testtag +test_atom tag objecttype tag +test_atom tag objectsize 154 +test_atom tag objectname 98b46b1d36e5b07909de1b3886224e3e81e87322 +test_atom tag tree '' +test_atom tag parent '' +test_atom tag numparent '' +test_atom tag object '67a36f10722846e891fbada1ba48ed035de75581' +test_atom tag type 'commit' +test_atom tag author '' +test_atom tag authorname '' +test_atom tag authoremail '' +test_atom tag authordate '' +test_atom tag committer '' +test_atom tag committername '' +test_atom tag committeremail '' +test_atom tag committerdate '' +test_atom tag tag 'testtag' +test_atom tag tagger 'C O Mitter <committer@example.com> 1151939925 +0200' +test_atom tag taggername 'C O Mitter' +test_atom tag taggeremail '<committer@example.com>' +test_atom tag taggerdate 'Mon Jul 3 17:18:45 2006 +0200' +test_atom tag creator 'C O Mitter <committer@example.com> 1151939925 +0200' +test_atom tag creatordate 'Mon Jul 3 17:18:45 2006 +0200' +test_atom tag subject 'Tagging at 1151939927' +test_atom tag body '' +test_atom tag contents 'Tagging at 1151939927 +' + +test_expect_success 'Check invalid atoms names are errors' ' + test_must_fail git-for-each-ref --format="%(INVALID)" refs/heads +' + +test_expect_success 'Check format specifiers are ignored in naming date atoms' ' + git-for-each-ref --format="%(authordate)" refs/heads && + git-for-each-ref --format="%(authordate:default) %(authordate)" refs/heads && + git-for-each-ref --format="%(authordate) %(authordate:default)" refs/heads && + git-for-each-ref --format="%(authordate:default) %(authordate:default)" refs/heads +' + +test_expect_success 'Check valid format specifiers for date fields' ' + git-for-each-ref --format="%(authordate:default)" refs/heads && + git-for-each-ref --format="%(authordate:relative)" refs/heads && + git-for-each-ref --format="%(authordate:short)" refs/heads && + git-for-each-ref --format="%(authordate:local)" refs/heads && + git-for-each-ref --format="%(authordate:iso8601)" refs/heads && + git-for-each-ref --format="%(authordate:rfc2822)" refs/heads +' + +test_expect_success 'Check invalid format specifiers are errors' ' + test_must_fail git-for-each-ref --format="%(authordate:INVALID)" refs/heads +' + +cat >expected <<\EOF +'refs/heads/master' 'Mon Jul 3 17:18:43 2006 +0200' 'Mon Jul 3 17:18:44 2006 +0200' +'refs/tags/testtag' 'Mon Jul 3 17:18:45 2006 +0200' +EOF + +test_expect_success 'Check unformatted date fields output' ' + (git for-each-ref --shell --format="%(refname) %(committerdate) %(authordate)" refs/heads && + git for-each-ref --shell --format="%(refname) %(taggerdate)" refs/tags) >actual && + test_cmp expected actual +' + +test_expect_success 'Check format "default" formatted date fields output' ' + f=default && + (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && + git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual && + test_cmp expected actual +' + +# Don't know how to do relative check because I can't know when this script +# is going to be run and can't fake the current time to git, and hence can't +# provide expected output. Instead, I'll just make sure that "relative" +# doesn't exit in error +# +#cat >expected <<\EOF +# +#EOF +# +test_expect_success 'Check format "relative" date fields output' ' + f=relative && + (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && + git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual +' + +cat >expected <<\EOF +'refs/heads/master' '2006-07-03' '2006-07-03' +'refs/tags/testtag' '2006-07-03' +EOF + +test_expect_success 'Check format "short" date fields output' ' + f=short && + (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && + git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +'refs/heads/master' 'Mon Jul 3 15:18:43 2006' 'Mon Jul 3 15:18:44 2006' +'refs/tags/testtag' 'Mon Jul 3 15:18:45 2006' +EOF + +test_expect_success 'Check format "local" date fields output' ' + f=local && + (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && + git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +'refs/heads/master' '2006-07-03 17:18:43 +0200' '2006-07-03 17:18:44 +0200' +'refs/tags/testtag' '2006-07-03 17:18:45 +0200' +EOF + +test_expect_success 'Check format "iso8601" date fields output' ' + f=iso8601 && + (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && + git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +'refs/heads/master' 'Mon, 3 Jul 2006 17:18:43 +0200' 'Mon, 3 Jul 2006 17:18:44 +0200' +'refs/tags/testtag' 'Mon, 3 Jul 2006 17:18:45 +0200' +EOF + +test_expect_success 'Check format "rfc2822" date fields output' ' + f=rfc2822 && + (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && + git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +refs/heads/master +refs/tags/testtag +EOF + +test_expect_success 'Verify ascending sort' ' + git-for-each-ref --format="%(refname)" --sort=refname >actual && + test_cmp expected actual +' + + +cat >expected <<\EOF +refs/tags/testtag +refs/heads/master +EOF + +test_expect_success 'Verify descending sort' ' + git-for-each-ref --format="%(refname)" --sort=-refname >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +'refs/heads/master' +'refs/tags/testtag' +EOF + +test_expect_success 'Quoting style: shell' ' + git for-each-ref --shell --format="%(refname)" >actual && + test_cmp expected actual +' + +test_expect_success 'Quoting style: perl' ' + git for-each-ref --perl --format="%(refname)" >actual && + test_cmp expected actual +' + +test_expect_success 'Quoting style: python' ' + git for-each-ref --python --format="%(refname)" >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +"refs/heads/master" +"refs/tags/testtag" +EOF + +test_expect_success 'Quoting style: tcl' ' + git for-each-ref --tcl --format="%(refname)" >actual && + test_cmp expected actual +' + +for i in "--perl --shell" "-s --python" "--python --tcl" "--tcl --perl"; do + test_expect_success "more than one quoting style: $i" " + git for-each-ref $i 2>&1 | (read line && + case \$line in + \"error: more than one quoting style\"*) : happy;; + *) false + esac) + " +done + +test_done diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh new file mode 100755 index 0000000000..910a28c7e2 --- /dev/null +++ b/t/t7001-mv.sh @@ -0,0 +1,213 @@ +#!/bin/sh + +test_description='git mv in subdirs' +. ./test-lib.sh + +test_expect_success \ + 'prepare reference tree' \ + 'mkdir path0 path1 && + cp ../../COPYING path0/COPYING && + git add path0/COPYING && + git-commit -m add -a' + +test_expect_success \ + 'moving the file out of subdirectory' \ + 'cd path0 && git mv COPYING ../path1/COPYING' + +# in path0 currently +test_expect_success \ + 'commiting the change' \ + 'cd .. && git-commit -m move-out -a' + +test_expect_success \ + 'checking the commit' \ + 'git diff-tree -r -M --name-status HEAD^ HEAD | \ + grep "^R100..*path0/COPYING..*path1/COPYING"' + +test_expect_success \ + 'moving the file back into subdirectory' \ + 'cd path0 && git mv ../path1/COPYING COPYING' + +# in path0 currently +test_expect_success \ + 'commiting the change' \ + 'cd .. && git-commit -m move-in -a' + +test_expect_success \ + 'checking the commit' \ + 'git diff-tree -r -M --name-status HEAD^ HEAD | \ + grep "^R100..*path1/COPYING..*path0/COPYING"' + +test_expect_success \ + 'adding another file' \ + 'cp ../../README path0/README && + git add path0/README && + git-commit -m add2 -a' + +test_expect_success \ + 'moving whole subdirectory' \ + 'git mv path0 path2' + +test_expect_success \ + 'commiting the change' \ + 'git-commit -m dir-move -a' + +test_expect_success \ + 'checking the commit' \ + 'git diff-tree -r -M --name-status HEAD^ HEAD | \ + grep "^R100..*path0/COPYING..*path2/COPYING" && + git diff-tree -r -M --name-status HEAD^ HEAD | \ + grep "^R100..*path0/README..*path2/README"' + +test_expect_success \ + 'succeed when source is a prefix of destination' \ + 'git mv path2/COPYING path2/COPYING-renamed' + +test_expect_success \ + 'moving whole subdirectory into subdirectory' \ + 'git mv path2 path1' + +test_expect_success \ + 'commiting the change' \ + 'git-commit -m dir-move -a' + +test_expect_success \ + 'checking the commit' \ + 'git diff-tree -r -M --name-status HEAD^ HEAD | \ + grep "^R100..*path2/COPYING..*path1/path2/COPYING" && + git diff-tree -r -M --name-status HEAD^ HEAD | \ + grep "^R100..*path2/README..*path1/path2/README"' + +test_expect_success \ + 'do not move directory over existing directory' \ + 'mkdir path0 && mkdir path0/path2 && test_must_fail git mv path2 path0' + +test_expect_success \ + 'move into "."' \ + 'git mv path1/path2/ .' + +test_expect_success "Michael Cassar's test case" ' + rm -fr .git papers partA && + git init && + mkdir -p papers/unsorted papers/all-papers partA && + echo a > papers/unsorted/Thesis.pdf && + echo b > partA/outline.txt && + echo c > papers/unsorted/_another && + git add papers partA && + T1=`git write-tree` && + + git mv papers/unsorted/Thesis.pdf papers/all-papers/moo-blah.pdf && + + T=`git write-tree` && + git ls-tree -r $T | grep partA/outline.txt || { + git ls-tree -r $T + (exit 1) + } +' + +rm -fr papers partA path? + +test_expect_success "Sergey Vlasov's test case" ' + rm -fr .git && + git init && + mkdir ab && + date >ab.c && + date >ab/d && + git add ab.c ab && + git commit -m 'initial' && + git mv ab a +' + +test_expect_success 'absolute pathname' '( + + rm -fr mine && + mkdir mine && + cd mine && + test_create_repo one && + cd one && + mkdir sub && + >sub/file && + git add sub/file && + + git mv sub "$(pwd)/in" && + ! test -d sub && + test -d in && + git ls-files --error-unmatch in/file + + +)' + +test_expect_success 'absolute pathname outside should fail' '( + + rm -fr mine && + mkdir mine && + cd mine && + out=$(pwd) && + test_create_repo one && + cd one && + mkdir sub && + >sub/file && + git add sub/file && + + test_must_fail git mv sub "$out/out" && + test -d sub && + ! test -d ../in && + git ls-files --error-unmatch sub/file + +)' + +test_expect_success 'git mv should not change sha1 of moved cache entry' ' + + rm -fr .git && + git init && + echo 1 >dirty && + git add dirty && + entry="$(git ls-files --stage dirty | cut -f 1)" + git mv dirty dirty2 && + [ "$entry" = "$(git ls-files --stage dirty2 | cut -f 1)" ] && + echo 2 >dirty2 && + git mv dirty2 dirty && + [ "$entry" = "$(git ls-files --stage dirty | cut -f 1)" ] + +' + +rm -f dirty dirty2 + +test_expect_success 'git mv should overwrite symlink to a file' ' + + rm -fr .git && + git init && + echo 1 >moved && + ln -s moved symlink && + git add moved symlink && + test_must_fail git mv moved symlink && + git mv -f moved symlink && + ! test -e moved && + test -f symlink && + test "$(cat symlink)" = 1 && + git update-index --refresh && + git diff-files --quiet + +' + +rm -f moved symlink + +test_expect_success 'git mv should overwrite file with a symlink' ' + + rm -fr .git && + git init && + echo 1 >moved && + ln -s moved symlink && + git add moved symlink && + test_must_fail git mv symlink moved && + git mv -f symlink moved && + ! test -e symlink && + test -h moved && + git update-index --refresh && + git diff-files --quiet + +' + +rm -f moved symlink + +test_done diff --git a/t/t7002-grep.sh b/t/t7002-grep.sh new file mode 100755 index 0000000000..c8b4f65f38 --- /dev/null +++ b/t/t7002-grep.sh @@ -0,0 +1,116 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='git grep various. +' + +. ./test-lib.sh + +test_expect_success setup ' + { + echo foo mmap bar + echo foo_mmap bar + echo foo_mmap bar mmap + echo foo mmap bar_mmap + echo foo_mmap bar mmap baz + } >file && + echo x x xx x >x && + echo y yy >y && + echo zzz > z && + mkdir t && + echo test >t/t && + git add file x y z t/t && + git commit -m initial +' + +for H in HEAD '' +do + case "$H" in + HEAD) HC='HEAD:' L='HEAD' ;; + '') HC= L='in working tree' ;; + esac + + test_expect_success "grep -w $L" ' + { + echo ${HC}file:1:foo mmap bar + echo ${HC}file:3:foo_mmap bar mmap + echo ${HC}file:4:foo mmap bar_mmap + echo ${HC}file:5:foo_mmap bar mmap baz + } >expected && + git grep -n -w -e mmap $H >actual && + diff expected actual + ' + + test_expect_success "grep -w $L (x)" ' + { + echo ${HC}x:1:x x xx x + } >expected && + git grep -n -w -e "x xx* x" $H >actual && + diff expected actual + ' + + test_expect_success "grep -w $L (y-1)" ' + { + echo ${HC}y:1:y yy + } >expected && + git grep -n -w -e "^y" $H >actual && + diff expected actual + ' + + test_expect_success "grep -w $L (y-2)" ' + : >expected && + if git grep -n -w -e "^y y" $H >actual + then + echo should not have matched + cat actual + false + else + diff expected actual + fi + ' + + test_expect_success "grep -w $L (z)" ' + : >expected && + if git grep -n -w -e "^z" $H >actual + then + echo should not have matched + cat actual + false + else + diff expected actual + fi + ' + + test_expect_success "grep $L (t-1)" ' + echo "${HC}t/t:1:test" >expected && + git grep -n -e test $H >actual && + diff expected actual + ' + + test_expect_success "grep $L (t-2)" ' + echo "${HC}t:1:test" >expected && + ( + cd t && + git grep -n -e test $H + ) >actual && + diff expected actual + ' + + test_expect_success "grep $L (t-3)" ' + echo "${HC}t/t:1:test" >expected && + ( + cd t && + git grep --full-name -n -e test $H + ) >actual && + diff expected actual + ' + + test_expect_success "grep -c $L (no /dev/null)" ' + ! git grep -c test $H | grep -q /dev/null + ' + +done + +test_done diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh new file mode 100755 index 0000000000..a0ab096c8f --- /dev/null +++ b/t/t7003-filter-branch.sh @@ -0,0 +1,253 @@ +#!/bin/sh + +test_description='git-filter-branch' +. ./test-lib.sh + +make_commit () { + lower=$(echo $1 | tr '[A-Z]' '[a-z]') + echo $lower > $lower + git add $lower + test_tick + git commit -m $1 + git tag $1 +} + +test_expect_success 'setup' ' + make_commit A + make_commit B + git checkout -b branch B + make_commit D + mkdir dir + make_commit dir/D + make_commit E + git checkout master + make_commit C + git checkout branch + git merge C + git tag F + make_commit G + make_commit H +' + +H=$(git rev-parse H) + +test_expect_success 'rewrite identically' ' + git-filter-branch branch +' +test_expect_success 'result is really identical' ' + test $H = $(git rev-parse HEAD) +' + +test_expect_success 'rewrite bare repository identically' ' + (git config core.bare true && cd .git && git-filter-branch branch) +' +git config core.bare false +test_expect_success 'result is really identical' ' + test $H = $(git rev-parse HEAD) +' + +test_expect_success 'rewrite, renaming a specific file' ' + git-filter-branch -f --tree-filter "mv d doh || :" HEAD +' + +test_expect_success 'test that the file was renamed' ' + test d = "$(git show HEAD:doh --)" && + ! test -f d && + test -f doh && + test d = "$(cat doh)" +' + +test_expect_success 'rewrite, renaming a specific directory' ' + git-filter-branch -f --tree-filter "mv dir diroh || :" HEAD +' + +test_expect_success 'test that the directory was renamed' ' + test dir/d = "$(git show HEAD:diroh/d --)" && + ! test -d dir && + test -d diroh && + ! test -d diroh/dir && + test -f diroh/d && + test dir/d = "$(cat diroh/d)" +' + +git tag oldD HEAD~4 +test_expect_success 'rewrite one branch, keeping a side branch' ' + git branch modD oldD && + git-filter-branch -f --tree-filter "mv b boh || :" D..modD +' + +test_expect_success 'common ancestor is still common (unchanged)' ' + test "$(git merge-base modD D)" = "$(git rev-parse B)" +' + +test_expect_success 'filter subdirectory only' ' + mkdir subdir && + touch subdir/new && + git add subdir/new && + test_tick && + git commit -m "subdir" && + echo H > a && + test_tick && + git commit -m "not subdir" a && + echo A > subdir/new && + test_tick && + git commit -m "again subdir" subdir/new && + git rm a && + test_tick && + git commit -m "again not subdir" && + git branch sub && + git-filter-branch -f --subdirectory-filter subdir refs/heads/sub +' + +test_expect_success 'subdirectory filter result looks okay' ' + test 2 = $(git rev-list sub | wc -l) && + git show sub:new && + test_must_fail git show sub:subdir +' + +test_expect_success 'more setup' ' + git checkout master && + mkdir subdir && + echo A > subdir/new && + git add subdir/new && + test_tick && + git commit -m "subdir on master" subdir/new && + git rm a && + test_tick && + git commit -m "again subdir on master" && + git merge branch +' + +test_expect_success 'use index-filter to move into a subdirectory' ' + git branch directorymoved && + git-filter-branch -f --index-filter \ + "git ls-files -s | sed \"s-\\t-&newsubdir/-\" | + GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \ + git update-index --index-info && + mv \"\$GIT_INDEX_FILE.new\" \"\$GIT_INDEX_FILE\"" directorymoved && + test -z "$(git diff HEAD directorymoved:newsubdir)"' + +test_expect_success 'stops when msg filter fails' ' + old=$(git rev-parse HEAD) && + test_must_fail git-filter-branch -f --msg-filter false HEAD && + test $old = $(git rev-parse HEAD) && + rm -rf .git-rewrite +' + +test_expect_success 'author information is preserved' ' + : > i && + git add i && + test_tick && + GIT_AUTHOR_NAME="B V Uips" git commit -m bvuips && + git branch preserved-author && + git-filter-branch -f --msg-filter "cat; \ + test \$GIT_COMMIT != $(git rev-parse master) || \ + echo Hallo" \ + preserved-author && + test 1 = $(git rev-list --author="B V Uips" preserved-author | wc -l) +' + +test_expect_success "remove a certain author's commits" ' + echo i > i && + test_tick && + git commit -m i i && + git branch removed-author && + git-filter-branch -f --commit-filter "\ + if [ \"\$GIT_AUTHOR_NAME\" = \"B V Uips\" ];\ + then\ + skip_commit \"\$@\"; + else\ + git commit-tree \"\$@\";\ + fi" removed-author && + cnt1=$(git rev-list master | wc -l) && + cnt2=$(git rev-list removed-author | wc -l) && + test $cnt1 -eq $(($cnt2 + 1)) && + test 0 = $(git rev-list --author="B V Uips" removed-author | wc -l) +' + +test_expect_success 'barf on invalid name' ' + test_must_fail git filter-branch -f master xy-problem && + test_must_fail git filter-branch -f HEAD^ +' + +test_expect_success '"map" works in commit filter' ' + git filter-branch -f --commit-filter "\ + parent=\$(git rev-parse \$GIT_COMMIT^) && + mapped=\$(map \$parent) && + actual=\$(echo \"\$@\" | sed \"s/^.*-p //\") && + test \$mapped = \$actual && + git commit-tree \"\$@\";" master~2..master && + git rev-parse --verify master +' + +test_expect_success 'Name needing quotes' ' + + git checkout -b rerere A && + mkdir foo && + name="れれれ" && + >foo/$name && + git add foo && + git commit -m "Adding a file" && + git filter-branch --tree-filter "rm -fr foo" && + test_must_fail git ls-files --error-unmatch "foo/$name" && + test $(git rev-parse --verify rerere) != $(git rev-parse --verify A) + +' + +test_expect_success 'Subdirectory filter with disappearing trees' ' + git reset --hard && + git checkout master && + + mkdir foo && + touch foo/bar && + git add foo && + test_tick && + git commit -m "Adding foo" && + + git rm -r foo && + test_tick && + git commit -m "Removing foo" && + + mkdir foo && + touch foo/bar && + git add foo && + test_tick && + git commit -m "Re-adding foo" && + + git filter-branch -f --subdirectory-filter foo && + test $(git rev-list master | wc -l) = 3 +' + +test_expect_success 'Tag name filtering retains tag message' ' + git tag -m atag T && + git cat-file tag T > expect && + git filter-branch -f --tag-name-filter cat && + git cat-file tag T > actual && + test_cmp expect actual +' + +faux_gpg_tag='object XXXXXX +type commit +tag S +tagger T A Gger <tagger@example.com> 1206026339 -0500 + +This is a faux gpg signed tag. +-----BEGIN PGP SIGNATURE----- +Version: FauxGPG v0.0.0 (FAUX/Linux) + +gdsfoewhxu/6l06f1kxyxhKdZkrcbaiOMtkJUA9ITAc1mlamh0ooasxkH1XwMbYQ +acmwXaWET20H0GeAGP+7vow= +=agpO +-----END PGP SIGNATURE----- +' +test_expect_success 'Tag name filtering strips gpg signature' ' + sha1=$(git rev-parse HEAD) && + sha1t=$(echo "$faux_gpg_tag" | sed -e s/XXXXXX/$sha1/ | git mktag) && + git update-ref "refs/tags/S" "$sha1t" && + echo "$faux_gpg_tag" | sed -e s/XXXXXX/$sha1/ | head -n 6 > expect && + git filter-branch -f --tag-name-filter cat && + git cat-file tag S > actual && + test_cmp expect actual +' + +test_done diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh new file mode 100755 index 0000000000..8d44c2ed1f --- /dev/null +++ b/t/t7004-tag.sh @@ -0,0 +1,1093 @@ +#!/bin/sh +# +# Copyright (c) 2007 Carlos Rica +# + +test_description='git-tag + +Tests for operations with tags.' + +. ./test-lib.sh + +# creating and listing lightweight tags: + +tag_exists () { + git show-ref --quiet --verify refs/tags/"$1" +} + +# todo: git tag -l now returns always zero, when fixed, change this test +test_expect_success 'listing all tags in an empty tree should succeed' ' + git tag -l && + git tag +' + +test_expect_success 'listing all tags in an empty tree should output nothing' ' + test `git-tag -l | wc -l` -eq 0 && + test `git-tag | wc -l` -eq 0 +' + +test_expect_success 'looking for a tag in an empty tree should fail' \ + '! (tag_exists mytag)' + +test_expect_success 'creating a tag in an empty tree should fail' ' + test_must_fail git-tag mynotag && + ! tag_exists mynotag +' + +test_expect_success 'creating a tag for HEAD in an empty tree should fail' ' + test_must_fail git-tag mytaghead HEAD && + ! tag_exists mytaghead +' + +test_expect_success 'creating a tag for an unknown revision should fail' ' + test_must_fail git-tag mytagnorev aaaaaaaaaaa && + ! tag_exists mytagnorev +' + +# commit used in the tests, test_tick is also called here to freeze the date: +test_expect_success 'creating a tag using default HEAD should succeed' ' + test_tick && + echo foo >foo && + git add foo && + git commit -m Foo && + git tag mytag +' + +test_expect_success 'listing all tags if one exists should succeed' ' + git-tag -l && + git-tag +' + +test_expect_success 'listing all tags if one exists should output that tag' ' + test `git-tag -l` = mytag && + test `git-tag` = mytag +' + +# pattern matching: + +test_expect_success 'listing a tag using a matching pattern should succeed' \ + 'git-tag -l mytag' + +test_expect_success \ + 'listing a tag using a matching pattern should output that tag' \ + 'test `git-tag -l mytag` = mytag' + +# todo: git tag -l now returns always zero, when fixed, change this test +test_expect_success \ + 'listing tags using a non-matching pattern should suceed' \ + 'git-tag -l xxx' + +test_expect_success \ + 'listing tags using a non-matching pattern should output nothing' \ + 'test `git-tag -l xxx | wc -l` -eq 0' + +# special cases for creating tags: + +test_expect_success \ + 'trying to create a tag with the name of one existing should fail' \ + 'test_must_fail git tag mytag' + +test_expect_success \ + 'trying to create a tag with a non-valid name should fail' ' + test `git-tag -l | wc -l` -eq 1 && + test_must_fail git tag "" && + test_must_fail git tag .othertag && + test_must_fail git tag "other tag" && + test_must_fail git tag "othertag^" && + test_must_fail git tag "other~tag" && + test `git-tag -l | wc -l` -eq 1 +' + +test_expect_success 'creating a tag using HEAD directly should succeed' ' + git tag myhead HEAD && + tag_exists myhead +' + +# deleting tags: + +test_expect_success 'trying to delete an unknown tag should fail' ' + ! tag_exists unknown-tag && + test_must_fail git-tag -d unknown-tag +' + +cat >expect <<EOF +myhead +mytag +EOF +test_expect_success \ + 'trying to delete tags without params should succeed and do nothing' ' + git tag -l > actual && test_cmp expect actual && + git-tag -d && + git tag -l > actual && test_cmp expect actual +' + +test_expect_success \ + 'deleting two existing tags in one command should succeed' ' + tag_exists mytag && + tag_exists myhead && + git-tag -d mytag myhead && + ! tag_exists mytag && + ! tag_exists myhead +' + +test_expect_success \ + 'creating a tag with the name of another deleted one should succeed' ' + ! tag_exists mytag && + git-tag mytag && + tag_exists mytag +' + +test_expect_success \ + 'trying to delete two tags, existing and not, should fail in the 2nd' ' + tag_exists mytag && + ! tag_exists myhead && + test_must_fail git-tag -d mytag anothertag && + ! tag_exists mytag && + ! tag_exists myhead +' + +test_expect_success 'trying to delete an already deleted tag should fail' \ + 'test_must_fail git-tag -d mytag' + +# listing various tags with pattern matching: + +cat >expect <<EOF +a1 +aa1 +cba +t210 +t211 +v0.2.1 +v1.0 +v1.0.1 +v1.1.3 +EOF +test_expect_success 'listing all tags should print them ordered' ' + git tag v1.0.1 && + git tag t211 && + git tag aa1 && + git tag v0.2.1 && + git tag v1.1.3 && + git tag cba && + git tag a1 && + git tag v1.0 && + git tag t210 && + git tag -l > actual && + test_cmp expect actual && + git tag > actual && + test_cmp expect actual +' + +cat >expect <<EOF +a1 +aa1 +cba +EOF +test_expect_success \ + 'listing tags with substring as pattern must print those matching' ' + git-tag -l "*a*" > actual && + test_cmp expect actual +' + +cat >expect <<EOF +v0.2.1 +v1.0.1 +EOF +test_expect_success \ + 'listing tags with a suffix as pattern must print those matching' ' + git-tag -l "*.1" > actual && + test_cmp expect actual +' + +cat >expect <<EOF +t210 +t211 +EOF +test_expect_success \ + 'listing tags with a prefix as pattern must print those matching' ' + git-tag -l "t21*" > actual && + test_cmp expect actual +' + +cat >expect <<EOF +a1 +EOF +test_expect_success \ + 'listing tags using a name as pattern must print that one matching' ' + git-tag -l a1 > actual && + test_cmp expect actual +' + +cat >expect <<EOF +v1.0 +EOF +test_expect_success \ + 'listing tags using a name as pattern must print that one matching' ' + git-tag -l v1.0 > actual && + test_cmp expect actual +' + +cat >expect <<EOF +v1.0.1 +v1.1.3 +EOF +test_expect_success \ + 'listing tags with ? in the pattern should print those matching' ' + git-tag -l "v1.?.?" > actual && + test_cmp expect actual +' + +>expect +test_expect_success \ + 'listing tags using v.* should print nothing because none have v.' ' + git-tag -l "v.*" > actual && + test_cmp expect actual +' + +cat >expect <<EOF +v0.2.1 +v1.0 +v1.0.1 +v1.1.3 +EOF +test_expect_success \ + 'listing tags using v* should print only those having v' ' + git-tag -l "v*" > actual && + test_cmp expect actual +' + +# creating and verifying lightweight tags: + +test_expect_success \ + 'a non-annotated tag created without parameters should point to HEAD' ' + git-tag non-annotated-tag && + test $(git cat-file -t non-annotated-tag) = commit && + test $(git rev-parse non-annotated-tag) = $(git rev-parse HEAD) +' + +test_expect_success 'trying to verify an unknown tag should fail' \ + 'test_must_fail git-tag -v unknown-tag' + +test_expect_success \ + 'trying to verify a non-annotated and non-signed tag should fail' \ + 'test_must_fail git-tag -v non-annotated-tag' + +test_expect_success \ + 'trying to verify many non-annotated or unknown tags, should fail' \ + 'test_must_fail git-tag -v unknown-tag1 non-annotated-tag unknown-tag2' + +# creating annotated tags: + +get_tag_msg () { + git cat-file tag "$1" | sed -e "/BEGIN PGP/q" +} + +# run test_tick before committing always gives the time in that timezone +get_tag_header () { +cat <<EOF +object $2 +type $3 +tag $1 +tagger C O Mitter <committer@example.com> $4 -0700 + +EOF +} + +commit=$(git rev-parse HEAD) +time=$test_tick + +get_tag_header annotated-tag $commit commit $time >expect +echo "A message" >>expect +test_expect_success \ + 'creating an annotated tag with -m message should succeed' ' + git-tag -m "A message" annotated-tag && + get_tag_msg annotated-tag >actual && + test_cmp expect actual +' + +cat >msgfile <<EOF +Another message +in a file. +EOF +get_tag_header file-annotated-tag $commit commit $time >expect +cat msgfile >>expect +test_expect_success \ + 'creating an annotated tag with -F messagefile should succeed' ' + git-tag -F msgfile file-annotated-tag && + get_tag_msg file-annotated-tag >actual && + test_cmp expect actual +' + +cat >inputmsg <<EOF +A message from the +standard input +EOF +get_tag_header stdin-annotated-tag $commit commit $time >expect +cat inputmsg >>expect +test_expect_success 'creating an annotated tag with -F - should succeed' ' + git-tag -F - stdin-annotated-tag <inputmsg && + get_tag_msg stdin-annotated-tag >actual && + test_cmp expect actual +' + +test_expect_success \ + 'trying to create a tag with a non-existing -F file should fail' ' + ! test -f nonexistingfile && + ! tag_exists notag && + test_must_fail git-tag -F nonexistingfile notag && + ! tag_exists notag +' + +test_expect_success \ + 'trying to create tags giving both -m or -F options should fail' ' + echo "message file 1" >msgfile1 && + echo "message file 2" >msgfile2 && + ! tag_exists msgtag && + test_must_fail git-tag -m "message 1" -F msgfile1 msgtag && + ! tag_exists msgtag && + test_must_fail git-tag -F msgfile1 -m "message 1" msgtag && + ! tag_exists msgtag && + test_must_fail git-tag -m "message 1" -F msgfile1 \ + -m "message 2" msgtag && + ! tag_exists msgtag +' + +# blank and empty messages: + +get_tag_header empty-annotated-tag $commit commit $time >expect +test_expect_success \ + 'creating a tag with an empty -m message should succeed' ' + git-tag -m "" empty-annotated-tag && + get_tag_msg empty-annotated-tag >actual && + test_cmp expect actual +' + +>emptyfile +get_tag_header emptyfile-annotated-tag $commit commit $time >expect +test_expect_success \ + 'creating a tag with an empty -F messagefile should succeed' ' + git-tag -F emptyfile emptyfile-annotated-tag && + get_tag_msg emptyfile-annotated-tag >actual && + test_cmp expect actual +' + +printf '\n\n \n\t\nLeading blank lines\n' >blanksfile +printf '\n\t \t \nRepeated blank lines\n' >>blanksfile +printf '\n\n\nTrailing spaces \t \n' >>blanksfile +printf '\nTrailing blank lines\n\n\t \n\n' >>blanksfile +get_tag_header blanks-annotated-tag $commit commit $time >expect +cat >>expect <<EOF +Leading blank lines + +Repeated blank lines + +Trailing spaces + +Trailing blank lines +EOF +test_expect_success \ + 'extra blanks in the message for an annotated tag should be removed' ' + git-tag -F blanksfile blanks-annotated-tag && + get_tag_msg blanks-annotated-tag >actual && + test_cmp expect actual +' + +get_tag_header blank-annotated-tag $commit commit $time >expect +test_expect_success \ + 'creating a tag with blank -m message with spaces should succeed' ' + git-tag -m " " blank-annotated-tag && + get_tag_msg blank-annotated-tag >actual && + test_cmp expect actual +' + +echo ' ' >blankfile +echo '' >>blankfile +echo ' ' >>blankfile +get_tag_header blankfile-annotated-tag $commit commit $time >expect +test_expect_success \ + 'creating a tag with blank -F messagefile with spaces should succeed' ' + git-tag -F blankfile blankfile-annotated-tag && + get_tag_msg blankfile-annotated-tag >actual && + test_cmp expect actual +' + +printf ' ' >blanknonlfile +get_tag_header blanknonlfile-annotated-tag $commit commit $time >expect +test_expect_success \ + 'creating a tag with -F file of spaces and no newline should succeed' ' + git-tag -F blanknonlfile blanknonlfile-annotated-tag && + get_tag_msg blanknonlfile-annotated-tag >actual && + test_cmp expect actual +' + +# messages with commented lines: + +cat >commentsfile <<EOF +# A comment + +############ +The message. +############ +One line. + + +# commented lines +# commented lines + +Another line. +# comments + +Last line. +EOF +get_tag_header comments-annotated-tag $commit commit $time >expect +cat >>expect <<EOF +The message. +One line. + +Another line. + +Last line. +EOF +test_expect_success \ + 'creating a tag using a -F messagefile with #comments should succeed' ' + git-tag -F commentsfile comments-annotated-tag && + get_tag_msg comments-annotated-tag >actual && + test_cmp expect actual +' + +get_tag_header comment-annotated-tag $commit commit $time >expect +test_expect_success \ + 'creating a tag with a #comment in the -m message should succeed' ' + git-tag -m "#comment" comment-annotated-tag && + get_tag_msg comment-annotated-tag >actual && + test_cmp expect actual +' + +echo '#comment' >commentfile +echo '' >>commentfile +echo '####' >>commentfile +get_tag_header commentfile-annotated-tag $commit commit $time >expect +test_expect_success \ + 'creating a tag with #comments in the -F messagefile should succeed' ' + git-tag -F commentfile commentfile-annotated-tag && + get_tag_msg commentfile-annotated-tag >actual && + test_cmp expect actual +' + +printf '#comment' >commentnonlfile +get_tag_header commentnonlfile-annotated-tag $commit commit $time >expect +test_expect_success \ + 'creating a tag with a file of #comment and no newline should succeed' ' + git-tag -F commentnonlfile commentnonlfile-annotated-tag && + get_tag_msg commentnonlfile-annotated-tag >actual && + test_cmp expect actual +' + +# listing messages for annotated non-signed tags: + +test_expect_success \ + 'listing the one-line message of a non-signed tag should succeed' ' + git-tag -m "A msg" tag-one-line && + + echo "tag-one-line" >expect && + git-tag -l | grep "^tag-one-line" >actual && + test_cmp expect actual && + git-tag -n0 -l | grep "^tag-one-line" >actual && + test_cmp expect actual && + git-tag -n0 -l tag-one-line >actual && + test_cmp expect actual && + + echo "tag-one-line A msg" >expect && + git-tag -n1 -l | grep "^tag-one-line" >actual && + test_cmp expect actual && + git-tag -n -l | grep "^tag-one-line" >actual && + test_cmp expect actual && + git-tag -n1 -l tag-one-line >actual && + test_cmp expect actual && + git-tag -n2 -l tag-one-line >actual && + test_cmp expect actual && + git-tag -n999 -l tag-one-line >actual && + test_cmp expect actual +' + +test_expect_success \ + 'listing the zero-lines message of a non-signed tag should succeed' ' + git-tag -m "" tag-zero-lines && + + echo "tag-zero-lines" >expect && + git-tag -l | grep "^tag-zero-lines" >actual && + test_cmp expect actual && + git-tag -n0 -l | grep "^tag-zero-lines" >actual && + test_cmp expect actual && + git-tag -n0 -l tag-zero-lines >actual && + test_cmp expect actual && + + echo "tag-zero-lines " >expect && + git-tag -n1 -l | grep "^tag-zero-lines" >actual && + test_cmp expect actual && + git-tag -n -l | grep "^tag-zero-lines" >actual && + test_cmp expect actual && + git-tag -n1 -l tag-zero-lines >actual && + test_cmp expect actual && + git-tag -n2 -l tag-zero-lines >actual && + test_cmp expect actual && + git-tag -n999 -l tag-zero-lines >actual && + test_cmp expect actual +' + +echo 'tag line one' >annotagmsg +echo 'tag line two' >>annotagmsg +echo 'tag line three' >>annotagmsg +test_expect_success \ + 'listing many message lines of a non-signed tag should succeed' ' + git-tag -F annotagmsg tag-lines && + + echo "tag-lines" >expect && + git-tag -l | grep "^tag-lines" >actual && + test_cmp expect actual && + git-tag -n0 -l | grep "^tag-lines" >actual && + test_cmp expect actual && + git-tag -n0 -l tag-lines >actual && + test_cmp expect actual && + + echo "tag-lines tag line one" >expect && + git-tag -n1 -l | grep "^tag-lines" >actual && + test_cmp expect actual && + git-tag -n -l | grep "^tag-lines" >actual && + test_cmp expect actual && + git-tag -n1 -l tag-lines >actual && + test_cmp expect actual && + + echo " tag line two" >>expect && + git-tag -n2 -l | grep "^ *tag.line" >actual && + test_cmp expect actual && + git-tag -n2 -l tag-lines >actual && + test_cmp expect actual && + + echo " tag line three" >>expect && + git-tag -n3 -l | grep "^ *tag.line" >actual && + test_cmp expect actual && + git-tag -n3 -l tag-lines >actual && + test_cmp expect actual && + git-tag -n4 -l | grep "^ *tag.line" >actual && + test_cmp expect actual && + git-tag -n4 -l tag-lines >actual && + test_cmp expect actual && + git-tag -n99 -l | grep "^ *tag.line" >actual && + test_cmp expect actual && + git-tag -n99 -l tag-lines >actual && + test_cmp expect actual +' + +# subsequent tests require gpg; check if it is available +gpg --version >/dev/null +if [ $? -eq 127 ]; then + echo "gpg not found - skipping tag signing and verification tests" + test_done + exit +fi + +# trying to verify annotated non-signed tags: + +test_expect_success \ + 'trying to verify an annotated non-signed tag should fail' ' + tag_exists annotated-tag && + test_must_fail git-tag -v annotated-tag +' + +test_expect_success \ + 'trying to verify a file-annotated non-signed tag should fail' ' + tag_exists file-annotated-tag && + test_must_fail git-tag -v file-annotated-tag +' + +test_expect_success \ + 'trying to verify two annotated non-signed tags should fail' ' + tag_exists annotated-tag file-annotated-tag && + test_must_fail git-tag -v annotated-tag file-annotated-tag +' + +# creating and verifying signed tags: + +# As said here: http://www.gnupg.org/documentation/faqs.html#q6.19 +# the gpg version 1.0.6 didn't parse trust packets correctly, so for +# that version, creation of signed tags using the generated key fails. +case "$(gpg --version)" in +'gpg (GnuPG) 1.0.6'*) + echo "Skipping signed tag tests, because a bug in 1.0.6 version" + test_done + exit + ;; +esac + +# key generation info: gpg --homedir t/t7004 --gen-key +# Type DSA and Elgamal, size 2048 bits, no expiration date. +# Name and email: C O Mitter <committer@example.com> +# No password given, to enable non-interactive operation. + +cp -R ../t7004 ./gpghome +chmod 0700 gpghome +GNUPGHOME="$(pwd)/gpghome" +export GNUPGHOME + +get_tag_header signed-tag $commit commit $time >expect +echo 'A signed tag message' >>expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success 'creating a signed tag with -m message should succeed' ' + git-tag -s -m "A signed tag message" signed-tag && + get_tag_msg signed-tag >actual && + test_cmp expect actual +' + +get_tag_header u-signed-tag $commit commit $time >expect +echo 'Another message' >>expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success 'sign with a given key id' ' + + git tag -u committer@example.com -m "Another message" u-signed-tag && + get_tag_msg u-signed-tag >actual && + test_cmp expect actual + +' + +test_expect_success 'sign with an unknown id (1)' ' + + test_must_fail git tag -u author@example.com \ + -m "Another message" o-signed-tag + +' + +test_expect_success 'sign with an unknown id (2)' ' + + test_must_fail git tag -u DEADBEEF -m "Another message" o-signed-tag + +' + +cat >fakeeditor <<'EOF' +#!/bin/sh +test -n "$1" && exec >"$1" +echo A signed tag message +echo from a fake editor. +EOF +chmod +x fakeeditor + +get_tag_header implied-sign $commit commit $time >expect +./fakeeditor >>expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success '-u implies signed tag' ' + GIT_EDITOR=./fakeeditor git-tag -u CDDE430D implied-sign && + get_tag_msg implied-sign >actual && + test_cmp expect actual +' + +cat >sigmsgfile <<EOF +Another signed tag +message in a file. +EOF +get_tag_header file-signed-tag $commit commit $time >expect +cat sigmsgfile >>expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag with -F messagefile should succeed' ' + git-tag -s -F sigmsgfile file-signed-tag && + get_tag_msg file-signed-tag >actual && + test_cmp expect actual +' + +cat >siginputmsg <<EOF +A signed tag message from +the standard input +EOF +get_tag_header stdin-signed-tag $commit commit $time >expect +cat siginputmsg >>expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success 'creating a signed tag with -F - should succeed' ' + git-tag -s -F - stdin-signed-tag <siginputmsg && + get_tag_msg stdin-signed-tag >actual && + test_cmp expect actual +' + +get_tag_header implied-annotate $commit commit $time >expect +./fakeeditor >>expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success '-s implies annotated tag' ' + GIT_EDITOR=./fakeeditor git-tag -s implied-annotate && + get_tag_msg implied-annotate >actual && + test_cmp expect actual +' + +test_expect_success \ + 'trying to create a signed tag with non-existing -F file should fail' ' + ! test -f nonexistingfile && + ! tag_exists nosigtag && + test_must_fail git-tag -s -F nonexistingfile nosigtag && + ! tag_exists nosigtag +' + +test_expect_success 'verifying a signed tag should succeed' \ + 'git-tag -v signed-tag' + +test_expect_success 'verifying two signed tags in one command should succeed' \ + 'git-tag -v signed-tag file-signed-tag' + +test_expect_success \ + 'verifying many signed and non-signed tags should fail' ' + test_must_fail git-tag -v signed-tag annotated-tag && + test_must_fail git-tag -v file-annotated-tag file-signed-tag && + test_must_fail git-tag -v annotated-tag \ + file-signed-tag file-annotated-tag && + test_must_fail git-tag -v signed-tag annotated-tag file-signed-tag +' + +test_expect_success 'verifying a forged tag should fail' ' + forged=$(git cat-file tag signed-tag | + sed -e "s/signed-tag/forged-tag/" | + git mktag) && + git tag forged-tag $forged && + test_must_fail git-tag -v forged-tag +' + +# blank and empty messages for signed tags: + +get_tag_header empty-signed-tag $commit commit $time >expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag with an empty -m message should succeed' ' + git-tag -s -m "" empty-signed-tag && + get_tag_msg empty-signed-tag >actual && + test_cmp expect actual && + git-tag -v empty-signed-tag +' + +>sigemptyfile +get_tag_header emptyfile-signed-tag $commit commit $time >expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag with an empty -F messagefile should succeed' ' + git-tag -s -F sigemptyfile emptyfile-signed-tag && + get_tag_msg emptyfile-signed-tag >actual && + test_cmp expect actual && + git-tag -v emptyfile-signed-tag +' + +printf '\n\n \n\t\nLeading blank lines\n' > sigblanksfile +printf '\n\t \t \nRepeated blank lines\n' >>sigblanksfile +printf '\n\n\nTrailing spaces \t \n' >>sigblanksfile +printf '\nTrailing blank lines\n\n\t \n\n' >>sigblanksfile +get_tag_header blanks-signed-tag $commit commit $time >expect +cat >>expect <<EOF +Leading blank lines + +Repeated blank lines + +Trailing spaces + +Trailing blank lines +EOF +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'extra blanks in the message for a signed tag should be removed' ' + git-tag -s -F sigblanksfile blanks-signed-tag && + get_tag_msg blanks-signed-tag >actual && + test_cmp expect actual && + git-tag -v blanks-signed-tag +' + +get_tag_header blank-signed-tag $commit commit $time >expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag with a blank -m message should succeed' ' + git-tag -s -m " " blank-signed-tag && + get_tag_msg blank-signed-tag >actual && + test_cmp expect actual && + git-tag -v blank-signed-tag +' + +echo ' ' >sigblankfile +echo '' >>sigblankfile +echo ' ' >>sigblankfile +get_tag_header blankfile-signed-tag $commit commit $time >expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag with blank -F file with spaces should succeed' ' + git-tag -s -F sigblankfile blankfile-signed-tag && + get_tag_msg blankfile-signed-tag >actual && + test_cmp expect actual && + git-tag -v blankfile-signed-tag +' + +printf ' ' >sigblanknonlfile +get_tag_header blanknonlfile-signed-tag $commit commit $time >expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag with spaces and no newline should succeed' ' + git-tag -s -F sigblanknonlfile blanknonlfile-signed-tag && + get_tag_msg blanknonlfile-signed-tag >actual && + test_cmp expect actual && + git-tag -v signed-tag +' + +# messages with commented lines for signed tags: + +cat >sigcommentsfile <<EOF +# A comment + +############ +The message. +############ +One line. + + +# commented lines +# commented lines + +Another line. +# comments + +Last line. +EOF +get_tag_header comments-signed-tag $commit commit $time >expect +cat >>expect <<EOF +The message. +One line. + +Another line. + +Last line. +EOF +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag with a -F file with #comments should succeed' ' + git-tag -s -F sigcommentsfile comments-signed-tag && + get_tag_msg comments-signed-tag >actual && + test_cmp expect actual && + git-tag -v comments-signed-tag +' + +get_tag_header comment-signed-tag $commit commit $time >expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag with #commented -m message should succeed' ' + git-tag -s -m "#comment" comment-signed-tag && + get_tag_msg comment-signed-tag >actual && + test_cmp expect actual && + git-tag -v comment-signed-tag +' + +echo '#comment' >sigcommentfile +echo '' >>sigcommentfile +echo '####' >>sigcommentfile +get_tag_header commentfile-signed-tag $commit commit $time >expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag with #commented -F messagefile should succeed' ' + git-tag -s -F sigcommentfile commentfile-signed-tag && + get_tag_msg commentfile-signed-tag >actual && + test_cmp expect actual && + git-tag -v commentfile-signed-tag +' + +printf '#comment' >sigcommentnonlfile +get_tag_header commentnonlfile-signed-tag $commit commit $time >expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag with a #comment and no newline should succeed' ' + git-tag -s -F sigcommentnonlfile commentnonlfile-signed-tag && + get_tag_msg commentnonlfile-signed-tag >actual && + test_cmp expect actual && + git-tag -v commentnonlfile-signed-tag +' + +# listing messages for signed tags: + +test_expect_success \ + 'listing the one-line message of a signed tag should succeed' ' + git-tag -s -m "A message line signed" stag-one-line && + + echo "stag-one-line" >expect && + git-tag -l | grep "^stag-one-line" >actual && + test_cmp expect actual && + git-tag -n0 -l | grep "^stag-one-line" >actual && + test_cmp expect actual && + git-tag -n0 -l stag-one-line >actual && + test_cmp expect actual && + + echo "stag-one-line A message line signed" >expect && + git-tag -n1 -l | grep "^stag-one-line" >actual && + test_cmp expect actual && + git-tag -n -l | grep "^stag-one-line" >actual && + test_cmp expect actual && + git-tag -n1 -l stag-one-line >actual && + test_cmp expect actual && + git-tag -n2 -l stag-one-line >actual && + test_cmp expect actual && + git-tag -n999 -l stag-one-line >actual && + test_cmp expect actual +' + +test_expect_success \ + 'listing the zero-lines message of a signed tag should succeed' ' + git-tag -s -m "" stag-zero-lines && + + echo "stag-zero-lines" >expect && + git-tag -l | grep "^stag-zero-lines" >actual && + test_cmp expect actual && + git-tag -n0 -l | grep "^stag-zero-lines" >actual && + test_cmp expect actual && + git-tag -n0 -l stag-zero-lines >actual && + test_cmp expect actual && + + echo "stag-zero-lines " >expect && + git-tag -n1 -l | grep "^stag-zero-lines" >actual && + test_cmp expect actual && + git-tag -n -l | grep "^stag-zero-lines" >actual && + test_cmp expect actual && + git-tag -n1 -l stag-zero-lines >actual && + test_cmp expect actual && + git-tag -n2 -l stag-zero-lines >actual && + test_cmp expect actual && + git-tag -n999 -l stag-zero-lines >actual && + test_cmp expect actual +' + +echo 'stag line one' >sigtagmsg +echo 'stag line two' >>sigtagmsg +echo 'stag line three' >>sigtagmsg +test_expect_success \ + 'listing many message lines of a signed tag should succeed' ' + git-tag -s -F sigtagmsg stag-lines && + + echo "stag-lines" >expect && + git-tag -l | grep "^stag-lines" >actual && + test_cmp expect actual && + git-tag -n0 -l | grep "^stag-lines" >actual && + test_cmp expect actual && + git-tag -n0 -l stag-lines >actual && + test_cmp expect actual && + + echo "stag-lines stag line one" >expect && + git-tag -n1 -l | grep "^stag-lines" >actual && + test_cmp expect actual && + git-tag -n -l | grep "^stag-lines" >actual && + test_cmp expect actual && + git-tag -n1 -l stag-lines >actual && + test_cmp expect actual && + + echo " stag line two" >>expect && + git-tag -n2 -l | grep "^ *stag.line" >actual && + test_cmp expect actual && + git-tag -n2 -l stag-lines >actual && + test_cmp expect actual && + + echo " stag line three" >>expect && + git-tag -n3 -l | grep "^ *stag.line" >actual && + test_cmp expect actual && + git-tag -n3 -l stag-lines >actual && + test_cmp expect actual && + git-tag -n4 -l | grep "^ *stag.line" >actual && + test_cmp expect actual && + git-tag -n4 -l stag-lines >actual && + test_cmp expect actual && + git-tag -n99 -l | grep "^ *stag.line" >actual && + test_cmp expect actual && + git-tag -n99 -l stag-lines >actual && + test_cmp expect actual +' + +# tags pointing to objects different from commits: + +tree=$(git rev-parse HEAD^{tree}) +blob=$(git rev-parse HEAD:foo) +tag=$(git rev-parse signed-tag) + +get_tag_header tree-signed-tag $tree tree $time >expect +echo "A message for a tree" >>expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag pointing to a tree should succeed' ' + git-tag -s -m "A message for a tree" tree-signed-tag HEAD^{tree} && + get_tag_msg tree-signed-tag >actual && + test_cmp expect actual +' + +get_tag_header blob-signed-tag $blob blob $time >expect +echo "A message for a blob" >>expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag pointing to a blob should succeed' ' + git-tag -s -m "A message for a blob" blob-signed-tag HEAD:foo && + get_tag_msg blob-signed-tag >actual && + test_cmp expect actual +' + +get_tag_header tag-signed-tag $tag tag $time >expect +echo "A message for another tag" >>expect +echo '-----BEGIN PGP SIGNATURE-----' >>expect +test_expect_success \ + 'creating a signed tag pointing to another tag should succeed' ' + git-tag -s -m "A message for another tag" tag-signed-tag signed-tag && + get_tag_msg tag-signed-tag >actual && + test_cmp expect actual +' + +# try to sign with bad user.signingkey +git config user.signingkey BobTheMouse +test_expect_success \ + 'git-tag -s fails if gpg is misconfigured' \ + 'test_must_fail git tag -s -m tail tag-gpg-failure' +git config --unset user.signingkey + +# try to verify without gpg: + +rm -rf gpghome +test_expect_success \ + 'verify signed tag fails when public key is not present' \ + 'test_must_fail git-tag -v signed-tag' + +test_expect_success \ + 'git-tag -a fails if tag annotation is empty' ' + ! (GIT_EDITOR=cat git tag -a initial-comment) +' + +test_expect_success \ + 'message in editor has initial comment' ' + GIT_EDITOR=cat git tag -a initial-comment > actual + # check the first line --- should be empty + first=$(sed -e 1q <actual) && + test -z "$first" && + # remove commented lines from the remainder -- should be empty + rest=$(sed -e 1d -e '/^#/d' <actual) && + test -z "$rest" +' + +get_tag_header reuse $commit commit $time >expect +echo "An annotation to be reused" >> expect +test_expect_success \ + 'overwriting an annoted tag should use its previous body' ' + git tag -a -m "An annotation to be reused" reuse && + GIT_EDITOR=true git tag -f -a reuse && + get_tag_msg reuse >actual && + test_cmp expect actual +' + +test_expect_success 'filename for the message is relative to cwd' ' + mkdir subdir && + echo "Tag message in top directory" >msgfile-5 && + echo "Tag message in sub directory" >subdir/msgfile-5 && + ( + cd subdir && + git tag -a -F msgfile-5 tag-from-subdir + ) && + git cat-file tag tag-from-subdir | grep "in sub directory" +' + +test_expect_success 'filename for the message is relative to cwd' ' + echo "Tag message in sub directory" >subdir/msgfile-6 && + ( + cd subdir && + git tag -a -F msgfile-6 tag-from-subdir-2 + ) && + git cat-file tag tag-from-subdir-2 | grep "in sub directory" +' + +test_done diff --git a/t/t7004/pubring.gpg b/t/t7004/pubring.gpg Binary files differnew file mode 100644 index 0000000000..83855fa4e1 --- /dev/null +++ b/t/t7004/pubring.gpg diff --git a/t/t7004/random_seed b/t/t7004/random_seed Binary files differnew file mode 100644 index 0000000000..8fed1339ed --- /dev/null +++ b/t/t7004/random_seed diff --git a/t/t7004/secring.gpg b/t/t7004/secring.gpg Binary files differnew file mode 100644 index 0000000000..d831cd9eb3 --- /dev/null +++ b/t/t7004/secring.gpg diff --git a/t/t7004/trustdb.gpg b/t/t7004/trustdb.gpg Binary files differnew file mode 100644 index 0000000000..abace962b8 --- /dev/null +++ b/t/t7004/trustdb.gpg diff --git a/t/t7005-editor.sh b/t/t7005-editor.sh new file mode 100755 index 0000000000..2d919d69ef --- /dev/null +++ b/t/t7005-editor.sh @@ -0,0 +1,117 @@ +#!/bin/sh + +test_description='GIT_EDITOR, core.editor, and stuff' + +. ./test-lib.sh + +for i in GIT_EDITOR core_editor EDITOR VISUAL vi +do + cat >e-$i.sh <<-EOF + echo "Edited by $i" >"\$1" + EOF + chmod +x e-$i.sh +done +unset vi +mv e-vi.sh vi +unset EDITOR VISUAL GIT_EDITOR + +test_expect_success setup ' + + msg="Hand edited" && + echo "$msg" >expect && + git add vi && + test_tick && + git commit -m "$msg" && + git show -s --pretty=oneline | + sed -e "s/^[0-9a-f]* //" >actual && + diff actual expect + +' + +TERM=dumb +export TERM +test_expect_success 'dumb should error out when falling back on vi' ' + + if git commit --amend + then + echo "Oops?" + false + else + : happy + fi +' + +TERM=vt100 +export TERM +for i in vi EDITOR VISUAL core_editor GIT_EDITOR +do + echo "Edited by $i" >expect + unset EDITOR VISUAL GIT_EDITOR + git config --unset-all core.editor + case "$i" in + core_editor) + git config core.editor ./e-core_editor.sh + ;; + [A-Z]*) + eval "$i=./e-$i.sh" + export $i + ;; + esac + test_expect_success "Using $i" ' + git --exec-path=. commit --amend && + git show -s --pretty=oneline | + sed -e "s/^[0-9a-f]* //" >actual && + diff actual expect + ' +done + +unset EDITOR VISUAL GIT_EDITOR +git config --unset-all core.editor +for i in vi EDITOR VISUAL core_editor GIT_EDITOR +do + echo "Edited by $i" >expect + case "$i" in + core_editor) + git config core.editor ./e-core_editor.sh + ;; + [A-Z]*) + eval "$i=./e-$i.sh" + export $i + ;; + esac + test_expect_success "Using $i (override)" ' + git --exec-path=. commit --amend && + git show -s --pretty=oneline | + sed -e "s/^[0-9a-f]* //" >actual && + diff actual expect + ' +done + +test_expect_success 'editor with a space' ' + + if echo "echo space > \"\$1\"" > "e space.sh" + then + chmod a+x "e space.sh" && + GIT_EDITOR="./e\ space.sh" git commit --amend && + test space = "$(git show -s --pretty=format:%s)" + else + say "Skipping; FS does not support spaces in filenames" + fi + +' + +unset GIT_EDITOR +test_expect_success 'core.editor with a space' ' + + if test -f "e space.sh" + then + git config core.editor \"./e\ space.sh\" && + git commit --amend && + test space = "$(git show -s --pretty=format:%s)" + else + say "Skipping; FS does not support spaces in filenames" + fi + +' + +test_done diff --git a/t/t7010-setup.sh b/t/t7010-setup.sh new file mode 100755 index 0000000000..d8a7c79852 --- /dev/null +++ b/t/t7010-setup.sh @@ -0,0 +1,165 @@ +#!/bin/sh + +test_description='setup taking and sanitizing funny paths' + +. ./test-lib.sh + +test_expect_success setup ' + + mkdir -p a/b/c a/e && + D=$(pwd) && + >a/b/c/d && + >a/e/f + +' + +test_expect_success 'git add (absolute)' ' + + git add "$D/a/b/c/d" && + git ls-files >current && + echo a/b/c/d >expect && + test_cmp expect current + +' + + +test_expect_success 'git add (funny relative)' ' + + rm -f .git/index && + ( + cd a/b && + git add "../e/./f" + ) && + git ls-files >current && + echo a/e/f >expect && + test_cmp expect current + +' + +test_expect_success 'git rm (absolute)' ' + + rm -f .git/index && + git add a && + git rm -f --cached "$D/a/b/c/d" && + git ls-files >current && + echo a/e/f >expect && + test_cmp expect current + +' + +test_expect_success 'git rm (funny relative)' ' + + rm -f .git/index && + git add a && + ( + cd a/b && + git rm -f --cached "../e/./f" + ) && + git ls-files >current && + echo a/b/c/d >expect && + test_cmp expect current + +' + +test_expect_success 'git ls-files (absolute)' ' + + rm -f .git/index && + git add a && + git ls-files "$D/a/e/../b" >current && + echo a/b/c/d >expect && + test_cmp expect current + +' + +test_expect_success 'git ls-files (relative #1)' ' + + rm -f .git/index && + git add a && + ( + cd a/b && + git ls-files "../b/c" + ) >current && + echo c/d >expect && + test_cmp expect current + +' + +test_expect_success 'git ls-files (relative #2)' ' + + rm -f .git/index && + git add a && + ( + cd a/b && + git ls-files --full-name "../e/f" + ) >current && + echo a/e/f >expect && + test_cmp expect current + +' + +test_expect_success 'git ls-files (relative #3)' ' + + rm -f .git/index && + git add a && + ( + cd a/b && + if git ls-files "../e/f" + then + echo Gaah, should have failed + exit 1 + else + : happy + fi + ) + +' + +test_expect_success 'commit using absolute path names' ' + git commit -m "foo" && + echo aa >>a/b/c/d && + git commit -m "aa" "$(pwd)/a/b/c/d" +' + +test_expect_success 'log using absolute path names' ' + echo bb >>a/b/c/d && + git commit -m "bb" "$(pwd)/a/b/c/d" && + + git log a/b/c/d >f1.txt && + git log "$(pwd)/a/b/c/d" >f2.txt && + test_cmp f1.txt f2.txt +' + +test_expect_success 'blame using absolute path names' ' + git blame a/b/c/d >f1.txt && + git blame "$(pwd)/a/b/c/d" >f2.txt && + test_cmp f1.txt f2.txt +' + +test_expect_success 'setup deeper work tree' ' + test_create_repo tester +' + +test_expect_success 'add a directory outside the work tree' '( + cd tester && + d1="$(cd .. ; pwd)" && + test_must_fail git add "$d1" +)' + + +test_expect_success 'add a file outside the work tree, nasty case 1' '( + cd tester && + f="$(pwd)x" && + echo "$f" && + touch "$f" && + test_must_fail git add "$f" +)' + +test_expect_success 'add a file outside the work tree, nasty case 2' '( + cd tester && + f="$(pwd | sed "s/.$//")x" && + echo "$f" && + touch "$f" && + test_must_fail git add "$f" +)' + +test_done diff --git a/t/t7101-reset.sh b/t/t7101-reset.sh new file mode 100755 index 0000000000..0d9874bfd7 --- /dev/null +++ b/t/t7101-reset.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# +# Copyright (c) 2006 Shawn Pearce +# + +test_description='git-reset should cull empty subdirs' +. ./test-lib.sh + +test_expect_success \ + 'creating initial files' \ + 'mkdir path0 && + cp ../../COPYING path0/COPYING && + git add path0/COPYING && + git-commit -m add -a' + +test_expect_success \ + 'creating second files' \ + 'mkdir path1 && + mkdir path1/path2 && + cp ../../COPYING path1/path2/COPYING && + cp ../../COPYING path1/COPYING && + cp ../../COPYING COPYING && + cp ../../COPYING path0/COPYING-TOO && + git add path1/path2/COPYING && + git add path1/COPYING && + git add COPYING && + git add path0/COPYING-TOO && + git-commit -m change -a' + +test_expect_success \ + 'resetting tree HEAD^' \ + 'git-reset --hard HEAD^' + +test_expect_success \ + 'checking initial files exist after rewind' \ + 'test -d path0 && + test -f path0/COPYING' + +test_expect_success \ + 'checking lack of path1/path2/COPYING' \ + '! test -f path1/path2/COPYING' + +test_expect_success \ + 'checking lack of path1/COPYING' \ + '! test -f path1/COPYING' + +test_expect_success \ + 'checking lack of COPYING' \ + '! test -f COPYING' + +test_expect_success \ + 'checking checking lack of path1/COPYING-TOO' \ + '! test -f path0/COPYING-TOO' + +test_expect_success \ + 'checking lack of path1/path2' \ + '! test -d path1/path2' + +test_expect_success \ + 'checking lack of path1' \ + '! test -d path1' + +test_done diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh new file mode 100755 index 0000000000..29f5678b4c --- /dev/null +++ b/t/t7102-reset.sh @@ -0,0 +1,478 @@ +#!/bin/sh +# +# Copyright (c) 2007 Carlos Rica +# + +test_description='git-reset + +Documented tests for git-reset' + +. ./test-lib.sh + +test_expect_success 'creating initial files and commits' ' + test_tick && + echo "1st file" >first && + git add first && + git commit -m "create 1st file" && + + echo "2nd file" >second && + git add second && + git commit -m "create 2nd file" && + + echo "2nd line 1st file" >>first && + git commit -a -m "modify 1st file" && + + git rm first && + git mv second secondfile && + git commit -a -m "remove 1st and rename 2nd" && + + echo "1st line 2nd file" >secondfile && + echo "2nd line 2nd file" >>secondfile && + git commit -a -m "modify 2nd file" +' +# git log --pretty=oneline # to see those SHA1 involved + +check_changes () { + test "$(git rev-parse HEAD)" = "$1" && + git diff | test_cmp .diff_expect - && + git diff --cached | test_cmp .cached_expect - && + for FILE in * + do + echo $FILE':' + cat $FILE || return + done | test_cmp .cat_expect - +} + +>.diff_expect +>.cached_expect +cat >.cat_expect <<EOF +secondfile: +1st line 2nd file +2nd line 2nd file +EOF + +test_expect_success 'giving a non existing revision should fail' ' + test_must_fail git reset aaaaaa && + test_must_fail git reset --mixed aaaaaa && + test_must_fail git reset --soft aaaaaa && + test_must_fail git reset --hard aaaaaa && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc +' + +test_expect_success 'reset --soft with unmerged index should fail' ' + touch .git/MERGE_HEAD && + echo "100644 44c5b5884550c17758737edcced463447b91d42b 1 un" | + git update-index --index-info && + test_must_fail git reset --soft HEAD && + rm .git/MERGE_HEAD && + git rm --cached -- un +' + +test_expect_success \ + 'giving paths with options different than --mixed should fail' ' + test_must_fail git reset --soft -- first && + test_must_fail git reset --hard -- first && + test_must_fail git reset --soft HEAD^ -- first && + test_must_fail git reset --hard HEAD^ -- first && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc +' + +test_expect_success 'giving unrecognized options should fail' ' + test_must_fail git reset --other && + test_must_fail git reset -o && + test_must_fail git reset --mixed --other && + test_must_fail git reset --mixed -o && + test_must_fail git reset --soft --other && + test_must_fail git reset --soft -o && + test_must_fail git reset --hard --other && + test_must_fail git reset --hard -o && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc +' + +test_expect_success \ + 'trying to do reset --soft with pending merge should fail' ' + git branch branch1 && + git branch branch2 && + + git checkout branch1 && + echo "3rd line in branch1" >>secondfile && + git commit -a -m "change in branch1" && + + git checkout branch2 && + echo "3rd line in branch2" >>secondfile && + git commit -a -m "change in branch2" && + + test_must_fail git merge branch1 && + test_must_fail git reset --soft && + + printf "1st line 2nd file\n2nd line 2nd file\n3rd line" >secondfile && + git commit -a -m "the change in branch2" && + + git checkout master && + git branch -D branch1 branch2 && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc +' + +test_expect_success \ + 'trying to do reset --soft with pending checkout merge should fail' ' + git branch branch3 && + git branch branch4 && + + git checkout branch3 && + echo "3rd line in branch3" >>secondfile && + git commit -a -m "line in branch3" && + + git checkout branch4 && + echo "3rd line in branch4" >>secondfile && + + git checkout -m branch3 && + test_must_fail git reset --soft && + + printf "1st line 2nd file\n2nd line 2nd file\n3rd line" >secondfile && + git commit -a -m "the line in branch3" && + + git checkout master && + git branch -D branch3 branch4 && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc +' + +test_expect_success \ + 'resetting to HEAD with no changes should succeed and do nothing' ' + git reset --hard && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + git reset --hard HEAD && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + git reset --soft && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + git reset --soft HEAD && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + git reset --mixed && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + git reset --mixed HEAD && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + git reset && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + git reset HEAD && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc +' + +>.diff_expect +cat >.cached_expect <<EOF +diff --git a/secondfile b/secondfile +index 1bbba79..44c5b58 100644 +--- a/secondfile ++++ b/secondfile +@@ -1 +1,2 @@ +-2nd file ++1st line 2nd file ++2nd line 2nd file +EOF +cat >.cat_expect <<EOF +secondfile: +1st line 2nd file +2nd line 2nd file +EOF +test_expect_success '--soft reset only should show changes in diff --cached' ' + git reset --soft HEAD^ && + check_changes d1a4bc3abce4829628ae2dcb0d60ef3d1a78b1c4 && + test "$(git rev-parse ORIG_HEAD)" = \ + 3ec39651e7f44ea531a5de18a9fa791c0fd370fc +' + +>.diff_expect +>.cached_expect +cat >.cat_expect <<EOF +secondfile: +1st line 2nd file +2nd line 2nd file +3rd line 2nd file +EOF +test_expect_success \ + 'changing files and redo the last commit should succeed' ' + echo "3rd line 2nd file" >>secondfile && + git commit -a -C ORIG_HEAD && + check_changes 3d3b7be011a58ca0c179ae45d94e6c83c0b0cd0d && + test "$(git rev-parse ORIG_HEAD)" = \ + 3ec39651e7f44ea531a5de18a9fa791c0fd370fc +' + +>.diff_expect +>.cached_expect +cat >.cat_expect <<EOF +first: +1st file +2nd line 1st file +second: +2nd file +EOF +test_expect_success \ + '--hard reset should change the files and undo commits permanently' ' + git reset --hard HEAD~2 && + check_changes ddaefe00f1da16864591c61fdc7adb5d7cd6b74e && + test "$(git rev-parse ORIG_HEAD)" = \ + 3d3b7be011a58ca0c179ae45d94e6c83c0b0cd0d +' + +>.diff_expect +cat >.cached_expect <<EOF +diff --git a/first b/first +deleted file mode 100644 +index 8206c22..0000000 +--- a/first ++++ /dev/null +@@ -1,2 +0,0 @@ +-1st file +-2nd line 1st file +diff --git a/second b/second +deleted file mode 100644 +index 1bbba79..0000000 +--- a/second ++++ /dev/null +@@ -1 +0,0 @@ +-2nd file +diff --git a/secondfile b/secondfile +new file mode 100644 +index 0000000..44c5b58 +--- /dev/null ++++ b/secondfile +@@ -0,0 +1,2 @@ ++1st line 2nd file ++2nd line 2nd file +EOF +cat >.cat_expect <<EOF +secondfile: +1st line 2nd file +2nd line 2nd file +EOF +test_expect_success \ + 'redoing changes adding them without commit them should succeed' ' + git rm first && + git mv second secondfile && + + echo "1st line 2nd file" >secondfile && + echo "2nd line 2nd file" >>secondfile && + git add secondfile && + check_changes ddaefe00f1da16864591c61fdc7adb5d7cd6b74e +' + +cat >.diff_expect <<EOF +diff --git a/first b/first +deleted file mode 100644 +index 8206c22..0000000 +--- a/first ++++ /dev/null +@@ -1,2 +0,0 @@ +-1st file +-2nd line 1st file +diff --git a/second b/second +deleted file mode 100644 +index 1bbba79..0000000 +--- a/second ++++ /dev/null +@@ -1 +0,0 @@ +-2nd file +EOF +>.cached_expect +cat >.cat_expect <<EOF +secondfile: +1st line 2nd file +2nd line 2nd file +EOF +test_expect_success '--mixed reset to HEAD should unadd the files' ' + git reset && + check_changes ddaefe00f1da16864591c61fdc7adb5d7cd6b74e && + test "$(git rev-parse ORIG_HEAD)" = \ + ddaefe00f1da16864591c61fdc7adb5d7cd6b74e +' + +>.diff_expect +>.cached_expect +cat >.cat_expect <<EOF +secondfile: +1st line 2nd file +2nd line 2nd file +EOF +test_expect_success 'redoing the last two commits should succeed' ' + git add secondfile && + git reset --hard ddaefe00f1da16864591c61fdc7adb5d7cd6b74e && + + git rm first && + git mv second secondfile && + git commit -a -m "remove 1st and rename 2nd" && + + echo "1st line 2nd file" >secondfile && + echo "2nd line 2nd file" >>secondfile && + git commit -a -m "modify 2nd file" && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc +' + +>.diff_expect +>.cached_expect +cat >.cat_expect <<EOF +secondfile: +1st line 2nd file +2nd line 2nd file +3rd line in branch2 +EOF +test_expect_success '--hard reset to HEAD should clear a failed merge' ' + git branch branch1 && + git branch branch2 && + + git checkout branch1 && + echo "3rd line in branch1" >>secondfile && + git commit -a -m "change in branch1" && + + git checkout branch2 && + echo "3rd line in branch2" >>secondfile && + git commit -a -m "change in branch2" && + + test_must_fail git pull . branch1 && + git reset --hard && + check_changes 77abb337073fb4369a7ad69ff6f5ec0e4d6b54bb +' + +>.diff_expect +>.cached_expect +cat >.cat_expect <<EOF +secondfile: +1st line 2nd file +2nd line 2nd file +EOF +test_expect_success \ + '--hard reset to ORIG_HEAD should clear a fast-forward merge' ' + git reset --hard HEAD^ && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc && + + git pull . branch1 && + git reset --hard ORIG_HEAD && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc && + + git checkout master && + git branch -D branch1 branch2 && + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc +' + +cat > expect << EOF +diff --git a/file1 b/file1 +index d00491f..7ed6ff8 100644 +--- a/file1 ++++ b/file1 +@@ -1 +1 @@ +-1 ++5 +diff --git a/file2 b/file2 +deleted file mode 100644 +index 0cfbf08..0000000 +--- a/file2 ++++ /dev/null +@@ -1 +0,0 @@ +-2 +EOF +cat > cached_expect << EOF +diff --git a/file4 b/file4 +new file mode 100644 +index 0000000..b8626c4 +--- /dev/null ++++ b/file4 +@@ -0,0 +1 @@ ++4 +EOF +test_expect_success 'test --mixed <paths>' ' + echo 1 > file1 && + echo 2 > file2 && + git add file1 file2 && + test_tick && + git commit -m files && + git rm file2 && + echo 3 > file3 && + echo 4 > file4 && + echo 5 > file1 && + git add file1 file3 file4 && + test_must_fail git reset HEAD -- file1 file2 file3 && + git diff > output && + test_cmp output expect && + git diff --cached > output && + test_cmp output cached_expect +' + +test_expect_success 'test resetting the index at give paths' ' + + mkdir sub && + >sub/file1 && + >sub/file2 && + git update-index --add sub/file1 sub/file2 && + T=$(git write-tree) && + test_must_fail git reset HEAD sub/file2 && + U=$(git write-tree) && + echo "$T" && + echo "$U" && + test_must_fail git diff-index --cached --exit-code "$T" && + test "$T" != "$U" + +' + +test_expect_success 'resetting an unmodified path is a no-op' ' + git reset --hard && + git reset -- file1 && + git diff-files --exit-code && + git diff-index --cached --exit-code HEAD +' + +cat > expect << EOF +file2: locally modified +EOF + +test_expect_success '--mixed refreshes the index' ' + echo 123 >> file2 && + git reset --mixed HEAD > output && + test_cmp expect output +' + +test_expect_success 'disambiguation (1)' ' + + git reset --hard && + >secondfile && + git add secondfile && + test_must_fail git reset secondfile && + test -z "$(git diff --cached --name-only)" && + test -f secondfile && + test ! -s secondfile + +' + +test_expect_success 'disambiguation (2)' ' + + git reset --hard && + >secondfile && + git add secondfile && + rm -f secondfile && + test_must_fail git reset secondfile && + test -n "$(git diff --cached --name-only -- secondfile)" && + test ! -f secondfile + +' + +test_expect_success 'disambiguation (3)' ' + + git reset --hard && + >secondfile && + git add secondfile && + rm -f secondfile && + test_must_fail git reset HEAD secondfile && + test -z "$(git diff --cached --name-only)" && + test ! -f secondfile + +' + +test_expect_success 'disambiguation (4)' ' + + git reset --hard && + >secondfile && + git add secondfile && + rm -f secondfile && + test_must_fail git reset -- secondfile && + test -z "$(git diff --cached --name-only)" && + test ! -f secondfile +' + +test_done diff --git a/t/t7103-reset-bare.sh b/t/t7103-reset-bare.sh new file mode 100755 index 0000000000..cdecebe456 --- /dev/null +++ b/t/t7103-reset-bare.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +test_description='git-reset in a bare repository' +. ./test-lib.sh + +test_expect_success 'setup non-bare' ' + echo one >file && + git add file && + git commit -m one && + echo two >file && + git commit -a -m two +' + +test_expect_success 'setup bare' ' + git clone --bare . bare.git && + cd bare.git +' + +test_expect_success 'hard reset is not allowed' ' + test_must_fail git reset --hard HEAD^ +' + +test_expect_success 'soft reset is allowed' ' + git reset --soft HEAD^ && + test "`git show --pretty=format:%s | head -n 1`" = "one" +' + +test_done diff --git a/t/t7104-reset.sh b/t/t7104-reset.sh new file mode 100755 index 0000000000..f136ee7bb5 --- /dev/null +++ b/t/t7104-reset.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +test_description='reset --hard unmerged' + +. ./test-lib.sh + +test_expect_success setup ' + + mkdir before later && + >before/1 && + >before/2 && + >hello && + >later/3 && + git add before hello later && + git commit -m world && + + H=$(git rev-parse :hello) && + git rm --cached hello && + echo "100644 $H 2 hello" | git update-index --index-info && + + rm -f hello && + mkdir -p hello && + >hello/world && + test "$(git ls-files -o)" = hello/world + +' + +test_expect_success 'reset --hard should restore unmerged ones' ' + + git reset --hard && + git ls-files --error-unmatch before/1 before/2 hello later/3 && + test -f hello + +' + +test_expect_success 'reset --hard did not corrupt index nor cached-tree' ' + + T=$(git write-tree) && + rm -f .git/index && + git add before hello later && + U=$(git write-tree) && + test "$T" = "$U" + +' + +test_done diff --git a/t/t7201-co.sh b/t/t7201-co.sh new file mode 100755 index 0000000000..9ad5d635a2 --- /dev/null +++ b/t/t7201-co.sh @@ -0,0 +1,340 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='git-checkout tests. + +Creates master, forks renamer and side branches from it. +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 + +' + +. ./test-lib.sh + +test_tick + +fill () { + for i + do + echo "$i" + done +} + + +test_expect_success setup ' + + fill x y z > same && + fill 1 2 3 4 5 6 7 8 >one && + fill a b c d e >two && + git add same one two && + git commit -m "Initial A one, A two" && + + git checkout -b renamer && + rm -f one && + fill 1 3 4 5 6 7 8 >uno && + git add uno && + fill a b c d e f >two && + git commit -a -m "Renamer R one->uno, M two" && + + git checkout -b side master && + fill 1 2 3 4 5 6 7 >one && + fill A B C D E >three && + rm -f two && + git update-index --add --remove one two three && + git commit -m "Side M one, D two, A three" && + + git checkout master +' + +test_expect_success "checkout from non-existing branch" ' + + git checkout -b delete-me master && + rm .git/refs/heads/delete-me && + test refs/heads/delete-me = "$(git symbolic-ref HEAD)" && + git checkout master && + test refs/heads/master = "$(git symbolic-ref HEAD)" +' + +test_expect_success "checkout with dirty tree without -m" ' + + fill 0 1 2 3 4 5 6 7 8 >one && + if git checkout side + then + echo Not happy + false + else + echo "happy - failed correctly" + fi + +' + +test_expect_success "checkout with unrelated dirty tree without -m" ' + + git checkout -f master && + fill 0 1 2 3 4 5 6 7 8 >same && + cp same kept + git checkout side >messages && + test_cmp same kept + (cat > messages.expect <<EOF +M same +EOF +) && + touch messages.expect && + test_cmp messages.expect messages +' + +test_expect_success "checkout -m with dirty tree" ' + + git checkout -f master && + git clean -f && + + fill 0 1 2 3 4 5 6 7 8 >one && + git checkout -m side > messages && + + test "$(git symbolic-ref HEAD)" = "refs/heads/side" && + + (cat >expect.messages <<EOF +M one +EOF +) && + test_cmp expect.messages messages && + + fill "M one" "A three" "D two" >expect.master && + git diff --name-status master >current.master && + test_cmp expect.master current.master && + + fill "M one" >expect.side && + git diff --name-status side >current.side && + test_cmp expect.side current.side && + + : >expect.index && + git diff --cached >current.index && + test_cmp expect.index current.index +' + +test_expect_success "checkout -m with dirty tree, renamed" ' + + git checkout -f master && git clean -f && + + fill 1 2 3 4 5 7 8 >one && + if git checkout renamer + then + echo Not happy + false + else + echo "happy - failed correctly" + fi && + + git checkout -m renamer && + fill 1 3 4 5 7 8 >expect && + test_cmp expect uno && + ! test -f one && + git diff --cached >current && + ! test -s current + +' + +test_expect_success 'checkout -m with merge conflict' ' + + git checkout -f master && git clean -f && + + fill 1 T 3 4 5 6 S 8 >one && + if git checkout renamer + then + echo Not happy + false + else + echo "happy - failed correctly" + fi && + + git checkout -m renamer && + + git diff master:one :3:uno | + sed -e "1,/^@@/d" -e "/^ /d" -e "s/^-/d/" -e "s/^+/a/" >current && + fill d2 aT d7 aS >expect && + test_cmp current expect && + git diff --cached two >current && + ! test -s current +' + +test_expect_success 'checkout to detach HEAD' ' + + git checkout -f renamer && git clean -f && + git checkout renamer^ 2>messages && + (cat >messages.expect <<EOF +Note: moving to "renamer^" which isn'"'"'t a local branch +If you want to create a new branch from this checkout, you may do so +(now or later) by using -b with the checkout command again. Example: + git checkout -b <new_branch_name> +HEAD is now at 7329388... Initial A one, A two +EOF +) && + test_cmp messages.expect messages && + H=$(git rev-parse --verify HEAD) && + M=$(git show-ref -s --verify refs/heads/master) && + test "z$H" = "z$M" && + if git symbolic-ref HEAD >/dev/null 2>&1 + then + echo "OOPS, HEAD is still symbolic???" + false + else + : happy + fi +' + +test_expect_success 'checkout to detach HEAD with branchname^' ' + + git checkout -f master && git clean -f && + git checkout renamer^ && + H=$(git rev-parse --verify HEAD) && + M=$(git show-ref -s --verify refs/heads/master) && + test "z$H" = "z$M" && + if git symbolic-ref HEAD >/dev/null 2>&1 + then + echo "OOPS, HEAD is still symbolic???" + false + else + : happy + fi +' + +test_expect_success 'checkout to detach HEAD with :/message' ' + + git checkout -f master && git clean -f && + git checkout ":/Initial" && + H=$(git rev-parse --verify HEAD) && + M=$(git show-ref -s --verify refs/heads/master) && + test "z$H" = "z$M" && + if git symbolic-ref HEAD >/dev/null 2>&1 + then + echo "OOPS, HEAD is still symbolic???" + false + else + : happy + fi +' + +test_expect_success 'checkout to detach HEAD with HEAD^0' ' + + git checkout -f master && git clean -f && + git checkout HEAD^0 && + H=$(git rev-parse --verify HEAD) && + M=$(git show-ref -s --verify refs/heads/master) && + test "z$H" = "z$M" && + if git symbolic-ref HEAD >/dev/null 2>&1 + then + echo "OOPS, HEAD is still symbolic???" + false + else + : happy + fi +' + +test_expect_success 'checkout with ambiguous tag/branch names' ' + + git tag both side && + git branch both master && + git reset --hard && + git checkout master && + + git checkout both && + H=$(git rev-parse --verify HEAD) && + M=$(git show-ref -s --verify refs/heads/master) && + test "z$H" = "z$M" && + name=$(git symbolic-ref HEAD 2>/dev/null) && + test "z$name" = zrefs/heads/both + +' + +test_expect_success 'checkout with ambiguous tag/branch names' ' + + git reset --hard && + git checkout master && + + git tag frotz side && + git branch frotz master && + git reset --hard && + git checkout master && + + git checkout tags/frotz && + H=$(git rev-parse --verify HEAD) && + S=$(git show-ref -s --verify refs/heads/side) && + test "z$H" = "z$S" && + if name=$(git symbolic-ref HEAD 2>/dev/null) + then + echo "Bad -- should have detached" + false + else + : happy + fi + +' + +test_expect_success 'switch branches while in subdirectory' ' + + git reset --hard && + git checkout master && + + mkdir subs && + ( + cd subs && + git checkout side + ) && + ! test -f subs/one && + rm -fr subs + +' + +test_expect_success 'checkout specific path while in subdirectory' ' + + git reset --hard && + git checkout side && + mkdir subs && + >subs/bero && + git add subs/bero && + git commit -m "add subs/bero" && + + git checkout master && + mkdir -p subs && + ( + cd subs && + git checkout side -- bero + ) && + test -f subs/bero + +' + +test_expect_success \ + 'checkout w/--track sets up tracking' ' + git config branch.autosetupmerge false && + git checkout master && + git checkout --track -b track1 && + test "$(git config branch.track1.remote)" && + test "$(git config branch.track1.merge)"' + +test_expect_success \ + 'checkout w/autosetupmerge=always sets up tracking' ' + git config branch.autosetupmerge always && + git checkout master && + git checkout -b track2 && + test "$(git config branch.track2.remote)" && + test "$(git config branch.track2.merge)" + git config branch.autosetupmerge false' + +test_expect_success \ + 'checkout w/--track from non-branch HEAD fails' ' + git checkout -b delete-me master && + rm .git/refs/heads/delete-me && + test refs/heads/delete-me = "$(git symbolic-ref HEAD)" && + test_must_fail git checkout --track -b track' + +test_done diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh new file mode 100755 index 0000000000..2b51c0d7d8 --- /dev/null +++ b/t/t7300-clean.sh @@ -0,0 +1,383 @@ +#!/bin/sh +# +# Copyright (c) 2007 Michael Spang +# + +test_description='git-clean basic tests' + +. ./test-lib.sh + +git config clean.requireForce no + +test_expect_success 'setup' ' + + mkdir -p src && + touch src/part1.c Makefile && + echo build >.gitignore && + echo \*.o >>.gitignore && + git add . && + git-commit -m setup && + touch src/part2.c README && + git add . + +' + +test_expect_success 'git-clean' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git-clean && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test ! -f a.out && + test ! -f src/part3.c && + test -f docs/manual.txt && + test -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'git-clean src/' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git-clean src/ && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test -f a.out && + test ! -f src/part3.c && + test -f docs/manual.txt && + test -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'git-clean src/ src/' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git-clean src/ src/ && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test -f a.out && + test ! -f src/part3.c && + test -f docs/manual.txt && + test -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'git-clean with prefix' ' + + mkdir -p build docs src/test && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so src/test/1.c && + (cd src/ && git-clean) && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test -f a.out && + test ! -f src/part3.c && + test -f src/test/1.c && + test -f docs/manual.txt && + test -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'git-clean with relative prefix' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + would_clean=$( + cd docs && + git clean -n ../src | + sed -n -e "s|^Would remove ||p" + ) && + test "$would_clean" = ../src/part3.c || { + echo "OOps <$would_clean>" + false + } +' + +test_expect_success 'git-clean with absolute path' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + would_clean=$( + cd docs && + git clean -n "$(pwd)/../src" | + sed -n -e "s|^Would remove ||p" + ) && + test "$would_clean" = ../src/part3.c || { + echo "OOps <$would_clean>" + false + } +' + +test_expect_success 'git-clean with out of work tree relative path' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + ( + cd docs && + test_must_fail git clean -n ../.. + ) +' + +test_expect_success 'git-clean with out of work tree absolute path' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + dd=$(cd .. && pwd) && + ( + cd docs && + test_must_fail git clean -n $dd + ) +' + +test_expect_success 'git-clean -d with prefix and path' ' + + mkdir -p build docs src/feature && + touch a.out src/part3.c src/feature/file.c docs/manual.txt obj.o build/lib.so && + (cd src/ && git-clean -d feature/) && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test -f a.out && + test -f src/part3.c && + test ! -f src/feature/file.c && + test -f docs/manual.txt && + test -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'git-clean symbolic link' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + ln -s docs/manual.txt src/part4.c + git-clean && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test ! -f a.out && + test ! -f src/part3.c && + test ! -f src/part4.c && + test -f docs/manual.txt && + test -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'git-clean with wildcard' ' + + touch a.clean b.clean other.c && + git-clean "*.clean" && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test ! -f a.clean && + test ! -f b.clean && + test -f other.c + +' + +test_expect_success 'git-clean -n' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git-clean -n && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test -f a.out && + test -f src/part3.c && + test -f docs/manual.txt && + test -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'git-clean -d' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git-clean -d && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test ! -f a.out && + test ! -f src/part3.c && + test ! -d docs && + test -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'git-clean -d src/ examples/' ' + + mkdir -p build docs examples && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so examples/1.c && + git-clean -d src/ examples/ && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test -f a.out && + test ! -f src/part3.c && + test ! -f examples/1.c && + test -f docs/manual.txt && + test -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'git-clean -x' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git-clean -x && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test ! -f a.out && + test ! -f src/part3.c && + test -f docs/manual.txt && + test ! -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'git-clean -d -x' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git-clean -d -x && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test ! -f a.out && + test ! -f src/part3.c && + test ! -d docs && + test ! -f obj.o && + test ! -d build + +' + +test_expect_success 'git-clean -X' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git-clean -X && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test -f a.out && + test -f src/part3.c && + test -f docs/manual.txt && + test ! -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'git-clean -d -X' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git-clean -d -X && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test -f a.out && + test -f src/part3.c && + test -f docs/manual.txt && + test ! -f obj.o && + test ! -d build + +' + +test_expect_success 'clean.requireForce defaults to true' ' + + git config --unset clean.requireForce && + test_must_fail git clean + +' + +test_expect_success 'clean.requireForce' ' + + git config clean.requireForce true && + test_must_fail git clean + +' + +test_expect_success 'clean.requireForce and -n' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git-clean -n && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test -f a.out && + test -f src/part3.c && + test -f docs/manual.txt && + test -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'clean.requireForce and -f' ' + + git-clean -f && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test ! -f a.out && + test ! -f src/part3.c && + test -f docs/manual.txt && + test -f obj.o && + test -f build/lib.so + +' + +test_expect_success 'core.excludesfile' ' + + echo excludes >excludes && + echo included >included && + git config core.excludesfile excludes && + output=$(git clean -n excludes included 2>&1) && + expr "$output" : ".*included" >/dev/null && + ! expr "$output" : ".*excludes" >/dev/null + +' + +test_expect_success 'removal failure' ' + + mkdir foo && + touch foo/bar && + exec <foo/bar && + chmod 0 foo && + test_must_fail git clean -f -d + +' +chmod 755 foo + +test_done diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh new file mode 100755 index 0000000000..cbc0c34ce2 --- /dev/null +++ b/t/t7400-submodule-basic.sh @@ -0,0 +1,212 @@ +#!/bin/sh +# +# Copyright (c) 2007 Lars Hjemli +# + +test_description='Basic porcelain support for submodules + +This test tries to verify basic sanity of the init, update and status +subcommands of git-submodule. +' + +. ./test-lib.sh + +# +# Test setup: +# -create a repository in directory init +# -add a couple of files +# -add directory init to 'superproject', this creates a DIRLINK entry +# -add a couple of regular files to enable testing of submodule filtering +# -mv init subrepo +# -add an entry to .gitmodules for submodule 'example' +# +test_expect_success 'Prepare submodule testing' ' + : > t && + git-add t && + git-commit -m "initial commit" && + git branch initial HEAD && + mkdir init && + cd init && + git init && + echo a >a && + git add a && + git-commit -m "submodule commit 1" && + git-tag -a -m "rev-1" rev-1 && + rev1=$(git rev-parse HEAD) && + if test -z "$rev1" + then + echo "[OOPS] submodule git rev-parse returned nothing" + false + fi && + cd .. && + echo a >a && + echo z >z && + git add a init z && + git-commit -m "super commit 1" && + mv init .subrepo && + GIT_CONFIG=.gitmodules git config submodule.example.url git://example.com/init.git +' + +test_expect_success 'status should fail for unmapped paths' ' + if git-submodule status + then + echo "[OOPS] submodule status succeeded" + false + elif ! GIT_CONFIG=.gitmodules git config submodule.example.path init + then + echo "[OOPS] git config failed to update .gitmodules" + false + fi +' + +test_expect_success 'status should only print one line' ' + lines=$(git-submodule status | wc -l) && + test $lines = 1 +' + +test_expect_success 'status should initially be "missing"' ' + git-submodule status | grep "^-$rev1" +' + +test_expect_success 'init should register submodule url in .git/config' ' + git-submodule init && + url=$(git config submodule.example.url) && + if test "$url" != "git://example.com/init.git" + then + echo "[OOPS] init succeeded but submodule url is wrong" + false + elif test_must_fail git config submodule.example.url ./.subrepo + then + echo "[OOPS] init succeeded but update of url failed" + false + fi +' + +test_expect_success 'update should fail when path is used by a file' ' + echo "hello" >init && + if git-submodule update + then + echo "[OOPS] update should have failed" + false + elif test "$(cat init)" != "hello" + then + echo "[OOPS] update failed but init file was molested" + false + else + rm init + fi +' + +test_expect_success 'update should fail when path is used by a nonempty directory' ' + mkdir init && + echo "hello" >init/a && + if git-submodule update + then + echo "[OOPS] update should have failed" + false + elif test "$(cat init/a)" != "hello" + then + echo "[OOPS] update failed but init/a was molested" + false + else + rm init/a + fi +' + +test_expect_success 'update should work when path is an empty dir' ' + rm -rf init && + mkdir init && + git-submodule update && + head=$(cd init && git rev-parse HEAD) && + if test -z "$head" + then + echo "[OOPS] Failed to obtain submodule head" + false + elif test "$head" != "$rev1" + then + echo "[OOPS] Submodule head is $head but should have been $rev1" + false + fi +' + +test_expect_success 'status should be "up-to-date" after update' ' + git-submodule status | grep "^ $rev1" +' + +test_expect_success 'status should be "modified" after submodule commit' ' + cd init && + echo b >b && + git add b && + git-commit -m "submodule commit 2" && + rev2=$(git rev-parse HEAD) && + cd .. && + if test -z "$rev2" + then + echo "[OOPS] submodule git rev-parse returned nothing" + false + fi && + git-submodule status | grep "^+$rev2" +' + +test_expect_success 'the --cached sha1 should be rev1' ' + git-submodule --cached status | grep "^+$rev1" +' + +test_expect_success 'git diff should report the SHA1 of the new submodule commit' ' + git-diff | grep "^+Subproject commit $rev2" +' + +test_expect_success 'update should checkout rev1' ' + git-submodule update init && + head=$(cd init && git rev-parse HEAD) && + if test -z "$head" + then + echo "[OOPS] submodule git rev-parse returned nothing" + false + elif test "$head" != "$rev1" + then + echo "[OOPS] init did not checkout correct head" + false + fi +' + +test_expect_success 'status should be "up-to-date" after update' ' + git-submodule status | grep "^ $rev1" +' + +test_expect_success 'checkout superproject with subproject already present' ' + git-checkout initial && + git-checkout master +' + +test_expect_success 'apply submodule diff' ' + git branch second && + ( + cd init && + echo s >s && + git add s && + git commit -m "change subproject" + ) && + git update-index --add init && + git-commit -m "change init" && + git-format-patch -1 --stdout >P.diff && + git checkout second && + git apply --index P.diff && + D=$(git diff --cached master) && + test -z "$D" +' + +test_expect_success 'update --init' ' + + mv init init2 && + git config -f .gitmodules submodule.example.url "$(pwd)/init2" && + git config --remove-section submodule.example + git submodule update init > update.out && + grep "not initialized" update.out && + test ! -d init/.git && + git submodule update --init init && + test -d init/.git + +' + +test_done diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh new file mode 100755 index 0000000000..bf12dbdeef --- /dev/null +++ b/t/t7401-submodule-summary.sh @@ -0,0 +1,208 @@ +#!/bin/sh +# +# Copyright (c) 2008 Ping Yin +# + +test_description='Summary support for submodules + +This test tries to verify the sanity of summary subcommand of git-submodule. +' + +. ./test-lib.sh + +add_file () { + sm=$1 + shift + owd=$(pwd) + cd "$sm" + for name; do + echo "$name" > "$name" && + git add "$name" && + test_tick && + git commit -m "Add $name" + done >/dev/null + git rev-parse --verify HEAD | cut -c1-7 + cd "$owd" +} +commit_file () { + test_tick && + git commit "$@" -m "Commit $*" >/dev/null +} + +test_create_repo sm1 && +add_file . foo >/dev/null + +head1=$(add_file sm1 foo1 foo2) + +test_expect_success 'added submodule' " + git add sm1 && + git submodule summary >actual && + diff actual - <<-EOF +* sm1 0000000...$head1 (2): + > Add foo2 + +EOF +" + +commit_file sm1 && +head2=$(add_file sm1 foo3) + +test_expect_success 'modified submodule(forward)' " + git submodule summary >actual && + diff actual - <<-EOF +* sm1 $head1...$head2 (1): + > Add foo3 + +EOF +" + +commit_file sm1 && +cd sm1 && +git reset --hard HEAD~2 >/dev/null && +head3=$(git rev-parse --verify HEAD | cut -c1-7) && +cd .. + +test_expect_success 'modified submodule(backward)' " + git submodule summary >actual && + diff actual - <<-EOF +* sm1 $head2...$head3 (2): + < Add foo3 + < Add foo2 + +EOF +" + +head4=$(add_file sm1 foo4 foo5) && +head4_full=$(GIT_DIR=sm1/.git git rev-parse --verify HEAD) +test_expect_success 'modified submodule(backward and forward)' " + git submodule summary >actual && + diff actual - <<-EOF +* sm1 $head2...$head4 (4): + > Add foo5 + > Add foo4 + < Add foo3 + < Add foo2 + +EOF +" + +test_expect_success '--summary-limit' " + git submodule summary -n 3 >actual && + diff actual - <<-EOF +* sm1 $head2...$head4 (4): + > Add foo5 + > Add foo4 + < Add foo3 + +EOF +" + +commit_file sm1 && +mv sm1 sm1-bak && +echo sm1 >sm1 && +head5=$(git hash-object sm1 | cut -c1-7) && +git add sm1 && +rm -f sm1 && +mv sm1-bak sm1 + +test_expect_success 'typechanged submodule(submodule->blob), --cached' " + git submodule summary --cached >actual && + diff actual - <<-EOF +* sm1 $head4(submodule)->$head5(blob) (3): + < Add foo5 + +EOF +" + +rm -rf sm1 && +git checkout-index sm1 +test_expect_success 'typechanged submodule(submodule->blob)' " + git submodule summary >actual && + diff actual - <<-EOF +* sm1 $head4(submodule)->$head5(blob): + +EOF +" + +rm -f sm1 && +test_create_repo sm1 && +head6=$(add_file sm1 foo6 foo7) +test_expect_success 'nonexistent commit' " + git submodule summary >actual && + diff actual - <<-EOF +* sm1 $head4...$head6: + Warn: sm1 doesn't contain commit $head4_full + +EOF +" + +commit_file +test_expect_success 'typechanged submodule(blob->submodule)' " + git submodule summary >actual && + diff actual - <<-EOF +* sm1 $head5(blob)->$head6(submodule) (2): + > Add foo7 + +EOF +" + +commit_file sm1 && +rm -rf sm1 +test_expect_success 'deleted submodule' " + git submodule summary >actual && + diff actual - <<-EOF +* sm1 $head6...0000000: + +EOF +" + +test_create_repo sm2 && +head7=$(add_file sm2 foo8 foo9) && +git add sm2 + +test_expect_success 'multiple submodules' " + git submodule summary >actual && + diff actual - <<-EOF +* sm1 $head6...0000000: + +* sm2 0000000...$head7 (2): + > Add foo9 + +EOF +" + +test_expect_success 'path filter' " + git submodule summary sm2 >actual && + diff actual - <<-EOF +* sm2 0000000...$head7 (2): + > Add foo9 + +EOF +" + +commit_file sm2 +test_expect_success 'given commit' " + git submodule summary HEAD^ >actual && + diff actual - <<-EOF +* sm1 $head6...0000000: + +* sm2 0000000...$head7 (2): + > Add foo9 + +EOF +" + +test_expect_success '--for-status' " + git submodule summary --for-status HEAD^ >actual && + test_cmp actual - <<EOF +# Modified submodules: +# +# * sm1 $head6...0000000: +# +# * sm2 0000000...$head7 (2): +# > Add foo9 +# +EOF +" + +test_done diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh new file mode 100755 index 0000000000..f919c8d34d --- /dev/null +++ b/t/t7402-submodule-rebase.sh @@ -0,0 +1,92 @@ +#!/bin/sh +# +# Copyright (c) 2008 Johannes Schindelin +# + +test_description='Test rebasing and stashing with dirty submodules' + +. ./test-lib.sh + +test_expect_success setup ' + + echo file > file && + git add file && + test_tick && + git commit -m initial && + git clone . submodule && + git add submodule && + test_tick && + git commit -m submodule && + echo second line >> file && + (cd submodule && git pull) && + test_tick && + git commit -m file-and-submodule -a + +' + +test_expect_success 'rebase with a dirty submodule' ' + + (cd submodule && + echo 3rd line >> file && + test_tick && + git commit -m fork -a) && + echo unrelated >> file2 && + git add file2 && + test_tick && + git commit -m unrelated file2 && + echo other line >> file && + test_tick && + git commit -m update file && + CURRENT=$(cd submodule && git rev-parse HEAD) && + EXPECTED=$(git rev-parse HEAD~2:submodule) && + GIT_TRACE=1 git rebase --onto HEAD~2 HEAD^ && + STORED=$(git rev-parse HEAD:submodule) && + test $EXPECTED = $STORED && + test $CURRENT = $(cd submodule && git rev-parse HEAD) + +' + +cat > fake-editor.sh << \EOF +#!/bin/sh +echo $EDITOR_TEXT +EOF +chmod a+x fake-editor.sh + +test_expect_success 'interactive rebase with a dirty submodule' ' + + test submodule = $(git diff --name-only) && + HEAD=$(git rev-parse HEAD) && + GIT_EDITOR="\"$(pwd)/fake-editor.sh\"" EDITOR_TEXT="pick $HEAD" \ + git rebase -i HEAD^ && + test submodule = $(git diff --name-only) + +' + +test_expect_success 'rebase with dirty file and submodule fails' ' + + echo yet another line >> file && + test_tick && + git commit -m next file && + echo rewrite > file && + test_tick && + git commit -m rewrite file && + echo dirty > file && + test_must_fail git rebase --onto HEAD~2 HEAD^ + +' + +test_expect_success 'stash with a dirty submodule' ' + + echo new > file && + CURRENT=$(cd submodule && git rev-parse HEAD) && + git stash && + test new != $(cat file) && + test submodule = $(git diff --name-only) && + test $CURRENT = $(cd submodule && git rev-parse HEAD) && + git stash apply && + test new = $(cat file) && + test $CURRENT = $(cd submodule && git rev-parse HEAD) + +' + +test_done diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh new file mode 100755 index 0000000000..809bdba630 --- /dev/null +++ b/t/t7500-commit.sh @@ -0,0 +1,170 @@ +#!/bin/sh +# +# Copyright (c) 2007 Steven Grimm +# + +test_description='git-commit + +Tests for selected commit options.' + +. ./test-lib.sh + +commit_msg_is () { + test "`git log --pretty=format:%s%b -1`" = "$1" +} + +# A sanity check to see if commit is working at all. +test_expect_success 'a basic commit in an empty tree should succeed' ' + echo content > foo && + git add foo && + git commit -m "initial commit" +' + +test_expect_success 'nonexistent template file should return error' ' + echo changes >> foo && + git add foo && + test_must_fail git commit --template "$PWD"/notexist +' + +test_expect_success 'nonexistent template file in config should return error' ' + git config commit.template "$PWD"/notexist && + test_must_fail git commit && + git config --unset commit.template +' + +# From now on we'll use a template file that exists. +TEMPLATE="$PWD"/template + +test_expect_success 'unedited template should not commit' ' + echo "template line" > "$TEMPLATE" && + test_must_fail git commit --template "$TEMPLATE" +' + +test_expect_success 'unedited template with comments should not commit' ' + echo "# comment in template" >> "$TEMPLATE" && + test_must_fail git commit --template "$TEMPLATE" +' + +test_expect_success 'a Signed-off-by line by itself should not commit' ' + ! GIT_EDITOR=../t7500/add-signed-off git commit --template "$TEMPLATE" +' + +test_expect_success 'adding comments to a template should not commit' ' + ! GIT_EDITOR=../t7500/add-comments git commit --template "$TEMPLATE" +' + +test_expect_success 'adding real content to a template should commit' ' + GIT_EDITOR=../t7500/add-content git commit --template "$TEMPLATE" && + commit_msg_is "template linecommit message" +' + +test_expect_success '-t option should be short for --template' ' + echo "short template" > "$TEMPLATE" && + echo "new content" >> foo && + git add foo && + GIT_EDITOR=../t7500/add-content git commit -t "$TEMPLATE" && + commit_msg_is "short templatecommit message" +' + +test_expect_success 'config-specified template should commit' ' + echo "new template" > "$TEMPLATE" && + git config commit.template "$TEMPLATE" && + echo "more content" >> foo && + git add foo && + GIT_EDITOR=../t7500/add-content git commit && + git config --unset commit.template && + commit_msg_is "new templatecommit message" +' + +test_expect_success 'explicit commit message should override template' ' + echo "still more content" >> foo && + git add foo && + GIT_EDITOR=../t7500/add-content git commit --template "$TEMPLATE" \ + -m "command line msg" && + commit_msg_is "command line msg" +' + +test_expect_success 'commit message from file should override template' ' + echo "content galore" >> foo && + git add foo && + echo "standard input msg" | + GIT_EDITOR=../t7500/add-content git commit \ + --template "$TEMPLATE" --file - && + commit_msg_is "standard input msg" +' + +test_expect_success 'using alternate GIT_INDEX_FILE (1)' ' + + cp .git/index saved-index && + ( + echo some new content >file && + GIT_INDEX_FILE=.git/another_index && + export GIT_INDEX_FILE && + git add file && + git commit -m "commit using another index" && + git diff-index --exit-code HEAD && + git diff-files --exit-code + ) && + cmp .git/index saved-index >/dev/null + +' + +test_expect_success 'using alternate GIT_INDEX_FILE (2)' ' + + cp .git/index saved-index && + ( + rm -f .git/no-such-index && + GIT_INDEX_FILE=.git/no-such-index && + export GIT_INDEX_FILE && + git commit -m "commit using nonexistent index" && + test -z "$(git ls-files)" && + test -z "$(git ls-tree HEAD)" + + ) && + cmp .git/index saved-index >/dev/null +' + +cat > expect << EOF +zort + +Signed-off-by: C O Mitter <committer@example.com> +EOF + +test_expect_success '--signoff' ' + echo "yet another content *narf*" >> foo && + echo "zort" | + GIT_EDITOR=../t7500/add-content git commit -s -F - foo && + git cat-file commit HEAD | sed "1,/^$/d" > output && + diff expect output +' + +test_expect_success 'commit message from file (1)' ' + mkdir subdir && + echo "Log in top directory" >log && + echo "Log in sub directory" >subdir/log && + ( + cd subdir && + git commit --allow-empty -F log + ) && + commit_msg_is "Log in sub directory" +' + +test_expect_success 'commit message from file (2)' ' + rm -f log && + echo "Log in sub directory" >subdir/log && + ( + cd subdir && + git commit --allow-empty -F log + ) && + commit_msg_is "Log in sub directory" +' + +test_expect_success 'commit message from stdin' ' + ( + cd subdir && + echo "Log with foo word" | git commit --allow-empty -F - + ) && + commit_msg_is "Log with foo word" +' + +test_done diff --git a/t/t7500/add-comments b/t/t7500/add-comments new file mode 100755 index 0000000000..a72e65c891 --- /dev/null +++ b/t/t7500/add-comments @@ -0,0 +1,4 @@ +#!/bin/sh +echo "# this is a new comment" >> "$1" +echo "# and so is this" >> "$1" +exit 0 diff --git a/t/t7500/add-content b/t/t7500/add-content new file mode 100755 index 0000000000..2fa3d86a10 --- /dev/null +++ b/t/t7500/add-content @@ -0,0 +1,3 @@ +#!/bin/sh +echo "commit message" >> "$1" +exit 0 diff --git a/t/t7500/add-signed-off b/t/t7500/add-signed-off new file mode 100755 index 0000000000..e1d856af6d --- /dev/null +++ b/t/t7500/add-signed-off @@ -0,0 +1,3 @@ +#!/bin/sh +echo "Signed-off-by: foo <bar@frotz>" >> "$1" +exit 0 diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh new file mode 100755 index 0000000000..0edd9ddf73 --- /dev/null +++ b/t/t7501-commit.sh @@ -0,0 +1,348 @@ +#!/bin/sh +# +# Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com> +# + +# FIXME: Test the various index usages, -i and -o, test reflog, +# signoff + +test_description='git-commit' +. ./test-lib.sh + +test_tick + +test_expect_success \ + "initial status" \ + "echo 'bongo bongo' >file && + git-add file && \ + git-status | grep 'Initial commit'" + +test_expect_success \ + "fail initial amend" \ + "test_must_fail git-commit --amend" + +test_expect_success \ + "initial commit" \ + "git-commit -m initial" + +test_expect_success \ + "invalid options 1" \ + "test_must_fail git-commit -m foo -m bar -F file" + +test_expect_success \ + "invalid options 2" \ + "test_must_fail git-commit -C HEAD -m illegal" + +test_expect_success \ + "using paths with -a" \ + "echo King of the bongo >file && + test_must_fail git-commit -m foo -a file" + +test_expect_success \ + "using paths with --interactive" \ + "echo bong-o-bong >file && + ! (echo 7 | git-commit -m foo --interactive file)" + +test_expect_success \ + "using invalid commit with -C" \ + "test_must_fail git-commit -C bogus" + +test_expect_success \ + "testing nothing to commit" \ + "test_must_fail git-commit -m initial" + +test_expect_success \ + "next commit" \ + "echo 'bongo bongo bongo' >file \ + git-commit -m next -a" + +test_expect_success \ + "commit message from non-existing file" \ + "echo 'more bongo: bongo bongo bongo bongo' >file && \ + test_must_fail git-commit -F gah -a" + +# Empty except stray tabs and spaces on a few lines. +sed -e 's/@$//' >msg <<EOF + @ + + @ +Signed-off-by: hula +EOF +test_expect_success \ + "empty commit message" \ + "test_must_fail git-commit -F msg -a" + +test_expect_success \ + "commit message from file" \ + "echo 'this is the commit message, coming from a file' >msg && \ + git-commit -F msg -a" + +cat >editor <<\EOF +#!/bin/sh +sed -e "s/a file/an amend commit/g" < "$1" > "$1-" +mv "$1-" "$1" +EOF +chmod 755 editor + +test_expect_success \ + "amend commit" \ + "VISUAL=./editor git-commit --amend" + +test_expect_success \ + "passing -m and -F" \ + "echo 'enough with the bongos' >file && \ + test_must_fail git-commit -F msg -m amending ." + +test_expect_success \ + "using message from other commit" \ + "git-commit -C HEAD^ ." + +cat >editor <<\EOF +#!/bin/sh +sed -e "s/amend/older/g" < "$1" > "$1-" +mv "$1-" "$1" +EOF +chmod 755 editor + +test_expect_success \ + "editing message from other commit" \ + "echo 'hula hula' >file && \ + VISUAL=./editor git-commit -c HEAD^ -a" + +test_expect_success \ + "message from stdin" \ + "echo 'silly new contents' >file && \ + echo commit message from stdin | git-commit -F - -a" + +test_expect_success \ + "overriding author from command line" \ + "echo 'gak' >file && \ + git-commit -m 'author' --author 'Rubber Duck <rduck@convoy.org>' -a" + +test_expect_success \ + "interactive add" \ + "echo 7 | git-commit --interactive | grep 'What now'" + +test_expect_success \ + "showing committed revisions" \ + "git-rev-list HEAD >current" + +# We could just check the head sha1, but checking each commit makes it +# easier to isolate bugs. + +cat >expected <<\EOF +72c0dc9855b0c9dadcbfd5a31cab072e0cb774ca +9b88fc14ce6b32e3d9ee021531a54f18a5cf38a2 +3536bbb352c3a1ef9a420f5b4242d48578b92aa7 +d381ac431806e53f3dd7ac2f1ae0534f36d738b9 +4fd44095ad6334f3ef72e4c5ec8ddf108174b54a +402702b49136e7587daa9280e91e4bb7cb2179f7 +EOF + +test_expect_success \ + 'validate git-rev-list output.' \ + 'diff current expected' + +test_expect_success 'partial commit that involves removal (1)' ' + + git rm --cached file && + mv file elif && + git add elif && + git commit -m "Partial: add elif" elif && + git diff-tree --name-status HEAD^ HEAD >current && + echo "A elif" >expected && + diff expected current + +' + +test_expect_success 'partial commit that involves removal (2)' ' + + git commit -m "Partial: remove file" file && + git diff-tree --name-status HEAD^ HEAD >current && + echo "D file" >expected && + diff expected current + +' + +test_expect_success 'partial commit that involves removal (3)' ' + + git rm --cached elif && + echo elif >elif && + git commit -m "Partial: modify elif" elif && + git diff-tree --name-status HEAD^ HEAD >current && + echo "M elif" >expected && + diff expected current + +' + +author="The Real Author <someguy@his.email.org>" +test_expect_success 'amend commit to fix author' ' + + oldtick=$GIT_AUTHOR_DATE && + test_tick && + git reset --hard && + git cat-file -p HEAD | + sed -e "s/author.*/author $author $oldtick/" \ + -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \ + expected && + git commit --amend --author="$author" && + git cat-file -p HEAD > current && + diff expected current + +' + +test_expect_success 'sign off (1)' ' + + echo 1 >positive && + git add positive && + git commit -s -m "thank you" && + git cat-file commit HEAD | sed -e "1,/^\$/d" >actual && + ( + echo thank you + echo + git var GIT_COMMITTER_IDENT | + sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" + ) >expected && + test_cmp expected actual + +' + +test_expect_success 'sign off (2)' ' + + echo 2 >positive && + git add positive && + existing="Signed-off-by: Watch This <watchthis@example.com>" && + git commit -s -m "thank you + +$existing" && + git cat-file commit HEAD | sed -e "1,/^\$/d" >actual && + ( + echo thank you + echo + echo $existing + git var GIT_COMMITTER_IDENT | + sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" + ) >expected && + test_cmp expected actual + +' + +test_expect_success 'multiple -m' ' + + >negative && + git add negative && + git commit -m "one" -m "two" -m "three" && + git cat-file commit HEAD | sed -e "1,/^\$/d" >actual && + ( + echo one + echo + echo two + echo + echo three + ) >expected && + test_cmp expected actual + +' + +author="The Real Author <someguy@his.email.org>" +test_expect_success 'amend commit to fix author' ' + + oldtick=$GIT_AUTHOR_DATE && + test_tick && + git reset --hard && + git cat-file -p HEAD | + sed -e "s/author.*/author $author $oldtick/" \ + -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \ + expected && + git commit --amend --author="$author" && + git cat-file -p HEAD > current && + diff expected current + +' + +test_expect_success 'git commit <file> with dirty index' ' + echo tacocat > elif && + echo tehlulz > chz && + git add chz && + git commit elif -m "tacocat is a palindrome" && + git show --stat | grep elif && + git diff --cached | grep chz +' + +test_expect_success 'same tree (single parent)' ' + + git reset --hard + + if git commit -m empty + then + echo oops -- should have complained + false + else + : happy + fi + +' + +test_expect_success 'same tree (single parent) --allow-empty' ' + + git commit --allow-empty -m "forced empty" && + git cat-file commit HEAD | grep forced + +' + +test_expect_success 'same tree (merge and amend merge)' ' + + git checkout -b side HEAD^ && + echo zero >zero && + git add zero && + git commit -m "add zero" && + git checkout master && + + git merge -s ours side -m "empty ok" && + git diff HEAD^ HEAD >actual && + : >expected && + test_cmp expected actual && + + git commit --amend -m "empty really ok" && + git diff HEAD^ HEAD >actual && + : >expected && + test_cmp expected actual + +' + +test_expect_success 'amend using the message from another commit' ' + + git reset --hard && + test_tick && + git commit --allow-empty -m "old commit" && + old=$(git rev-parse --verify HEAD) && + test_tick && + git commit --allow-empty -m "new commit" && + new=$(git rev-parse --verify HEAD) && + test_tick && + git commit --allow-empty --amend -C "$old" && + git show --pretty="format:%ad %s" "$old" >expected && + git show --pretty="format:%ad %s" HEAD >actual && + test_cmp expected actual + +' + +test_expect_success 'amend using the message from a commit named with tag' ' + + git reset --hard && + test_tick && + git commit --allow-empty -m "old commit" && + old=$(git rev-parse --verify HEAD) && + git tag -a -m "tag on old" tagged-old HEAD && + test_tick && + git commit --allow-empty -m "new commit" && + new=$(git rev-parse --verify HEAD) && + test_tick && + git commit --allow-empty --amend -C tagged-old && + git show --pretty="format:%ad %s" "$old" >expected && + git show --pretty="format:%ad %s" HEAD >actual && + test_cmp expected actual + +' + +test_done diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh new file mode 100755 index 0000000000..3eb9faedcf --- /dev/null +++ b/t/t7502-commit.sh @@ -0,0 +1,253 @@ +#!/bin/sh + +test_description='git commit porcelain-ish' + +. ./test-lib.sh + +test_expect_success 'the basics' ' + + echo doing partial >"commit is" && + mkdir not && + echo very much encouraged but we should >not/forbid && + git add "commit is" not && + echo update added "commit is" file >"commit is" && + echo also update another >not/forbid && + test_tick && + git commit -a -m "initial with -a" && + + git cat-file blob HEAD:"commit is" >current.1 && + git cat-file blob HEAD:not/forbid >current.2 && + + cmp current.1 "commit is" && + cmp current.2 not/forbid + +' + +test_expect_success 'partial' ' + + echo another >"commit is" && + echo another >not/forbid && + test_tick && + git commit -m "partial commit to handle a file" "commit is" && + + changed=$(git diff-tree --name-only HEAD^ HEAD) && + test "$changed" = "commit is" + +' + +test_expect_success 'partial modification in a subdirecotry' ' + + test_tick && + git commit -m "partial commit to subdirectory" not && + + changed=$(git diff-tree -r --name-only HEAD^ HEAD) && + test "$changed" = "not/forbid" + +' + +test_expect_success 'partial removal' ' + + git rm not/forbid && + git commit -m "partial commit to remove not/forbid" not && + + changed=$(git diff-tree -r --name-only HEAD^ HEAD) && + test "$changed" = "not/forbid" && + remain=$(git ls-tree -r --name-only HEAD) && + test "$remain" = "commit is" + +' + +test_expect_success 'sign off' ' + + >positive && + git add positive && + git commit -s -m "thank you" && + actual=$(git cat-file commit HEAD | sed -ne "s/Signed-off-by: //p") && + expected=$(git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/") && + test "z$actual" = "z$expected" + +' + +test_expect_success 'multiple -m' ' + + >negative && + git add negative && + git commit -m "one" -m "two" -m "three" && + actual=$(git cat-file commit HEAD | sed -e "1,/^\$/d") && + expected=$(echo one; echo; echo two; echo; echo three) && + test "z$actual" = "z$expected" + +' + +test_expect_success 'verbose' ' + + echo minus >negative && + git add negative && + git status -v | sed -ne "/^diff --git /p" >actual && + echo "diff --git a/negative b/negative" >expect && + test_cmp expect actual + +' + +test_expect_success 'cleanup commit messages (verbatim,-t)' ' + + echo >>negative && + { echo;echo "# text";echo; } >expect && + git commit --cleanup=verbatim -t expect -a && + git cat-file -p HEAD |sed -e "1,/^\$/d" |head -n 3 >actual && + test_cmp expect actual + +' + +test_expect_success 'cleanup commit messages (verbatim,-F)' ' + + echo >>negative && + git commit --cleanup=verbatim -F expect -a && + git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + test_cmp expect actual + +' + +test_expect_success 'cleanup commit messages (verbatim,-m)' ' + + echo >>negative && + git commit --cleanup=verbatim -m "$(cat expect)" -a && + git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + test_cmp expect actual + +' + +test_expect_success 'cleanup commit messages (whitespace,-F)' ' + + echo >>negative && + { echo;echo "# text";echo; } >text && + echo "# text" >expect && + git commit --cleanup=whitespace -F text -a && + git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + test_cmp expect actual + +' + +test_expect_success 'cleanup commit messages (strip,-F)' ' + + echo >>negative && + { echo;echo "# text";echo sample;echo; } >text && + echo sample >expect && + git commit --cleanup=strip -F text -a && + git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + test_cmp expect actual + +' + +echo "sample + +# Please enter the commit message for your changes. Lines starting +# with '#' will be ignored, and an empty message aborts the commit." >expect + +test_expect_success 'cleanup commit messages (strip,-F,-e)' ' + + echo >>negative && + { echo;echo sample;echo; } >text && + git commit -e -F text -a && + head -n 4 .git/COMMIT_EDITMSG >actual && + test_cmp expect actual + +' + +echo "# +# Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> +#" >> expect + +test_expect_success 'author different from committer' ' + + echo >>negative && + git commit -e -m "sample" + head -n 7 .git/COMMIT_EDITMSG >actual && + test_cmp expect actual +' + +mv expect expect.tmp +sed '$d' < expect.tmp > expect +rm -f expect.tmp +echo "# Committer: +#" >> expect + +test_expect_success 'committer is automatic' ' + + echo >>negative && + ( + unset GIT_COMMITTER_EMAIL + unset GIT_COMMITTER_NAME + # must fail because there is no change + test_must_fail git commit -e -m "sample" + ) && + head -n 8 .git/COMMIT_EDITMSG | \ + sed "s/^# Committer: .*/# Committer:/" >actual && + test_cmp expect actual +' + +pwd=`pwd` +cat >> .git/FAKE_EDITOR << EOF +#! /bin/sh +echo editor started > "$pwd/.git/result" +exit 0 +EOF +chmod +x .git/FAKE_EDITOR + +test_expect_success 'do not fire editor in the presence of conflicts' ' + + git clean -f && + echo f >g && + git add g && + git commit -m "add g" && + git branch second && + echo master >g && + echo g >h && + git add g h && + git commit -m "modify g and add h" && + git checkout second && + echo second >g && + git add g && + git commit -m second && + # Must fail due to conflict + test_must_fail git cherry-pick -n master && + echo "editor not started" >.git/result && + ( + GIT_EDITOR="$(pwd)/.git/FAKE_EDITOR" && + export GIT_EDITOR && + test_must_fail git commit + ) && + test "$(cat .git/result)" = "editor not started" +' + +pwd=`pwd` +cat >.git/FAKE_EDITOR <<EOF +#! $SHELL_PATH +# kill -TERM command added below. +EOF + +test_expect_success 'a SIGTERM should break locks' ' + echo >>negative && + ! "$SHELL_PATH" -c '\'' + echo kill -TERM $$ >> .git/FAKE_EDITOR + GIT_EDITOR=.git/FAKE_EDITOR + export GIT_EDITOR + exec git commit -a'\'' && + test ! -f .git/index.lock +' + +rm -f .git/MERGE_MSG .git/COMMIT_EDITMSG +git reset -q --hard + +test_expect_success 'Hand committing of a redundant merge removes dups' ' + + git rev-parse second master >expect && + test_must_fail git merge second master && + git checkout master g && + EDITOR=: git commit -a && + git cat-file commit HEAD | sed -n -e "s/^parent //p" -e "/^$/q" >actual && + test_cmp expect actual + +' + +test_done diff --git a/t/t7502-status.sh b/t/t7502-status.sh new file mode 100755 index 0000000000..38a48b57c7 --- /dev/null +++ b/t/t7502-status.sh @@ -0,0 +1,384 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes E. Schindelin +# + +test_description='git-status' + +. ./test-lib.sh + +test_expect_success 'setup' ' + : > tracked && + : > modified && + mkdir dir1 && + : > dir1/tracked && + : > dir1/modified && + mkdir dir2 && + : > dir1/tracked && + : > dir1/modified && + git add . && + + git status >output && + + test_tick && + git commit -m initial && + : > untracked && + : > dir1/untracked && + : > dir2/untracked && + echo 1 > dir1/modified && + echo 2 > dir2/modified && + echo 3 > dir2/added && + git add dir2/added +' + +test_expect_success 'status (1)' ' + + grep "use \"git rm --cached <file>\.\.\.\" to unstage" output + +' + +cat > expect << \EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: dir2/added +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +EOF + +test_expect_success 'status (2)' ' + + git status > output && + test_cmp expect output + +' + +cat >expect <<EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: dir2/added +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Untracked files not listed (use -u option to show untracked files) +EOF +test_expect_success 'status -uno' ' + mkdir dir3 && + : > dir3/untracked1 && + : > dir3/untracked2 && + git status -uno >output && + test_cmp expect output +' + +test_expect_success 'status (status.showUntrackedFiles no)' ' + git config status.showuntrackedfiles no + git status >output && + test_cmp expect output +' + +cat >expect <<EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: dir2/added +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/modified +# dir2/untracked +# dir3/ +# expect +# output +# untracked +EOF +test_expect_success 'status -unormal' ' + git status -unormal >output && + test_cmp expect output +' + +test_expect_success 'status (status.showUntrackedFiles normal)' ' + git config status.showuntrackedfiles normal + git status >output && + test_cmp expect output +' + +cat >expect <<EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: dir2/added +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/modified +# dir2/untracked +# dir3/untracked1 +# dir3/untracked2 +# expect +# output +# untracked +EOF +test_expect_success 'status -uall' ' + git status -uall >output && + test_cmp expect output +' +test_expect_success 'status (status.showUntrackedFiles all)' ' + git config status.showuntrackedfiles all + git status >output && + rm -rf dir3 && + git config --unset status.showuntrackedfiles && + test_cmp expect output +' + +cat > expect << \EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: ../dir2/added +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# untracked +# ../dir2/modified +# ../dir2/untracked +# ../expect +# ../output +# ../untracked +EOF + +test_expect_success 'status with relative paths' ' + + (cd dir1 && git status) > output && + test_cmp expect output + +' + +cat > expect << \EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: dir2/added +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +EOF + +test_expect_success 'status without relative paths' ' + + git config status.relativePaths false + (cd dir1 && git status) > output && + test_cmp expect output + +' + +cat <<EOF >expect +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# modified: dir1/modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/ +# expect +# output +# untracked +EOF +test_expect_success 'status of partial commit excluding new file in index' ' + git status dir1/modified >output && + test_cmp expect output +' + +test_expect_success 'setup status submodule summary' ' + test_create_repo sm && ( + cd sm && + >foo && + git add foo && + git commit -m "Add foo" + ) && + git add sm +' + +cat >expect <<EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: dir2/added +# new file: sm +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +EOF +test_expect_success 'status submodule summary is disabled by default' ' + git status >output && + test_cmp expect output +' + +head=$(cd sm && git rev-parse --short=7 --verify HEAD) + +cat >expect <<EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: dir2/added +# new file: sm +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Modified submodules: +# +# * sm 0000000...$head (1): +# > Add foo +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +EOF +test_expect_success 'status submodule summary' ' + git config status.submodulesummary 10 && + git status >output && + test_cmp expect output +' + + +cat >expect <<EOF +# On branch master +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +no changes added to commit (use "git add" and/or "git commit -a") +EOF +test_expect_success 'status submodule summary (clean submodule)' ' + git commit -m "commit submodule" && + git config status.submodulesummary 10 && + test_must_fail git status >output && + test_cmp expect output +' + +cat >expect <<EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD^1 <file>..." to unstage) +# +# new file: dir2/added +# new file: sm +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Modified submodules: +# +# * sm 0000000...$head (1): +# > Add foo +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +EOF +test_expect_success 'status submodule summary (--amend)' ' + git config status.submodulesummary 10 && + git status --amend >output && + test_cmp expect output +' + +test_done diff --git a/t/t7503-pre-commit-hook.sh b/t/t7503-pre-commit-hook.sh new file mode 100755 index 0000000000..b069095995 --- /dev/null +++ b/t/t7503-pre-commit-hook.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +test_description='pre-commit hook' + +. ./test-lib.sh + +test_expect_success 'with no hook' ' + + echo "foo" > file && + git add file && + git commit -m "first" + +' + +test_expect_success '--no-verify with no hook' ' + + echo "bar" > file && + git add file && + git commit --no-verify -m "bar" + +' + +# now install hook that always succeeds +HOOKDIR="$(git rev-parse --git-dir)/hooks" +HOOK="$HOOKDIR/pre-commit" +mkdir -p "$HOOKDIR" +cat > "$HOOK" <<EOF +#!/bin/sh +exit 0 +EOF +chmod +x "$HOOK" + +test_expect_success 'with succeeding hook' ' + + echo "more" >> file && + git add file && + git commit -m "more" + +' + +test_expect_success '--no-verify with succeeding hook' ' + + echo "even more" >> file && + git add file && + git commit --no-verify -m "even more" + +' + +# now a hook that fails +cat > "$HOOK" <<EOF +#!/bin/sh +exit 1 +EOF + +test_expect_success 'with failing hook' ' + + echo "another" >> file && + git add file && + test_must_fail git commit -m "another" + +' + +test_expect_success '--no-verify with failing hook' ' + + echo "stuff" >> file && + git add file && + git commit --no-verify -m "stuff" + +' + +chmod -x "$HOOK" +test_expect_success 'with non-executable hook' ' + + echo "content" >> file && + git add file && + git commit -m "content" + +' + +test_expect_success '--no-verify with non-executable hook' ' + + echo "more content" >> file && + git add file && + git commit --no-verify -m "more content" + +' + +test_done diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh new file mode 100755 index 0000000000..47680e6df4 --- /dev/null +++ b/t/t7504-commit-msg-hook.sh @@ -0,0 +1,223 @@ +#!/bin/sh + +test_description='commit-msg hook' + +. ./test-lib.sh + +test_expect_success 'with no hook' ' + + echo "foo" > file && + git add file && + git commit -m "first" + +' + +# set up fake editor for interactive editing +cat > fake-editor <<'EOF' +#!/bin/sh +cp FAKE_MSG "$1" +exit 0 +EOF +chmod +x fake-editor + +## Not using test_set_editor here so we can easily ensure the editor variable +## is only set for the editor tests +FAKE_EDITOR="$(pwd)/fake-editor" +export FAKE_EDITOR + +test_expect_success 'with no hook (editor)' ' + + echo "more foo" >> file && + git add file && + echo "more foo" > FAKE_MSG && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit + +' + +test_expect_success '--no-verify with no hook' ' + + echo "bar" > file && + git add file && + git commit --no-verify -m "bar" + +' + +test_expect_success '--no-verify with no hook (editor)' ' + + echo "more bar" > file && + git add file && + echo "more bar" > FAKE_MSG && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify + +' + +# now install hook that always succeeds +HOOKDIR="$(git rev-parse --git-dir)/hooks" +HOOK="$HOOKDIR/commit-msg" +mkdir -p "$HOOKDIR" +cat > "$HOOK" <<EOF +#!/bin/sh +exit 0 +EOF +chmod +x "$HOOK" + +test_expect_success 'with succeeding hook' ' + + echo "more" >> file && + git add file && + git commit -m "more" + +' + +test_expect_success 'with succeeding hook (editor)' ' + + echo "more more" >> file && + git add file && + echo "more more" > FAKE_MSG && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit + +' + +test_expect_success '--no-verify with succeeding hook' ' + + echo "even more" >> file && + git add file && + git commit --no-verify -m "even more" + +' + +test_expect_success '--no-verify with succeeding hook (editor)' ' + + echo "even more more" >> file && + git add file && + echo "even more more" > FAKE_MSG && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify + +' + +# now a hook that fails +cat > "$HOOK" <<EOF +#!/bin/sh +exit 1 +EOF + +test_expect_success 'with failing hook' ' + + echo "another" >> file && + git add file && + test_must_fail git commit -m "another" + +' + +test_expect_success 'with failing hook (editor)' ' + + echo "more another" >> file && + git add file && + echo "more another" > FAKE_MSG && + ! (GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit) + +' + +test_expect_success '--no-verify with failing hook' ' + + echo "stuff" >> file && + git add file && + git commit --no-verify -m "stuff" + +' + +test_expect_success '--no-verify with failing hook (editor)' ' + + echo "more stuff" >> file && + git add file && + echo "more stuff" > FAKE_MSG && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify + +' + +chmod -x "$HOOK" +test_expect_success 'with non-executable hook' ' + + echo "content" >> file && + git add file && + git commit -m "content" + +' + +test_expect_success 'with non-executable hook (editor)' ' + + echo "content again" >> file && + git add file && + echo "content again" > FAKE_MSG && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -m "content again" + +' + +test_expect_success '--no-verify with non-executable hook' ' + + echo "more content" >> file && + git add file && + git commit --no-verify -m "more content" + +' + +test_expect_success '--no-verify with non-executable hook (editor)' ' + + echo "even more content" >> file && + git add file && + echo "even more content" > FAKE_MSG && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify + +' + +# now a hook that edits the commit message +cat > "$HOOK" <<'EOF' +#!/bin/sh +echo "new message" > "$1" +exit 0 +EOF +chmod +x "$HOOK" + +commit_msg_is () { + test "`git log --pretty=format:%s%b -1`" = "$1" +} + +test_expect_success 'hook edits commit message' ' + + echo "additional" >> file && + git add file && + git commit -m "additional" && + commit_msg_is "new message" + +' + +test_expect_success 'hook edits commit message (editor)' ' + + echo "additional content" >> file && + git add file && + echo "additional content" > FAKE_MSG && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit && + commit_msg_is "new message" + +' + +test_expect_success "hook doesn't edit commit message" ' + + echo "plus" >> file && + git add file && + git commit --no-verify -m "plus" && + commit_msg_is "plus" + +' + +test_expect_success "hook doesn't edit commit message (editor)" ' + + echo "more plus" >> file && + git add file && + echo "more plus" > FAKE_MSG && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify && + commit_msg_is "more plus" + +' + +test_done diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh new file mode 100755 index 0000000000..cd6c7c8342 --- /dev/null +++ b/t/t7505-prepare-commit-msg-hook.sh @@ -0,0 +1,159 @@ +#!/bin/sh + +test_description='prepare-commit-msg hook' + +. ./test-lib.sh + +test_expect_success 'with no hook' ' + + echo "foo" > file && + git add file && + git commit -m "first" + +' + +# set up fake editor for interactive editing +cat > fake-editor <<'EOF' +#!/bin/sh +exit 0 +EOF +chmod +x fake-editor + +## Not using test_set_editor here so we can easily ensure the editor variable +## is only set for the editor tests +FAKE_EDITOR="$(pwd)/fake-editor" +export FAKE_EDITOR + +# now install hook that always succeeds and adds a message +HOOKDIR="$(git rev-parse --git-dir)/hooks" +HOOK="$HOOKDIR/prepare-commit-msg" +mkdir -p "$HOOKDIR" +echo "#!$SHELL_PATH" > "$HOOK" +cat >> "$HOOK" <<'EOF' + +if test "$2" = commit; then + source=$(git-rev-parse "$3") +else + source=${2-default} +fi +if test "$GIT_EDITOR" = :; then + sed -e "1s/.*/$source (no editor)/" "$1" > msg.tmp +else + sed -e "1s/.*/$source/" "$1" > msg.tmp +fi +mv msg.tmp "$1" +exit 0 +EOF +chmod +x "$HOOK" + +echo dummy template > "$(git rev-parse --git-dir)/template" + +test_expect_success 'with hook (-m)' ' + + echo "more" >> file && + git add file && + git commit -m "more" && + test "`git log -1 --pretty=format:%s`" = "message (no editor)" + +' + +test_expect_success 'with hook (-m editor)' ' + + echo "more" >> file && + git add file && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -e -m "more more" && + test "`git log -1 --pretty=format:%s`" = message + +' + +test_expect_success 'with hook (-t)' ' + + echo "more" >> file && + git add file && + git commit -t "$(git rev-parse --git-dir)/template" && + test "`git log -1 --pretty=format:%s`" = template + +' + +test_expect_success 'with hook (-F)' ' + + echo "more" >> file && + git add file && + (echo more | git commit -F -) && + test "`git log -1 --pretty=format:%s`" = "message (no editor)" + +' + +test_expect_success 'with hook (-F editor)' ' + + echo "more" >> file && + git add file && + (echo more more | GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -e -F -) && + test "`git log -1 --pretty=format:%s`" = message + +' + +test_expect_success 'with hook (-C)' ' + + head=`git rev-parse HEAD` && + echo "more" >> file && + git add file && + git commit -C $head && + test "`git log -1 --pretty=format:%s`" = "$head (no editor)" + +' + +test_expect_success 'with hook (editor)' ' + + echo "more more" >> file && + git add file && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit && + test "`git log -1 --pretty=format:%s`" = default + +' + +test_expect_success 'with hook (--amend)' ' + + head=`git rev-parse HEAD` && + echo "more" >> file && + git add file && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --amend && + test "`git log -1 --pretty=format:%s`" = "$head" + +' + +test_expect_success 'with hook (-c)' ' + + head=`git rev-parse HEAD` && + echo "more" >> file && + git add file && + GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head && + test "`git log -1 --pretty=format:%s`" = "$head" + +' + +cat > "$HOOK" <<'EOF' +#!/bin/sh +exit 1 +EOF + +test_expect_success 'with failing hook' ' + + head=`git rev-parse HEAD` && + echo "more" >> file && + git add file && + ! GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head + +' + +test_expect_success 'with failing hook (--no-verify)' ' + + head=`git rev-parse HEAD` && + echo "more" >> file && + git add file && + ! GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify -c $head + +' + + +test_done diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh new file mode 100755 index 0000000000..a75130cdbb --- /dev/null +++ b/t/t7506-status-submodule.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +test_description='git-status for submodule' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_create_repo sub + cd sub && + : >bar && + git add bar && + git commit -m " Add bar" && + cd .. && + git add sub && + git commit -m "Add submodule sub" +' + +test_expect_success 'status clean' ' + git status | + grep "nothing to commit" +' +test_expect_success 'status -a clean' ' + git status -a | + grep "nothing to commit" +' +test_expect_success 'rm submodule contents' ' + rm -rf sub/* sub/.git +' +test_expect_success 'status clean (empty submodule dir)' ' + git status | + grep "nothing to commit" +' +test_expect_success 'status -a clean (empty submodule dir)' ' + git status -a | + grep "nothing to commit" +' + +test_done diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh new file mode 100755 index 0000000000..5eeb6c2b27 --- /dev/null +++ b/t/t7600-merge.sh @@ -0,0 +1,491 @@ +#!/bin/sh +# +# Copyright (c) 2007 Lars Hjemli +# + +test_description='git-merge + +Testing basic merge operations/option parsing.' + +. ./test-lib.sh + +cat >file <<EOF +1 +2 +3 +4 +5 +6 +7 +8 +9 +EOF + +cat >file.1 <<EOF +1 X +2 +3 +4 +5 +6 +7 +8 +9 +EOF + +cat >file.5 <<EOF +1 +2 +3 +4 +5 X +6 +7 +8 +9 +EOF + +cat >file.9 <<EOF +1 +2 +3 +4 +5 +6 +7 +8 +9 X +EOF + +cat >result.1 <<EOF +1 X +2 +3 +4 +5 +6 +7 +8 +9 +EOF + +cat >result.1-5 <<EOF +1 X +2 +3 +4 +5 X +6 +7 +8 +9 +EOF + +cat >result.1-5-9 <<EOF +1 X +2 +3 +4 +5 X +6 +7 +8 +9 X +EOF + +create_merge_msgs() { + echo "Merge commit 'c2'" >msg.1-5 && + echo "Merge commit 'c2'; commit 'c3'" >msg.1-5-9 && + echo "Squashed commit of the following:" >squash.1 && + echo >>squash.1 && + git log --no-merges ^HEAD c1 >>squash.1 && + echo "Squashed commit of the following:" >squash.1-5 && + echo >>squash.1-5 && + git log --no-merges ^HEAD c2 >>squash.1-5 && + echo "Squashed commit of the following:" >squash.1-5-9 && + echo >>squash.1-5-9 && + git log --no-merges ^HEAD c2 c3 >>squash.1-5-9 && + echo > msg.nolog && + echo "* commit 'c3':" >msg.log && + echo " commit 3" >>msg.log && + echo >>msg.log +} + +verify_diff() { + if ! test_cmp "$1" "$2" + then + echo "$3" + false + fi +} + +verify_merge() { + verify_diff "$2" "$1" "[OOPS] bad merge result" && + if test $(git ls-files -u | wc -l) -gt 0 + then + echo "[OOPS] unmerged files" + false + fi && + if test_must_fail git diff --exit-code + then + echo "[OOPS] working tree != index" + false + fi && + if test -n "$3" + then + git show -s --pretty=format:%s HEAD >msg.act && + verify_diff "$3" msg.act "[OOPS] bad merge message" + fi +} + +verify_head() { + if test "$1" != "$(git rev-parse HEAD)" + then + echo "[OOPS] HEAD != $1" + false + fi +} + +verify_parents() { + i=1 + while test $# -gt 0 + do + if test "$1" != "$(git rev-parse HEAD^$i)" + then + echo "[OOPS] HEAD^$i != $1" + return 1 + fi + i=$(expr $i + 1) + shift + done +} + +verify_mergeheads() { + i=1 + if ! test -f .git/MERGE_HEAD + then + echo "[OOPS] MERGE_HEAD is missing" + false + fi && + while test $# -gt 0 + do + head=$(head -n $i .git/MERGE_HEAD | sed -ne \$p) + if test "$1" != "$head" + then + echo "[OOPS] MERGE_HEAD $i != $1" + return 1 + fi + i=$(expr $i + 1) + shift + done +} + +verify_no_mergehead() { + if test -f .git/MERGE_HEAD + then + echo "[OOPS] MERGE_HEAD exists" + false + fi +} + + +test_expect_success 'setup' ' + git add file && + test_tick && + git commit -m "commit 0" && + git tag c0 && + c0=$(git rev-parse HEAD) && + cp file.1 file && + git add file && + test_tick && + git commit -m "commit 1" && + git tag c1 && + c1=$(git rev-parse HEAD) && + git reset --hard "$c0" && + cp file.5 file && + git add file && + test_tick && + git commit -m "commit 2" && + git tag c2 && + c2=$(git rev-parse HEAD) && + git reset --hard "$c0" && + cp file.9 file && + git add file && + test_tick && + git commit -m "commit 3" && + git tag c3 && + c3=$(git rev-parse HEAD) + git reset --hard "$c0" && + create_merge_msgs +' + +test_debug 'gitk --all' + +test_expect_success 'test option parsing' ' + test_must_fail git merge -$ c1 && + test_must_fail git merge --no-such c1 && + test_must_fail git merge -s foobar c1 && + test_must_fail git merge -s=foobar c1 && + test_must_fail git merge -m && + test_must_fail git merge +' + +test_expect_success 'merge c0 with c1' ' + git reset --hard c0 && + git merge c1 && + verify_merge file result.1 && + verify_head "$c1" +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c2' ' + git reset --hard c1 && + test_tick && + git merge c2 && + verify_merge file result.1-5 msg.1-5 && + verify_parents $c1 $c2 +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c2 and c3' ' + git reset --hard c1 && + test_tick && + git merge c2 c3 && + verify_merge file result.1-5-9 msg.1-5-9 && + verify_parents $c1 $c2 $c3 +' + +test_debug 'gitk --all' + +test_expect_success 'merge c0 with c1 (no-commit)' ' + git reset --hard c0 && + git merge --no-commit c1 && + verify_merge file result.1 && + verify_head $c1 +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c2 (no-commit)' ' + git reset --hard c1 && + git merge --no-commit c2 && + verify_merge file result.1-5 && + verify_head $c1 && + verify_mergeheads $c2 +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c2 and c3 (no-commit)' ' + git reset --hard c1 && + git merge --no-commit c2 c3 && + verify_merge file result.1-5-9 && + verify_head $c1 && + verify_mergeheads $c2 $c3 +' + +test_debug 'gitk --all' + +test_expect_success 'merge c0 with c1 (squash)' ' + git reset --hard c0 && + git merge --squash c1 && + verify_merge file result.1 && + verify_head $c0 && + verify_no_mergehead && + verify_diff squash.1 .git/SQUASH_MSG "[OOPS] bad squash message" +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c2 (squash)' ' + git reset --hard c1 && + git merge --squash c2 && + verify_merge file result.1-5 && + verify_head $c1 && + verify_no_mergehead && + verify_diff squash.1-5 .git/SQUASH_MSG "[OOPS] bad squash message" +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c2 and c3 (squash)' ' + git reset --hard c1 && + git merge --squash c2 c3 && + verify_merge file result.1-5-9 && + verify_head $c1 && + verify_no_mergehead && + verify_diff squash.1-5-9 .git/SQUASH_MSG "[OOPS] bad squash message" +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c2 (no-commit in config)' ' + git reset --hard c1 && + git config branch.master.mergeoptions "--no-commit" && + git merge c2 && + verify_merge file result.1-5 && + verify_head $c1 && + verify_mergeheads $c2 +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c2 (squash in config)' ' + git reset --hard c1 && + git config branch.master.mergeoptions "--squash" && + git merge c2 && + verify_merge file result.1-5 && + verify_head $c1 && + verify_no_mergehead && + verify_diff squash.1-5 .git/SQUASH_MSG "[OOPS] bad squash message" +' + +test_debug 'gitk --all' + +test_expect_success 'override config option -n with --summary' ' + git reset --hard c1 && + git config branch.master.mergeoptions "-n" && + test_tick && + git merge --summary c2 >diffstat.txt && + verify_merge file result.1-5 msg.1-5 && + verify_parents $c1 $c2 && + if ! grep "^ file | *2 +-$" diffstat.txt + then + echo "[OOPS] diffstat was not generated with --summary" + false + fi +' + +test_expect_success 'override config option -n with --stat' ' + git reset --hard c1 && + git config branch.master.mergeoptions "-n" && + test_tick && + git merge --stat c2 >diffstat.txt && + verify_merge file result.1-5 msg.1-5 && + verify_parents $c1 $c2 && + if ! grep "^ file | *2 +-$" diffstat.txt + then + echo "[OOPS] diffstat was not generated with --stat" + false + fi +' + +test_debug 'gitk --all' + +test_expect_success 'override config option --stat' ' + git reset --hard c1 && + git config branch.master.mergeoptions "--stat" && + test_tick && + git merge -n c2 >diffstat.txt && + verify_merge file result.1-5 msg.1-5 && + verify_parents $c1 $c2 && + if grep "^ file | *2 +-$" diffstat.txt + then + echo "[OOPS] diffstat was generated" + false + fi +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c2 (override --no-commit)' ' + git reset --hard c1 && + git config branch.master.mergeoptions "--no-commit" && + test_tick && + git merge --commit c2 && + verify_merge file result.1-5 msg.1-5 && + verify_parents $c1 $c2 +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c2 (override --squash)' ' + git reset --hard c1 && + git config branch.master.mergeoptions "--squash" && + test_tick && + git merge --no-squash c2 && + verify_merge file result.1-5 msg.1-5 && + verify_parents $c1 $c2 +' + +test_debug 'gitk --all' + +test_expect_success 'merge c0 with c1 (no-ff)' ' + git reset --hard c0 && + git config branch.master.mergeoptions "" && + test_tick && + git merge --no-ff c1 && + verify_merge file result.1 && + verify_parents $c0 $c1 +' + +test_debug 'gitk --all' + +test_expect_success 'combining --squash and --no-ff is refused' ' + test_must_fail git merge --squash --no-ff c1 && + test_must_fail git merge --no-ff --squash c1 +' + +test_expect_success 'merge c0 with c1 (ff overrides no-ff)' ' + git reset --hard c0 && + git config branch.master.mergeoptions "--no-ff" && + git merge --ff c1 && + verify_merge file result.1 && + verify_head $c1 +' + +test_expect_success 'merge log message' ' + git reset --hard c0 && + git merge --no-log c2 && + git show -s --pretty=format:%b HEAD >msg.act && + verify_diff msg.nolog msg.act "[OOPS] bad merge log message" && + + git merge --log c3 && + git show -s --pretty=format:%b HEAD >msg.act && + verify_diff msg.log msg.act "[OOPS] bad merge log message" && + + git reset --hard HEAD^ && + git config merge.log yes && + git merge c3 && + git show -s --pretty=format:%b HEAD >msg.act && + verify_diff msg.log msg.act "[OOPS] bad merge log message" +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c0, c2, c0, and c1' ' + git reset --hard c1 && + git config branch.master.mergeoptions "" && + test_tick && + git merge c0 c2 c0 c1 && + verify_merge file result.1-5 && + verify_parents $c1 $c2 +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c0, c2, c0, and c1' ' + git reset --hard c1 && + git config branch.master.mergeoptions "" && + test_tick && + git merge c0 c2 c0 c1 && + verify_merge file result.1-5 && + verify_parents $c1 $c2 +' + +test_debug 'gitk --all' + +test_expect_success 'merge c1 with c1 and c2' ' + git reset --hard c1 && + git config branch.master.mergeoptions "" && + test_tick && + git merge c1 c2 && + verify_merge file result.1-5 && + verify_parents $c1 $c2 +' + +test_debug 'gitk --all' + +test_done diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh new file mode 100755 index 0000000000..55aa6b5f27 --- /dev/null +++ b/t/t7601-merge-pull-config.sh @@ -0,0 +1,156 @@ +#!/bin/sh + +test_description='git-merge + +Testing pull.* configuration parsing.' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo c0 >c0.c && + git add c0.c && + git commit -m c0 && + git tag c0 && + echo c1 >c1.c && + git add c1.c && + git commit -m c1 && + git tag c1 && + git reset --hard c0 && + echo c2 >c2.c && + git add c2.c && + git commit -m c2 && + git tag c2 && + git reset --hard c0 && + echo c3 >c3.c && + git add c3.c && + git commit -m c3 && + git tag c3 +' + +test_expect_success 'merge c1 with c2' ' + git reset --hard c1 && + test -f c0.c && + test -f c1.c && + test ! -f c2.c && + test ! -f c3.c && + git merge c2 && + test -f c1.c && + test -f c2.c +' + +test_expect_success 'merge c1 with c2 (ours in pull.twohead)' ' + git reset --hard c1 && + git config pull.twohead ours && + git merge c2 && + test -f c1.c && + ! test -f c2.c +' + +test_expect_success 'merge c1 with c2 and c3 (recursive in pull.octopus)' ' + git reset --hard c1 && + git config pull.octopus "recursive" && + test_must_fail git merge c2 c3 && + test "$(git rev-parse c1)" = "$(git rev-parse HEAD)" +' + +test_expect_success 'merge c1 with c2 and c3 (recursive and octopus in pull.octopus)' ' + git reset --hard c1 && + git config pull.octopus "recursive octopus" && + git merge c2 c3 && + test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" && + test "$(git rev-parse c1)" = "$(git rev-parse HEAD^1)" && + test "$(git rev-parse c2)" = "$(git rev-parse HEAD^2)" && + test "$(git rev-parse c3)" = "$(git rev-parse HEAD^3)" && + git diff --exit-code && + test -f c0.c && + test -f c1.c && + test -f c2.c && + test -f c3.c +' + +conflict_count() +{ + { + git diff-files --name-only + git ls-files --unmerged + } | wc -l +} + +# c4 - c5 +# \ c6 +# +# There are two conflicts here: +# +# 1) Because foo.c is renamed to bar.c, recursive will handle this, +# resolve won't. +# +# 2) One in conflict.c and that will always fail. + +test_expect_success 'setup conflicted merge' ' + git reset --hard c0 && + echo A >conflict.c && + git add conflict.c && + echo contents >foo.c && + git add foo.c && + git commit -m c4 && + git tag c4 && + echo B >conflict.c && + git add conflict.c && + git mv foo.c bar.c && + git commit -m c5 && + git tag c5 && + git reset --hard c4 && + echo C >conflict.c && + git add conflict.c && + echo secondline >> foo.c && + git add foo.c && + git commit -m c6 && + git tag c6 +' + +# First do the merge with resolve and recursive then verify that +# recusive is choosen. + +test_expect_success 'merge picks up the best result' ' + git config --unset-all pull.twohead && + git reset --hard c5 && + git merge -s resolve c6 + resolve_count=$(conflict_count) && + git reset --hard c5 && + git merge -s recursive c6 + recursive_count=$(conflict_count) && + git reset --hard c5 && + git merge -s recursive -s resolve c6 + auto_count=$(conflict_count) && + test $auto_count = $recursive_count && + test $auto_count != $resolve_count +' + +test_expect_success 'merge picks up the best result (from config)' ' + git config pull.twohead "recursive resolve" && + git reset --hard c5 && + git merge -s resolve c6 + resolve_count=$(conflict_count) && + git reset --hard c5 && + git merge -s recursive c6 + recursive_count=$(conflict_count) && + git reset --hard c5 && + git merge c6 + auto_count=$(conflict_count) && + test $auto_count = $recursive_count && + test $auto_count != $resolve_count +' + +test_expect_success 'merge errors out on invalid strategy' ' + git config pull.twohead "foobar" && + git reset --hard c5 && + test_must_fail git merge c6 +' + +test_expect_success 'merge errors out on invalid strategy' ' + git config --unset-all pull.twohead && + git reset --hard c5 && + test_must_fail git merge -s "resolve recursive" c6 +' + +test_done diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh new file mode 100755 index 0000000000..fcb8285746 --- /dev/null +++ b/t/t7602-merge-octopus-many.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +test_description='git-merge + +Testing octopus merge with more than 25 refs.' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo c0 > c0.c && + git add c0.c && + git commit -m c0 && + git tag c0 && + i=1 && + while test $i -le 30 + do + git reset --hard c0 && + echo c$i > c$i.c && + git add c$i.c && + git commit -m c$i && + git tag c$i && + i=`expr $i + 1` || return 1 + done +' + +test_expect_success 'merge c1 with c2, c3, c4, ... c29' ' + git reset --hard c1 && + i=2 && + refs="" && + while test $i -le 30 + do + refs="$refs c$i" + i=`expr $i + 1` + done + git merge $refs && + test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" && + i=1 && + while test $i -le 30 + do + test "$(git rev-parse c$i)" = "$(git rev-parse HEAD^$i)" && + i=`expr $i + 1` || return 1 + done && + git diff --exit-code && + i=1 && + while test $i -le 30 + do + test -f c$i.c && + i=`expr $i + 1` || return 1 + done +' + +test_done diff --git a/t/t7603-merge-reduce-heads.sh b/t/t7603-merge-reduce-heads.sh new file mode 100755 index 0000000000..17b19dc11f --- /dev/null +++ b/t/t7603-merge-reduce-heads.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +test_description='git-merge + +Testing octopus merge when reducing parents to independent branches.' + +. ./test-lib.sh + +# 0 - 1 +# \ 2 +# \ 3 +# \ 4 - 5 +# +# So 1, 2, 3 and 5 should be kept, 4 should be avoided. + +test_expect_success 'setup' ' + echo c0 > c0.c && + git add c0.c && + git commit -m c0 && + git tag c0 && + echo c1 > c1.c && + git add c1.c && + git commit -m c1 && + git tag c1 && + git reset --hard c0 && + echo c2 > c2.c && + git add c2.c && + git commit -m c2 && + git tag c2 && + git reset --hard c0 && + echo c3 > c3.c && + git add c3.c && + git commit -m c3 && + git tag c3 && + git reset --hard c0 && + echo c4 > c4.c && + git add c4.c && + git commit -m c4 && + git tag c4 && + echo c5 > c5.c && + git add c5.c && + git commit -m c5 && + git tag c5 +' + +test_expect_success 'merge c1 with c2, c3, c4, c5' ' + git reset --hard c1 && + git merge c2 c3 c4 c5 && + test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" && + test "$(git rev-parse c1)" = "$(git rev-parse HEAD^1)" && + test "$(git rev-parse c2)" = "$(git rev-parse HEAD^2)" && + test "$(git rev-parse c3)" = "$(git rev-parse HEAD^3)" && + test "$(git rev-parse c5)" = "$(git rev-parse HEAD^4)" && + git diff --exit-code && + test -f c0.c && + test -f c1.c && + test -f c2.c && + test -f c3.c && + test -f c4.c && + test -f c5.c +' + +test_done diff --git a/t/t7604-merge-custom-message.sh b/t/t7604-merge-custom-message.sh new file mode 100755 index 0000000000..6081677d23 --- /dev/null +++ b/t/t7604-merge-custom-message.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +test_description='git-merge + +Testing merge when using a custom message for the merge commit.' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo c0 > c0.c && + git add c0.c && + git commit -m c0 && + git tag c0 && + echo c1 > c1.c && + git add c1.c && + git commit -m c1 && + git tag c1 && + git reset --hard c0 && + echo c2 > c2.c && + git add c2.c && + git commit -m c2 && + git tag c2 +' + +cat >expected <<\EOF +custom message + +Merge commit 'c2' +EOF +test_expect_success 'merge c2 with a custom message' ' + git reset --hard c1 && + git merge -m "custom message" c2 && + git cat-file commit HEAD | sed -e "1,/^$/d" > actual && + test_cmp expected actual +' + +test_done diff --git a/t/t7605-merge-resolve.sh b/t/t7605-merge-resolve.sh new file mode 100755 index 0000000000..ee21a107fd --- /dev/null +++ b/t/t7605-merge-resolve.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +test_description='git-merge + +Testing the resolve strategy.' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo c0 > c0.c && + git add c0.c && + git commit -m c0 && + git tag c0 && + echo c1 > c1.c && + git add c1.c && + git commit -m c1 && + git tag c1 && + git reset --hard c0 && + echo c2 > c2.c && + git add c2.c && + git commit -m c2 && + git tag c2 && + git reset --hard c0 && + echo c3 > c2.c && + git add c2.c && + git commit -m c3 && + git tag c3 +' + +test_expect_success 'merge c1 to c2' ' + git reset --hard c1 && + git merge -s resolve c2 && + test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" && + test "$(git rev-parse c1)" = "$(git rev-parse HEAD^1)" && + test "$(git rev-parse c2)" = "$(git rev-parse HEAD^2)" && + git diff --exit-code && + test -f c0.c && + test -f c1.c && + test -f c2.c +' + +test_expect_success 'merge c2 to c3 (fails)' ' + git reset --hard c2 && + test_must_fail git merge -s resolve c3 +' +test_done diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh new file mode 100755 index 0000000000..9285071c47 --- /dev/null +++ b/t/t7610-mergetool.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# +# Copyright (c) 2008 Charles Bailey +# + +test_description='git-mergetool + +Testing basic merge tool invocation' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo master >file1 && + git add file1 && + git commit -m "added file1" && + git checkout -b branch1 master && + echo branch1 change >file1 && + echo branch1 newfile >file2 && + git add file1 file2 && + git commit -m "branch1 changes" && + git checkout -b branch2 master && + echo branch2 change >file1 && + echo branch2 newfile >file2 && + git add file1 file2 && + git commit -m "branch2 changes" && + git checkout master && + echo master updated >file1 && + echo master new >file2 && + git add file1 file2 && + git commit -m "master updates" +' + +test_expect_success 'custom mergetool' ' + git config merge.tool mytool && + git config mergetool.mytool.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" && + git config mergetool.mytool.trustExitCode true && + git checkout branch1 && + test_must_fail git merge master >/dev/null 2>&1 && + ( yes "" | git mergetool file1>/dev/null 2>&1 ) && + ( yes "" | git mergetool file2>/dev/null 2>&1 ) && + test "$(cat file1)" = "master updated" && + test "$(cat file2)" = "master new" && + git commit -m "branch1 resolved with mergetool" +' + +test_done diff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh new file mode 100755 index 0000000000..31c340fd38 --- /dev/null +++ b/t/t7701-repack-unpack-unreachable.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +test_description='git-repack works correctly' + +. ./test-lib.sh + +fsha1= +csha1= +tsha1= + +test_expect_success '-A option leaves unreachable objects unpacked' ' + echo content > file1 && + git add . && + git commit -m initial_commit && + # create a transient branch with unique content + git checkout -b transient_branch && + echo more content >> file1 && + # record the objects created in the database for file, commit, tree + fsha1=$(git hash-object file1) && + git commit -a -m more_content && + csha1=$(git rev-parse HEAD^{commit}) && + tsha1=$(git rev-parse HEAD^{tree}) && + git checkout master && + echo even more content >> file1 && + git commit -a -m even_more_content && + # delete the transient branch + git branch -D transient_branch && + # pack the repo + git repack -A -d -l && + # verify objects are packed in repository + test 3 = $(git verify-pack -v -- .git/objects/pack/*.idx | + grep -e "^$fsha1 " -e "^$csha1 " -e "^$tsha1 " | + sort | uniq | wc -l) && + git show $fsha1 && + git show $csha1 && + git show $tsha1 && + # now expire the reflog + sleep 1 && + git reflog expire --expire-unreachable=now --all && + # and repack + git repack -A -d -l && + # verify objects are retained unpacked + test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx | + grep -e "^$fsha1 " -e "^$csha1 " -e "^$tsha1 " | + sort | uniq | wc -l) && + git show $fsha1 && + git show $csha1 && + git show $tsha1 +' + +compare_mtimes () +{ + perl -e 'my $reference = shift; + foreach my $file (@ARGV) { + exit(1) unless(-f $file && -M $file == -M $reference); + } + exit(0); + ' -- "$@" +} + +test_expect_success 'unpacked objects receive timestamp of pack file' ' + fsha1path=$(echo "$fsha1" | sed -e "s|\(..\)|\1/|") && + fsha1path=".git/objects/$fsha1path" && + csha1path=$(echo "$csha1" | sed -e "s|\(..\)|\1/|") && + csha1path=".git/objects/$csha1path" && + tsha1path=$(echo "$tsha1" | sed -e "s|\(..\)|\1/|") && + tsha1path=".git/objects/$tsha1path" && + git branch transient_branch $csha1 && + git repack -a -d -l && + test ! -f "$fsha1path" && + test ! -f "$csha1path" && + test ! -f "$tsha1path" && + test 1 = $(ls -1 .git/objects/pack/pack-*.pack | wc -l) && + packfile=$(ls .git/objects/pack/pack-*.pack) && + git branch -D transient_branch && + sleep 1 && + git repack -A -l && + compare_mtimes "$packfile" "$fsha1path" "$csha1path" "$tsha1path" +' + +test_done diff --git a/t/t8001-annotate.sh b/t/t8001-annotate.sh new file mode 100755 index 0000000000..eabec2e06e --- /dev/null +++ b/t/t8001-annotate.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +test_description='git annotate' +. ./test-lib.sh + +PROG='git annotate' +. ../annotate-tests.sh + +test_expect_success \ + 'Annotating an old revision works' \ + '[ $(git annotate file master | awk "{print \$3}" | grep -c "^A$") -eq 2 ] && \ + [ $(git annotate file master | awk "{print \$3}" | grep -c "^B$") -eq 2 ]' + + +test_done diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh new file mode 100755 index 0000000000..92ece30fa9 --- /dev/null +++ b/t/t8002-blame.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +test_description='git blame' +. ./test-lib.sh + +PROG='git blame -c' +. ../annotate-tests.sh + +test_done diff --git a/t/t8003-blame.sh b/t/t8003-blame.sh new file mode 100755 index 0000000000..966bb0a61a --- /dev/null +++ b/t/t8003-blame.sh @@ -0,0 +1,132 @@ +#!/bin/sh + +test_description='git blame corner cases' +. ./test-lib.sh + +pick_fc='s/^[0-9a-f^]* *\([^ ]*\) *(\([^ ]*\) .*/\1-\2/' + +test_expect_success setup ' + + echo A A A A A >one && + echo B B B B B >two && + echo C C C C C >tres && + echo ABC >mouse && + git add one two tres mouse && + test_tick && + GIT_AUTHOR_NAME=Initial git commit -m Initial && + + cat one >uno && + mv two dos && + cat one >>tres && + echo DEF >>mouse + git add uno dos tres mouse && + test_tick && + GIT_AUTHOR_NAME=Second git commit -a -m Second && + + echo GHIJK >>mouse && + git add mouse && + test_tick && + GIT_AUTHOR_NAME=Third git commit -m Third && + + cat mouse >cow && + git add cow && + test_tick && + GIT_AUTHOR_NAME=Fourth git commit -m Fourth && + + { + echo ABC + echo DEF + echo XXXX + echo GHIJK + } >cow && + git add cow && + test_tick && + GIT_AUTHOR_NAME=Fifth git commit -m Fifth +' + +test_expect_success 'straight copy without -C' ' + + git blame uno | grep Second + +' + +test_expect_success 'straight move without -C' ' + + git blame dos | grep Initial + +' + +test_expect_success 'straight copy with -C' ' + + git blame -C1 uno | grep Second + +' + +test_expect_success 'straight move with -C' ' + + git blame -C1 dos | grep Initial + +' + +test_expect_success 'straight copy with -C -C' ' + + git blame -C -C1 uno | grep Initial + +' + +test_expect_success 'straight move with -C -C' ' + + git blame -C -C1 dos | grep Initial + +' + +test_expect_success 'append without -C' ' + + git blame -L2 tres | grep Second + +' + +test_expect_success 'append with -C' ' + + git blame -L2 -C1 tres | grep Second + +' + +test_expect_success 'append with -C -C' ' + + git blame -L2 -C -C1 tres | grep Second + +' + +test_expect_success 'append with -C -C -C' ' + + git blame -L2 -C -C -C1 tres | grep Initial + +' + +test_expect_success 'blame wholesale copy' ' + + git blame -f -C -C1 HEAD^ -- cow | sed -e "$pick_fc" >current && + { + echo mouse-Initial + echo mouse-Second + echo mouse-Third + } >expected && + test_cmp expected current + +' + +test_expect_success 'blame wholesale copy and more' ' + + git blame -f -C -C1 HEAD -- cow | sed -e "$pick_fc" >current && + { + echo mouse-Initial + echo mouse-Second + echo cow-Fifth + echo mouse-Third + } >expected && + test_cmp expected current + +' + +test_done diff --git a/t/t8004-blame.sh b/t/t8004-blame.sh new file mode 100755 index 0000000000..ba19ac127e --- /dev/null +++ b/t/t8004-blame.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +# Based on a test case submitted by Björn Steinbrink. + +test_description='git blame on conflicted files' +. ./test-lib.sh + +test_expect_success 'setup first case' ' + # Create the old file + echo "Old line" > file1 && + git add file1 && + git commit --author "Old Line <ol@localhost>" -m file1.a && + + # Branch + git checkout -b foo && + + # Do an ugly move and change + git rm file1 && + echo "New line ..." > file2 && + echo "... and more" >> file2 && + git add file2 && + git commit --author "U Gly <ug@localhost>" -m ugly && + + # Back to master and change something + git checkout master && + echo " + +bla" >> file1 && + git commit --author "Old Line <ol@localhost>" -a -m file1.b && + + # Back to foo and merge master + git checkout foo && + if git merge master; then + echo needed conflict here + exit 1 + else + echo merge failed - resolving automatically + fi && + echo "New line ... +... and more + +bla +Even more" > file2 && + git rm file1 && + git commit --author "M Result <mr@localhost>" -a -m merged && + + # Back to master and change file1 again + git checkout master && + sed s/bla/foo/ <file1 >X && + rm file1 && + mv X file1 && + git commit --author "No Bla <nb@localhost>" -a -m replace && + + # Try to merge into foo again + git checkout foo && + if git merge master; then + echo needed conflict here + exit 1 + else + echo merge failed - test is setup + fi +' + +test_expect_success \ + 'blame runs on unconflicted file while other file has conflicts' ' + git blame file2 +' + +test_expect_success 'blame runs on conflicted file in stages 1,3' ' + git blame file1 +' + +test_done diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh new file mode 100755 index 0000000000..1c857cf4ab --- /dev/null +++ b/t/t9001-send-email.sh @@ -0,0 +1,295 @@ +#!/bin/sh + +test_description='git-send-email' +. ./test-lib.sh + +PROG='git send-email' +test_expect_success \ + 'prepare reference tree' \ + 'echo "1A quick brown fox jumps over the" >file && + echo "lazy dog" >>file && + git add file && + GIT_AUTHOR_NAME="A" git commit -a -m "Initial."' + +test_expect_success \ + 'Setup helper tool' \ + '(echo "#!$SHELL_PATH" + echo shift + echo output=1 + echo "while test -f commandline\$output; do output=\$((\$output+1)); done" + echo for a + echo do + echo " echo \"!\$a!\"" + echo "done >commandline\$output" + echo "cat > msgtxt\$output" + ) >fake.sendmail && + chmod +x ./fake.sendmail && + git add fake.sendmail && + GIT_AUTHOR_NAME="A" git commit -a -m "Second."' + +clean_fake_sendmail() { + rm -f commandline* msgtxt* +} + +test_expect_success 'Extract patches' ' + patches=`git format-patch -n HEAD^1` +' + +test_expect_success 'Send patches' ' + git send-email --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors +' + +cat >expected <<\EOF +!nobody@example.com! +!author@example.com! +EOF +test_expect_success \ + 'Verify commandline' \ + 'diff commandline1 expected' + +cat >expected-show-all-headers <<\EOF +0001-Second.patch +(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>' +Dry-OK. Log says: +Server: relay.example.com +MAIL FROM:<from@example.com> +RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<bcc@example.com> +From: Example <from@example.com> +To: to@example.com +Cc: cc@example.com, A <author@example.com> +Subject: [PATCH 1/1] Second. +Date: DATE-STRING +Message-Id: MESSAGE-ID-STRING +X-Mailer: X-MAILER-STRING +In-Reply-To: <unique-message-id@example.com> +References: <unique-message-id@example.com> + +Result: OK +EOF + +test_expect_success 'Show all headers' ' + git send-email \ + --dry-run \ + --from="Example <from@example.com>" \ + --to=to@example.com \ + --cc=cc@example.com \ + --bcc=bcc@example.com \ + --in-reply-to="<unique-message-id@example.com>" \ + --smtp-server relay.example.com \ + $patches | + sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \ + -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \ + -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \ + >actual-show-all-headers && + test_cmp expected-show-all-headers actual-show-all-headers +' + +z8=zzzzzzzz +z64=$z8$z8$z8$z8$z8$z8$z8$z8 +z512=$z64$z64$z64$z64$z64$z64$z64$z64 +test_expect_success 'reject long lines' ' + clean_fake_sendmail && + cp $patches longline.patch && + echo $z512$z512 >>longline.patch && + test_must_fail git send-email \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches longline.patch \ + 2>errors && + grep longline.patch errors +' + +test_expect_success 'no patch was sent' ' + ! test -e commandline1 +' + +test_expect_success 'allow long lines with --no-validate' ' + git send-email \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + --no-validate \ + $patches longline.patch \ + 2>errors +' + +test_expect_success 'Invalid In-Reply-To' ' + clean_fake_sendmail && + git send-email \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --in-reply-to=" " \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches + 2>errors + ! grep "^In-Reply-To: < *>" msgtxt1 +' + +test_expect_success 'Valid In-Reply-To when prompting' ' + clean_fake_sendmail && + (echo "From Example <from@example.com>" + echo "To Example <to@example.com>" + echo "" + ) | env GIT_SEND_EMAIL_NOTTY=1 git send-email \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches 2>errors && + ! grep "^In-Reply-To: < *>" msgtxt1 +' + +test_expect_success 'setup fake editor' ' + (echo "#!$SHELL_PATH" && + echo "echo fake edit >>\"\$1\"" + ) >fake-editor && + chmod +x fake-editor +' + +test_set_editor "$(pwd)/fake-editor" + +test_expect_success '--compose works' ' + clean_fake_sendmail && + echo y | \ + GIT_SEND_EMAIL_NOTTY=1 \ + git send-email \ + --compose --subject foo \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches \ + 2>errors +' + +test_expect_success 'first message is compose text' ' + grep "^fake edit" msgtxt1 +' + +test_expect_success 'second message is patch' ' + grep "Subject:.*Second" msgtxt2 +' + +cat >expected-show-all-headers <<\EOF +0001-Second.patch +(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>' +Dry-OK. Log says: +Server: relay.example.com +MAIL FROM:<from@example.com> +RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com> +From: Example <from@example.com> +To: to@example.com +Cc: cc@example.com, A <author@example.com> +Subject: [PATCH 1/1] Second. +Date: DATE-STRING +Message-Id: MESSAGE-ID-STRING +X-Mailer: X-MAILER-STRING + +Result: OK +EOF + +test_expect_success 'sendemail.cc set' ' + git config sendemail.cc cc@example.com && + git send-email \ + --dry-run \ + --from="Example <from@example.com>" \ + --to=to@example.com \ + --smtp-server relay.example.com \ + $patches | + sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \ + -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \ + -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \ + >actual-show-all-headers && + test_cmp expected-show-all-headers actual-show-all-headers +' + +cat >expected-show-all-headers <<\EOF +0001-Second.patch +(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>' +Dry-OK. Log says: +Server: relay.example.com +MAIL FROM:<from@example.com> +RCPT TO:<to@example.com>,<author@example.com> +From: Example <from@example.com> +To: to@example.com +Cc: A <author@example.com> +Subject: [PATCH 1/1] Second. +Date: DATE-STRING +Message-Id: MESSAGE-ID-STRING +X-Mailer: X-MAILER-STRING + +Result: OK +EOF + +test_expect_success 'sendemail.cc unset' ' + git config --unset sendemail.cc && + git send-email \ + --dry-run \ + --from="Example <from@example.com>" \ + --to=to@example.com \ + --smtp-server relay.example.com \ + $patches | + sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \ + -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \ + -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \ + >actual-show-all-headers && + test_cmp expected-show-all-headers actual-show-all-headers +' + +test_expect_success '--compose adds MIME for utf8 body' ' + clean_fake_sendmail && + (echo "#!$SHELL_PATH" && + echo "echo utf8 body: à éìöú >>\"\$1\"" + ) >fake-editor-utf8 && + chmod +x fake-editor-utf8 && + echo y | \ + GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \ + GIT_SEND_EMAIL_NOTTY=1 \ + git send-email \ + --compose --subject foo \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches && + grep "^utf8 body" msgtxt1 && + grep "^Content-Type: text/plain; charset=utf-8" msgtxt1 +' + +test_expect_success '--compose respects user mime type' ' + clean_fake_sendmail && + (echo "#!$SHELL_PATH" && + echo "(echo MIME-Version: 1.0" + echo " echo Content-Type: text/plain\\; charset=iso-8859-1" + echo " echo Content-Transfer-Encoding: 8bit" + echo " echo Subject: foo" + echo " echo " + echo " echo utf8 body: à éìöú) >\"\$1\"" + ) >fake-editor-utf8-mime && + chmod +x fake-editor-utf8-mime && + echo y | \ + GIT_EDITOR="\"$(pwd)/fake-editor-utf8-mime\"" \ + GIT_SEND_EMAIL_NOTTY=1 \ + git send-email \ + --compose --subject foo \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches && + grep "^utf8 body" msgtxt1 && + grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 && + ! grep "^Content-Type: text/plain; charset=utf-8" msgtxt1 +' + +test_expect_success '--compose adds MIME for utf8 subject' ' + clean_fake_sendmail && + echo y | \ + GIT_EDITOR="\"$(pwd)/fake-editor\"" \ + GIT_SEND_EMAIL_NOTTY=1 \ + git send-email \ + --compose --subject utf8-sübjëct \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches && + grep "^fake edit" msgtxt1 && + grep "^Subject: =?utf-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1 +' + +test_done diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh new file mode 100755 index 0000000000..843a5013b9 --- /dev/null +++ b/t/t9100-git-svn-basic.sh @@ -0,0 +1,268 @@ +#!/bin/sh +# +# Copyright (c) 2006 Eric Wong +# + +test_description='git-svn basic tests' +GIT_SVN_LC_ALL=${LC_ALL:-$LANG} + +case "$GIT_SVN_LC_ALL" in +*.UTF-8) + have_utf8=t + ;; +*) + have_utf8= + ;; +esac + +. ./lib-git-svn.sh + +say 'define NO_SVN_TESTS to skip git-svn tests' + +test_expect_success \ + 'initialize git-svn' ' + mkdir import && + cd import && + echo foo > foo && + ln -s foo foo.link + mkdir -p dir/a/b/c/d/e && + echo "deep dir" > dir/a/b/c/d/e/file && + mkdir bar && + echo "zzz" > bar/zzz && + echo "#!/bin/sh" > exec.sh && + chmod +x exec.sh && + svn import -m "import for git-svn" . "$svnrepo" >/dev/null && + cd .. && + rm -rf import && + git-svn init "$svnrepo"' + +test_expect_success \ + 'import an SVN revision into git' \ + 'git-svn fetch' + +test_expect_success "checkout from svn" 'svn co "$svnrepo" "$SVN_TREE"' + +name='try a deep --rmdir with a commit' +test_expect_success "$name" ' + git checkout -f -b mybranch remotes/git-svn && + mv dir/a/b/c/d/e/file dir/file && + cp dir/file file && + git update-index --add --remove dir/a/b/c/d/e/file dir/file file && + git commit -m "$name" && + git-svn set-tree --find-copies-harder --rmdir \ + remotes/git-svn..mybranch && + svn up "$SVN_TREE" && + test -d "$SVN_TREE"/dir && test ! -d "$SVN_TREE"/dir/a' + + +name='detect node change from file to directory #1' +test_expect_success "$name" " + mkdir dir/new_file && + mv dir/file dir/new_file/file && + mv dir/new_file dir/file && + git update-index --remove dir/file && + git update-index --add dir/file/file && + git commit -m '$name' && + test_must_fail git-svn set-tree --find-copies-harder --rmdir \ + remotes/git-svn..mybranch" || true + + +name='detect node change from directory to file #1' +test_expect_success "$name" ' + rm -rf dir "$GIT_DIR"/index && + git checkout -f -b mybranch2 remotes/git-svn && + mv bar/zzz zzz && + rm -rf bar && + mv zzz bar && + git update-index --remove -- bar/zzz && + git update-index --add -- bar && + git commit -m "$name" && + test_must_fail git-svn set-tree --find-copies-harder --rmdir \ + remotes/git-svn..mybranch2' || true + + +name='detect node change from file to directory #2' +test_expect_success "$name" ' + rm -f "$GIT_DIR"/index && + git checkout -f -b mybranch3 remotes/git-svn && + rm bar/zzz && + git update-index --remove bar/zzz && + mkdir bar/zzz && + echo yyy > bar/zzz/yyy && + git update-index --add bar/zzz/yyy && + git commit -m "$name" && + test_must_fail git-svn set-tree --find-copies-harder --rmdir \ + remotes/git-svn..mybranch3' || true + + +name='detect node change from directory to file #2' +test_expect_success "$name" ' + rm -f "$GIT_DIR"/index && + git checkout -f -b mybranch4 remotes/git-svn && + rm -rf dir && + git update-index --remove -- dir/file && + touch dir && + echo asdf > dir && + git update-index --add -- dir && + git commit -m "$name" && + test_must_fail git-svn set-tree --find-copies-harder --rmdir \ + remotes/git-svn..mybranch4' || true + + +name='remove executable bit from a file' +test_expect_success "$name" ' + rm -f "$GIT_DIR"/index && + git checkout -f -b mybranch5 remotes/git-svn && + chmod -x exec.sh && + git update-index exec.sh && + git commit -m "$name" && + git-svn set-tree --find-copies-harder --rmdir \ + remotes/git-svn..mybranch5 && + svn up "$SVN_TREE" && + test ! -x "$SVN_TREE"/exec.sh' + + +name='add executable bit back file' +test_expect_success "$name" ' + chmod +x exec.sh && + git update-index exec.sh && + git commit -m "$name" && + git-svn set-tree --find-copies-harder --rmdir \ + remotes/git-svn..mybranch5 && + svn up "$SVN_TREE" && + test -x "$SVN_TREE"/exec.sh' + + +name='executable file becomes a symlink to bar/zzz (file)' +test_expect_success "$name" ' + rm exec.sh && + ln -s bar/zzz exec.sh && + git update-index exec.sh && + git commit -m "$name" && + git-svn set-tree --find-copies-harder --rmdir \ + remotes/git-svn..mybranch5 && + svn up "$SVN_TREE" && + test -L "$SVN_TREE"/exec.sh' + +name='new symlink is added to a file that was also just made executable' + +test_expect_success "$name" ' + chmod +x bar/zzz && + ln -s bar/zzz exec-2.sh && + git update-index --add bar/zzz exec-2.sh && + git commit -m "$name" && + git-svn set-tree --find-copies-harder --rmdir \ + remotes/git-svn..mybranch5 && + svn up "$SVN_TREE" && + test -x "$SVN_TREE"/bar/zzz && + test -L "$SVN_TREE"/exec-2.sh' + +name='modify a symlink to become a file' +test_expect_success "$name" ' + echo git help > help || true && + rm exec-2.sh && + cp help exec-2.sh && + git update-index exec-2.sh && + git commit -m "$name" && + git-svn set-tree --find-copies-harder --rmdir \ + remotes/git-svn..mybranch5 && + svn up "$SVN_TREE" && + test -f "$SVN_TREE"/exec-2.sh && + test ! -L "$SVN_TREE"/exec-2.sh && + test_cmp help "$SVN_TREE"/exec-2.sh' + +if test "$have_utf8" = t +then + name="commit with UTF-8 message: locale: $GIT_SVN_LC_ALL" + LC_ALL="$GIT_SVN_LC_ALL" + export LC_ALL + test_expect_success "$name" " + echo '# hello' >> exec-2.sh && + git update-index exec-2.sh && + git commit -m 'éïâˆ' && + git-svn set-tree HEAD" + unset LC_ALL +else + say "UTF-8 locale not set, test skipped ($GIT_SVN_LC_ALL)" +fi + +name='test fetch functionality (svn => git) with alternate GIT_SVN_ID' +GIT_SVN_ID=alt +export GIT_SVN_ID +test_expect_success "$name" \ + 'git-svn init "$svnrepo" && git-svn fetch && + git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a && + git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b && + test_cmp a b' + +name='check imported tree checksums expected tree checksums' +rm -f expected +if test "$have_utf8" = t +then + echo tree bf522353586b1b883488f2bc73dab0d9f774b9a9 > expected +fi +cat >> expected <<\EOF +tree 83654bb36f019ae4fe77a0171f81075972087624 +tree 031b8d557afc6fea52894eaebb45bec52f1ba6d1 +tree 0b094cbff17168f24c302e297f55bfac65eb8bd3 +tree d667270a1f7b109f5eb3aaea21ede14b56bfdd6e +tree 56a30b966619b863674f5978696f4a3594f2fca9 +tree d667270a1f7b109f5eb3aaea21ede14b56bfdd6e +tree 8f51f74cf0163afc9ad68a4b1537288c4558b5a4 +EOF + +test_expect_success "$name" "test_cmp a expected" + +test_expect_success 'exit if remote refs are ambigious' " + git config --add svn-remote.svn.fetch \ + bar:refs/remotes/git-svn && + test_must_fail git-svn migrate +" + +test_expect_success 'exit if init-ing a would clobber a URL' ' + svnadmin create "${PWD}/svnrepo2" && + svn mkdir -m "mkdir bar" "${svnrepo}2/bar" && + git config --unset svn-remote.svn.fetch \ + "^bar:refs/remotes/git-svn$" && + test_must_fail git-svn init "${svnrepo}2/bar" + ' + +test_expect_success \ + 'init allows us to connect to another directory in the same repo' ' + git-svn init --minimize-url -i bar "$svnrepo/bar" && + git config --get svn-remote.svn.fetch \ + "^bar:refs/remotes/bar$" && + git config --get svn-remote.svn.fetch \ + "^:refs/remotes/git-svn$" + ' + +test_expect_success 'able to dcommit to a subdirectory' " + git-svn fetch -i bar && + git checkout -b my-bar refs/remotes/bar && + echo abc > d && + git update-index --add d && + git commit -m '/bar/d should be in the log' && + git-svn dcommit -i bar && + test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\" && + mkdir newdir && + echo new > newdir/dir && + git update-index --add newdir/dir && + git commit -m 'add a new directory' && + git-svn dcommit -i bar && + test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\" && + echo foo >> newdir/dir && + git update-index newdir/dir && + git commit -m 'modify a file in new directory' && + git-svn dcommit -i bar && + test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\" + " + +test_expect_success 'able to set-tree to a subdirectory' " + echo cba > d && + git update-index d && + git commit -m 'update /bar/d' && + git-svn set-tree -i bar HEAD && + test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\" + " + +test_done diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh new file mode 100755 index 0000000000..f420796c31 --- /dev/null +++ b/t/t9101-git-svn-props.sh @@ -0,0 +1,217 @@ +#!/bin/sh +# +# Copyright (c) 2006 Eric Wong +# + +test_description='git-svn property tests' +. ./lib-git-svn.sh + +mkdir import + +a_crlf= +a_lf= +a_cr= +a_ne_crlf= +a_ne_lf= +a_ne_cr= +a_empty= +a_empty_lf= +a_empty_cr= +a_empty_crlf= + +cd import + cat >> kw.c <<\EOF +/* Somebody prematurely put a keyword into this file */ +/* $Id$ */ +EOF + + printf "Hello\r\nWorld\r\n" > crlf + a_crlf=`git-hash-object -w crlf` + printf "Hello\rWorld\r" > cr + a_cr=`git-hash-object -w cr` + printf "Hello\nWorld\n" > lf + a_lf=`git-hash-object -w lf` + + printf "Hello\r\nWorld" > ne_crlf + a_ne_crlf=`git-hash-object -w ne_crlf` + printf "Hello\nWorld" > ne_lf + a_ne_lf=`git-hash-object -w ne_lf` + printf "Hello\rWorld" > ne_cr + a_ne_cr=`git-hash-object -w ne_cr` + + touch empty + a_empty=`git-hash-object -w empty` + printf "\n" > empty_lf + a_empty_lf=`git-hash-object -w empty_lf` + printf "\r" > empty_cr + a_empty_cr=`git-hash-object -w empty_cr` + printf "\r\n" > empty_crlf + a_empty_crlf=`git-hash-object -w empty_crlf` + + svn import --no-auto-props -m 'import for git-svn' . "$svnrepo" >/dev/null +cd .. + +rm -rf import +test_expect_success 'checkout working copy from svn' 'svn co "$svnrepo" test_wc' +test_expect_success 'setup some commits to svn' \ + 'cd test_wc && + echo Greetings >> kw.c && + poke kw.c && + svn commit -m "Not yet an Id" && + echo Hello world >> kw.c && + poke kw.c && + svn commit -m "Modified file, but still not yet an Id" && + svn propset svn:keywords Id kw.c && + poke kw.c && + svn commit -m "Propset Id" && + cd ..' + +test_expect_success 'initialize git-svn' 'git-svn init "$svnrepo"' +test_expect_success 'fetch revisions from svn' 'git-svn fetch' + +name='test svn:keywords ignoring' +test_expect_success "$name" \ + 'git checkout -b mybranch remotes/git-svn && + echo Hi again >> kw.c && + git commit -a -m "test keywords ignoring" && + git-svn set-tree remotes/git-svn..mybranch && + git pull . remotes/git-svn' + +expect='/* $Id$ */' +got="`sed -ne 2p kw.c`" +test_expect_success 'raw $Id$ found in kw.c' "test '$expect' = '$got'" + +test_expect_success "propset CR on crlf files" \ + 'cd test_wc && + svn propset svn:eol-style CR empty && + svn propset svn:eol-style CR crlf && + svn propset svn:eol-style CR ne_crlf && + svn commit -m "propset CR on crlf files" && + cd ..' + +test_expect_success 'fetch and pull latest from svn and checkout a new wc' \ + 'git-svn fetch && + git pull . remotes/git-svn && + svn co "$svnrepo" new_wc' + +for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf +do + test_expect_success "Comparing $i" "cmp $i new_wc/$i" +done + + +cd test_wc + printf '$Id$\rHello\rWorld\r' > cr + printf '$Id$\rHello\rWorld' > ne_cr + a_cr=`printf '$Id$\r\nHello\r\nWorld\r\n' | git-hash-object --stdin` + a_ne_cr=`printf '$Id$\r\nHello\r\nWorld' | git-hash-object --stdin` + test_expect_success 'Set CRLF on cr files' \ + 'svn propset svn:eol-style CRLF cr && + svn propset svn:eol-style CRLF ne_cr && + svn propset svn:keywords Id cr && + svn propset svn:keywords Id ne_cr && + svn commit -m "propset CRLF on cr files"' +cd .. +test_expect_success 'fetch and pull latest from svn' \ + 'git-svn fetch && git pull . remotes/git-svn' + +b_cr="`git-hash-object cr`" +b_ne_cr="`git-hash-object ne_cr`" + +test_expect_success 'CRLF + $Id$' "test '$a_cr' = '$b_cr'" +test_expect_success 'CRLF + $Id$ (no newline)' "test '$a_ne_cr' = '$b_ne_cr'" + +cat > show-ignore.expect <<\EOF + +# / +/no-such-file* + +# /deeply/ +/deeply/no-such-file* + +# /deeply/nested/ +/deeply/nested/no-such-file* + +# /deeply/nested/directory/ +/deeply/nested/directory/no-such-file* +EOF + +test_expect_success 'test show-ignore' " + cd test_wc && + mkdir -p deeply/nested/directory && + touch deeply/nested/directory/.keep && + svn add deeply && + svn up && + svn propset -R svn:ignore 'no-such-file*' . + svn commit -m 'propset svn:ignore' + cd .. && + git-svn show-ignore > show-ignore.got && + cmp show-ignore.expect show-ignore.got + " + +cat >create-ignore.expect <<\EOF +/no-such-file* +EOF + +cat >create-ignore-index.expect <<\EOF +100644 8c52e5dfcd0a8b6b6bcfe6b41b89bcbf493718a5 0 .gitignore +100644 8c52e5dfcd0a8b6b6bcfe6b41b89bcbf493718a5 0 deeply/.gitignore +100644 8c52e5dfcd0a8b6b6bcfe6b41b89bcbf493718a5 0 deeply/nested/.gitignore +100644 8c52e5dfcd0a8b6b6bcfe6b41b89bcbf493718a5 0 deeply/nested/directory/.gitignore +EOF + +test_expect_success 'test create-ignore' " + git-svn fetch && git pull . remotes/git-svn && + git-svn create-ignore && + cmp ./.gitignore create-ignore.expect && + cmp ./deeply/.gitignore create-ignore.expect && + cmp ./deeply/nested/.gitignore create-ignore.expect && + cmp ./deeply/nested/directory/.gitignore create-ignore.expect && + git ls-files -s | grep gitignore | cmp - create-ignore-index.expect + " + +cat >prop.expect <<\EOF +no-such-file* + +EOF +cat >prop2.expect <<\EOF +8 +EOF + +# This test can be improved: since all the svn:ignore contain the same +# pattern, it can pass even though the propget did not execute on the +# right directory. +test_expect_success 'test propget' " + git-svn propget svn:ignore . | cmp - prop.expect && + cd deeply && + git-svn propget svn:ignore . | cmp - ../prop.expect && + git-svn propget svn:entry:committed-rev nested/directory/.keep \ + | cmp - ../prop2.expect && + git-svn propget svn:ignore .. | cmp - ../prop.expect && + git-svn propget svn:ignore nested/ | cmp - ../prop.expect && + git-svn propget svn:ignore ./nested | cmp - ../prop.expect && + git-svn propget svn:ignore .././deeply/nested | cmp - ../prop.expect + " + +cat >prop.expect <<\EOF +Properties on '.': + svn:entry:committed-date + svn:entry:committed-rev + svn:entry:last-author + svn:entry:uuid + svn:ignore +EOF +cat >prop2.expect <<\EOF +Properties on 'nested/directory/.keep': + svn:entry:committed-date + svn:entry:committed-rev + svn:entry:last-author + svn:entry:uuid +EOF + +test_expect_success 'test proplist' " + git-svn proplist . | cmp - prop.expect && + git-svn proplist nested/directory/.keep | cmp - prop2.expect + " + +test_done diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh new file mode 100755 index 0000000000..0e7ce34b9b --- /dev/null +++ b/t/t9102-git-svn-deep-rmdir.sh @@ -0,0 +1,30 @@ +#!/bin/sh +test_description='git-svn rmdir' +. ./lib-git-svn.sh + +test_expect_success 'initialize repo' ' + mkdir import && + cd import && + mkdir -p deeply/nested/directory/number/1 && + mkdir -p deeply/nested/directory/number/2 && + echo foo > deeply/nested/directory/number/1/file && + echo foo > deeply/nested/directory/number/2/another && + svn import -m "import for git-svn" . "$svnrepo" && + cd .. + ' + +test_expect_success 'mirror via git-svn' ' + git-svn init "$svnrepo" && + git-svn fetch && + git checkout -f -b test-rmdir remotes/git-svn + ' + +test_expect_success 'Try a commit on rmdir' ' + git rm -f deeply/nested/directory/number/2/another && + git commit -a -m "remove another" && + git-svn set-tree --rmdir HEAD && + svn ls -R "$svnrepo" | grep ^deeply/nested/directory/number/1 + ' + + +test_done diff --git a/t/t9103-git-svn-tracked-directory-removed.sh b/t/t9103-git-svn-tracked-directory-removed.sh new file mode 100755 index 0000000000..9ffd8458ef --- /dev/null +++ b/t/t9103-git-svn-tracked-directory-removed.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# +# Copyright (c) 2007 Eric Wong +# + +test_description='git-svn tracking removed top-level path' +. ./lib-git-svn.sh + +test_expect_success 'make history for tracking' ' + mkdir import && + mkdir import/trunk && + echo hello >> import/trunk/README && + svn import -m initial import "$svnrepo" && + rm -rf import && + svn co "$svnrepo"/trunk trunk && + echo bye bye >> trunk/README && + svn rm -m "gone" "$svnrepo"/trunk && + rm -rf trunk && + mkdir trunk && + echo "new" > trunk/FOLLOWME && + svn import -m "new trunk" trunk "$svnrepo"/trunk +' + +test_expect_success 'clone repo with git' ' + git svn clone -s "$svnrepo" x && + test -f x/FOLLOWME && + test ! -f x/README +' + +test_expect_success 'make sure r2 still has old file' " + cd x && + test -n \"\$(git svn find-rev r1)\" && + git reset --hard \$(git svn find-rev r1) && + test -f README && + test ! -f FOLLOWME && + test x\$(git svn find-rev r2) = x +" + +test_done diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh new file mode 100755 index 0000000000..4d964e2db7 --- /dev/null +++ b/t/t9104-git-svn-follow-parent.sh @@ -0,0 +1,171 @@ +#!/bin/sh +# +# Copyright (c) 2006 Eric Wong +# + +test_description='git-svn fetching' +. ./lib-git-svn.sh + +test_expect_success 'initialize repo' ' + mkdir import && + cd import && + mkdir -p trunk && + echo hello > trunk/readme && + svn import -m "initial" . "$svnrepo" && + cd .. && + svn co "$svnrepo" wc && + cd wc && + echo world >> trunk/readme && + poke trunk/readme && + svn commit -m "another commit" && + svn up && + svn mv trunk thunk && + echo goodbye >> thunk/readme && + poke thunk/readme && + svn commit -m "bye now" && + cd .. + ' + +test_expect_success 'init and fetch a moved directory' ' + git-svn init --minimize-url -i thunk "$svnrepo"/thunk && + git-svn fetch -i thunk && + test "`git rev-parse --verify refs/remotes/thunk@2`" \ + = "`git rev-parse --verify refs/remotes/thunk~1`" && + test "`git cat-file blob refs/remotes/thunk:readme |\ + sed -n -e "3p"`" = goodbye && + test -z "`git config --get svn-remote.svn.fetch \ + "^trunk:refs/remotes/thunk@2$"`" + ' + +test_expect_success 'init and fetch from one svn-remote' ' + git config svn-remote.svn.url "$svnrepo" && + git config --add svn-remote.svn.fetch \ + trunk:refs/remotes/svn/trunk && + git config --add svn-remote.svn.fetch \ + thunk:refs/remotes/svn/thunk && + git-svn fetch -i svn/thunk && + test "`git rev-parse --verify refs/remotes/svn/trunk`" \ + = "`git rev-parse --verify refs/remotes/svn/thunk~1`" && + test "`git cat-file blob refs/remotes/svn/thunk:readme |\ + sed -n -e "3p"`" = goodbye + ' + +test_expect_success 'follow deleted parent' ' + (svn cp -m "resurrecting trunk as junk" \ + "$svnrepo"/trunk@2 "$svnrepo"/junk || + svn cp -m "resurrecting trunk as junk" \ + -r2 "$svnrepo"/trunk "$svnrepo"/junk) && + git config --add svn-remote.svn.fetch \ + junk:refs/remotes/svn/junk && + git-svn fetch -i svn/thunk && + git-svn fetch -i svn/junk && + test -z "`git diff svn/junk svn/trunk`" && + test "`git merge-base svn/junk svn/trunk`" \ + = "`git rev-parse svn/trunk`" + ' + +test_expect_success 'follow larger parent' ' + mkdir -p import/trunk/thunk/bump/thud && + echo hi > import/trunk/thunk/bump/thud/file && + svn import -m "import a larger parent" import "$svnrepo"/larger-parent && + svn cp -m "hi" "$svnrepo"/larger-parent "$svnrepo"/another-larger && + git-svn init --minimize-url -i larger \ + "$svnrepo"/another-larger/trunk/thunk/bump/thud && + git-svn fetch -i larger && + git rev-parse --verify refs/remotes/larger && + git rev-parse --verify \ + refs/remotes/larger-parent/trunk/thunk/bump/thud && + test "`git merge-base \ + refs/remotes/larger-parent/trunk/thunk/bump/thud \ + refs/remotes/larger`" = \ + "`git rev-parse refs/remotes/larger`" + true + ' + +test_expect_success 'follow higher-level parent' ' + svn mkdir -m "follow higher-level parent" "$svnrepo"/blob && + svn co "$svnrepo"/blob blob && + cd blob && + echo hi > hi && + svn add hi && + svn commit -m "hihi" && + cd .. + svn mkdir -m "new glob at top level" "$svnrepo"/glob && + svn mv -m "move blob down a level" "$svnrepo"/blob "$svnrepo"/glob/blob && + git-svn init --minimize-url -i blob "$svnrepo"/glob/blob && + git-svn fetch -i blob + ' + +test_expect_success 'follow deleted directory' ' + svn mv -m "bye!" "$svnrepo"/glob/blob/hi "$svnrepo"/glob/blob/bye && + svn rm -m "remove glob" "$svnrepo"/glob && + git-svn init --minimize-url -i glob "$svnrepo"/glob && + git-svn fetch -i glob && + test "`git cat-file blob refs/remotes/glob:blob/bye`" = hi && + test "`git ls-tree refs/remotes/glob | wc -l `" -eq 1 + ' + +# ref: r9270 of the Subversion repository: (http://svn.collab.net/repos/svn) +# in trunk/subversion/bindings/swig/perl +test_expect_success 'follow-parent avoids deleting relevant info' ' + mkdir -p import/trunk/subversion/bindings/swig/perl/t && + for i in a b c ; do \ + echo $i > import/trunk/subversion/bindings/swig/perl/$i.pm && + echo _$i > import/trunk/subversion/bindings/swig/perl/t/$i.t; \ + done && + echo "bad delete test" > \ + import/trunk/subversion/bindings/swig/perl/t/larger-parent && + echo "bad delete test 2" > \ + import/trunk/subversion/bindings/swig/perl/another-larger && + cd import && + svn import -m "r9270 test" . "$svnrepo"/r9270 && + cd .. && + svn co "$svnrepo"/r9270/trunk/subversion/bindings/swig/perl r9270 && + cd r9270 && + svn mkdir native && + svn mv t native/t && + for i in a b c; do svn mv $i.pm native/$i.pm; done && + echo z >> native/t/c.t && + poke native/t/c.t && + svn commit -m "reorg test" && + cd .. && + git-svn init --minimize-url -i r9270-t \ + "$svnrepo"/r9270/trunk/subversion/bindings/swig/perl/native/t && + git-svn fetch -i r9270-t && + test `git rev-list r9270-t | wc -l` -eq 2 && + test "`git ls-tree --name-only r9270-t~1`" = \ + "`git ls-tree --name-only r9270-t`" + ' + +test_expect_success "track initial change if it was only made to parent" ' + svn cp -m "wheee!" "$svnrepo"/r9270/trunk "$svnrepo"/r9270/drunk && + git-svn init --minimize-url -i r9270-d \ + "$svnrepo"/r9270/drunk/subversion/bindings/swig/perl/native/t && + git-svn fetch -i r9270-d && + test `git rev-list r9270-d | wc -l` -eq 3 && + test "`git ls-tree --name-only r9270-t`" = \ + "`git ls-tree --name-only r9270-d`" && + test "`git rev-parse r9270-t`" = \ + "`git rev-parse r9270-d~1`" + ' + +test_expect_success "track multi-parent paths" ' + svn cp -m "resurrect /glob" "$svnrepo"/r9270 "$svnrepo"/glob && + git-svn multi-fetch && + test `git cat-file commit refs/remotes/glob | \ + grep "^parent " | wc -l` -eq 2 + ' + +test_expect_success "multi-fetch continues to work" " + git-svn multi-fetch + " + +test_expect_success "multi-fetch works off a 'clean' repository" ' + rm -r "$GIT_DIR/svn" "$GIT_DIR/refs/remotes" "$GIT_DIR/logs" && + mkdir "$GIT_DIR/svn" && + git-svn multi-fetch + ' + +test_debug 'gitk --all &' + +test_done diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh new file mode 100755 index 0000000000..63230367bb --- /dev/null +++ b/t/t9105-git-svn-commit-diff.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# +# Copyright (c) 2006 Eric Wong +test_description='git-svn commit-diff' +. ./lib-git-svn.sh + +test_expect_success 'initialize repo' ' + mkdir import && + cd import && + echo hello > readme && + svn import -m "initial" . "$svnrepo" && + cd .. && + echo hello > readme && + git update-index --add readme && + git commit -a -m "initial" && + echo world >> readme && + git commit -a -m "another" + ' + +head=`git rev-parse --verify HEAD^0` +prev=`git rev-parse --verify HEAD^1` + +# the internals of the commit-diff command are the same as the regular +# commit, so only a basic test of functionality is needed since we've +# already tested commit extensively elsewhere + +test_expect_success 'test the commit-diff command' ' + test -n "$prev" && test -n "$head" && + git-svn commit-diff -r1 "$prev" "$head" "$svnrepo" && + svn co "$svnrepo" wc && + cmp readme wc/readme + ' + +test_expect_success 'commit-diff to a sub-directory (with git-svn config)' ' + svn import -m "sub-directory" import "$svnrepo"/subdir && + git-svn init --minimize-url "$svnrepo"/subdir && + git-svn fetch && + git-svn commit-diff -r3 "$prev" "$head" && + svn cat "$svnrepo"/subdir/readme > readme.2 && + cmp readme readme.2 + ' + +test_done diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh new file mode 100755 index 0000000000..83896e9687 --- /dev/null +++ b/t/t9106-git-svn-commit-diff-clobber.sh @@ -0,0 +1,101 @@ +#!/bin/sh +# +# Copyright (c) 2006 Eric Wong +test_description='git-svn commit-diff clobber' +. ./lib-git-svn.sh + +test_expect_success 'initialize repo' ' + mkdir import && + cd import && + echo initial > file && + svn import -m "initial" . "$svnrepo" && + cd .. && + echo initial > file && + git update-index --add file && + git commit -a -m "initial" + ' +test_expect_success 'commit change from svn side' ' + svn co "$svnrepo" t.svn && + cd t.svn && + echo second line from svn >> file && + poke file && + svn commit -m "second line from svn" && + cd .. && + rm -rf t.svn + ' + +test_expect_success 'commit conflicting change from git' ' + echo second line from git >> file && + git commit -a -m "second line from git" && + test_must_fail git-svn commit-diff -r1 HEAD~1 HEAD "$svnrepo" +' + +test_expect_success 'commit complementing change from git' ' + git reset --hard HEAD~1 && + echo second line from svn >> file && + git commit -a -m "second line from svn" && + echo third line from git >> file && + git commit -a -m "third line from git" && + git-svn commit-diff -r2 HEAD~1 HEAD "$svnrepo" + ' + +test_expect_success 'dcommit fails to commit because of conflict' ' + git-svn init "$svnrepo" && + git-svn fetch && + git reset --hard refs/remotes/git-svn && + svn co "$svnrepo" t.svn && + cd t.svn && + echo fourth line from svn >> file && + poke file && + svn commit -m "fourth line from svn" && + cd .. && + rm -rf t.svn && + echo "fourth line from git" >> file && + git commit -a -m "fourth line from git" && + test_must_fail git-svn dcommit + ' + +test_expect_success 'dcommit does the svn equivalent of an index merge' " + git reset --hard refs/remotes/git-svn && + echo 'index merge' > file2 && + git update-index --add file2 && + git commit -a -m 'index merge' && + echo 'more changes' >> file2 && + git update-index file2 && + git commit -a -m 'more changes' && + git-svn dcommit + " + +test_expect_success 'commit another change from svn side' ' + svn co "$svnrepo" t.svn && + cd t.svn && + echo third line from svn >> file && + poke file && + svn commit -m "third line from svn" && + cd .. && + rm -rf t.svn + ' + +test_expect_success 'multiple dcommit from git-svn will not clobber svn' " + git reset --hard refs/remotes/git-svn && + echo new file >> new-file && + git update-index --add new-file && + git commit -a -m 'new file' && + echo clobber > file && + git commit -a -m 'clobber' && + test_must_fail git svn dcommit + " + + +test_expect_success 'check that rebase really failed' ' + test -d .git/rebase-apply +' + +test_expect_success 'resolve, continue the rebase and dcommit' " + echo clobber and I really mean it > file && + git update-index file && + git rebase --continue && + git svn dcommit + " + +test_done diff --git a/t/t9106-git-svn-dcommit-clobber-series.sh b/t/t9106-git-svn-dcommit-clobber-series.sh new file mode 100755 index 0000000000..bc37db9d62 --- /dev/null +++ b/t/t9106-git-svn-dcommit-clobber-series.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# +# Copyright (c) 2007 Eric Wong +test_description='git-svn dcommit clobber series' +. ./lib-git-svn.sh + +test_expect_success 'initialize repo' ' + mkdir import && + cd import && + awk "BEGIN { for (i = 1; i < 64; i++) { print i } }" > file + svn import -m "initial" . "$svnrepo" && + cd .. && + git svn init "$svnrepo" && + git svn fetch && + test -e file + ' + +test_expect_success '(supposedly) non-conflicting change from SVN' ' + test x"`sed -n -e 58p < file`" = x58 && + test x"`sed -n -e 61p < file`" = x61 && + svn co "$svnrepo" tmp && + cd tmp && + perl -i.bak -p -e "s/^58$/5588/" file && + perl -i.bak -p -e "s/^61$/6611/" file && + poke file && + test x"`sed -n -e 58p < file`" = x5588 && + test x"`sed -n -e 61p < file`" = x6611 && + svn commit -m "58 => 5588, 61 => 6611" && + cd .. + ' + +test_expect_success 'some unrelated changes to git' " + echo hi > life && + git update-index --add life && + git commit -m hi-life && + echo bye >> life && + git commit -m bye-life life + " + +test_expect_success 'change file but in unrelated area' " + test x\"\`sed -n -e 4p < file\`\" = x4 && + test x\"\`sed -n -e 7p < file\`\" = x7 && + perl -i.bak -p -e 's/^4\$/4444/' file && + perl -i.bak -p -e 's/^7\$/7777/' file && + test x\"\`sed -n -e 4p < file\`\" = x4444 && + test x\"\`sed -n -e 7p < file\`\" = x7777 && + git commit -m '4 => 4444, 7 => 7777' file && + git svn dcommit && + svn up tmp && + cd tmp && + test x\"\`sed -n -e 4p < file\`\" = x4444 && + test x\"\`sed -n -e 7p < file\`\" = x7777 && + test x\"\`sed -n -e 58p < file\`\" = x5588 && + test x\"\`sed -n -e 61p < file\`\" = x6611 + " + +test_expect_success 'attempt to dcommit with a dirty index' ' + echo foo >>file && + git add file && + test_must_fail git svn dcommit +' + +test_done diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh new file mode 100755 index 0000000000..d9b553ad55 --- /dev/null +++ b/t/t9107-git-svn-migrate.sh @@ -0,0 +1,115 @@ +#!/bin/sh +# Copyright (c) 2006 Eric Wong +test_description='git-svn metadata migrations from previous versions' +. ./lib-git-svn.sh + +test_expect_success 'setup old-looking metadata' ' + cp "$GIT_DIR"/config "$GIT_DIR"/config-old-git-svn && + mkdir import && + cd import && + for i in trunk branches/a branches/b \ + tags/0.1 tags/0.2 tags/0.3; do + mkdir -p $i && \ + echo hello >> $i/README || exit 1 + done && \ + svn import -m test . "$svnrepo" + cd .. && + git-svn init "$svnrepo" && + git-svn fetch && + mv "$GIT_DIR"/svn/* "$GIT_DIR"/ && + mv "$GIT_DIR"/svn/.metadata "$GIT_DIR"/ && + rmdir "$GIT_DIR"/svn && + git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn && + git update-ref refs/heads/svn-HEAD refs/remotes/git-svn && + git update-ref -d refs/remotes/git-svn refs/remotes/git-svn + ' + +head=`git rev-parse --verify refs/heads/git-svn-HEAD^0` +test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'" + +test_expect_success 'initialize old-style (v0) git-svn layout' ' + mkdir -p "$GIT_DIR"/git-svn/info "$GIT_DIR"/svn/info && + echo "$svnrepo" > "$GIT_DIR"/git-svn/info/url && + echo "$svnrepo" > "$GIT_DIR"/svn/info/url && + git-svn migrate && + ! test -d "$GIT_DIR"/git-svn && + git rev-parse --verify refs/remotes/git-svn^0 && + git rev-parse --verify refs/remotes/svn^0 && + test "$(git config --get svn-remote.svn.url)" = "$svnrepo" && + test `git config --get svn-remote.svn.fetch` = \ + ":refs/remotes/git-svn" + ' + +test_expect_success 'initialize a multi-repository repo' ' + git-svn init "$svnrepo" -T trunk -t tags -b branches && + git config --get-all svn-remote.svn.fetch > fetch.out && + grep "^trunk:refs/remotes/trunk$" fetch.out && + test -n "`git config --get svn-remote.svn.branches \ + "^branches/\*:refs/remotes/\*$"`" && + test -n "`git config --get svn-remote.svn.tags \ + "^tags/\*:refs/remotes/tags/\*$"`" && + git config --unset svn-remote.svn.branches \ + "^branches/\*:refs/remotes/\*$" && + git config --unset svn-remote.svn.tags \ + "^tags/\*:refs/remotes/tags/\*$" && + git config --add svn-remote.svn.fetch "branches/a:refs/remotes/a" && + git config --add svn-remote.svn.fetch "branches/b:refs/remotes/b" && + for i in tags/0.1 tags/0.2 tags/0.3; do + git config --add svn-remote.svn.fetch \ + $i:refs/remotes/$i || exit 1; done + ' + +# refs should all be different, but the trees should all be the same: +test_expect_success 'multi-fetch works on partial urls + paths' " + git-svn multi-fetch && + for i in trunk a b tags/0.1 tags/0.2 tags/0.3; do + git rev-parse --verify refs/remotes/\$i^0 >> refs.out || exit 1; + done && + test -z \"\`sort < refs.out | uniq -d\`\" && + for i in trunk a b tags/0.1 tags/0.2 tags/0.3; do + for j in trunk a b tags/0.1 tags/0.2 tags/0.3; do + if test \$j != \$i; then continue; fi + test -z \"\`git diff refs/remotes/\$i \ + refs/remotes/\$j\`\" ||exit 1; done; done + " + +test_expect_success 'migrate --minimize on old inited layout' ' + git config --unset-all svn-remote.svn.fetch && + git config --unset-all svn-remote.svn.url && + rm -rf "$GIT_DIR"/svn && + for i in `cat fetch.out`; do + path=`expr $i : "\([^:]*\):.*$"` + ref=`expr $i : "[^:]*:refs/remotes/\(.*\)$"` + if test -z "$ref"; then continue; fi + if test -n "$path"; then path="/$path"; fi + ( mkdir -p "$GIT_DIR"/svn/$ref/info/ && + echo "$svnrepo"$path > "$GIT_DIR"/svn/$ref/info/url ) || exit 1; + done && + git-svn migrate --minimize && + test -z "`git config -l |grep -v "^svn-remote\.git-svn\."`" && + git config --get-all svn-remote.svn.fetch > fetch.out && + grep "^trunk:refs/remotes/trunk$" fetch.out && + grep "^branches/a:refs/remotes/a$" fetch.out && + grep "^branches/b:refs/remotes/b$" fetch.out && + grep "^tags/0\.1:refs/remotes/tags/0\.1$" fetch.out && + grep "^tags/0\.2:refs/remotes/tags/0\.2$" fetch.out && + grep "^tags/0\.3:refs/remotes/tags/0\.3$" fetch.out + grep "^:refs/remotes/git-svn" fetch.out + ' + +test_expect_success ".rev_db auto-converted to .rev_map.UUID" ' + git-svn fetch -i trunk && + test -z "$(ls "$GIT_DIR"/svn/trunk/.rev_db.* 2>/dev/null)" && + expect="$(ls "$GIT_DIR"/svn/trunk/.rev_map.*)" && + test -n "$expect" && + rev_db="$(echo $expect | sed -e "s,_map,_db,")" && + convert_to_rev_db "$expect" "$rev_db" && + rm -f "$expect" && + test -f "$rev_db" && + git-svn fetch -i trunk && + test -z "$(ls "$GIT_DIR"/svn/trunk/.rev_db.* 2>/dev/null)" && + test ! -e "$GIT_DIR"/svn/trunk/.rev_db && + test -f "$expect" + ' + +test_done diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh new file mode 100755 index 0000000000..8b792a1370 --- /dev/null +++ b/t/t9108-git-svn-glob.sh @@ -0,0 +1,111 @@ +#!/bin/sh +# Copyright (c) 2007 Eric Wong +test_description='git-svn globbing refspecs' +. ./lib-git-svn.sh + +cat > expect.end <<EOF +the end +hi +start a new branch +initial +EOF + +test_expect_success 'test refspec globbing' ' + mkdir -p trunk/src/a trunk/src/b trunk/doc && + echo "hello world" > trunk/src/a/readme && + echo "goodbye world" > trunk/src/b/readme && + svn import -m "initial" trunk "$svnrepo"/trunk && + svn co "$svnrepo" tmp && + ( + cd tmp && + mkdir branches tags && + svn add branches tags && + svn cp trunk branches/start && + svn commit -m "start a new branch" && + svn up && + echo "hi" >> branches/start/src/b/readme && + poke branches/start/src/b/readme && + echo "hey" >> branches/start/src/a/readme && + poke branches/start/src/a/readme && + svn commit -m "hi" && + svn up && + svn cp branches/start tags/end && + echo "bye" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + echo "aye" >> tags/end/src/a/readme && + poke tags/end/src/a/readme && + svn commit -m "the end" && + echo "byebye" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + svn commit -m "nothing to see here" + ) && + git config --add svn-remote.svn.url "$svnrepo" && + git config --add svn-remote.svn.fetch \ + "trunk/src/a:refs/remotes/trunk" && + git config --add svn-remote.svn.branches \ + "branches/*/src/a:refs/remotes/branches/*" && + git config --add svn-remote.svn.tags\ + "tags/*/src/a:refs/remotes/tags/*" && + git-svn multi-fetch && + git log --pretty=oneline refs/remotes/tags/end | \ + sed -e "s/^.\{41\}//" > output.end && + test_cmp expect.end output.end && + test "`git rev-parse refs/remotes/tags/end~1`" = \ + "`git rev-parse refs/remotes/branches/start`" && + test "`git rev-parse refs/remotes/branches/start~2`" = \ + "`git rev-parse refs/remotes/trunk`" && + test_must_fail git rev-parse refs/remotes/tags/end@3 + ' + +echo try to try > expect.two +echo nothing to see here >> expect.two +cat expect.end >> expect.two + +test_expect_success 'test left-hand-side only globbing' ' + git config --add svn-remote.two.url "$svnrepo" && + git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk && + git config --add svn-remote.two.branches \ + "branches/*:refs/remotes/two/branches/*" && + git config --add svn-remote.two.tags \ + "tags/*:refs/remotes/two/tags/*" && + ( + cd tmp && + echo "try try" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + svn commit -m "try to try" + ) && + git-svn fetch two && + test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 && + test `git rev-list refs/remotes/two/branches/start | wc -l` -eq 3 && + test `git rev-parse refs/remotes/two/branches/start~2` = \ + `git rev-parse refs/remotes/two/trunk` && + test `git rev-parse refs/remotes/two/tags/end~3` = \ + `git rev-parse refs/remotes/two/branches/start` && + git log --pretty=oneline refs/remotes/two/tags/end | \ + sed -e "s/^.\{41\}//" > output.two && + test_cmp expect.two output.two + ' + +echo "Only one set of wildcard directories" \ + "(e.g. '*' or '*/*/*') is supported: 'branches/*/t/*'" > expect.three +echo "" >> expect.three + +test_expect_success 'test disallow multi-globs' ' + git config --add svn-remote.three.url "$svnrepo" && + git config --add svn-remote.three.fetch \ + trunk:refs/remotes/three/trunk && + git config --add svn-remote.three.branches \ + "branches/*/t/*:refs/remotes/three/branches/*" && + git config --add svn-remote.three.tags \ + "tags/*/*:refs/remotes/three/tags/*" && + ( + cd tmp && + echo "try try" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + svn commit -m "try to try" + ) && + test_must_fail git-svn fetch three 2> stderr.three && + test_cmp expect.three stderr.three + ' + +test_done diff --git a/t/t9108-git-svn-multi-glob.sh b/t/t9108-git-svn-multi-glob.sh new file mode 100755 index 0000000000..3583721652 --- /dev/null +++ b/t/t9108-git-svn-multi-glob.sh @@ -0,0 +1,160 @@ +#!/bin/sh +# Copyright (c) 2007 Eric Wong +test_description='git-svn globbing refspecs' +. ./lib-git-svn.sh + +cat > expect.end <<EOF +the end +hi +start a new branch +initial +EOF + +test_expect_success 'test refspec globbing' ' + mkdir -p trunk/src/a trunk/src/b trunk/doc && + echo "hello world" > trunk/src/a/readme && + echo "goodbye world" > trunk/src/b/readme && + svn import -m "initial" trunk "$svnrepo"/trunk && + svn co "$svnrepo" tmp && + ( + cd tmp && + mkdir branches branches/v1 tags && + svn add branches tags && + svn cp trunk branches/v1/start && + svn commit -m "start a new branch" && + svn up && + echo "hi" >> branches/v1/start/src/b/readme && + poke branches/v1/start/src/b/readme && + echo "hey" >> branches/v1/start/src/a/readme && + poke branches/v1/start/src/a/readme && + svn commit -m "hi" && + svn up && + svn cp branches/v1/start tags/end && + echo "bye" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + echo "aye" >> tags/end/src/a/readme && + poke tags/end/src/a/readme && + svn commit -m "the end" && + echo "byebye" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + svn commit -m "nothing to see here" + ) && + git config --add svn-remote.svn.url "$svnrepo" && + git config --add svn-remote.svn.fetch \ + "trunk/src/a:refs/remotes/trunk" && + git config --add svn-remote.svn.branches \ + "branches/*/*/src/a:refs/remotes/branches/*/*" && + git config --add svn-remote.svn.tags\ + "tags/*/src/a:refs/remotes/tags/*" && + git-svn multi-fetch && + git log --pretty=oneline refs/remotes/tags/end | \ + sed -e "s/^.\{41\}//" > output.end && + test_cmp expect.end output.end && + test "`git rev-parse refs/remotes/tags/end~1`" = \ + "`git rev-parse refs/remotes/branches/v1/start`" && + test "`git rev-parse refs/remotes/branches/v1/start~2`" = \ + "`git rev-parse refs/remotes/trunk`" && + test_must_fail git rev-parse refs/remotes/tags/end@3 + ' + +echo try to try > expect.two +echo nothing to see here >> expect.two +cat expect.end >> expect.two + +test_expect_success 'test left-hand-side only globbing' ' + git config --add svn-remote.two.url "$svnrepo" && + git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk && + git config --add svn-remote.two.branches \ + "branches/*/*:refs/remotes/two/branches/*/*" && + git config --add svn-remote.two.tags \ + "tags/*:refs/remotes/two/tags/*" && + ( + cd tmp && + echo "try try" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + svn commit -m "try to try" + ) && + git-svn fetch two && + test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 && + test `git rev-list refs/remotes/two/branches/v1/start | wc -l` -eq 3 && + test `git rev-parse refs/remotes/two/branches/v1/start~2` = \ + `git rev-parse refs/remotes/two/trunk` && + test `git rev-parse refs/remotes/two/tags/end~3` = \ + `git rev-parse refs/remotes/two/branches/v1/start` && + git log --pretty=oneline refs/remotes/two/tags/end | \ + sed -e "s/^.\{41\}//" > output.two && + test_cmp expect.two output.two + ' +cat > expect.four <<EOF +adios +adding more +Changed 2 in v2/start +Another versioned branch +initial +EOF + +test_expect_success 'test another branch' ' + ( + cd tmp && + mkdir branches/v2 && + svn add branches/v2 && + svn cp trunk branches/v2/start && + svn commit -m "Another versioned branch" && + svn up && + echo "hello" >> branches/v2/start/src/b/readme && + poke branches/v2/start/src/b/readme && + echo "howdy" >> branches/v2/start/src/a/readme && + poke branches/v2/start/src/a/readme && + svn commit -m "Changed 2 in v2/start" && + svn up && + svn cp branches/v2/start tags/next && + echo "bye" >> tags/next/src/b/readme && + poke tags/next/src/b/readme && + echo "aye" >> tags/next/src/a/readme && + poke tags/next/src/a/readme && + svn commit -m "adding more" && + echo "byebye" >> tags/next/src/b/readme && + poke tags/next/src/b/readme && + svn commit -m "adios" + ) && + git config --add svn-remote.four.url "$svnrepo" && + git config --add svn-remote.four.fetch trunk:refs/remotes/four/trunk && + git config --add svn-remote.four.branches \ + "branches/*/*:refs/remotes/four/branches/*/*" && + git config --add svn-remote.four.tags \ + "tags/*:refs/remotes/four/tags/*" && + git-svn fetch four && + test `git rev-list refs/remotes/four/tags/next | wc -l` -eq 5 && + test `git rev-list refs/remotes/four/branches/v2/start | wc -l` -eq 3 && + test `git rev-parse refs/remotes/four/branches/v2/start~2` = \ + `git rev-parse refs/remotes/four/trunk` && + test `git rev-parse refs/remotes/four/tags/next~2` = \ + `git rev-parse refs/remotes/four/branches/v2/start` && + git log --pretty=oneline refs/remotes/four/tags/next | \ + sed -e "s/^.\{41\}//" > output.four && + test_cmp expect.four output.four + ' + +echo "Only one set of wildcard directories" \ + "(e.g. '*' or '*/*/*') is supported: 'branches/*/t/*'" > expect.three +echo "" >> expect.three + +test_expect_success 'test disallow multiple globs' ' + git config --add svn-remote.three.url "$svnrepo" && + git config --add svn-remote.three.fetch \ + trunk:refs/remotes/three/trunk && + git config --add svn-remote.three.branches \ + "branches/*/t/*:refs/remotes/three/branches/*/*" && + git config --add svn-remote.three.tags \ + "tags/*:refs/remotes/three/tags/*" && + ( + cd tmp && + echo "try try" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + svn commit -m "try to try" + ) && + test_must_fail git-svn fetch three 2> stderr.three && + test_cmp expect.three stderr.three + ' + +test_done diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh new file mode 100755 index 0000000000..04d2a65c08 --- /dev/null +++ b/t/t9110-git-svn-use-svm-props.sh @@ -0,0 +1,61 @@ +#!/bin/sh +# +# Copyright (c) 2007 Eric Wong +# + +test_description='git-svn useSvmProps test' + +. ./lib-git-svn.sh + +test_expect_success 'load svm repo' ' + svnadmin load -q "$rawsvnrepo" < ../t9110/svm.dump && + git-svn init --minimize-url -R arr -i bar "$svnrepo"/mirror/arr && + git-svn init --minimize-url -R argh -i dir "$svnrepo"/mirror/argh && + git-svn init --minimize-url -R argh -i e \ + "$svnrepo"/mirror/argh/a/b/c/d/e && + git config svn.useSvmProps true && + git-svn fetch --all + ' + +uuid=161ce429-a9dd-4828-af4a-52023f968c89 + +bar_url=http://mayonaise/svnrepo/bar +test_expect_success 'verify metadata for /bar' " + git cat-file commit refs/remotes/bar | \ + grep '^git-svn-id: $bar_url@12 $uuid$' && + git cat-file commit refs/remotes/bar~1 | \ + grep '^git-svn-id: $bar_url@11 $uuid$' && + git cat-file commit refs/remotes/bar~2 | \ + grep '^git-svn-id: $bar_url@10 $uuid$' && + git cat-file commit refs/remotes/bar~3 | \ + grep '^git-svn-id: $bar_url@9 $uuid$' && + git cat-file commit refs/remotes/bar~4 | \ + grep '^git-svn-id: $bar_url@6 $uuid$' && + git cat-file commit refs/remotes/bar~5 | \ + grep '^git-svn-id: $bar_url@1 $uuid$' + " + +e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e +test_expect_success 'verify metadata for /dir/a/b/c/d/e' " + git cat-file commit refs/remotes/e | \ + grep '^git-svn-id: $e_url@1 $uuid$' + " + +dir_url=http://mayonaise/svnrepo/dir +test_expect_success 'verify metadata for /dir' " + git cat-file commit refs/remotes/dir | \ + grep '^git-svn-id: $dir_url@2 $uuid$' && + git cat-file commit refs/remotes/dir~1 | \ + grep '^git-svn-id: $dir_url@1 $uuid$' + " + +test_expect_success 'find commit based on SVN revision number' " + git-svn find-rev r12 | + grep `git rev-parse HEAD` + " + +test_expect_success 'empty rebase' " + git-svn rebase + " + +test_done diff --git a/t/t9110/svm.dump b/t/t9110/svm.dump new file mode 100644 index 0000000000..cc799c238d --- /dev/null +++ b/t/t9110/svm.dump @@ -0,0 +1,511 @@ +SVN-fs-dump-format-version: 2 + +UUID: de5973c6-545d-41da-aded-c265f9039e74 + +Revision-number: 0 +Prop-content-length: 56 +Content-length: 56 + +K 8 +svn:date +V 27 +2007-02-17T06:54:59.793104Z +PROPS-END + +Revision-number: 1 +Prop-content-length: 200 +Content-length: 200 + +K 7 +svn:log +V 40 +SVM: initializing mirror for /mirror/arr +K 10 +svn:author +V 3 +svm +K 11 +svm:headrev +V 39 +161ce429-a9dd-4828-af4a-52023f968c89:0 + +K 8 +svn:date +V 27 +2007-02-17T06:55:00.121647Z +PROPS-END + +Node-path: +Node-kind: dir +Node-action: change +Prop-content-length: 44 +Content-length: 44 + +K 10 +svm:mirror +V 12 +/mirror/arr + +PROPS-END + + +Node-path: mirror +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: mirror/arr +Node-kind: dir +Node-action: add +Prop-content-length: 116 +Content-length: 116 + +K 10 +svm:source +V 29 +http://mayonaise/svnrepo!/bar +K 8 +svm:uuid +V 36 +161ce429-a9dd-4828-af4a-52023f968c89 +PROPS-END + + +Revision-number: 2 +Prop-content-length: 182 +Content-length: 182 + +K 7 +svn:log +V 18 +import for git-svn +K 10 +svn:author +V 7 +svnsync +K 11 +svm:headrev +V 39 +161ce429-a9dd-4828-af4a-52023f968c89:1 + +K 8 +svn:date +V 27 +2007-02-17T05:10:52.108847Z +PROPS-END + +Node-path: mirror/arr +Node-kind: dir +Node-action: change +Prop-content-length: 116 +Content-length: 116 + +K 10 +svm:source +V 29 +http://mayonaise/svnrepo!/bar +K 8 +svm:uuid +V 36 +161ce429-a9dd-4828-af4a-52023f968c89 +PROPS-END + + +Node-path: mirror/arr/zzz +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 4 +Text-content-md5: 33b02bc15ce9557d2dd8484d58f95ac4 +Content-length: 14 + +PROPS-END +zzz + + +Revision-number: 3 +Prop-content-length: 230 +Content-length: 230 + +K 7 +svn:log +V 66 +new symlink is added to a file that was also just made executable + +K 10 +svn:author +V 7 +svnsync +K 11 +svm:headrev +V 39 +161ce429-a9dd-4828-af4a-52023f968c89:6 + +K 8 +svn:date +V 27 +2007-02-17T05:11:01.686891Z +PROPS-END + +Node-path: mirror/arr/zzz +Node-kind: file +Node-action: change +Prop-content-length: 36 +Text-content-length: 4 +Text-content-md5: 33b02bc15ce9557d2dd8484d58f95ac4 +Content-length: 40 + +K 14 +svn:executable +V 1 +* +PROPS-END +zzz + + +Revision-number: 4 +Prop-content-length: 192 +Content-length: 192 + +K 7 +svn:log +V 28 +/bar/d should be in the log + +K 10 +svn:author +V 7 +svnsync +K 11 +svm:headrev +V 39 +161ce429-a9dd-4828-af4a-52023f968c89:9 + +K 8 +svn:date +V 27 +2007-02-17T05:11:07.686552Z +PROPS-END + +Node-path: mirror/arr/d +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 4 +Text-content-md5: 0bee89b07a248e27c83fc3d5951213c1 +Content-length: 14 + +PROPS-END +abc + + +Revision-number: 5 +Prop-content-length: 185 +Content-length: 185 + +K 7 +svn:log +V 20 +add a new directory + +K 10 +svn:author +V 7 +svnsync +K 11 +svm:headrev +V 40 +161ce429-a9dd-4828-af4a-52023f968c89:10 + +K 8 +svn:date +V 27 +2007-02-17T05:11:08.405953Z +PROPS-END + +Node-path: mirror/arr/newdir +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: mirror/arr/newdir/dir +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 4 +Text-content-md5: 9cd599a3523898e6a12e13ec787da50a +Content-length: 14 + +PROPS-END +new + + +Revision-number: 6 +Prop-content-length: 196 +Content-length: 196 + +K 7 +svn:log +V 31 +modify a file in new directory + +K 10 +svn:author +V 7 +svnsync +K 11 +svm:headrev +V 40 +161ce429-a9dd-4828-af4a-52023f968c89:11 + +K 8 +svn:date +V 27 +2007-02-17T05:11:09.126645Z +PROPS-END + +Node-path: mirror/arr/newdir/dir +Node-kind: file +Node-action: change +Text-content-length: 8 +Text-content-md5: a950e20332358e523a5e9d571e47fa64 +Content-length: 8 + +new +foo + + +Revision-number: 7 +Prop-content-length: 179 +Content-length: 179 + +K 7 +svn:log +V 14 +update /bar/d + +K 10 +svn:author +V 7 +svnsync +K 11 +svm:headrev +V 40 +161ce429-a9dd-4828-af4a-52023f968c89:12 + +K 8 +svn:date +V 27 +2007-02-17T05:11:09.846221Z +PROPS-END + +Node-path: mirror/arr/d +Node-kind: file +Node-action: change +Text-content-length: 4 +Text-content-md5: 7abb78de7f2756ca8b511cbc879fd5e7 +Content-length: 4 + +cba + + +Revision-number: 8 +Prop-content-length: 201 +Content-length: 201 + +K 7 +svn:log +V 41 +SVM: initializing mirror for /mirror/argh +K 10 +svn:author +V 3 +svm +K 11 +svm:headrev +V 39 +161ce429-a9dd-4828-af4a-52023f968c89:0 + +K 8 +svn:date +V 27 +2007-02-17T06:56:03.703677Z +PROPS-END + +Node-path: +Node-kind: dir +Node-action: change +Prop-content-length: 57 +Content-length: 57 + +K 10 +svm:mirror +V 25 +/mirror/argh +/mirror/arr + +PROPS-END + + +Node-path: mirror/argh +Node-kind: dir +Node-action: add +Prop-content-length: 116 +Content-length: 116 + +K 10 +svm:source +V 29 +http://mayonaise/svnrepo!/dir +K 8 +svm:uuid +V 36 +161ce429-a9dd-4828-af4a-52023f968c89 +PROPS-END + + +Revision-number: 9 +Prop-content-length: 182 +Content-length: 182 + +K 7 +svn:log +V 18 +import for git-svn +K 10 +svn:author +V 7 +svnsync +K 11 +svm:headrev +V 39 +161ce429-a9dd-4828-af4a-52023f968c89:1 + +K 8 +svn:date +V 27 +2007-02-17T05:10:52.108847Z +PROPS-END + +Node-path: mirror/argh +Node-kind: dir +Node-action: change +Prop-content-length: 116 +Content-length: 116 + +K 10 +svm:source +V 29 +http://mayonaise/svnrepo!/dir +K 8 +svm:uuid +V 36 +161ce429-a9dd-4828-af4a-52023f968c89 +PROPS-END + + +Node-path: mirror/argh/a +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: mirror/argh/a/b +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: mirror/argh/a/b/c +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: mirror/argh/a/b/c/d +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: mirror/argh/a/b/c/d/e +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: mirror/argh/a/b/c/d/e/file +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 9 +Text-content-md5: 3fd46fe46fcdcf062c802ca60dc826d5 +Content-length: 19 + +PROPS-END +deep dir + + +Revision-number: 10 +Prop-content-length: 197 +Content-length: 197 + +K 7 +svn:log +V 33 +try a deep --rmdir with a commit + +K 10 +svn:author +V 7 +svnsync +K 11 +svm:headrev +V 39 +161ce429-a9dd-4828-af4a-52023f968c89:2 + +K 8 +svn:date +V 27 +2007-02-17T05:10:54.847015Z +PROPS-END + +Node-path: mirror/argh/file +Node-kind: file +Node-action: add +Node-copyfrom-rev: 9 +Node-copyfrom-path: mirror/argh/a/b/c/d/e/file +Text-content-length: 9 +Text-content-md5: 3fd46fe46fcdcf062c802ca60dc826d5 +Content-length: 9 + +deep dir + + +Node-path: mirror/argh/a +Node-action: delete + + diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh new file mode 100755 index 0000000000..a8d74dcd3a --- /dev/null +++ b/t/t9111-git-svn-use-svnsync-props.sh @@ -0,0 +1,51 @@ +#!/bin/sh +# +# Copyright (c) 2007 Eric Wong +# + +test_description='git-svn useSvnsyncProps test' + +. ./lib-git-svn.sh + +test_expect_success 'load svnsync repo' ' + svnadmin load -q "$rawsvnrepo" < ../t9111/svnsync.dump && + git-svn init --minimize-url -R arr -i bar "$svnrepo"/bar && + git-svn init --minimize-url -R argh -i dir "$svnrepo"/dir && + git-svn init --minimize-url -R argh -i e "$svnrepo"/dir/a/b/c/d/e && + git config svn.useSvnsyncProps true && + git-svn fetch --all + ' + +uuid=161ce429-a9dd-4828-af4a-52023f968c89 + +bar_url=http://mayonaise/svnrepo/bar +test_expect_success 'verify metadata for /bar' " + git cat-file commit refs/remotes/bar | \ + grep '^git-svn-id: $bar_url@12 $uuid$' && + git cat-file commit refs/remotes/bar~1 | \ + grep '^git-svn-id: $bar_url@11 $uuid$' && + git cat-file commit refs/remotes/bar~2 | \ + grep '^git-svn-id: $bar_url@10 $uuid$' && + git cat-file commit refs/remotes/bar~3 | \ + grep '^git-svn-id: $bar_url@9 $uuid$' && + git cat-file commit refs/remotes/bar~4 | \ + grep '^git-svn-id: $bar_url@6 $uuid$' && + git cat-file commit refs/remotes/bar~5 | \ + grep '^git-svn-id: $bar_url@1 $uuid$' + " + +e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e +test_expect_success 'verify metadata for /dir/a/b/c/d/e' " + git cat-file commit refs/remotes/e | \ + grep '^git-svn-id: $e_url@1 $uuid$' + " + +dir_url=http://mayonaise/svnrepo/dir +test_expect_success 'verify metadata for /dir' " + git cat-file commit refs/remotes/dir | \ + grep '^git-svn-id: $dir_url@2 $uuid$' && + git cat-file commit refs/remotes/dir~1 | \ + grep '^git-svn-id: $dir_url@1 $uuid$' + " + +test_done diff --git a/t/t9111/svnsync.dump b/t/t9111/svnsync.dump new file mode 100644 index 0000000000..499fa9594f --- /dev/null +++ b/t/t9111/svnsync.dump @@ -0,0 +1,560 @@ +SVN-fs-dump-format-version: 2 + +UUID: b4bfe35e-f256-4096-874c-08c5639ecad7 + +Revision-number: 0 +Prop-content-length: 240 +Content-length: 240 + +K 18 +svn:sync-from-uuid +V 36 +161ce429-a9dd-4828-af4a-52023f968c89 +K 10 +svn:author +V 7 +svnsync +K 24 +svn:sync-last-merged-rev +V 2 +12 +K 8 +svn:date +V 27 +2007-02-17T05:10:52.017552Z +K 17 +svn:sync-from-url +V 24 +http://mayonaise/svnrepo +PROPS-END + +Revision-number: 1 +Prop-content-length: 120 +Content-length: 120 + +K 7 +svn:log +V 18 +import for git-svn +K 10 +svn:author +V 7 +svnsync +K 8 +svn:date +V 27 +2007-02-17T05:10:52.108847Z +PROPS-END + +Node-path: bar +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: bar/zzz +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 4 +Text-content-md5: 33b02bc15ce9557d2dd8484d58f95ac4 +Content-length: 14 + +PROPS-END +zzz + + +Node-path: dir +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: dir/a +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: dir/a/b +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: dir/a/b/c +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: dir/a/b/c/d +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: dir/a/b/c/d/e +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: dir/a/b/c/d/e/file +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 9 +Text-content-md5: 3fd46fe46fcdcf062c802ca60dc826d5 +Content-length: 19 + +PROPS-END +deep dir + + +Node-path: exec.sh +Node-kind: file +Node-action: add +Prop-content-length: 35 +Text-content-length: 10 +Text-content-md5: 3e2b31c72181b87149ff995e7202c0e3 +Content-length: 45 + +K 14 +svn:executable +V 0 + +PROPS-END +#!/bin/sh + + +Node-path: foo +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 4 +Text-content-md5: d3b07384d113edec49eaa6238ad5ff00 +Content-length: 14 + +PROPS-END +foo + + +Node-path: foo.link +Node-kind: file +Node-action: add +Prop-content-length: 33 +Text-content-length: 8 +Text-content-md5: 1043146e49ef02cab12eef865cb34ff3 +Content-length: 41 + +K 11 +svn:special +V 1 +* +PROPS-END +link foo + +Revision-number: 2 +Prop-content-length: 135 +Content-length: 135 + +K 7 +svn:log +V 33 +try a deep --rmdir with a commit + +K 10 +svn:author +V 7 +svnsync +K 8 +svn:date +V 27 +2007-02-17T05:10:54.847015Z +PROPS-END + +Node-path: dir/file +Node-kind: file +Node-action: add +Node-copyfrom-rev: 1 +Node-copyfrom-path: dir/a/b/c/d/e/file +Text-content-length: 9 +Text-content-md5: 3fd46fe46fcdcf062c802ca60dc826d5 +Content-length: 9 + +deep dir + + +Node-path: dir/a +Node-action: delete + + +Node-path: file +Node-kind: file +Node-action: add +Node-copyfrom-rev: 1 +Node-copyfrom-path: dir/a/b/c/d/e/file +Text-content-length: 9 +Text-content-md5: 3fd46fe46fcdcf062c802ca60dc826d5 +Content-length: 9 + +deep dir + + +Revision-number: 3 +Prop-content-length: 136 +Content-length: 136 + +K 7 +svn:log +V 34 +remove executable bit from a file + +K 10 +svn:author +V 7 +svnsync +K 8 +svn:date +V 27 +2007-02-17T05:10:58.232691Z +PROPS-END + +Node-path: exec.sh +Node-kind: file +Node-action: change +Prop-content-length: 10 +Text-content-length: 10 +Text-content-md5: 3e2b31c72181b87149ff995e7202c0e3 +Content-length: 20 + +PROPS-END +#!/bin/sh + + +Revision-number: 4 +Prop-content-length: 131 +Content-length: 131 + +K 7 +svn:log +V 29 +add executable bit back file + +K 10 +svn:author +V 7 +svnsync +K 8 +svn:date +V 27 +2007-02-17T05:10:59.666560Z +PROPS-END + +Node-path: exec.sh +Node-kind: file +Node-action: change +Prop-content-length: 36 +Text-content-length: 10 +Text-content-md5: 3e2b31c72181b87149ff995e7202c0e3 +Content-length: 46 + +K 14 +svn:executable +V 1 +* +PROPS-END +#!/bin/sh + + +Revision-number: 5 +Prop-content-length: 154 +Content-length: 154 + +K 7 +svn:log +V 52 +executable file becomes a symlink to bar/zzz (file) + +K 10 +svn:author +V 7 +svnsync +K 8 +svn:date +V 27 +2007-02-17T05:11:00.676495Z +PROPS-END + +Node-path: exec.sh +Node-kind: file +Node-action: change +Prop-content-length: 33 +Text-content-length: 12 +Text-content-md5: f138693371665cc117742508761d684d +Content-length: 45 + +K 11 +svn:special +V 1 +* +PROPS-END +link bar/zzz + +Revision-number: 6 +Prop-content-length: 168 +Content-length: 168 + +K 7 +svn:log +V 66 +new symlink is added to a file that was also just made executable + +K 10 +svn:author +V 7 +svnsync +K 8 +svn:date +V 27 +2007-02-17T05:11:01.686891Z +PROPS-END + +Node-path: bar/zzz +Node-kind: file +Node-action: change +Prop-content-length: 36 +Text-content-length: 4 +Text-content-md5: 33b02bc15ce9557d2dd8484d58f95ac4 +Content-length: 40 + +K 14 +svn:executable +V 1 +* +PROPS-END +zzz + + +Node-path: exec-2.sh +Node-kind: file +Node-action: add +Node-copyfrom-rev: 5 +Node-copyfrom-path: exec.sh +Text-content-length: 12 +Text-content-md5: f138693371665cc117742508761d684d +Content-length: 12 + +link bar/zzz + +Revision-number: 7 +Prop-content-length: 136 +Content-length: 136 + +K 7 +svn:log +V 34 +modify a symlink to become a file + +K 10 +svn:author +V 7 +svnsync +K 8 +svn:date +V 27 +2007-02-17T05:11:02.677035Z +PROPS-END + +Node-path: exec-2.sh +Node-kind: file +Node-action: change +Prop-content-length: 10 +Text-content-length: 9 +Text-content-md5: 8e92eff9e911886cede27d420f89c735 +Content-length: 19 + +PROPS-END +git help + + +Revision-number: 8 +Prop-content-length: 109 +Content-length: 109 + +K 7 +svn:log +V 8 +éï∠+ +K 10 +svn:author +V 7 +svnsync +K 8 +svn:date +V 27 +2007-02-17T05:11:03.676862Z +PROPS-END + +Node-path: exec-2.sh +Node-kind: file +Node-action: change +Text-content-length: 17 +Text-content-md5: 49881954063cf26ca48c212396a957ca +Content-length: 17 + +git help +# hello + + +Revision-number: 9 +Prop-content-length: 130 +Content-length: 130 + +K 7 +svn:log +V 28 +/bar/d should be in the log + +K 10 +svn:author +V 7 +svnsync +K 8 +svn:date +V 27 +2007-02-17T05:11:07.686552Z +PROPS-END + +Node-path: bar/d +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 4 +Text-content-md5: 0bee89b07a248e27c83fc3d5951213c1 +Content-length: 14 + +PROPS-END +abc + + +Revision-number: 10 +Prop-content-length: 122 +Content-length: 122 + +K 7 +svn:log +V 20 +add a new directory + +K 10 +svn:author +V 7 +svnsync +K 8 +svn:date +V 27 +2007-02-17T05:11:08.405953Z +PROPS-END + +Node-path: bar/newdir +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: bar/newdir/dir +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 4 +Text-content-md5: 9cd599a3523898e6a12e13ec787da50a +Content-length: 14 + +PROPS-END +new + + +Revision-number: 11 +Prop-content-length: 133 +Content-length: 133 + +K 7 +svn:log +V 31 +modify a file in new directory + +K 10 +svn:author +V 7 +svnsync +K 8 +svn:date +V 27 +2007-02-17T05:11:09.126645Z +PROPS-END + +Node-path: bar/newdir/dir +Node-kind: file +Node-action: change +Text-content-length: 8 +Text-content-md5: a950e20332358e523a5e9d571e47fa64 +Content-length: 8 + +new +foo + + +Revision-number: 12 +Prop-content-length: 116 +Content-length: 116 + +K 7 +svn:log +V 14 +update /bar/d + +K 10 +svn:author +V 7 +svnsync +K 8 +svn:date +V 27 +2007-02-17T05:11:09.846221Z +PROPS-END + +Node-path: bar/d +Node-kind: file +Node-action: change +Text-content-length: 4 +Text-content-md5: 7abb78de7f2756ca8b511cbc879fd5e7 +Content-length: 4 + +cba diff --git a/t/t9112-git-svn-md5less-file.sh b/t/t9112-git-svn-md5less-file.sh new file mode 100755 index 0000000000..d470a920e4 --- /dev/null +++ b/t/t9112-git-svn-md5less-file.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +test_description='test that git handles an svn repository with missing md5sums' + +. ./lib-git-svn.sh + +# Loading a node from a svn dumpfile without a Text-Content-Length +# field causes svn to neglect to store or report an md5sum. (it will +# calculate one if you had put Text-Content-Length: 0). This showed +# up in a repository creted with cvs2svn. + +cat > dumpfile.svn <<EOF +SVN-fs-dump-format-version: 1 + +Revision-number: 1 +Prop-content-length: 98 +Content-length: 98 + +K 7 +svn:log +V 0 + +K 10 +svn:author +V 4 +test +K 8 +svn:date +V 27 +2007-05-06T12:37:01.153339Z +PROPS-END + +Node-path: md5less-file +Node-kind: file +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + +EOF + +test_expect_success 'load svn dumpfile' 'svnadmin load "$rawsvnrepo" < dumpfile.svn' + +test_expect_success 'initialize git-svn' 'git-svn init "$svnrepo"' +test_expect_success 'fetch revisions from svn' 'git-svn fetch' +test_done diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh new file mode 100755 index 0000000000..ae78e334ac --- /dev/null +++ b/t/t9113-git-svn-dcommit-new-file.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# +# Copyright (c) 2007 Eric Wong +# + +# Don't run this test by default unless the user really wants it +# I don't like the idea of taking a port and possibly leaving a +# daemon running on a users system if the test fails. +# Not all git users will need to interact with SVN. + +test_description='git-svn dcommit new files over svn:// test' + +. ./lib-git-svn.sh + +if test -z "$SVNSERVE_PORT" +then + say 'skipping svnserve test. (set $SVNSERVE_PORT to enable)' + test_done + exit +fi + +start_svnserve () { + svnserve --listen-port $SVNSERVE_PORT \ + --root "$rawsvnrepo" \ + --listen-once \ + --listen-host 127.0.0.1 & +} + +test_expect_success 'start tracking an empty repo' ' + svn mkdir -m "empty dir" "$svnrepo"/empty-dir && + echo "[general]" > "$rawsvnrepo"/conf/svnserve.conf && + echo anon-access = write >> "$rawsvnrepo"/conf/svnserve.conf && + start_svnserve && + git svn init svn://127.0.0.1:$SVNSERVE_PORT && + git svn fetch + ' + +test_expect_success 'create files in new directory with dcommit' " + mkdir git-new-dir && + echo hello > git-new-dir/world && + git update-index --add git-new-dir/world && + git commit -m hello && + start_svnserve && + git svn dcommit + " + +test_done diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh new file mode 100755 index 0000000000..61d7781616 --- /dev/null +++ b/t/t9114-git-svn-dcommit-merge.sh @@ -0,0 +1,94 @@ +#!/bin/sh +# +# Copyright (c) 2007 Eric Wong +# Based on a script by Joakim Tjernlund <joakim.tjernlund@transmode.se> + +test_description='git-svn dcommit handles merges' + +. ./lib-git-svn.sh + +big_text_block () { +cat << EOF +# +# (C) Copyright 2000 - 2005 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +EOF +} + +test_expect_success 'setup svn repository' ' + svn co "$svnrepo" mysvnwork && + mkdir -p mysvnwork/trunk && + cd mysvnwork && + big_text_block >> trunk/README && + svn add trunk && + svn ci -m "first commit" trunk && + cd .. + ' + +test_expect_success 'setup git mirror and merge' ' + git svn init "$svnrepo" -t tags -T trunk -b branches && + git svn fetch && + git checkout --track -b svn remotes/trunk && + git checkout -b merge && + echo new file > new_file && + git add new_file && + git commit -a -m "New file" && + echo hello >> README && + git commit -a -m "hello" && + echo add some stuff >> new_file && + git commit -a -m "add some stuff" && + git checkout svn && + mv -f README tmp && + echo friend > README && + cat tmp >> README && + git commit -a -m "friend" && + git pull . merge + ' + +test_debug 'gitk --all & sleep 1' + +test_expect_success 'verify pre-merge ancestry' " + test x\`git rev-parse --verify refs/heads/svn^2\` = \ + x\`git rev-parse --verify refs/heads/merge\` && + git cat-file commit refs/heads/svn^ | grep '^friend$' + " + +test_expect_success 'git svn dcommit merges' " + git svn dcommit + " + +test_debug 'gitk --all & sleep 1' + +test_expect_success 'verify post-merge ancestry' " + test x\`git rev-parse --verify refs/heads/svn\` = \ + x\`git rev-parse --verify refs/remotes/trunk \` && + test x\`git rev-parse --verify refs/heads/svn^2\` = \ + x\`git rev-parse --verify refs/heads/merge\` && + git cat-file commit refs/heads/svn^ | grep '^friend$' + " + +test_expect_success 'verify merge commit message' " + git rev-list --pretty=raw -1 refs/heads/svn | \ + grep \" Merge branch 'merge' into svn\" + " + +test_done diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh new file mode 100755 index 0000000000..f0fbd3aff7 --- /dev/null +++ b/t/t9115-git-svn-dcommit-funky-renames.sh @@ -0,0 +1,87 @@ +#!/bin/sh +# +# Copyright (c) 2007 Eric Wong + + +test_description='git-svn dcommit can commit renames of files with ugly names' + +. ./lib-git-svn.sh + +test_expect_success 'load repository with strange names' ' + svnadmin load -q "$rawsvnrepo" < ../t9115/funky-names.dump && + start_httpd gtk+ + ' + +test_expect_success 'init and fetch repository' ' + git svn init "$svnrepo" && + git svn fetch && + git reset --hard git-svn + ' + +test_expect_success 'create file in existing ugly and empty dir' ' + mkdir "#{bad_directory_name}" && + echo hi > "#{bad_directory_name}/ foo" && + git update-index --add "#{bad_directory_name}/ foo" && + git commit -m "new file in ugly parent" && + git svn dcommit + ' + +test_expect_success 'rename ugly file' ' + git mv "#{bad_directory_name}/ foo" "file name with feces" && + git commit -m "rename ugly file" && + git svn dcommit + ' + +test_expect_success 'rename pretty file' ' + echo :x > pretty && + git update-index --add pretty && + git commit -m "pretty :x" && + git svn dcommit && + mkdir regular_dir_name && + git mv pretty regular_dir_name/pretty && + git commit -m "moved pretty file" && + git svn dcommit + ' + +test_expect_success 'rename pretty file into ugly one' ' + git mv regular_dir_name/pretty "#{bad_directory_name}/ booboo" && + git commit -m booboo && + git svn dcommit + ' + +test_expect_success 'add a file with plus signs' ' + echo .. > +_+ && + git update-index --add +_+ && + git commit -m plus && + mkdir gtk+ && + git mv +_+ gtk+/_+_ && + git commit -m plus_dir && + git svn dcommit + ' + +test_expect_success 'clone the repository to test rebase' ' + git svn clone "$svnrepo" test-rebase && + cd test-rebase && + echo test-rebase > test-rebase && + git add test-rebase && + git commit -m test-rebase && + cd .. + ' + +test_expect_success 'make a commit to test rebase' ' + echo test-rebase-main > test-rebase-main && + git add test-rebase-main && + git commit -m test-rebase-main && + git svn dcommit + ' + +test_expect_success 'git-svn rebase works inside a fresh-cloned repository' ' + cd test-rebase && + git svn rebase && + test -e test-rebase-main && + test -e test-rebase + ' + +stop_httpd + +test_done diff --git a/t/t9115/funky-names.dump b/t/t9115/funky-names.dump new file mode 100644 index 0000000000..42422f791e --- /dev/null +++ b/t/t9115/funky-names.dump @@ -0,0 +1,103 @@ +SVN-fs-dump-format-version: 2 + +UUID: 819c44fe-2bcc-4066-88e4-985e2bc0b418 + +Revision-number: 0 +Prop-content-length: 56 +Content-length: 56 + +K 8 +svn:date +V 27 +2007-07-12T07:54:26.062914Z +PROPS-END + +Revision-number: 1 +Prop-content-length: 152 +Content-length: 152 + +K 7 +svn:log +V 44 +what will those wacky people think of next? + +K 10 +svn:author +V 12 +normalperson +K 8 +svn:date +V 27 +2007-07-12T08:00:05.011573Z +PROPS-END + +Node-path: leading space +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: leading space file +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 5 +Text-content-md5: e4fa20c67542cdc21271e08d329397ab +Content-length: 15 + +PROPS-END +ugly + + +Node-path: #{bad_directory_name} +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: #{cool_name} +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 18 +Text-content-md5: 87dac40ca337dfa3dcc8911388c3ddda +Content-length: 28 + +PROPS-END +strange name here + + +Node-path: dir name with spaces +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: file name with spaces +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 7 +Text-content-md5: c1f10cfd640618484a2a475c11410fd3 +Content-length: 17 + +PROPS-END +spaces + + +Node-path: regular_dir_name +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh new file mode 100755 index 0000000000..4b2cc878f6 --- /dev/null +++ b/t/t9116-git-svn-log.sh @@ -0,0 +1,128 @@ +#!/bin/sh +# +# Copyright (c) 2007 Eric Wong +# + +test_description='git-svn log tests' +. ./lib-git-svn.sh + +test_expect_success 'setup repository and import' ' + mkdir import && + cd import && + for i in trunk branches/a branches/b \ + tags/0.1 tags/0.2 tags/0.3; do + mkdir -p $i && \ + echo hello >> $i/README || exit 1 + done && \ + svn import -m test . "$svnrepo" + cd .. && + git-svn init "$svnrepo" -T trunk -b branches -t tags && + git-svn fetch && + git reset --hard trunk && + echo bye >> README && + git commit -a -m bye && + git svn dcommit && + git reset --hard a && + echo why >> FEEDME && + git update-index --add FEEDME && + git commit -m feedme && + git svn dcommit && + git reset --hard trunk && + echo aye >> README && + git commit -a -m aye && + git svn dcommit && + git reset --hard b && + echo spy >> README && + git commit -a -m spy && + echo try >> README && + git commit -a -m try && + git svn dcommit + ' + +test_expect_success 'run log' " + git reset --hard a && + git svn log -r2 trunk | grep ^r2 && + git svn log -r4 trunk | grep ^r4 && + git svn log -r3 | grep ^r3 + " + +test_expect_success 'run log against a from trunk' " + git reset --hard trunk && + git svn log -r3 a | grep ^r3 + " + +printf 'r1 \nr2 \nr4 \n' > expected-range-r1-r2-r4 + +test_expect_success 'test ascending revision range' " + git reset --hard trunk && + git svn log -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r1-r2-r4 - + " + +printf 'r4 \nr2 \nr1 \n' > expected-range-r4-r2-r1 + +test_expect_success 'test descending revision range' " + git reset --hard trunk && + git svn log -r 4:1 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4-r2-r1 - + " + +printf 'r1 \nr2 \n' > expected-range-r1-r2 + +test_expect_success 'test ascending revision range with unreachable revision' " + git reset --hard trunk && + git svn log -r 1:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r1-r2 - + " + +printf 'r2 \nr1 \n' > expected-range-r2-r1 + +test_expect_success 'test descending revision range with unreachable revision' " + git reset --hard trunk && + git svn log -r 3:1 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r2-r1 - + " + +printf 'r2 \n' > expected-range-r2 + +test_expect_success 'test ascending revision range with unreachable upper boundary revision and 1 commit' " + git reset --hard trunk && + git svn log -r 2:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r2 - + " + +test_expect_success 'test descending revision range with unreachable upper boundary revision and 1 commit' " + git reset --hard trunk && + git svn log -r 3:2 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r2 - + " + +printf 'r4 \n' > expected-range-r4 + +test_expect_success 'test ascending revision range with unreachable lower boundary revision and 1 commit' " + git reset --hard trunk && + git svn log -r 3:4 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4 - + " + +test_expect_success 'test descending revision range with unreachable lower boundary revision and 1 commit' " + git reset --hard trunk && + git svn log -r 4:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4 - + " + +printf -- '------------------------------------------------------------------------\n' > expected-separator + +test_expect_success 'test ascending revision range with unreachable boundary revisions and no commits' " + git reset --hard trunk && + git svn log -r 5:6 | test_cmp expected-separator - + " + +test_expect_success 'test descending revision range with unreachable boundary revisions and no commits' " + git reset --hard trunk && + git svn log -r 6:5 | test_cmp expected-separator - + " + +test_expect_success 'test ascending revision range with unreachable boundary revisions and 1 commit' " + git reset --hard trunk && + git svn log -r 3:5 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4 - + " + +test_expect_success 'test descending revision range with unreachable boundary revisions and 1 commit' " + git reset --hard trunk && + git svn log -r 5:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4 - + " + +test_done diff --git a/t/t9117-git-svn-init-clone.sh b/t/t9117-git-svn-init-clone.sh new file mode 100755 index 0000000000..7a689bb1cd --- /dev/null +++ b/t/t9117-git-svn-init-clone.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Copyright (c) 2007 Eric Wong +# + +test_description='git-svn init/clone tests' + +. ./lib-git-svn.sh + +# setup, run inside tmp so we don't have any conflicts with $svnrepo +set -e +rm -r .git +mkdir tmp +cd tmp + +test_expect_success 'setup svnrepo' ' + mkdir project project/trunk project/branches project/tags && + echo foo > project/trunk/foo && + svn import -m "$test_description" project "$svnrepo"/project && + rm -rf project + ' + +test_expect_success 'basic clone' ' + test ! -d trunk && + git svn clone "$svnrepo"/project/trunk && + test -d trunk/.git/svn && + test -e trunk/foo && + rm -rf trunk + ' + +test_expect_success 'clone to target directory' ' + test ! -d target && + git svn clone "$svnrepo"/project/trunk target && + test -d target/.git/svn && + test -e target/foo && + rm -rf target + ' + +test_expect_success 'clone with --stdlayout' ' + test ! -d project && + git svn clone -s "$svnrepo"/project && + test -d project/.git/svn && + test -e project/foo && + rm -rf project + ' + +test_expect_success 'clone to target directory with --stdlayout' ' + test ! -d target && + git svn clone -s "$svnrepo"/project target && + test -d target/.git/svn && + test -e target/foo && + rm -rf target + ' + +test_done diff --git a/t/t9118-git-svn-funky-branch-names.sh b/t/t9118-git-svn-funky-branch-names.sh new file mode 100755 index 0000000000..3281cbd347 --- /dev/null +++ b/t/t9118-git-svn-funky-branch-names.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +# Copyright (c) 2007 Eric Wong +# + +test_description='git-svn funky branch names' +. ./lib-git-svn.sh + +test_expect_success 'setup svnrepo' ' + mkdir project project/trunk project/branches project/tags && + echo foo > project/trunk/foo && + svn import -m "$test_description" project "$svnrepo/pr ject" && + rm -rf project && + svn cp -m "fun" "$svnrepo/pr ject/trunk" \ + "$svnrepo/pr ject/branches/fun plugin" && + svn cp -m "more fun!" "$svnrepo/pr ject/branches/fun plugin" \ + "$svnrepo/pr ject/branches/more fun plugin!" && + start_httpd + ' + +test_expect_success 'test clone with funky branch names' ' + git svn clone -s "$svnrepo/pr ject" project && + cd project && + git rev-parse "refs/remotes/fun%20plugin" && + git rev-parse "refs/remotes/more%20fun%20plugin!" && + cd .. + ' + +test_expect_success 'test dcommit to funky branch' " + cd project && + git reset --hard 'refs/remotes/more%20fun%20plugin!' && + echo hello >> foo && + git commit -m 'hello' -- foo && + git svn dcommit && + cd .. + " + +stop_httpd + +test_done diff --git a/t/t9119-git-svn-info.sh b/t/t9119-git-svn-info.sh new file mode 100755 index 0000000000..5fd36a1483 --- /dev/null +++ b/t/t9119-git-svn-info.sh @@ -0,0 +1,388 @@ +#!/bin/sh +# +# Copyright (c) 2007 David D. Kilzer + +test_description='git-svn info' + +. ./lib-git-svn.sh + +set -e + +# Tested with: svn, version 1.4.4 (r25188) +v=`svn --version | sed -n -e 's/^svn, version \(1\.4\.[0-9]\).*$/\1/p'` +case $v in +1.4.*) + ;; +*) + say "skipping svn-info test (SVN version: $v not supported)" + test_done + ;; +esac + +ptouch() { + perl -w -e ' + use strict; + use POSIX qw(mktime); + die "ptouch requires exactly 2 arguments" if @ARGV != 2; + my $text_last_updated = shift @ARGV; + my $git_file = shift @ARGV; + die "\"$git_file\" does not exist" if ! -e $git_file; + if ($text_last_updated + =~ /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/) { + my $mtime = mktime($6, $5, $4, $3, $2 - 1, $1 - 1900); + my $atime = $mtime; + utime $atime, $mtime, $git_file; + } + ' "`svn info $2 | grep '^Text Last Updated:'`" "$1" +} + +test_expect_success 'setup repository and import' ' + mkdir info && + cd info && + echo FIRST > A && + echo one > file && + ln -s file symlink-file && + mkdir directory && + touch directory/.placeholder && + ln -s directory symlink-directory && + svn import -m "initial" . "$svnrepo" && + cd .. && + mkdir gitwc && + cd gitwc && + git-svn init "$svnrepo" && + git-svn fetch && + cd .. && + svn co "$svnrepo" svnwc && + ptouch svnwc/file gitwc/file && + ptouch svnwc/directory gitwc/directory && + ptouch svnwc/symlink-file gitwc/symlink-file && + ptouch svnwc/symlink-directory gitwc/symlink-directory + ' + +test_expect_success 'info' " + (cd svnwc; svn info) > expected.info && + (cd gitwc; git-svn info) > actual.info && + git-diff expected.info actual.info + " + +test_expect_success 'info --url' ' + test "$(cd gitwc; git-svn info --url)" = "$svnrepo" + ' + +test_expect_success 'info .' " + (cd svnwc; svn info .) > expected.info-dot && + (cd gitwc; git-svn info .) > actual.info-dot && + git-diff expected.info-dot actual.info-dot + " + +test_expect_success 'info --url .' ' + test "$(cd gitwc; git-svn info --url .)" = "$svnrepo" + ' + +test_expect_success 'info file' " + (cd svnwc; svn info file) > expected.info-file && + (cd gitwc; git-svn info file) > actual.info-file && + git-diff expected.info-file actual.info-file + " + +test_expect_success 'info --url file' ' + test "$(cd gitwc; git-svn info --url file)" = "$svnrepo/file" + ' + +test_expect_success 'info directory' " + (cd svnwc; svn info directory) > expected.info-directory && + (cd gitwc; git-svn info directory) > actual.info-directory && + git-diff expected.info-directory actual.info-directory + " + +test_expect_success 'info --url directory' ' + test "$(cd gitwc; git-svn info --url directory)" = "$svnrepo/directory" + ' + +test_expect_success 'info symlink-file' " + (cd svnwc; svn info symlink-file) > expected.info-symlink-file && + (cd gitwc; git-svn info symlink-file) > actual.info-symlink-file && + git-diff expected.info-symlink-file actual.info-symlink-file + " + +test_expect_success 'info --url symlink-file' ' + test "$(cd gitwc; git-svn info --url symlink-file)" \ + = "$svnrepo/symlink-file" + ' + +test_expect_success 'info symlink-directory' " + (cd svnwc; svn info symlink-directory) \ + > expected.info-symlink-directory && + (cd gitwc; git-svn info symlink-directory) \ + > actual.info-symlink-directory && + git-diff expected.info-symlink-directory actual.info-symlink-directory + " + +test_expect_success 'info --url symlink-directory' ' + test "$(cd gitwc; git-svn info --url symlink-directory)" \ + = "$svnrepo/symlink-directory" + ' + +test_expect_success 'info added-file' " + echo two > gitwc/added-file && + cd gitwc && + git add added-file && + cd .. && + cp gitwc/added-file svnwc/added-file && + ptouch gitwc/added-file svnwc/added-file && + cd svnwc && + svn add added-file > /dev/null && + cd .. && + (cd svnwc; svn info added-file) > expected.info-added-file && + (cd gitwc; git-svn info added-file) > actual.info-added-file && + git-diff expected.info-added-file actual.info-added-file + " + +test_expect_success 'info --url added-file' ' + test "$(cd gitwc; git-svn info --url added-file)" \ + = "$svnrepo/added-file" + ' + +test_expect_success 'info added-directory' " + mkdir gitwc/added-directory svnwc/added-directory && + ptouch gitwc/added-directory svnwc/added-directory && + touch gitwc/added-directory/.placeholder && + cd svnwc && + svn add added-directory > /dev/null && + cd .. && + cd gitwc && + git add added-directory && + cd .. && + (cd svnwc; svn info added-directory) \ + > expected.info-added-directory && + (cd gitwc; git-svn info added-directory) \ + > actual.info-added-directory && + git-diff expected.info-added-directory actual.info-added-directory + " + +test_expect_success 'info --url added-directory' ' + test "$(cd gitwc; git-svn info --url added-directory)" \ + = "$svnrepo/added-directory" + ' + +test_expect_success 'info added-symlink-file' " + cd gitwc && + ln -s added-file added-symlink-file && + git add added-symlink-file && + cd .. && + cd svnwc && + ln -s added-file added-symlink-file && + svn add added-symlink-file > /dev/null && + cd .. && + ptouch gitwc/added-symlink-file svnwc/added-symlink-file && + (cd svnwc; svn info added-symlink-file) \ + > expected.info-added-symlink-file && + (cd gitwc; git-svn info added-symlink-file) \ + > actual.info-added-symlink-file && + git-diff expected.info-added-symlink-file \ + actual.info-added-symlink-file + " + +test_expect_success 'info --url added-symlink-file' ' + test "$(cd gitwc; git-svn info --url added-symlink-file)" \ + = "$svnrepo/added-symlink-file" + ' + +test_expect_success 'info added-symlink-directory' " + cd gitwc && + ln -s added-directory added-symlink-directory && + git add added-symlink-directory && + cd .. && + cd svnwc && + ln -s added-directory added-symlink-directory && + svn add added-symlink-directory > /dev/null && + cd .. && + ptouch gitwc/added-symlink-directory svnwc/added-symlink-directory && + (cd svnwc; svn info added-symlink-directory) \ + > expected.info-added-symlink-directory && + (cd gitwc; git-svn info added-symlink-directory) \ + > actual.info-added-symlink-directory && + git-diff expected.info-added-symlink-directory \ + actual.info-added-symlink-directory + " + +test_expect_success 'info --url added-symlink-directory' ' + test "$(cd gitwc; git-svn info --url added-symlink-directory)" \ + = "$svnrepo/added-symlink-directory" + ' + +# The next few tests replace the "Text Last Updated" value with a +# placeholder since git doesn't have a way to know the date that a +# now-deleted file was last checked out locally. Internally it +# simply reuses the Last Changed Date. + +test_expect_success 'info deleted-file' " + cd gitwc && + git rm -f file > /dev/null && + cd .. && + cd svnwc && + svn rm --force file > /dev/null && + cd .. && + (cd svnwc; svn info file) | + sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ + > expected.info-deleted-file && + (cd gitwc; git-svn info file) | + sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ + > actual.info-deleted-file && + git-diff expected.info-deleted-file actual.info-deleted-file + " + +test_expect_success 'info --url file (deleted)' ' + test "$(cd gitwc; git-svn info --url file)" \ + = "$svnrepo/file" + ' + +test_expect_success 'info deleted-directory' " + cd gitwc && + git rm -r -f directory > /dev/null && + cd .. && + cd svnwc && + svn rm --force directory > /dev/null && + cd .. && + (cd svnwc; svn info directory) | + sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ + > expected.info-deleted-directory && + (cd gitwc; git-svn info directory) | + sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ + > actual.info-deleted-directory && + git-diff expected.info-deleted-directory actual.info-deleted-directory + " + +test_expect_success 'info --url directory (deleted)' ' + test "$(cd gitwc; git-svn info --url directory)" \ + = "$svnrepo/directory" + ' + +test_expect_success 'info deleted-symlink-file' " + cd gitwc && + git rm -f symlink-file > /dev/null && + cd .. && + cd svnwc && + svn rm --force symlink-file > /dev/null && + cd .. && + (cd svnwc; svn info symlink-file) | + sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ + > expected.info-deleted-symlink-file && + (cd gitwc; git-svn info symlink-file) | + sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ + > actual.info-deleted-symlink-file && + git-diff expected.info-deleted-symlink-file \ + actual.info-deleted-symlink-file + " + +test_expect_success 'info --url symlink-file (deleted)' ' + test "$(cd gitwc; git-svn info --url symlink-file)" \ + = "$svnrepo/symlink-file" + ' + +test_expect_success 'info deleted-symlink-directory' " + cd gitwc && + git rm -f symlink-directory > /dev/null && + cd .. && + cd svnwc && + svn rm --force symlink-directory > /dev/null && + cd .. && + (cd svnwc; svn info symlink-directory) | + sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ + > expected.info-deleted-symlink-directory && + (cd gitwc; git-svn info symlink-directory) | + sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ + > actual.info-deleted-symlink-directory && + git-diff expected.info-deleted-symlink-directory \ + actual.info-deleted-symlink-directory + " + +test_expect_success 'info --url symlink-directory (deleted)' ' + test "$(cd gitwc; git-svn info --url symlink-directory)" \ + = "$svnrepo/symlink-directory" + ' + +# NOTE: git does not have the concept of replaced objects, +# so we can't test for files in that state. + +test_expect_success 'info unknown-file' " + echo two > gitwc/unknown-file && + cp gitwc/unknown-file svnwc/unknown-file && + ptouch gitwc/unknown-file svnwc/unknown-file && + (cd svnwc; svn info unknown-file) 2> expected.info-unknown-file && + (cd gitwc; git-svn info unknown-file) 2> actual.info-unknown-file && + git-diff expected.info-unknown-file actual.info-unknown-file + " + +test_expect_success 'info --url unknown-file' ' + test -z "$(cd gitwc; git-svn info --url unknown-file \ + 2> ../actual.info--url-unknown-file)" && + git-diff expected.info-unknown-file actual.info--url-unknown-file + ' + +test_expect_success 'info unknown-directory' " + mkdir gitwc/unknown-directory svnwc/unknown-directory && + ptouch gitwc/unknown-directory svnwc/unknown-directory && + touch gitwc/unknown-directory/.placeholder && + (cd svnwc; svn info unknown-directory) \ + 2> expected.info-unknown-directory && + (cd gitwc; git-svn info unknown-directory) \ + 2> actual.info-unknown-directory && + git-diff expected.info-unknown-directory actual.info-unknown-directory + " + +test_expect_success 'info --url unknown-directory' ' + test -z "$(cd gitwc; git-svn info --url unknown-directory \ + 2> ../actual.info--url-unknown-directory)" && + git-diff expected.info-unknown-directory \ + actual.info--url-unknown-directory + ' + +test_expect_success 'info unknown-symlink-file' " + cd gitwc && + ln -s unknown-file unknown-symlink-file && + cd .. && + cd svnwc && + ln -s unknown-file unknown-symlink-file && + cd .. && + ptouch gitwc/unknown-symlink-file svnwc/unknown-symlink-file && + (cd svnwc; svn info unknown-symlink-file) \ + 2> expected.info-unknown-symlink-file && + (cd gitwc; git-svn info unknown-symlink-file) \ + 2> actual.info-unknown-symlink-file && + git-diff expected.info-unknown-symlink-file \ + actual.info-unknown-symlink-file + " + +test_expect_success 'info --url unknown-symlink-file' ' + test -z "$(cd gitwc; git-svn info --url unknown-symlink-file \ + 2> ../actual.info--url-unknown-symlink-file)" && + git-diff expected.info-unknown-symlink-file \ + actual.info--url-unknown-symlink-file + ' + +test_expect_success 'info unknown-symlink-directory' " + cd gitwc && + ln -s unknown-directory unknown-symlink-directory && + cd .. && + cd svnwc && + ln -s unknown-directory unknown-symlink-directory && + cd .. && + ptouch gitwc/unknown-symlink-directory \ + svnwc/unknown-symlink-directory && + (cd svnwc; svn info unknown-symlink-directory) \ + 2> expected.info-unknown-symlink-directory && + (cd gitwc; git-svn info unknown-symlink-directory) \ + 2> actual.info-unknown-symlink-directory && + git-diff expected.info-unknown-symlink-directory \ + actual.info-unknown-symlink-directory + " + +test_expect_success 'info --url unknown-symlink-directory' ' + test -z "$(cd gitwc; git-svn info --url unknown-symlink-directory \ + 2> ../actual.info--url-unknown-symlink-directory)" && + git-diff expected.info-unknown-symlink-directory \ + actual.info--url-unknown-symlink-directory + ' + +test_done diff --git a/t/t9120-git-svn-clone-with-percent-escapes.sh b/t/t9120-git-svn-clone-with-percent-escapes.sh new file mode 100755 index 0000000000..5979e133b9 --- /dev/null +++ b/t/t9120-git-svn-clone-with-percent-escapes.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# +# Copyright (c) 2008 Kevin Ballard +# + +test_description='git-svn clone with percent escapes' +. ./lib-git-svn.sh + +test_expect_success 'setup svnrepo' ' + mkdir project project/trunk project/branches project/tags && + echo foo > project/trunk/foo && + svn import -m "$test_description" project "$svnrepo/pr ject" && + rm -rf project && + start_httpd +' + +if test "$SVN_HTTPD_PORT" = "" +then + test_expect_failure 'test clone with percent escapes - needs SVN_HTTPD_PORT set' 'false' +else + test_expect_success 'test clone with percent escapes' ' + git svn clone "$svnrepo/pr%20ject" clone && + cd clone && + git rev-parse refs/remotes/git-svn && + cd .. + ' +fi + +stop_httpd + +test_done diff --git a/t/t9121-git-svn-fetch-renamed-dir.sh b/t/t9121-git-svn-fetch-renamed-dir.sh new file mode 100755 index 0000000000..99230b0810 --- /dev/null +++ b/t/t9121-git-svn-fetch-renamed-dir.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# +# Copyright (c) 2008 Santhosh Kumar Mani + + +test_description='git-svn can fetch renamed directories' + +. ./lib-git-svn.sh + +test_expect_success 'load repository with renamed directory' ' + svnadmin load -q "$rawsvnrepo" < ../t9121/renamed-dir.dump + ' + +test_expect_success 'init and fetch repository' ' + git svn init "$svnrepo/newname" && + git svn fetch + ' + +test_done + diff --git a/t/t9121/renamed-dir.dump b/t/t9121/renamed-dir.dump new file mode 100644 index 0000000000..5f9127be92 --- /dev/null +++ b/t/t9121/renamed-dir.dump @@ -0,0 +1,90 @@ +SVN-fs-dump-format-version: 2 + +UUID: 06b9b3ad-f546-4fbe-8328-fcb4e6ef5c3f + +Revision-number: 0 +Prop-content-length: 56 +Content-length: 56 + +K 8 +svn:date +V 27 +2008-04-02T09:11:59.778557Z +PROPS-END + +Revision-number: 1 +Prop-content-length: 117 +Content-length: 117 + +K 7 +svn:log +V 14 +initial import +K 10 +svn:author +V 8 +santhosh +K 8 +svn:date +V 27 +2008-04-02T09:13:03.170863Z +PROPS-END + +Node-path: name +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: name/a.txt +Node-kind: file +Node-action: add +Prop-content-length: 71 +Text-content-length: 6 +Text-content-md5: b1946ac92492d2347c6235b4d2611184 +Content-length: 77 + +K 13 +svn:mime-type +V 10 +text/plain +K 13 +svn:eol-style +V 2 +LF +PROPS-END +hello + + +Revision-number: 2 +Prop-content-length: 109 +Content-length: 109 + +K 7 +svn:log +V 7 +renamed +K 10 +svn:author +V 8 +santhosh +K 8 +svn:date +V 27 +2008-04-02T09:14:22.952186Z +PROPS-END + +Node-path: newname +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 1 +Node-copyfrom-path: name + + +Node-path: name +Node-action: delete + + diff --git a/t/t9122-git-svn-author.sh b/t/t9122-git-svn-author.sh new file mode 100755 index 0000000000..1190576a65 --- /dev/null +++ b/t/t9122-git-svn-author.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +test_description='git svn authorship' +. ./lib-git-svn.sh + +test_expect_success 'setup svn repository' ' + svn checkout "$svnrepo" work.svn && + ( + cd work.svn && + echo >file + svn add file + svn commit -m "first commit" file + ) +' + +test_expect_success 'interact with it via git-svn' ' + mkdir work.git && + ( + cd work.git && + git svn init "$svnrepo" + git svn fetch && + + echo modification >file && + test_tick && + git commit -a -m second && + + test_tick && + git svn dcommit && + + echo "further modification" >file && + test_tick && + git commit -a -m third && + + test_tick && + git svn --add-author-from dcommit && + + echo "yet further modification" >file && + test_tick && + git commit -a -m fourth && + + test_tick && + git svn --add-author-from --use-log-author dcommit && + + git log && + + git show -s HEAD^^ >../actual.2 && + git show -s HEAD^ >../actual.3 && + git show -s HEAD >../actual.4 + + ) && + + # Make sure that --add-author-from without --use-log-author + # did not affect the authorship information + myself=$(grep "^Author: " actual.2) && + unaffected=$(grep "^Author: " actual.3) && + test "z$myself" = "z$unaffected" && + + # Make sure lack of --add-author-from did not add cruft + ! grep "^ From: A U Thor " actual.2 && + + # Make sure --add-author-from added cruft + grep "^ From: A U Thor " actual.3 && + grep "^ From: A U Thor " actual.4 && + + # Make sure --add-author-from with --use-log-author affected + # the authorship information + grep "^Author: A U Thor " actual.4 && + + # Make sure there are no commit messages with excess blank lines + test $(grep "^ " actual.2 | wc -l) = 3 && + test $(grep "^ " actual.3 | wc -l) = 5 && + test $(grep "^ " actual.4 | wc -l) = 5 && + + # Make sure there are no svn commit messages with excess blank lines + ( + cd work.svn && + svn up && + + test $(svn log -r2:2 | wc -l) = 5 && + test $(svn log -r4:4 | wc -l) = 7 + ) +' + +test_done diff --git a/t/t9123-git-svn-rebuild-with-rewriteroot.sh b/t/t9123-git-svn-rebuild-with-rewriteroot.sh new file mode 100755 index 0000000000..c18878fad1 --- /dev/null +++ b/t/t9123-git-svn-rebuild-with-rewriteroot.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# +# Copyright (c) 2008 Jan Krüger +# + +test_description='git-svn respects rewriteRoot during rebuild' + +. ./lib-git-svn.sh + +mkdir import +cd import + touch foo + svn import -m 'import for git-svn' . "$svnrepo" >/dev/null +cd .. +rm -rf import + +test_expect_success 'init, fetch and checkout repository' ' + git svn init --rewrite-root=http://invalid.invalid/ "$svnrepo" && + git svn fetch + git checkout -b mybranch remotes/git-svn + ' + +test_expect_success 'remove rev_map' ' + rm "$GIT_SVN_DIR"/.rev_map.* + ' + +test_expect_success 'rebuild rev_map' ' + git svn rebase >/dev/null + ' + +test_done + diff --git a/t/t9124-git-svn-dcommit-auto-props.sh b/t/t9124-git-svn-dcommit-auto-props.sh new file mode 100755 index 0000000000..8223c5909e --- /dev/null +++ b/t/t9124-git-svn-dcommit-auto-props.sh @@ -0,0 +1,86 @@ +#!/bin/sh +# +# Copyright (c) 2008 Brad King + +test_description='git-svn dcommit honors auto-props' + +. ./lib-git-svn.sh + +generate_auto_props() { +cat << EOF +[miscellany] +enable-auto-props=$1 +[auto-props] +*.sh = svn:mime-type=application/x-shellscript; svn:eol-style=LF +*.txt = svn:mime-type=text/plain; svn:eol-style = native +EOF +} + +test_expect_success 'initialize git-svn' ' + mkdir import && + ( + cd import && + echo foo >foo && + svn import -m "import for git-svn" . "$svnrepo" + ) && + rm -rf import && + git-svn init "$svnrepo" + git-svn fetch +' + +test_expect_success 'enable auto-props config' ' + cd "$gittestrepo" && + mkdir user && + generate_auto_props yes >user/config +' + +test_expect_success 'add files matching auto-props' ' + cd "$gittestrepo" && + echo "#!$SHELL_PATH" >exec1.sh && + chmod +x exec1.sh && + echo "hello" >hello.txt && + echo bar >bar && + git add exec1.sh hello.txt bar && + git commit -m "files for enabled auto-props" && + git svn dcommit --config-dir=user +' + +test_expect_success 'disable auto-props config' ' + cd "$gittestrepo" && + generate_auto_props no >user/config +' + +test_expect_success 'add files matching disabled auto-props' ' + cd "$gittestrepo" && + echo "#$SHELL_PATH" >exec2.sh && + chmod +x exec2.sh && + echo "world" >world.txt && + echo zot >zot && + git add exec2.sh world.txt zot && + git commit -m "files for disabled auto-props" && + git svn dcommit --config-dir=user +' + +test_expect_success 'check resulting svn repository' ' + mkdir work && + cd work && + svn co "$svnrepo" && + cd svnrepo && + + # Check properties from first commit. + test "x$(svn propget svn:executable exec1.sh)" = "x*" && + test "x$(svn propget svn:mime-type exec1.sh)" = \ + "xapplication/x-shellscript" && + test "x$(svn propget svn:mime-type hello.txt)" = "xtext/plain" && + test "x$(svn propget svn:eol-style hello.txt)" = "xnative" && + test "x$(svn propget svn:mime-type bar)" = "x" && + + # Check properties from second commit. + test "x$(svn propget svn:executable exec2.sh)" = "x*" && + test "x$(svn propget svn:mime-type exec2.sh)" = "x" && + test "x$(svn propget svn:mime-type world.txt)" = "x" && + test "x$(svn propget svn:eol-style world.txt)" = "x" && + test "x$(svn propget svn:mime-type zot)" = "x" +' + +test_done diff --git a/t/t9125-git-svn-multi-glob-branch-names.sh b/t/t9125-git-svn-multi-glob-branch-names.sh new file mode 100755 index 0000000000..6b62b52f54 --- /dev/null +++ b/t/t9125-git-svn-multi-glob-branch-names.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# Copyright (c) 2008 Marcus Griep + +test_description='git-svn multi-glob branch names' +. ./lib-git-svn.sh + +test_expect_success 'setup svnrepo' ' + mkdir project project/trunk project/branches \ + project/branches/v14.1 project/tags && + echo foo > project/trunk/foo && + svn import -m "$test_description" project "$svnrepo/project" && + rm -rf project && + svn cp -m "fun" "$svnrepo/project/trunk" \ + "$svnrepo/project/branches/v14.1/beta" && + svn cp -m "more fun!" "$svnrepo/project/branches/v14.1/beta" \ + "$svnrepo/project/branches/v14.1/gold" + ' + +test_expect_success 'test clone with multi-glob in branch names' ' + git svn clone -T trunk -b branches/*/* -t tags \ + "$svnrepo/project" project && + cd project && + git rev-parse "refs/remotes/v14.1/beta" && + git rev-parse "refs/remotes/v14.1/gold" && + cd .. + ' + +test_expect_success 'test dcommit to multi-globbed branch' " + cd project && + git reset --hard 'refs/remotes/v14.1/gold' && + echo hello >> foo && + git commit -m 'hello' -- foo && + git svn dcommit && + cd .. + " + +test_done diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh new file mode 100755 index 0000000000..3e32e84e6c --- /dev/null +++ b/t/t9200-git-cvsexportcommit.sh @@ -0,0 +1,317 @@ +#!/bin/sh +# +# Copyright (c) Robin Rosenberg +# +test_description='Test export of commits to CVS' + +. ./test-lib.sh + +cvs >/dev/null 2>&1 +if test $? -ne 1 +then + test_expect_success 'skipping git-cvsexportcommit tests, cvs not found' : + test_done + exit +fi + +CVSROOT=$(pwd)/cvsroot +CVSWORK=$(pwd)/cvswork +GIT_DIR=$(pwd)/.git +export CVSROOT CVSWORK GIT_DIR + +rm -rf "$CVSROOT" "$CVSWORK" +mkdir "$CVSROOT" && +cvs init && +cvs -Q co -d "$CVSWORK" . && +echo >empty && +git add empty && +git commit -q -a -m "Initial" 2>/dev/null || +exit 1 + +check_entries () { + # $1 == directory, $2 == expected + grep '^/' "$1/CVS/Entries" | sort | cut -d/ -f2,3,5 >actual + if test -z "$2" + then + >expected + else + printf '%s\n' "$2" | tr '|' '\012' >expected + fi + test_cmp expected actual +} + +test_expect_success \ + 'New file' \ + 'mkdir A B C D E F && + echo hello1 >A/newfile1.txt && + echo hello2 >B/newfile2.txt && + cp ../test9200a.png C/newfile3.png && + cp ../test9200a.png D/newfile4.png && + git add A/newfile1.txt && + git add B/newfile2.txt && + git add C/newfile3.png && + git add D/newfile4.png && + git commit -a -m "Test: New file" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + check_entries A "newfile1.txt/1.1/" && + check_entries B "newfile2.txt/1.1/" && + check_entries C "newfile3.png/1.1/-kb" && + check_entries D "newfile4.png/1.1/-kb" && + diff A/newfile1.txt ../A/newfile1.txt && + diff B/newfile2.txt ../B/newfile2.txt && + diff C/newfile3.png ../C/newfile3.png && + diff D/newfile4.png ../D/newfile4.png + )' + +test_expect_success \ + 'Remove two files, add two and update two' \ + 'echo Hello1 >>A/newfile1.txt && + rm -f B/newfile2.txt && + rm -f C/newfile3.png && + echo Hello5 >E/newfile5.txt && + cp ../test9200b.png D/newfile4.png && + cp ../test9200a.png F/newfile6.png && + git add E/newfile5.txt && + git add F/newfile6.png && + git commit -a -m "Test: Remove, add and update" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + check_entries A "newfile1.txt/1.2/" && + check_entries B "" && + check_entries C "" && + check_entries D "newfile4.png/1.2/-kb" && + check_entries E "newfile5.txt/1.1/" && + check_entries F "newfile6.png/1.1/-kb" && + diff A/newfile1.txt ../A/newfile1.txt && + diff D/newfile4.png ../D/newfile4.png && + diff E/newfile5.txt ../E/newfile5.txt && + diff F/newfile6.png ../F/newfile6.png + )' + +# Should fail (but only on the git-cvsexportcommit stage) +test_expect_success \ + 'Fail to change binary more than one generation old' \ + 'cat F/newfile6.png >>D/newfile4.png && + git commit -a -m "generatiion 1" && + cat F/newfile6.png >>D/newfile4.png && + git commit -a -m "generation 2" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + test_must_fail git cvsexportcommit -c $id + )' + +#test_expect_success \ +# 'Fail to remove binary file more than one generation old' \ +# 'git reset --hard HEAD^ && +# cat F/newfile6.png >>D/newfile4.png && +# git commit -a -m "generation 2 (again)" && +# rm -f D/newfile4.png && +# git commit -a -m "generation 3" && +# id=$(git rev-list --max-count=1 HEAD) && +# (cd "$CVSWORK" && +# test_must_fail git cvsexportcommit -c $id +# )' + +# We reuse the state from two tests back here + +# This test is here because a patch for only binary files will +# fail with gnu patch, so cvsexportcommit must handle that. +test_expect_success \ + 'Remove only binary files' \ + 'git reset --hard HEAD^^ && + rm -f D/newfile4.png && + git commit -a -m "test: remove only a binary file" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + check_entries A "newfile1.txt/1.2/" && + check_entries B "" && + check_entries C "" && + check_entries D "" && + check_entries E "newfile5.txt/1.1/" && + check_entries F "newfile6.png/1.1/-kb" && + diff A/newfile1.txt ../A/newfile1.txt && + diff E/newfile5.txt ../E/newfile5.txt && + diff F/newfile6.png ../F/newfile6.png + )' + +test_expect_success \ + 'Remove only a text file' \ + 'rm -f A/newfile1.txt && + git commit -a -m "test: remove only a binary file" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + check_entries A "" && + check_entries B "" && + check_entries C "" && + check_entries D "" && + check_entries E "newfile5.txt/1.1/" && + check_entries F "newfile6.png/1.1/-kb" && + diff E/newfile5.txt ../E/newfile5.txt && + diff F/newfile6.png ../F/newfile6.png + )' + +test_expect_success \ + 'New file with spaces in file name' \ + 'mkdir "G g" && + echo ok then >"G g/with spaces.txt" && + git add "G g/with spaces.txt" && \ + cp ../test9200a.png "G g/with spaces.png" && \ + git add "G g/with spaces.png" && + git commit -a -m "With spaces" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git-cvsexportcommit -c $id && + check_entries "G g" "with spaces.png/1.1/-kb|with spaces.txt/1.1/" + )' + +test_expect_success \ + 'Update file with spaces in file name' \ + 'echo Ok then >>"G g/with spaces.txt" && + cat ../test9200a.png >>"G g/with spaces.png" && \ + git add "G g/with spaces.png" && + git commit -a -m "Update with spaces" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git-cvsexportcommit -c $id + check_entries "G g" "with spaces.png/1.2/-kb|with spaces.txt/1.2/" + )' + +# Some filesystems mangle pathnames with UTF-8 characters -- +# check and skip +if p="Ã…/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/Ã¥/ä/ö" && + mkdir -p "tst/$p" && + date >"tst/$p/day" && + found=$(find tst -type f -print) && + test "z$found" = "ztst/$p/day" && + rm -fr tst +then + +# This test contains UTF-8 characters +test_expect_success \ + 'File with non-ascii file name' \ + 'mkdir -p Ã…/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/Ã¥/ä/ö && + echo Foo >Ã…/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/Ã¥/ä/ö/gÃ¥rdetsÃ¥gÃ¥rdet.txt && + git add Ã…/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/Ã¥/ä/ö/gÃ¥rdetsÃ¥gÃ¥rdet.txt && + cp ../test9200a.png Ã…/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/Ã¥/ä/ö/gÃ¥rdetsÃ¥gÃ¥rdet.png && + git add Ã…/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/Ã¥/ä/ö/gÃ¥rdetsÃ¥gÃ¥rdet.png && + git commit -a -m "GÃ¥r det sÃ¥ gÃ¥r det" && \ + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git-cvsexportcommit -v -c $id && + check_entries \ + "Ã…/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/Ã¥/ä/ö" \ + "gÃ¥rdetsÃ¥gÃ¥rdet.png/1.1/-kb|gÃ¥rdetsÃ¥gÃ¥rdet.txt/1.1/" + )' + +fi + +rm -fr tst + +test_expect_success \ + 'Mismatching patch should fail' \ + 'date >>"E/newfile5.txt" && + git add "E/newfile5.txt" && + git commit -a -m "Update one" && + date >>"E/newfile5.txt" && + git add "E/newfile5.txt" && + git commit -a -m "Update two" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + test_must_fail git-cvsexportcommit -c $id + )' + +case "$(git config --bool core.filemode)" in +false) + ;; +*) +test_expect_success \ + 'Retain execute bit' \ + 'mkdir G && + echo executeon >G/on && + chmod +x G/on && + echo executeoff >G/off && + git add G/on && + git add G/off && + git commit -a -m "Execute test" && + (cd "$CVSWORK" && + git-cvsexportcommit -c HEAD + test -x G/on && + ! test -x G/off + )' + ;; +esac + +test_expect_success '-w option should work with relative GIT_DIR' ' + mkdir W && + echo foobar >W/file1.txt && + echo bazzle >W/file2.txt && + git add W/file1.txt && + git add W/file2.txt && + git commit -m "More updates" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$GIT_DIR" && + GIT_DIR=. git cvsexportcommit -w "$CVSWORK" -c $id && + check_entries "$CVSWORK/W" "file1.txt/1.1/|file2.txt/1.1/" && + test_cmp "$CVSWORK/W/file1.txt" ../W/file1.txt && + test_cmp "$CVSWORK/W/file2.txt" ../W/file2.txt + ) +' + +test_expect_success 'check files before directories' ' + + echo Notes > release-notes && + git add release-notes && + git commit -m "Add release notes" release-notes && + id=$(git rev-parse HEAD) && + git cvsexportcommit -w "$CVSWORK" -c $id && + + echo new > DS && + echo new > E/DS && + echo modified > release-notes && + git add DS E/DS release-notes && + git commit -m "Add two files with the same basename" && + id=$(git rev-parse HEAD) && + git cvsexportcommit -w "$CVSWORK" -c $id && + check_entries "$CVSWORK/E" "DS/1.1/|newfile5.txt/1.1/" && + check_entries "$CVSWORK" "DS/1.1/|release-notes/1.2/" && + test_cmp "$CVSWORK/DS" DS && + test_cmp "$CVSWORK/E/DS" E/DS && + test_cmp "$CVSWORK/release-notes" release-notes + +' + +test_expect_success 'commit a file with leading spaces in the name' ' + + echo space > " space" && + git add " space" && + git commit -m "Add a file with a leading space" && + id=$(git rev-parse HEAD) && + git cvsexportcommit -w "$CVSWORK" -c $id && + check_entries "$CVSWORK" " space/1.1/|DS/1.1/|release-notes/1.2/" && + test_cmp "$CVSWORK/ space" " space" + +' + +test_expect_success 'use the same checkout for Git and CVS' ' + + (mkdir shared && + cd shared && + unset GIT_DIR && + cvs co . && + git init && + git add " space" && + git commit -m "fake initial commit" && + echo Hello >> " space" && + git commit -m "Another change" " space" && + git cvsexportcommit -W -p -u -c HEAD && + grep Hello " space" && + git diff-files) + +' + +test_done diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh new file mode 100755 index 0000000000..1fc06c5a23 --- /dev/null +++ b/t/t9300-fast-import.sh @@ -0,0 +1,1073 @@ +#!/bin/sh +# +# Copyright (c) 2007 Shawn Pearce +# + +test_description='test git-fast-import utility' +. ./test-lib.sh +. ../diff-lib.sh ;# test-lib chdir's into trash + +file2_data='file2 +second line of EOF' + +file3_data='EOF +in 3rd file + END' + +file4_data=abcd +file4_len=4 + +file5_data='an inline file. + we should see it later.' + +file6_data='#!/bin/sh +echo "$@"' + +### +### series A +### + +test_tick +cat >input <<INPUT_END +blob +mark :2 +data <<EOF +$file2_data +EOF + +blob +mark :3 +data <<END +$file3_data +END + +blob +mark :4 +data $file4_len +$file4_data +commit refs/heads/master +mark :5 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +initial +COMMIT + +M 644 :2 file2 +M 644 :3 file3 +M 755 :4 file4 + +INPUT_END +test_expect_success \ + 'A: create pack from stdin' \ + 'git-fast-import --export-marks=marks.out <input && + git whatchanged master' +test_expect_success \ + 'A: verify pack' \ + 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done' + +cat >expect <<EOF +author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + +initial +EOF +test_expect_success \ + 'A: verify commit' \ + 'git cat-file commit master | sed 1d >actual && + test_cmp expect actual' + +cat >expect <<EOF +100644 blob file2 +100644 blob file3 +100755 blob file4 +EOF +test_expect_success \ + 'A: verify tree' \ + 'git cat-file -p master^{tree} | sed "s/ [0-9a-f]* / /" >actual && + test_cmp expect actual' + +echo "$file2_data" >expect +test_expect_success \ + 'A: verify file2' \ + 'git cat-file blob master:file2 >actual && test_cmp expect actual' + +echo "$file3_data" >expect +test_expect_success \ + 'A: verify file3' \ + 'git cat-file blob master:file3 >actual && test_cmp expect actual' + +printf "$file4_data" >expect +test_expect_success \ + 'A: verify file4' \ + 'git cat-file blob master:file4 >actual && test_cmp expect actual' + +cat >expect <<EOF +:2 `git rev-parse --verify master:file2` +:3 `git rev-parse --verify master:file3` +:4 `git rev-parse --verify master:file4` +:5 `git rev-parse --verify master^0` +EOF +test_expect_success \ + 'A: verify marks output' \ + 'test_cmp expect marks.out' + +test_expect_success \ + 'A: verify marks import' \ + 'git-fast-import \ + --import-marks=marks.out \ + --export-marks=marks.new \ + </dev/null && + test_cmp expect marks.new' + +test_tick +cat >input <<INPUT_END +commit refs/heads/verify--import-marks +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +recreate from :5 +COMMIT + +from :5 +M 755 :2 copy-of-file2 + +INPUT_END +test_expect_success \ + 'A: verify marks import does not crash' \ + 'git-fast-import --import-marks=marks.out <input && + git whatchanged verify--import-marks' +test_expect_success \ + 'A: verify pack' \ + 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done' +cat >expect <<EOF +:000000 100755 0000000000000000000000000000000000000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 A copy-of-file2 +EOF +git diff-tree -M -r master verify--import-marks >actual +test_expect_success \ + 'A: verify diff' \ + 'compare_diff_raw expect actual && + test `git rev-parse --verify master:file2` \ + = `git rev-parse --verify verify--import-marks:copy-of-file2`' + +### +### series B +### + +test_tick +cat >input <<INPUT_END +commit refs/heads/branch +mark :1 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +corrupt +COMMIT + +from refs/heads/master +M 755 0000000000000000000000000000000000000001 zero1 + +INPUT_END +test_expect_success 'B: fail on invalid blob sha1' ' + test_must_fail git-fast-import <input +' +rm -f .git/objects/pack_* .git/objects/index_* + +cat >input <<INPUT_END +commit .badbranchname +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +corrupt +COMMIT + +from refs/heads/master + +INPUT_END +test_expect_success 'B: fail on invalid branch name ".badbranchname"' ' + test_must_fail git-fast-import <input +' +rm -f .git/objects/pack_* .git/objects/index_* + +cat >input <<INPUT_END +commit bad[branch]name +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +corrupt +COMMIT + +from refs/heads/master + +INPUT_END +test_expect_success 'B: fail on invalid branch name "bad[branch]name"' ' + test_must_fail git-fast-import <input +' +rm -f .git/objects/pack_* .git/objects/index_* + +cat >input <<INPUT_END +commit TEMP_TAG +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +tag base +COMMIT + +from refs/heads/master + +INPUT_END +test_expect_success \ + 'B: accept branch name "TEMP_TAG"' \ + 'git-fast-import <input && + test -f .git/TEMP_TAG && + test `git rev-parse master` = `git rev-parse TEMP_TAG^`' +rm -f .git/TEMP_TAG + +### +### series C +### + +newf=`echo hi newf | git-hash-object -w --stdin` +oldf=`git rev-parse --verify master:file2` +test_tick +cat >input <<INPUT_END +commit refs/heads/branch +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +second +COMMIT + +from refs/heads/master +M 644 $oldf file2/oldf +M 755 $newf file2/newf +D file3 + +INPUT_END +test_expect_success \ + 'C: incremental import create pack from stdin' \ + 'git-fast-import <input && + git whatchanged branch' +test_expect_success \ + 'C: verify pack' \ + 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done' +test_expect_success \ + 'C: validate reuse existing blob' \ + 'test $newf = `git rev-parse --verify branch:file2/newf` + test $oldf = `git rev-parse --verify branch:file2/oldf`' + +cat >expect <<EOF +parent `git rev-parse --verify master^0` +author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + +second +EOF +test_expect_success \ + 'C: verify commit' \ + 'git cat-file commit branch | sed 1d >actual && + test_cmp expect actual' + +cat >expect <<EOF +:000000 100755 0000000000000000000000000000000000000000 f1fb5da718392694d0076d677d6d0e364c79b0bc A file2/newf +:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100 file2 file2/oldf +:100644 000000 0d92e9f3374ae2947c23aa477cbc68ce598135f1 0000000000000000000000000000000000000000 D file3 +EOF +git diff-tree -M -r master branch >actual +test_expect_success \ + 'C: validate rename result' \ + 'compare_diff_raw expect actual' + +### +### series D +### + +test_tick +cat >input <<INPUT_END +commit refs/heads/branch +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +third +COMMIT + +from refs/heads/branch^0 +M 644 inline newdir/interesting +data <<EOF +$file5_data +EOF + +M 755 inline newdir/exec.sh +data <<EOF +$file6_data +EOF + +INPUT_END +test_expect_success \ + 'D: inline data in commit' \ + 'git-fast-import <input && + git whatchanged branch' +test_expect_success \ + 'D: verify pack' \ + 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done' + +cat >expect <<EOF +:000000 100755 0000000000000000000000000000000000000000 35a59026a33beac1569b1c7f66f3090ce9c09afc A newdir/exec.sh +:000000 100644 0000000000000000000000000000000000000000 046d0371e9220107917db0d0e030628de8a1de9b A newdir/interesting +EOF +git diff-tree -M -r branch^ branch >actual +test_expect_success \ + 'D: validate new files added' \ + 'compare_diff_raw expect actual' + +echo "$file5_data" >expect +test_expect_success \ + 'D: verify file5' \ + 'git cat-file blob branch:newdir/interesting >actual && + test_cmp expect actual' + +echo "$file6_data" >expect +test_expect_success \ + 'D: verify file6' \ + 'git cat-file blob branch:newdir/exec.sh >actual && + test_cmp expect actual' + +### +### series E +### + +cat >input <<INPUT_END +commit refs/heads/branch +author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> Tue Feb 6 11:22:18 2007 -0500 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> Tue Feb 6 12:35:02 2007 -0500 +data <<COMMIT +RFC 2822 type date +COMMIT + +from refs/heads/branch^0 + +INPUT_END +test_expect_success 'E: rfc2822 date, --date-format=raw' ' + test_must_fail git-fast-import --date-format=raw <input +' +test_expect_success \ + 'E: rfc2822 date, --date-format=rfc2822' \ + 'git-fast-import --date-format=rfc2822 <input' +test_expect_success \ + 'E: verify pack' \ + 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done' + +cat >expect <<EOF +author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 1170778938 -0500 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1170783302 -0500 + +RFC 2822 type date +EOF +test_expect_success \ + 'E: verify commit' \ + 'git cat-file commit branch | sed 1,2d >actual && + test_cmp expect actual' + +### +### series F +### + +old_branch=`git rev-parse --verify branch^0` +test_tick +cat >input <<INPUT_END +commit refs/heads/branch +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +losing things already? +COMMIT + +from refs/heads/branch~1 + +reset refs/heads/other +from refs/heads/branch + +INPUT_END +test_expect_success \ + 'F: non-fast-forward update skips' \ + 'if git-fast-import <input + then + echo BAD gfi did not fail + return 1 + else + if test $old_branch = `git rev-parse --verify branch^0` + then + : branch unaffected and failure returned + return 0 + else + echo BAD gfi changed branch $old_branch + return 1 + fi + fi + ' +test_expect_success \ + 'F: verify pack' \ + 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done' + +cat >expect <<EOF +tree `git rev-parse branch~1^{tree}` +parent `git rev-parse branch~1` +author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + +losing things already? +EOF +test_expect_success \ + 'F: verify other commit' \ + 'git cat-file commit other >actual && + test_cmp expect actual' + +### +### series G +### + +old_branch=`git rev-parse --verify branch^0` +test_tick +cat >input <<INPUT_END +commit refs/heads/branch +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +losing things already? +COMMIT + +from refs/heads/branch~1 + +INPUT_END +test_expect_success \ + 'G: non-fast-forward update forced' \ + 'git-fast-import --force <input' +test_expect_success \ + 'G: verify pack' \ + 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done' +test_expect_success \ + 'G: branch changed, but logged' \ + 'test $old_branch != `git rev-parse --verify branch^0` && + test $old_branch = `git rev-parse --verify branch@{1}`' + +### +### series H +### + +test_tick +cat >input <<INPUT_END +commit refs/heads/H +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +third +COMMIT + +from refs/heads/branch^0 +M 644 inline i-will-die +data <<EOF +this file will never exist. +EOF + +deleteall +M 644 inline h/e/l/lo +data <<EOF +$file5_data +EOF + +INPUT_END +test_expect_success \ + 'H: deletall, add 1' \ + 'git-fast-import <input && + git whatchanged H' +test_expect_success \ + 'H: verify pack' \ + 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done' + +cat >expect <<EOF +:100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D file2/newf +:100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D file2/oldf +:100755 000000 85df50785d62d3b05ab03d9cbf7e4a0b49449730 0000000000000000000000000000000000000000 D file4 +:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100 newdir/interesting h/e/l/lo +:100755 000000 e74b7d465e52746be2b4bae983670711e6e66657 0000000000000000000000000000000000000000 D newdir/exec.sh +EOF +git diff-tree -M -r H^ H >actual +test_expect_success \ + 'H: validate old files removed, new files added' \ + 'compare_diff_raw expect actual' + +echo "$file5_data" >expect +test_expect_success \ + 'H: verify file' \ + 'git cat-file blob H:h/e/l/lo >actual && + test_cmp expect actual' + +### +### series I +### + +cat >input <<INPUT_END +commit refs/heads/export-boundary +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +we have a border. its only 40 characters wide. +COMMIT + +from refs/heads/branch + +INPUT_END +test_expect_success \ + 'I: export-pack-edges' \ + 'git-fast-import --export-pack-edges=edges.list <input' + +cat >expect <<EOF +.git/objects/pack/pack-.pack: `git rev-parse --verify export-boundary` +EOF +test_expect_success \ + 'I: verify edge list' \ + 'sed -e s/pack-.*pack/pack-.pack/ edges.list >actual && + test_cmp expect actual' + +### +### series J +### + +cat >input <<INPUT_END +commit refs/heads/J +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +create J +COMMIT + +from refs/heads/branch + +reset refs/heads/J + +commit refs/heads/J +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +initialize J +COMMIT + +INPUT_END +test_expect_success \ + 'J: reset existing branch creates empty commit' \ + 'git-fast-import <input' +test_expect_success \ + 'J: branch has 1 commit, empty tree' \ + 'test 1 = `git rev-list J | wc -l` && + test 0 = `git ls-tree J | wc -l`' + +### +### series K +### + +cat >input <<INPUT_END +commit refs/heads/K +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +create K +COMMIT + +from refs/heads/branch + +commit refs/heads/K +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +redo K +COMMIT + +from refs/heads/branch^1 + +INPUT_END +test_expect_success \ + 'K: reinit branch with from' \ + 'git-fast-import <input' +test_expect_success \ + 'K: verify K^1 = branch^1' \ + 'test `git rev-parse --verify branch^1` \ + = `git rev-parse --verify K^1`' + +### +### series L +### + +cat >input <<INPUT_END +blob +mark :1 +data <<EOF +some data +EOF + +blob +mark :2 +data <<EOF +other data +EOF + +commit refs/heads/L +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +create L +COMMIT + +M 644 :1 b. +M 644 :1 b/other +M 644 :1 ba + +commit refs/heads/L +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +update L +COMMIT + +M 644 :2 b. +M 644 :2 b/other +M 644 :2 ba +INPUT_END + +cat >expect <<EXPECT_END +:100644 100644 4268632... 55d3a52... M b. +:040000 040000 0ae5cac... 443c768... M b +:100644 100644 4268632... 55d3a52... M ba +EXPECT_END + +test_expect_success \ + 'L: verify internal tree sorting' \ + 'git-fast-import <input && + git diff-tree --abbrev --raw L^ L >output && + test_cmp expect output' + +### +### series M +### + +test_tick +cat >input <<INPUT_END +commit refs/heads/M1 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +file rename +COMMIT + +from refs/heads/branch^0 +R file2/newf file2/n.e.w.f + +INPUT_END + +cat >expect <<EOF +:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 file2/newf file2/n.e.w.f +EOF +test_expect_success \ + 'M: rename file in same subdirectory' \ + 'git-fast-import <input && + git diff-tree -M -r M1^ M1 >actual && + compare_diff_raw expect actual' + +cat >input <<INPUT_END +commit refs/heads/M2 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +file rename +COMMIT + +from refs/heads/branch^0 +R file2/newf i/am/new/to/you + +INPUT_END + +cat >expect <<EOF +:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 file2/newf i/am/new/to/you +EOF +test_expect_success \ + 'M: rename file to new subdirectory' \ + 'git-fast-import <input && + git diff-tree -M -r M2^ M2 >actual && + compare_diff_raw expect actual' + +cat >input <<INPUT_END +commit refs/heads/M3 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +file rename +COMMIT + +from refs/heads/M2^0 +R i other/sub + +INPUT_END + +cat >expect <<EOF +:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 i/am/new/to/you other/sub/am/new/to/you +EOF +test_expect_success \ + 'M: rename subdirectory to new subdirectory' \ + 'git-fast-import <input && + git diff-tree -M -r M3^ M3 >actual && + compare_diff_raw expect actual' + +### +### series N +### + +test_tick +cat >input <<INPUT_END +commit refs/heads/N1 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +file copy +COMMIT + +from refs/heads/branch^0 +C file2/newf file2/n.e.w.f + +INPUT_END + +cat >expect <<EOF +:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file2/n.e.w.f +EOF +test_expect_success \ + 'N: copy file in same subdirectory' \ + 'git-fast-import <input && + git diff-tree -C --find-copies-harder -r N1^ N1 >actual && + compare_diff_raw expect actual' + +cat >input <<INPUT_END +commit refs/heads/N2 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +clean directory copy +COMMIT + +from refs/heads/branch^0 +C file2 file3 + +commit refs/heads/N2 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +modify directory copy +COMMIT + +M 644 inline file3/file5 +data <<EOF +$file5_data +EOF + +INPUT_END + +cat >expect <<EOF +:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting file3/file5 +:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf +:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf +EOF +test_expect_success \ + 'N: copy then modify subdirectory' \ + 'git-fast-import <input && + git diff-tree -C --find-copies-harder -r N2^^ N2 >actual && + compare_diff_raw expect actual' + +cat >input <<INPUT_END +commit refs/heads/N3 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +dirty directory copy +COMMIT + +from refs/heads/branch^0 +M 644 inline file2/file5 +data <<EOF +$file5_data +EOF + +C file2 file3 +D file2/file5 + +INPUT_END + +test_expect_success \ + 'N: copy dirty subdirectory' \ + 'git-fast-import <input && + test `git-rev-parse N2^{tree}` = `git-rev-parse N3^{tree}`' + +### +### series O +### + +cat >input <<INPUT_END +#we will +commit refs/heads/O1 +# -- ignore all of this text +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +# $GIT_COMMITTER_NAME has inserted here for his benefit. +data <<COMMIT +dirty directory copy +COMMIT + +# don't forget the import blank line! +# +# yes, we started from our usual base of branch^0. +# i like branch^0. +from refs/heads/branch^0 +# and we need to reuse file2/file5 from N3 above. +M 644 inline file2/file5 +# otherwise the tree will be different +data <<EOF +$file5_data +EOF + +# don't forget to copy file2 to file3 +C file2 file3 +# +# or to delete file5 from file2. +D file2/file5 +# are we done yet? + +INPUT_END + +test_expect_success \ + 'O: comments are all skipped' \ + 'git-fast-import <input && + test `git-rev-parse N3` = `git-rev-parse O1`' + +cat >input <<INPUT_END +commit refs/heads/O2 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +dirty directory copy +COMMIT +from refs/heads/branch^0 +M 644 inline file2/file5 +data <<EOF +$file5_data +EOF +C file2 file3 +D file2/file5 + +INPUT_END + +test_expect_success \ + 'O: blank lines not necessary after data commands' \ + 'git-fast-import <input && + test `git-rev-parse N3` = `git-rev-parse O2`' + +test_expect_success \ + 'O: repack before next test' \ + 'git repack -a -d' + +cat >input <<INPUT_END +commit refs/heads/O3 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +zstring +COMMIT +commit refs/heads/O3 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +zof +COMMIT +checkpoint +commit refs/heads/O3 +mark :5 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +zempty +COMMIT +checkpoint +commit refs/heads/O3 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +zcommits +COMMIT +reset refs/tags/O3-2nd +from :5 +reset refs/tags/O3-3rd +from :5 +INPUT_END + +cat >expect <<INPUT_END +string +of +empty +commits +INPUT_END +test_expect_success \ + 'O: blank lines not necessary after other commands' \ + 'git-fast-import <input && + test 8 = `find .git/objects/pack -type f | wc -l` && + test `git rev-parse refs/tags/O3-2nd` = `git rev-parse O3^` && + git log --reverse --pretty=oneline O3 | sed s/^.*z// >actual && + test_cmp expect actual' + +cat >input <<INPUT_END +commit refs/heads/O4 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +zstring +COMMIT +commit refs/heads/O4 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +zof +COMMIT +progress Two commits down, 2 to go! +commit refs/heads/O4 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +zempty +COMMIT +progress Three commits down, 1 to go! +commit refs/heads/O4 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +zcommits +COMMIT +progress I'm done! +INPUT_END +test_expect_success \ + 'O: progress outputs as requested by input' \ + 'git-fast-import <input >actual && + grep "progress " <input >expect && + test_cmp expect actual' + +### +### series P (gitlinks) +### + +cat >input <<INPUT_END +blob +mark :1 +data 10 +test file + +reset refs/heads/sub +commit refs/heads/sub +mark :2 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data 12 +sub_initial +M 100644 :1 file + +blob +mark :3 +data <<DATAEND +[submodule "sub"] + path = sub + url = "`pwd`/sub" +DATAEND + +commit refs/heads/subuse1 +mark :4 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data 8 +initial +from refs/heads/master +M 100644 :3 .gitmodules +M 160000 :2 sub + +blob +mark :5 +data 20 +test file +more data + +commit refs/heads/sub +mark :6 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data 11 +sub_second +from :2 +M 100644 :5 file + +commit refs/heads/subuse1 +mark :7 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data 7 +second +from :4 +M 160000 :6 sub + +INPUT_END + +test_expect_success \ + 'P: supermodule & submodule mix' \ + 'git-fast-import <input && + git checkout subuse1 && + rm -rf sub && mkdir sub && cd sub && + git init && + git fetch .. refs/heads/sub:refs/heads/master && + git checkout master && + cd .. && + git submodule init && + git submodule update' + +SUBLAST=$(git-rev-parse --verify sub) +SUBPREV=$(git-rev-parse --verify sub^) + +cat >input <<INPUT_END +blob +mark :1 +data <<DATAEND +[submodule "sub"] + path = sub + url = "`pwd`/sub" +DATAEND + +commit refs/heads/subuse2 +mark :2 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data 8 +initial +from refs/heads/master +M 100644 :1 .gitmodules +M 160000 $SUBPREV sub + +commit refs/heads/subuse2 +mark :3 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data 7 +second +from :2 +M 160000 $SUBLAST sub + +INPUT_END + +test_expect_success \ + 'P: verbatim SHA gitlinks' \ + 'git branch -D sub && + git gc && git prune && + git-fast-import <input && + test $(git-rev-parse --verify subuse2) = $(git-rev-parse --verify subuse1)' + +test_tick +cat >input <<INPUT_END +commit refs/heads/subuse3 +mark :1 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +corrupt +COMMIT + +from refs/heads/subuse2 +M 160000 inline sub +data <<DATA +$SUBPREV +DATA + +INPUT_END + +test_expect_success 'P: fail on inline gitlink' ' + ! git-fast-import <input' + +test_tick +cat >input <<INPUT_END +blob +mark :1 +data <<DATA +$SUBPREV +DATA + +commit refs/heads/subuse3 +mark :2 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +corrupt +COMMIT + +from refs/heads/subuse2 +M 160000 :1 sub + +INPUT_END + +test_expect_success 'P: fail on blob mark in gitlink' ' + ! git-fast-import <input' + +test_done diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh new file mode 100755 index 0000000000..c19b4a2bab --- /dev/null +++ b/t/t9301-fast-export.sh @@ -0,0 +1,234 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes E. Schindelin +# + +test_description='git-fast-export' +. ./test-lib.sh + +test_expect_success 'setup' ' + + echo Wohlauf > file && + git add file && + test_tick && + git commit -m initial && + echo die Luft > file && + echo geht frisch > file2 && + git add file file2 && + test_tick && + git commit -m second && + echo und > file2 && + test_tick && + git commit -m third file2 && + test_tick && + git tag rein && + git checkout -b wer HEAD^ && + echo lange > file2 + test_tick && + git commit -m sitzt file2 && + test_tick && + git tag -a -m valentin muss && + git merge -s ours master + +' + +test_expect_success 'fast-export | fast-import' ' + + MASTER=$(git rev-parse --verify master) && + REIN=$(git rev-parse --verify rein) && + WER=$(git rev-parse --verify wer) && + MUSS=$(git rev-parse --verify muss) && + mkdir new && + git --git-dir=new/.git init && + git fast-export --all | + (cd new && + git fast-import && + test $MASTER = $(git rev-parse --verify refs/heads/master) && + test $REIN = $(git rev-parse --verify refs/tags/rein) && + test $WER = $(git rev-parse --verify refs/heads/wer) && + test $MUSS = $(git rev-parse --verify refs/tags/muss)) + +' + +test_expect_success 'fast-export master~2..master' ' + + git fast-export master~2..master | + sed "s/master/partial/" | + (cd new && + git fast-import && + test $MASTER != $(git rev-parse --verify refs/heads/partial) && + git diff master..partial && + git diff master^..partial^ && + test_must_fail git rev-parse partial~2) + +' + +test_expect_success 'iso-8859-1' ' + + git config i18n.commitencoding ISO-8859-1 && + # use author and committer name in ISO-8859-1 to match it. + . ../t3901-8859-1.txt && + test_tick && + echo rosten >file && + git commit -s -m den file && + git fast-export wer^..wer | + sed "s/wer/i18n/" | + (cd new && + git fast-import && + git cat-file commit i18n | grep "Ãéà óú") + +' +test_expect_success 'import/export-marks' ' + + git checkout -b marks master && + git fast-export --export-marks=tmp-marks HEAD && + test -s tmp-marks && + test $(wc -l < tmp-marks) -eq 3 && + test $( + git fast-export --import-marks=tmp-marks\ + --export-marks=tmp-marks HEAD | + grep ^commit | + wc -l) \ + -eq 0 && + echo change > file && + git commit -m "last commit" file && + test $( + git fast-export --import-marks=tmp-marks \ + --export-marks=tmp-marks HEAD | + grep ^commit\ | + wc -l) \ + -eq 1 && + test $(wc -l < tmp-marks) -eq 4 + +' + +cat > signed-tag-import << EOF +tag sign-your-name +from $(git rev-parse HEAD) +tagger C O Mitter <committer@example.com> 1112911993 -0700 +data 210 +A message for a sign +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.5 (GNU/Linux) + +fakedsignaturefakedsignaturefakedsignaturefakedsignaturfakedsign +aturefakedsignaturefake= +=/59v +-----END PGP SIGNATURE----- +EOF + +test_expect_success 'set up faked signed tag' ' + + cat signed-tag-import | git fast-import + +' + +test_expect_success 'signed-tags=abort' ' + + test_must_fail git fast-export --signed-tags=abort sign-your-name + +' + +test_expect_success 'signed-tags=verbatim' ' + + git fast-export --signed-tags=verbatim sign-your-name > output && + grep PGP output + +' + +test_expect_success 'signed-tags=strip' ' + + git fast-export --signed-tags=strip sign-your-name > output && + ! grep PGP output + +' + +test_expect_success 'setup submodule' ' + + git checkout -f master && + mkdir sub && + cd sub && + git init && + echo test file > file && + git add file && + git commit -m sub_initial && + cd .. && + git submodule add "`pwd`/sub" sub && + git commit -m initial && + test_tick && + cd sub && + echo more data >> file && + git add file && + git commit -m sub_second && + cd .. && + git add sub && + git commit -m second + +' + +test_expect_success 'submodule fast-export | fast-import' ' + + SUBENT1=$(git ls-tree master^ sub) && + SUBENT2=$(git ls-tree master sub) && + rm -rf new && + mkdir new && + git --git-dir=new/.git init && + git fast-export --signed-tags=strip --all | + (cd new && + git fast-import && + test "$SUBENT1" = "$(git ls-tree refs/heads/master^ sub)" && + test "$SUBENT2" = "$(git ls-tree refs/heads/master sub)" && + git checkout master && + git submodule init && + git submodule update && + cmp sub/file ../sub/file) + +' + +export GIT_AUTHOR_NAME='A U Thor' +export GIT_COMMITTER_NAME='C O Mitter' + +test_expect_success 'setup copies' ' + + git config --unset i18n.commitencoding && + git checkout -b copy rein && + git mv file file3 && + git commit -m move1 && + test_tick && + cp file2 file4 && + git add file4 && + git mv file2 file5 && + git commit -m copy1 && + test_tick && + cp file3 file6 && + git add file6 && + git commit -m copy2 && + test_tick && + echo more text >> file6 && + echo even more text >> file6 && + git add file6 && + git commit -m modify && + test_tick && + cp file6 file7 && + echo test >> file7 && + git add file7 && + git commit -m copy_modify + +' + +test_expect_success 'fast-export -C -C | fast-import' ' + + ENTRY=$(git rev-parse --verify copy) && + rm -rf new && + mkdir new && + git --git-dir=new/.git init && + git fast-export -C -C --signed-tags=strip --all > output && + grep "^C \"file6\" \"file7\"\$" output && + cat output | + (cd new && + git fast-import && + test $ENTRY = $(git rev-parse --verify refs/heads/copy)) + +' + +test_done diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh new file mode 100755 index 0000000000..4b91f8d4c4 --- /dev/null +++ b/t/t9400-git-cvsserver-server.sh @@ -0,0 +1,491 @@ +#!/bin/sh +# +# Copyright (c) 2007 Frank Lichtenheld +# + +test_description='git-cvsserver access + +tests read access to a git repository with the +cvs CLI client via git-cvsserver server' + +. ./test-lib.sh + +cvs >/dev/null 2>&1 +if test $? -ne 1 +then + test_expect_success 'skipping git-cvsserver tests, cvs not found' : + test_done + exit +fi +perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || { + test_expect_success 'skipping git-cvsserver tests, Perl SQLite interface unavailable' : + test_done + exit +} + +unset GIT_DIR GIT_CONFIG +WORKDIR=$(pwd) +SERVERDIR=$(pwd)/gitcvs.git +git_config="$SERVERDIR/config" +CVSROOT=":fork:$SERVERDIR" +CVSWORK="$(pwd)/cvswork" +CVS_SERVER=git-cvsserver +export CVSROOT CVS_SERVER + +rm -rf "$CVSWORK" "$SERVERDIR" +test_expect_success 'setup' ' + echo >empty && + git add empty && + git commit -q -m "First Commit" && + mkdir secondroot && + ( cd secondroot && + git init && + touch secondrootfile && + git add secondrootfile && + git commit -m "second root") && + git pull secondroot master && + git clone -q --local --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 && + GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true && + GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log" +' + +# note that cvs doesn't accept absolute pathnames +# as argument to co -d +test_expect_success 'basic checkout' \ + 'GIT_CONFIG="$git_config" cvs -Q co -d cvswork master && + test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | head -n 1))" = "empty/1.1/" + test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | sed -ne \$p))" = "secondrootfile/1.1/"' + +#------------------------ +# PSERVER AUTHENTICATION +#------------------------ + +cat >request-anonymous <<EOF +BEGIN AUTH REQUEST +$SERVERDIR +anonymous + +END AUTH REQUEST +EOF + +cat >request-git <<EOF +BEGIN AUTH REQUEST +$SERVERDIR +git + +END AUTH REQUEST +EOF + +cat >login-anonymous <<EOF +BEGIN VERIFICATION REQUEST +$SERVERDIR +anonymous + +END VERIFICATION REQUEST +EOF + +cat >login-git <<EOF +BEGIN VERIFICATION REQUEST +$SERVERDIR +git + +END VERIFICATION REQUEST +EOF + +test_expect_success 'pserver authentication' \ + 'cat request-anonymous | git-cvsserver pserver >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU$"' + +test_expect_success 'pserver authentication failure (non-anonymous user)' \ + 'if cat request-git | git-cvsserver pserver >log 2>&1 + then + false + else + true + fi && + sed -ne \$p log | grep "^I HATE YOU$"' + +test_expect_success 'pserver authentication (login)' \ + 'cat login-anonymous | git-cvsserver pserver >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU$"' + +test_expect_success 'pserver authentication failure (login/non-anonymous user)' \ + 'if cat login-git | git-cvsserver pserver >log 2>&1 + then + false + else + true + fi && + sed -ne \$p log | grep "^I HATE YOU$"' + + +# misuse pserver authentication for testing of req_Root + +cat >request-relative <<EOF +BEGIN AUTH REQUEST +gitcvs.git +anonymous + +END AUTH REQUEST +EOF + +cat >request-conflict <<EOF +BEGIN AUTH REQUEST +$SERVERDIR +anonymous + +END AUTH REQUEST +Root $WORKDIR +EOF + +test_expect_success 'req_Root failure (relative pathname)' \ + 'if cat request-relative | git-cvsserver pserver >log 2>&1 + then + echo unexpected success + false + else + true + fi && + tail log | grep "^error 1 Root must be an absolute pathname$"' + +test_expect_success 'req_Root failure (conflicting roots)' \ + 'cat request-conflict | git-cvsserver pserver >log 2>&1 && + tail log | grep "^error 1 Conflicting roots specified$"' + +test_expect_success 'req_Root (strict paths)' \ + 'cat request-anonymous | git-cvsserver --strict-paths pserver "$SERVERDIR" >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU$"' + +test_expect_success 'req_Root failure (strict-paths)' ' + ! cat request-anonymous | + git-cvsserver --strict-paths pserver "$WORKDIR" >log 2>&1 +' + +test_expect_success 'req_Root (w/o strict-paths)' \ + 'cat request-anonymous | git-cvsserver pserver "$WORKDIR/" >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU$"' + +test_expect_success 'req_Root failure (w/o strict-paths)' ' + ! cat request-anonymous | + git-cvsserver pserver "$WORKDIR/gitcvs" >log 2>&1 +' + +cat >request-base <<EOF +BEGIN AUTH REQUEST +/gitcvs.git +anonymous + +END AUTH REQUEST +Root /gitcvs.git +EOF + +test_expect_success 'req_Root (base-path)' \ + 'cat request-base | git-cvsserver --strict-paths --base-path "$WORKDIR/" pserver "$SERVERDIR" >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU$"' + +test_expect_success 'req_Root failure (base-path)' ' + ! cat request-anonymous | + git-cvsserver --strict-paths --base-path "$WORKDIR" pserver "$SERVERDIR" >log 2>&1 +' + +GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false || exit 1 + +test_expect_success 'req_Root (export-all)' \ + 'cat request-anonymous | git-cvsserver --export-all pserver "$WORKDIR" >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU$"' + +test_expect_success 'req_Root failure (export-all w/o whitelist)' \ + '! (cat request-anonymous | git-cvsserver --export-all pserver >log 2>&1 || false)' + +test_expect_success 'req_Root (everything together)' \ + 'cat request-base | git-cvsserver --export-all --strict-paths --base-path "$WORKDIR/" pserver "$SERVERDIR" >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU$"' + +GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true || exit 1 + +#-------------- +# CONFIG TESTS +#-------------- + +test_expect_success 'gitcvs.enabled = false' \ + 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false && + if GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 + then + echo unexpected cvs success + false + else + true + fi && + grep "GITCVS emulation disabled" cvs.log && + test ! -d cvswork2' + +rm -fr cvswork2 +test_expect_success 'gitcvs.ext.enabled = true' \ + 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true && + GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false && + GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 && + diff -q cvswork cvswork2' + +rm -fr cvswork2 +test_expect_success 'gitcvs.ext.enabled = false' \ + 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled false && + GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true && + if GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 + then + echo unexpected cvs success + false + else + true + fi && + grep "GITCVS emulation disabled" cvs.log && + test ! -d cvswork2' + +rm -fr cvswork2 +test_expect_success 'gitcvs.dbname' \ + 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true && + GIT_DIR="$SERVERDIR" git config gitcvs.dbname %Ggitcvs.%a.%m.sqlite && + GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 && + diff -q cvswork cvswork2 && + test -f "$SERVERDIR/gitcvs.ext.master.sqlite" && + cmp "$SERVERDIR/gitcvs.master.sqlite" "$SERVERDIR/gitcvs.ext.master.sqlite"' + +rm -fr cvswork2 +test_expect_success 'gitcvs.ext.dbname' \ + 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true && + GIT_DIR="$SERVERDIR" git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite && + GIT_DIR="$SERVERDIR" git config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite && + GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 && + diff -q cvswork cvswork2 && + test -f "$SERVERDIR/gitcvs1.ext.master.sqlite" && + test ! -f "$SERVERDIR/gitcvs2.ext.master.sqlite" && + cmp "$SERVERDIR/gitcvs.master.sqlite" "$SERVERDIR/gitcvs1.ext.master.sqlite"' + + +#------------ +# CVS UPDATE +#------------ + +rm -fr "$SERVERDIR" +cd "$WORKDIR" && +git clone -q --local --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 && +GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true && +GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log" || +exit 1 + +test_expect_success 'cvs update (create new file)' \ + 'echo testfile1 >testfile1 && + git add testfile1 && + git commit -q -m "Add testfile1" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.1/" && + diff -q testfile1 ../testfile1' + +cd "$WORKDIR" +test_expect_success 'cvs update (update existing file)' \ + 'echo line 2 >>testfile1 && + git add testfile1 && + git commit -q -m "Append to testfile1" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.2/" && + diff -q testfile1 ../testfile1' + +cd "$WORKDIR" +#TODO: cvsserver doesn't support update w/o -d +test_expect_failure "cvs update w/o -d doesn't create subdir (TODO)" ' + mkdir test && + echo >test/empty && + git add test && + git commit -q -m "Single Subdirectory" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test ! -d test +' + +cd "$WORKDIR" +test_expect_success 'cvs update (subdirectories)' \ + '(for dir in A A/B A/B/C A/D E; do + mkdir $dir && + echo "test file in $dir" >"$dir/file_in_$(echo $dir|sed -e "s#/# #g")" && + git add $dir; + done) && + git commit -q -m "deep sub directory structure" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update -d && + (for dir in A A/B A/B/C A/D E; do + filename="file_in_$(echo $dir|sed -e "s#/# #g")" && + if test "$(echo $(grep -v ^D $dir/CVS/Entries|cut -d/ -f2,3,5))" = "$filename/1.1/" && + diff -q "$dir/$filename" "../$dir/$filename"; then + : + else + echo >failure + fi + done) && + test ! -f failure' + +cd "$WORKDIR" +test_expect_success 'cvs update (delete file)' \ + 'git rm testfile1 && + git commit -q -m "Remove testfile1" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test -z "$(grep testfile1 CVS/Entries)" && + test ! -f testfile1' + +cd "$WORKDIR" +test_expect_success 'cvs update (re-add deleted file)' \ + 'echo readded testfile >testfile1 && + git add testfile1 && + git commit -q -m "Re-Add testfile1" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.4/" && + diff -q testfile1 ../testfile1' + +cd "$WORKDIR" +test_expect_success 'cvs update (merge)' \ + 'echo Line 0 >expected && + for i in 1 2 3 4 5 6 7 + do + echo Line $i >>merge + echo Line $i >>expected + done && + echo Line 8 >>expected && + git add merge && + git commit -q -m "Merge test (pre-merge)" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test "$(echo $(grep merge CVS/Entries|cut -d/ -f2,3,5))" = "merge/1.1/" && + diff -q merge ../merge && + ( echo Line 0; cat merge ) >merge.tmp && + mv merge.tmp merge && + cd "$WORKDIR" && + echo Line 8 >>merge && + git add merge && + git commit -q -m "Merge test (merge)" && + git push gitcvs.git >/dev/null && + cd cvswork && + sleep 1 && touch merge && + GIT_CONFIG="$git_config" cvs -Q update && + diff -q merge ../expected' + +cd "$WORKDIR" + +cat >expected.C <<EOF +<<<<<<< merge.mine +Line 0 +======= +LINE 0 +>>>>>>> merge.3 +EOF + +for i in 1 2 3 4 5 6 7 8 +do + echo Line $i >>expected.C +done + +test_expect_success 'cvs update (conflict merge)' \ + '( echo LINE 0; cat merge ) >merge.tmp && + mv merge.tmp merge && + git add merge && + git commit -q -m "Merge test (conflict)" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + diff -q merge ../expected.C' + +cd "$WORKDIR" +test_expect_success 'cvs update (-C)' \ + 'cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update -C && + diff -q merge ../merge' + +cd "$WORKDIR" +test_expect_success 'cvs update (merge no-op)' \ + 'echo Line 9 >>merge && + cp merge cvswork/merge && + git add merge && + git commit -q -m "Merge test (no-op)" && + git push gitcvs.git >/dev/null && + cd cvswork && + sleep 1 && touch merge && + GIT_CONFIG="$git_config" cvs -Q update && + diff -q merge ../merge' + +cd "$WORKDIR" +test_expect_success 'cvs update (-p)' ' + touch really-empty && + echo Line 1 > no-lf && + echo -n Line 2 >> no-lf && + git add really-empty no-lf && + git commit -q -m "Update -p test" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs update && + rm -f failures && + for i in merge no-lf empty really-empty; do + GIT_CONFIG="$git_config" cvs update -p "$i" >$i.out + diff $i.out ../$i >>failures 2>&1 + done && + test -z "$(cat failures)" +' + +cd "$WORKDIR" +test_expect_success 'cvs update (module list supports packed refs)' ' + GIT_DIR="$SERVERDIR" git pack-refs --all && + GIT_CONFIG="$git_config" cvs -n up -d 2> out && + grep "cvs update: New directory \`master'\''" < out +' + +#------------ +# CVS STATUS +#------------ + +cd "$WORKDIR" +test_expect_success 'cvs status' ' + mkdir status.dir && + echo Line > status.dir/status.file && + echo Line > status.file && + git add status.dir status.file && + git commit -q -m "Status test" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs update && + GIT_CONFIG="$git_config" cvs status | grep "^File: status.file" >../out && + test $(wc -l <../out) = 2 +' + +cd "$WORKDIR" +test_expect_success 'cvs status (nonrecursive)' ' + cd cvswork && + GIT_CONFIG="$git_config" cvs status -l | grep "^File: status.file" >../out && + test $(wc -l <../out) = 1 +' + +cd "$WORKDIR" +test_expect_success 'cvs status (no subdirs in header)' ' + cd cvswork && + GIT_CONFIG="$git_config" cvs status | grep ^File: >../out && + ! grep / <../out +' + +#------------ +# CVS CHECKOUT +#------------ + +cd "$WORKDIR" +test_expect_success 'cvs co -c (shows module database)' ' + GIT_CONFIG="$git_config" cvs co -c > out && + grep "^master[ ]\+master$" < out && + ! grep -v "^master[ ]\+master$" < out +' + +test_done diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh new file mode 100755 index 0000000000..e27a1c5f85 --- /dev/null +++ b/t/t9401-git-cvsserver-crlf.sh @@ -0,0 +1,337 @@ +#!/bin/sh +# +# Copyright (c) 2008 Matthew Ogilvie +# Parts adapted from other tests. +# + +test_description='git-cvsserver -kb modes + +tests -kb mode for binary files when accessing a git +repository using cvs CLI client via git-cvsserver server' + +. ./test-lib.sh + +q_to_nul () { + perl -pe 'y/Q/\000/' +} + +q_to_cr () { + tr Q '\015' +} + +marked_as () { + foundEntry="$(grep "^/$2/" "$1/CVS/Entries")" + if [ x"$foundEntry" = x"" ] ; then + echo "NOT FOUND: $1 $2 1 $3" >> "${WORKDIR}/marked.log" + return 1 + fi + test x"$(grep "^/$2/" "$1/CVS/Entries" | cut -d/ -f5)" = x"$3" + stat=$? + echo "$1 $2 $stat '$3'" >> "${WORKDIR}/marked.log" + return $stat +} + +not_present() { + foundEntry="$(grep "^/$2/" "$1/CVS/Entries")" + if [ -r "$1/$2" ] ; then + echo "Error: File still exists: $1 $2" >> "${WORKDIR}/marked.log" + return 1; + fi + if [ x"$foundEntry" != x"" ] ; then + echo "Error: should not have found: $1 $2" >> "${WORKDIR}/marked.log" + return 1; + else + echo "Correctly not found: $1 $2" >> "${WORKDIR}/marked.log" + return 0; + fi +} + +cvs >/dev/null 2>&1 +if test $? -ne 1 +then + test_expect_success 'skipping git-cvsserver tests, cvs not found' : + test_done + exit +fi +perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || { + test_expect_success 'skipping git-cvsserver tests, Perl SQLite interface unavailable' : + test_done + exit +} + +unset GIT_DIR GIT_CONFIG +WORKDIR=$(pwd) +SERVERDIR=$(pwd)/gitcvs.git +git_config="$SERVERDIR/config" +CVSROOT=":fork:$SERVERDIR" +CVSWORK="$(pwd)/cvswork" +CVS_SERVER=git-cvsserver +export CVSROOT CVS_SERVER + +rm -rf "$CVSWORK" "$SERVERDIR" +test_expect_success 'setup' ' + echo "Simple text file" >textfile.c && + echo "File with embedded NUL: Q <- there" | q_to_nul > binfile.bin && + mkdir subdir && + echo "Another text file" > subdir/file.h && + echo "Another binary: Q (this time CR)" | q_to_cr > subdir/withCr.bin && + echo "Mixed up NUL, but marked text: Q <- there" | q_to_nul > mixedUp.c + echo "Unspecified" > subdir/unspecified.other && + echo "/*.bin -crlf" > .gitattributes && + echo "/*.c crlf" >> .gitattributes && + echo "subdir/*.bin -crlf" >> .gitattributes && + echo "subdir/*.c crlf" >> .gitattributes && + echo "subdir/file.h crlf" >> .gitattributes && + git add .gitattributes textfile.c binfile.bin mixedUp.c subdir/* && + git commit -q -m "First Commit" && + git clone -q --local --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 && + GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true && + GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log" +' + +test_expect_success 'cvs co (default crlf)' ' + GIT_CONFIG="$git_config" cvs -Q co -d cvswork master >cvs.log 2>&1 && + test x"$(grep '/-k' cvswork/CVS/Entries cvswork/subdir/CVS/Entries)" = x"" +' + +rm -rf cvswork +test_expect_success 'cvs co (allbinary)' ' + GIT_DIR="$SERVERDIR" git config --bool gitcvs.allbinary true && + GIT_CONFIG="$git_config" cvs -Q co -d cvswork master >cvs.log 2>&1 && + marked_as cvswork textfile.c -kb && + marked_as cvswork binfile.bin -kb && + marked_as cvswork .gitattributes -kb && + marked_as cvswork mixedUp.c -kb && + marked_as cvswork/subdir withCr.bin -kb && + marked_as cvswork/subdir file.h -kb && + marked_as cvswork/subdir unspecified.other -kb +' + +rm -rf cvswork cvs.log +test_expect_success 'cvs co (use attributes/allbinary)' ' + GIT_DIR="$SERVERDIR" git config --bool gitcvs.usecrlfattr true && + GIT_CONFIG="$git_config" cvs -Q co -d cvswork master >cvs.log 2>&1 && + marked_as cvswork textfile.c "" && + marked_as cvswork binfile.bin -kb && + marked_as cvswork .gitattributes -kb && + marked_as cvswork mixedUp.c "" && + marked_as cvswork/subdir withCr.bin -kb && + marked_as cvswork/subdir file.h "" && + marked_as cvswork/subdir unspecified.other -kb +' + +rm -rf cvswork +test_expect_success 'cvs co (use attributes)' ' + GIT_DIR="$SERVERDIR" git config --bool gitcvs.allbinary false && + GIT_CONFIG="$git_config" cvs -Q co -d cvswork master >cvs.log 2>&1 && + marked_as cvswork textfile.c "" && + marked_as cvswork binfile.bin -kb && + marked_as cvswork .gitattributes "" && + marked_as cvswork mixedUp.c "" && + marked_as cvswork/subdir withCr.bin -kb && + marked_as cvswork/subdir file.h "" && + marked_as cvswork/subdir unspecified.other "" +' + +test_expect_success 'adding files' ' + cd cvswork/subdir && + echo "more text" > src.c && + GIT_CONFIG="$git_config" cvs -Q add src.c >cvs.log 2>&1 && + marked_as . src.c "" && + echo "psuedo-binary" > temp.bin && + cd .. && + GIT_CONFIG="$git_config" cvs -Q add subdir/temp.bin >cvs.log 2>&1 && + marked_as subdir temp.bin "-kb" && + cd subdir && + GIT_CONFIG="$git_config" cvs -Q ci -m "adding files" >cvs.log 2>&1 && + marked_as . temp.bin "-kb" && + marked_as . src.c "" +' + +cd "$WORKDIR" +test_expect_success 'updating' ' + git pull gitcvs.git && + echo 'hi' > subdir/newfile.bin && + echo 'junk' > subdir/file.h && + echo 'hi' > subdir/newfile.c && + echo 'hello' >> binfile.bin && + git add subdir/newfile.bin subdir/file.h subdir/newfile.c binfile.bin && + git commit -q -m "Add and change some files" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + cd .. && + marked_as cvswork textfile.c "" && + marked_as cvswork binfile.bin -kb && + marked_as cvswork .gitattributes "" && + marked_as cvswork mixedUp.c "" && + marked_as cvswork/subdir withCr.bin -kb && + marked_as cvswork/subdir file.h "" && + marked_as cvswork/subdir unspecified.other "" && + marked_as cvswork/subdir newfile.bin -kb && + marked_as cvswork/subdir newfile.c "" && + echo "File with embedded NUL: Q <- there" | q_to_nul > tmpExpect1 && + echo "hello" >> tmpExpect1 && + cmp cvswork/binfile.bin tmpExpect1 +' + +rm -rf cvswork +test_expect_success 'cvs co (use attributes/guess)' ' + GIT_DIR="$SERVERDIR" git config gitcvs.allbinary guess && + GIT_CONFIG="$git_config" cvs -Q co -d cvswork master >cvs.log 2>&1 && + marked_as cvswork textfile.c "" && + marked_as cvswork binfile.bin -kb && + marked_as cvswork .gitattributes "" && + marked_as cvswork mixedUp.c "" && + marked_as cvswork/subdir withCr.bin -kb && + marked_as cvswork/subdir file.h "" && + marked_as cvswork/subdir unspecified.other "" && + marked_as cvswork/subdir newfile.bin -kb && + marked_as cvswork/subdir newfile.c "" +' + +test_expect_success 'setup multi-line files' ' + ( echo "line 1" && + echo "line 2" && + echo "line 3" && + echo "line 4 with NUL: Q <-" ) | q_to_nul > multiline.c && + git add multiline.c && + ( echo "line 1" && + echo "line 2" && + echo "line 3" && + echo "line 4" ) | q_to_nul > multilineTxt.c && + git add multilineTxt.c && + git commit -q -m "multiline files" && + git push gitcvs.git >/dev/null +' + +rm -rf cvswork +test_expect_success 'cvs co (guess)' ' + GIT_DIR="$SERVERDIR" git config --bool gitcvs.usecrlfattr false && + GIT_CONFIG="$git_config" cvs -Q co -d cvswork master >cvs.log 2>&1 && + marked_as cvswork textfile.c "" && + marked_as cvswork binfile.bin -kb && + marked_as cvswork .gitattributes "" && + marked_as cvswork mixedUp.c -kb && + marked_as cvswork multiline.c -kb && + marked_as cvswork multilineTxt.c "" && + marked_as cvswork/subdir withCr.bin -kb && + marked_as cvswork/subdir file.h "" && + marked_as cvswork/subdir unspecified.other "" && + marked_as cvswork/subdir newfile.bin "" && + marked_as cvswork/subdir newfile.c "" +' + +test_expect_success 'cvs co another copy (guess)' ' + GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 && + marked_as cvswork2 textfile.c "" && + marked_as cvswork2 binfile.bin -kb && + marked_as cvswork2 .gitattributes "" && + marked_as cvswork2 mixedUp.c -kb && + marked_as cvswork2 multiline.c -kb && + marked_as cvswork2 multilineTxt.c "" && + marked_as cvswork2/subdir withCr.bin -kb && + marked_as cvswork2/subdir file.h "" && + marked_as cvswork2/subdir unspecified.other "" && + marked_as cvswork2/subdir newfile.bin "" && + marked_as cvswork2/subdir newfile.c "" +' + +test_expect_success 'add text (guess)' ' + cd cvswork && + echo "simpleText" > simpleText.c && + GIT_CONFIG="$git_config" cvs -Q add simpleText.c && + cd .. && + marked_as cvswork simpleText.c "" +' + +test_expect_success 'add bin (guess)' ' + cd cvswork && + echo "simpleBin: NUL: Q <- there" | q_to_nul > simpleBin.bin && + GIT_CONFIG="$git_config" cvs -Q add simpleBin.bin && + cd .. && + marked_as cvswork simpleBin.bin -kb +' + +test_expect_success 'remove files (guess)' ' + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q rm -f subdir/file.h && + cd subdir && + GIT_CONFIG="$git_config" cvs -Q rm -f withCr.bin && + cd ../.. && + marked_as cvswork/subdir withCr.bin -kb && + marked_as cvswork/subdir file.h "" +' + +test_expect_success 'cvs ci (guess)' ' + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q ci -m "add/rm files" >cvs.log 2>&1 && + cd .. && + marked_as cvswork textfile.c "" && + marked_as cvswork binfile.bin -kb && + marked_as cvswork .gitattributes "" && + marked_as cvswork mixedUp.c -kb && + marked_as cvswork multiline.c -kb && + marked_as cvswork multilineTxt.c "" && + not_present cvswork/subdir withCr.bin && + not_present cvswork/subdir file.h && + marked_as cvswork/subdir unspecified.other "" && + marked_as cvswork/subdir newfile.bin "" && + marked_as cvswork/subdir newfile.c "" && + marked_as cvswork simpleBin.bin -kb && + marked_as cvswork simpleText.c "" +' + +test_expect_success 'update subdir of other copy (guess)' ' + cd cvswork2/subdir && + GIT_CONFIG="$git_config" cvs -Q update && + cd ../.. && + marked_as cvswork2 textfile.c "" && + marked_as cvswork2 binfile.bin -kb && + marked_as cvswork2 .gitattributes "" && + marked_as cvswork2 mixedUp.c -kb && + marked_as cvswork2 multiline.c -kb && + marked_as cvswork2 multilineTxt.c "" && + not_present cvswork2/subdir withCr.bin && + not_present cvswork2/subdir file.h && + marked_as cvswork2/subdir unspecified.other "" && + marked_as cvswork2/subdir newfile.bin "" && + marked_as cvswork2/subdir newfile.c "" && + not_present cvswork2 simpleBin.bin && + not_present cvswork2 simpleText.c +' + +echo "starting update/merge" >> "${WORKDIR}/marked.log" +test_expect_success 'update/merge full other copy (guess)' ' + git pull gitcvs.git master && + sed "s/3/replaced_3/" < multilineTxt.c > ml.temp && + mv ml.temp multilineTxt.c && + git add multilineTxt.c && + git commit -q -m "modify multiline file" >> "${WORKDIR}/marked.log" && + git push gitcvs.git >/dev/null && + cd cvswork2 && + sed "s/1/replaced_1/" < multilineTxt.c > ml.temp && + mv ml.temp multilineTxt.c && + GIT_CONFIG="$git_config" cvs update > cvs.log 2>&1 && + cd .. && + marked_as cvswork2 textfile.c "" && + marked_as cvswork2 binfile.bin -kb && + marked_as cvswork2 .gitattributes "" && + marked_as cvswork2 mixedUp.c -kb && + marked_as cvswork2 multiline.c -kb && + marked_as cvswork2 multilineTxt.c "" && + not_present cvswork2/subdir withCr.bin && + not_present cvswork2/subdir file.h && + marked_as cvswork2/subdir unspecified.other "" && + marked_as cvswork2/subdir newfile.bin "" && + marked_as cvswork2/subdir newfile.c "" && + marked_as cvswork2 simpleBin.bin -kb && + marked_as cvswork2 simpleText.c "" && + echo "line replaced_1" > tmpExpect2 && + echo "line 2" >> tmpExpect2 && + echo "line replaced_3" >> tmpExpect2 && + echo "line 4" | q_to_nul >> tmpExpect2 && + cmp cvswork2/multilineTxt.c tmpExpect2 +' + +test_done diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh new file mode 100755 index 0000000000..ae7082be1d --- /dev/null +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -0,0 +1,627 @@ +#!/bin/sh +# +# Copyright (c) 2007 Jakub Narebski +# + +test_description='gitweb as standalone script (basic tests). + +This test runs gitweb (git web interface) as CGI script from +commandline, and checks that it would not write any errors +or warnings to log.' + +gitweb_init () { + safe_pwd="$(perl -MPOSIX=getcwd -e 'print quotemeta(getcwd)')" + cat >gitweb_config.perl <<EOF +#!/usr/bin/perl + +# gitweb configuration for tests + +our \$version = "current"; +our \$GIT = "git"; +our \$projectroot = "$safe_pwd"; +our \$project_maxdepth = 8; +our \$home_link_str = "projects"; +our \$site_name = "[localhost]"; +our \$site_header = ""; +our \$site_footer = ""; +our \$home_text = "indextext.html"; +our @stylesheets = ("file:///$safe_pwd/../../gitweb/gitweb.css"); +our \$logo = "file:///$safe_pwd/../../gitweb/git-logo.png"; +our \$favicon = "file:///$safe_pwd/../../gitweb/git-favicon.png"; +our \$projects_list = ""; +our \$export_ok = ""; +our \$strict_export = ""; + +EOF + + cat >.git/description <<EOF +$0 test repository +EOF +} + +gitweb_run () { + GATEWAY_INTERFACE="CGI/1.1" + HTTP_ACCEPT="*/*" + REQUEST_METHOD="GET" + QUERY_STRING=""$1"" + PATH_INFO=""$2"" + export GATEWAY_INTERFACE HTTP_ACCEPT REQUEST_METHOD QUERY_STRING PATH_INFO + + GITWEB_CONFIG=$(pwd)/gitweb_config.perl + export GITWEB_CONFIG + + # some of git commands write to STDERR on error, but this is not + # written to web server logs, so we are not interested in that: + # we are interested only in properly formatted errors/warnings + rm -f gitweb.log && + perl -- "$(pwd)/../../gitweb/gitweb.perl" \ + >/dev/null 2>gitweb.log && + if grep -q -s "^[[]" gitweb.log >/dev/null; then false; else true; fi + + # gitweb.log is left for debugging +} + +safe_chmod () { + chmod "$1" "$2" && + if [ "$(git config --get core.filemode)" = false ] + then + git update-index --chmod="$1" "$2" + fi +} + +. ./test-lib.sh + +perl -MEncode -e 'decode_utf8("", Encode::FB_CROAK)' >/dev/null 2>&1 || { + test_expect_success 'skipping gitweb tests, perl version is too old' : + test_done + exit +} + +gitweb_init + +# ---------------------------------------------------------------------- +# no commits (empty, just initialized repository) + +test_expect_success \ + 'no commits: projects_list (implicit)' \ + 'gitweb_run' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'no commits: projects_index' \ + 'gitweb_run "a=project_index"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'no commits: .git summary (implicit)' \ + 'gitweb_run "p=.git"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'no commits: .git commit (implicit HEAD)' \ + 'gitweb_run "p=.git;a=commit"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'no commits: .git commitdiff (implicit HEAD)' \ + 'gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'no commits: .git tree (implicit HEAD)' \ + 'gitweb_run "p=.git;a=tree"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'no commits: .git heads' \ + 'gitweb_run "p=.git;a=heads"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'no commits: .git tags' \ + 'gitweb_run "p=.git;a=tags"' +test_debug 'cat gitweb.log' + + +# ---------------------------------------------------------------------- +# initial commit + +test_expect_success \ + 'Make initial commit' \ + 'echo "Not an empty file." > file && + git add file && + git commit -a -m "Initial commit." && + git branch b' + +test_expect_success \ + 'projects_list (implicit)' \ + 'gitweb_run' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'projects_index' \ + 'gitweb_run "a=project_index"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git summary (implicit)' \ + 'gitweb_run "p=.git"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git commit (implicit HEAD)' \ + 'gitweb_run "p=.git;a=commit"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git commitdiff (implicit HEAD, root commit)' \ + 'gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git commitdiff_plain (implicit HEAD, root commit)' \ + 'gitweb_run "p=.git;a=commitdiff_plain"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git commit (HEAD)' \ + 'gitweb_run "p=.git;a=commit;h=HEAD"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git tree (implicit HEAD)' \ + 'gitweb_run "p=.git;a=tree"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git blob (file)' \ + 'gitweb_run "p=.git;a=blob;f=file"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git blob_plain (file)' \ + 'gitweb_run "p=.git;a=blob_plain;f=file"' +test_debug 'cat gitweb.log' + +# ---------------------------------------------------------------------- +# nonexistent objects + +test_expect_success \ + '.git commit (non-existent)' \ + 'gitweb_run "p=.git;a=commit;h=non-existent"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git commitdiff (non-existent)' \ + 'gitweb_run "p=.git;a=commitdiff;h=non-existent"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git commitdiff (non-existent vs HEAD)' \ + 'gitweb_run "p=.git;a=commitdiff;hp=non-existent;h=HEAD"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git tree (0000000000000000000000000000000000000000)' \ + 'gitweb_run "p=.git;a=tree;h=0000000000000000000000000000000000000000"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git tag (0000000000000000000000000000000000000000)' \ + 'gitweb_run "p=.git;a=tag;h=0000000000000000000000000000000000000000"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git blob (non-existent)' \ + 'gitweb_run "p=.git;a=blob;f=non-existent"' +test_debug 'cat gitweb.log' + +test_expect_success \ + '.git blob_plain (non-existent)' \ + 'gitweb_run "p=.git;a=blob_plain;f=non-existent"' +test_debug 'cat gitweb.log' + + +# ---------------------------------------------------------------------- +# commitdiff testing (implicit, one implicit tree-ish) + +test_expect_success \ + 'commitdiff(0): root' \ + 'gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(0): file added' \ + 'echo "New file" > new_file && + git add new_file && + git commit -a -m "File added." && + gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(0): mode change' \ + 'safe_chmod +x new_file && + git commit -a -m "Mode changed." && + gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(0): file renamed' \ + 'git mv new_file renamed_file && + git commit -a -m "File renamed." && + gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(0): file to symlink' \ + 'rm renamed_file && + ln -s file renamed_file && + git commit -a -m "File to symlink." && + gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(0): file deleted' \ + 'git rm renamed_file && + rm -f renamed_file && + git commit -a -m "File removed." && + gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(0): file copied / new file' \ + 'cp file file2 && + git add file2 && + git commit -a -m "File copied." && + gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(0): mode change and modified' \ + 'echo "New line" >> file2 && + safe_chmod +x file2 && + git commit -a -m "Mode change and modification." && + gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(0): renamed and modified' \ + 'cat >file2<<EOF && +Dominus regit me, +et nihil mihi deerit. +In loco pascuae ibi me collocavit, +super aquam refectionis educavit me; +animam meam convertit, +deduxit me super semitas jusitiae, +propter nomen suum. +EOF + git commit -a -m "File added." && + git mv file2 file3 && + echo "Propter nomen suum." >> file3 && + git commit -a -m "File rename and modification." && + gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(0): renamed, mode change and modified' \ + 'git mv file3 file2 && + echo "Propter nomen suum." >> file2 && + safe_chmod +x file2 && + git commit -a -m "File rename, mode change and modification." && + gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +# ---------------------------------------------------------------------- +# commitdiff testing (taken from t4114-apply-typechange.sh) + +test_expect_success 'setup typechange commits' ' + echo "hello world" > foo && + echo "hi planet" > bar && + git update-index --add foo bar && + git commit -m initial && + git branch initial && + rm -f foo && + ln -s bar foo && + git update-index foo && + git commit -m "foo symlinked to bar" && + git branch foo-symlinked-to-bar && + rm -f foo && + echo "how far is the sun?" > foo && + git update-index foo && + git commit -m "foo back to file" && + git branch foo-back-to-file && + rm -f foo && + git update-index --remove foo && + mkdir foo && + echo "if only I knew" > foo/baz && + git update-index --add foo/baz && + git commit -m "foo becomes a directory" && + git branch "foo-becomes-a-directory" && + echo "hello world" > foo/baz && + git update-index foo/baz && + git commit -m "foo/baz is the original foo" && + git branch foo-baz-renamed-from-foo + ' + +test_expect_success \ + 'commitdiff(2): file renamed from foo to foo/baz' \ + 'gitweb_run "p=.git;a=commitdiff;hp=initial;h=foo-baz-renamed-from-foo"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(2): file renamed from foo/baz to foo' \ + 'gitweb_run "p=.git;a=commitdiff;hp=foo-baz-renamed-from-foo;h=initial"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(2): directory becomes file' \ + 'gitweb_run "p=.git;a=commitdiff;hp=foo-becomes-a-directory;h=initial"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(2): file becomes directory' \ + 'gitweb_run "p=.git;a=commitdiff;hp=initial;h=foo-becomes-a-directory"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(2): file becomes symlink' \ + 'gitweb_run "p=.git;a=commitdiff;hp=initial;h=foo-symlinked-to-bar"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(2): symlink becomes file' \ + 'gitweb_run "p=.git;a=commitdiff;hp=foo-symlinked-to-bar;h=foo-back-to-file"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(2): symlink becomes directory' \ + 'gitweb_run "p=.git;a=commitdiff;hp=foo-symlinked-to-bar;h=foo-becomes-a-directory"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(2): directory becomes symlink' \ + 'gitweb_run "p=.git;a=commitdiff;hp=foo-becomes-a-directory;h=foo-symlinked-to-bar"' +test_debug 'cat gitweb.log' + +# ---------------------------------------------------------------------- +# commit, commitdiff: merge, large +test_expect_success \ + 'Create a merge' \ + 'git checkout b && + echo "Branch" >> b && + git add b && + git commit -a -m "On branch" && + git checkout master && + git pull . b' + +test_expect_success \ + 'commit(0): merge commit' \ + 'gitweb_run "p=.git;a=commit"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(0): merge commit' \ + 'gitweb_run "p=.git;a=commitdiff"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'Prepare large commit' \ + 'git checkout b && + echo "To be changed" > 01-change && + echo "To be renamed" > 02-pure-rename-from && + echo "To be deleted" > 03-delete && + echo "To be renamed and changed" > 04-rename-from && + echo "To have mode changed" > 05-mode-change && + echo "File to symlink" > 06-file-or-symlink && + echo "To be changed and have mode changed" > 07-change-mode-change && + git add 0* && + git commit -a -m "Prepare large commit" && + echo "Changed" > 01-change && + git mv 02-pure-rename-from 02-pure-rename-to && + git rm 03-delete && rm -f 03-delete && + echo "A new file" > 03-new && + git add 03-new && + git mv 04-rename-from 04-rename-to && + echo "Changed" >> 04-rename-to && + safe_chmod +x 05-mode-change && + rm -f 06-file-or-symlink && ln -s 01-change 06-file-or-symlink && + echo "Changed and have mode changed" > 07-change-mode-change && + safe_chmod +x 07-change-mode-change && + git commit -a -m "Large commit" && + git checkout master' + +test_expect_success \ + 'commit(1): large commit' \ + 'gitweb_run "p=.git;a=commit;h=b"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'commitdiff(1): large commit' \ + 'gitweb_run "p=.git;a=commitdiff;h=b"' +test_debug 'cat gitweb.log' + +# ---------------------------------------------------------------------- +# tags testing + +test_expect_success \ + 'tags: list of different types of tags' \ + 'git checkout master && + git tag -a -m "Tag commit object" tag-commit HEAD && + git tag -a -m "" tag-commit-nomessage HEAD && + git tag -a -m "Tag tag object" tag-tag tag-commit && + git tag -a -m "Tag tree object" tag-tree HEAD^{tree} && + git tag -a -m "Tag blob object" tag-blob HEAD:file && + git tag lightweight/tag-commit HEAD && + git tag lightweight/tag-tag tag-commit && + git tag lightweight/tag-tree HEAD^{tree} && + git tag lightweight/tag-blob HEAD:file && + gitweb_run "p=.git;a=tags"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'tag: Tag to commit object' \ + 'gitweb_run "p=.git;a=tag;h=tag-commit"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'tag: on lightweight tag (invalid)' \ + 'gitweb_run "p=.git;a=tag;h=lightweight/tag-commit"' +test_debug 'cat gitweb.log' + +# ---------------------------------------------------------------------- +# logs + +test_expect_success \ + 'logs: log (implicit HEAD)' \ + 'gitweb_run "p=.git;a=log"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'logs: shortlog (implicit HEAD)' \ + 'gitweb_run "p=.git;a=shortlog"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'logs: history (implicit HEAD, file)' \ + 'gitweb_run "p=.git;a=history;f=file"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'logs: history (implicit HEAD, non-existent file)' \ + 'gitweb_run "p=.git;a=history;f=non-existent"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'logs: history (implicit HEAD, deleted file)' \ + 'git checkout master && + echo "to be deleted" > deleted_file && + git add deleted_file && + git commit -m "Add file to be deleted" && + git rm deleted_file && + git commit -m "Delete file" && + gitweb_run "p=.git;a=history;f=deleted_file"' +test_debug 'cat gitweb.log' + +# ---------------------------------------------------------------------- +# feed generation + +test_expect_success \ + 'feeds: OPML' \ + 'gitweb_run "a=opml"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'feed: RSS' \ + 'gitweb_run "p=.git;a=rss"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'feed: Atom' \ + 'gitweb_run "p=.git;a=atom"' +test_debug 'cat gitweb.log' + +# ---------------------------------------------------------------------- +# encoding/decoding + +test_expect_success \ + 'encode(commit): utf8' \ + '. ../t3901-utf8.txt && + echo "UTF-8" >> file && + git add file && + git commit -F ../t3900/1-UTF-8.txt && + gitweb_run "p=.git;a=commit"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'encode(commit): iso-8859-1' \ + '. ../t3901-8859-1.txt && + echo "ISO-8859-1" >> file && + git add file && + git config i18n.commitencoding ISO-8859-1 && + git commit -F ../t3900/ISO-8859-1.txt && + git config --unset i18n.commitencoding && + gitweb_run "p=.git;a=commit"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'encode(log): utf-8 and iso-8859-1' \ + 'gitweb_run "p=.git;a=log"' +test_debug 'cat gitweb.log' + +# ---------------------------------------------------------------------- +# extra options + +test_expect_success \ + 'opt: log --no-merges' \ + 'gitweb_run "p=.git;a=log;opt=--no-merges"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'opt: atom --no-merges' \ + 'gitweb_run "p=.git;a=log;opt=--no-merges"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'opt: "file" history --no-merges' \ + 'gitweb_run "p=.git;a=history;f=file;opt=--no-merges"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'opt: log --no-such-option (invalid option)' \ + 'gitweb_run "p=.git;a=log;opt=--no-such-option"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'opt: tree --no-merges (invalid option for action)' \ + 'gitweb_run "p=.git;a=tree;opt=--no-merges"' +test_debug 'cat gitweb.log' + +# ---------------------------------------------------------------------- +# testing config_to_multi / cloneurl + +test_expect_success \ + 'URL: no project URLs, no base URL' \ + 'gitweb_run "p=.git;a=summary"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'URL: project URLs via gitweb.url' \ + 'git config --add gitweb.url git://example.com/git/trash.git && + git config --add gitweb.url http://example.com/git/trash.git && + gitweb_run "p=.git;a=summary"' +test_debug 'cat gitweb.log' + +cat >.git/cloneurl <<\EOF +git://example.com/git/trash.git +http://example.com/git/trash.git +EOF + +test_expect_success \ + 'URL: project URLs via cloneurl file' \ + 'gitweb_run "p=.git;a=summary"' +test_debug 'cat gitweb.log' + +# ---------------------------------------------------------------------- +# gitweb config and repo config + +cat >>gitweb_config.perl <<EOF + +\$feature{'blame'}{'override'} = 1; +\$feature{'snapshot'}{'override'} = 1; +EOF + +test_expect_success \ + 'config override: tree view, features disabled in repo config' \ + 'git config gitweb.blame no && + git config gitweb.snapshot none && + gitweb_run "p=.git;a=tree"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'config override: tree view, features enabled in repo config' \ + 'git config gitweb.blame yes && + git config gitweb.snapshot "zip,tgz, tbz2" && + gitweb_run "p=.git;a=tree"' +test_debug 'cat gitweb.log' + +test_done diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh new file mode 100755 index 0000000000..0d7786a8c7 --- /dev/null +++ b/t/t9600-cvsimport.sh @@ -0,0 +1,151 @@ +#!/bin/sh + +test_description='git-cvsimport basic tests' +. ./test-lib.sh + +CVSROOT=$(pwd)/cvsroot +export CVSROOT +unset CVS_SERVER +# for clean cvsps cache +HOME=$(pwd) +export HOME + +if ! type cvs >/dev/null 2>&1 +then + say 'skipping cvsimport tests, cvs not found' + test_done + exit +fi + +cvsps_version=`cvsps -h 2>&1 | sed -ne 's/cvsps version //p'` +case "$cvsps_version" in +2.1 | 2.2*) + ;; +'') + say 'skipping cvsimport tests, cvsps not found' + test_done + exit + ;; +*) + say 'skipping cvsimport tests, unsupported cvsps version' + test_done + exit + ;; +esac + +test_expect_success 'setup cvsroot' 'cvs init' + +test_expect_success 'setup a cvs module' ' + + mkdir "$CVSROOT/module" && + cvs co -d module-cvs module && + cd module-cvs && + cat <<EOF >o_fortuna && +O Fortuna +velut luna +statu variabilis, + +semper crescis +aut decrescis; +vita detestabilis + +nunc obdurat +et tunc curat +ludo mentis aciem, + +egestatem, +potestatem +dissolvit ut glaciem. +EOF + cvs add o_fortuna && + cat <<EOF >message && +add "O Fortuna" lyrics + +These public domain lyrics make an excellent sample text. +EOF + cvs commit -F message && + cd .. +' + +test_expect_success 'import a trivial module' ' + + git cvsimport -a -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 'update cvs module' ' + + cd module-cvs && + cat <<EOF >o_fortuna && +O Fortune, +like the moon +you are changeable, + +ever waxing +and waning; +hateful life + +first oppresses +and then soothes +as fancy takes it; + +poverty +and power +it melts them like ice. +EOF + cat <<EOF >message && +translate to English + +My Latin is terrible. +EOF + cvs commit -F message && + cd .. +' + +test_expect_success 'update git module' ' + + cd module-git && + git cvsimport -a -z 0 module && + git merge origin && + cd .. && + test_cmp module-cvs/o_fortuna module-git/o_fortuna + +' + +test_expect_success 'update cvs module' ' + + cd module-cvs && + echo 1 >tick && + cvs add tick && + cvs commit -m 1 + cd .. + +' + +test_expect_success 'cvsimport.module config works' ' + + cd module-git && + git config cvsimport.module module && + git cvsimport -a -z0 && + git merge origin && + cd .. && + test_cmp module-cvs/tick module-git/tick + +' + +test_expect_success 'import from a CVS working tree' ' + + cvs co -d import-from-wt module && + cd import-from-wt && + git cvsimport -a -z0 && + echo 1 >expect && + git log -1 --pretty=format:%s%n >actual && + test_cmp actual expect && + cd .. + +' + +test_done diff --git a/t/t9700-perl-git.sh b/t/t9700-perl-git.sh new file mode 100755 index 0000000000..9706ee5773 --- /dev/null +++ b/t/t9700-perl-git.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# +# Copyright (c) 2008 Lea Wiemann +# + +test_description='perl interface (Git.pm)' +. ./test-lib.sh + +perl -MTest::More -e 0 2>/dev/null || { + say_color skip "Perl Test::More unavailable, skipping test" + test_done +} + +# set up test repository + +test_expect_success \ + 'set up test repository' \ + 'echo "test file 1" > file1 && + echo "test file 2" > file2 && + mkdir directory1 && + echo "in directory1" >> directory1/file && + mkdir directory2 && + echo "in directory2" >> directory2/file && + git add . && + git commit -m "first commit" && + + echo "changed file 1" > file1 && + git commit -a -m "second commit" && + + git-config --add color.test.slot1 green && + git-config --add test.string value && + git-config --add test.dupstring value1 && + git-config --add test.dupstring value2 && + git-config --add test.booltrue true && + git-config --add test.boolfalse no && + git-config --add test.boolother other && + git-config --add test.int 2k + ' + +test_external_without_stderr \ + 'Perl API' \ + perl ../t9700/test.pl + +test_done diff --git a/t/t9700/test.pl b/t/t9700/test.pl new file mode 100755 index 0000000000..4d2312548a --- /dev/null +++ b/t/t9700/test.pl @@ -0,0 +1,100 @@ +#!/usr/bin/perl +use lib (split(/:/, $ENV{GITPERLLIB})); + +use 5.006002; +use warnings; +use strict; + +use Test::More qw(no_plan); + +use Cwd; +use File::Basename; +use File::Temp; + +BEGIN { use_ok('Git') } + +# set up +our $repo_dir = "trash directory"; +our $abs_repo_dir = Cwd->cwd; +die "this must be run by calling the t/t97* shell script(s)\n" + if basename(Cwd->cwd) ne $repo_dir; +ok(our $r = Git->repository(Directory => "."), "open repository"); + +# config +is($r->config("test.string"), "value", "config scalar: string"); +is_deeply([$r->config("test.dupstring")], ["value1", "value2"], + "config array: string"); +is($r->config("test.nonexistent"), undef, "config scalar: nonexistent"); +is_deeply([$r->config("test.nonexistent")], [], "config array: nonexistent"); +is($r->config_int("test.int"), 2048, "config_int: integer"); +is($r->config_int("test.nonexistent"), undef, "config_int: nonexistent"); +ok($r->config_bool("test.booltrue"), "config_bool: true"); +ok(!$r->config_bool("test.boolfalse"), "config_bool: false"); +our $ansi_green = "\x1b[32m"; +is($r->get_color("color.test.slot1", "red"), $ansi_green, "get_color"); +# Cannot test $r->get_colorbool("color.foo")) because we do not +# control whether our STDOUT is a terminal. + +# Failure cases for config: +# Save and restore STDERR; we will probably extract this into a +# "dies_ok" method and possibly move the STDERR handling to Git.pm. +open our $tmpstderr, ">&", STDERR or die "cannot save STDERR"; close STDERR; +eval { $r->config("test.dupstring") }; +ok($@, "config: duplicate entry in scalar context fails"); +eval { $r->config_bool("test.boolother") }; +ok($@, "config_bool: non-boolean values fail"); +open STDERR, ">&", $tmpstderr or die "cannot restore STDERR"; + +# ident +like($r->ident("aUthor"), qr/^A U Thor <author\@example.com> [0-9]+ \+0000$/, + "ident scalar: author (type)"); +like($r->ident("cOmmitter"), qr/^C O Mitter <committer\@example.com> [0-9]+ \+0000$/, + "ident scalar: committer (type)"); +is($r->ident("invalid"), "invalid", "ident scalar: invalid ident string (no parsing)"); +my ($name, $email, $time_tz) = $r->ident('author'); +is_deeply([$name, $email], ["A U Thor", "author\@example.com"], + "ident array: author"); +like($time_tz, qr/[0-9]+ \+0000/, "ident array: author"); +is_deeply([$r->ident("Name <email> 123 +0000")], ["Name", "email", "123 +0000"], + "ident array: ident string"); +is_deeply([$r->ident("invalid")], [], "ident array: invalid ident string"); + +# ident_person +is($r->ident_person("aUthor"), "A U Thor <author\@example.com>", + "ident_person: author (type)"); +is($r->ident_person("Name <email> 123 +0000"), "Name <email>", + "ident_person: ident string"); +is($r->ident_person("Name", "email", "123 +0000"), "Name <email>", + "ident_person: array"); + +# objects and hashes +ok(our $file1hash = $r->command_oneline('rev-parse', "HEAD:file1"), "(get file hash)"); +our $tmpfile = File::Temp->new; +is($r->cat_blob($file1hash, $tmpfile), 15, "cat_blob: size"); +our $blobcontents; +{ local $/; seek $tmpfile, 0, 0; $blobcontents = <$tmpfile>; } +is($blobcontents, "changed file 1\n", "cat_blob: data"); +seek $tmpfile, 0, 0; +is(Git::hash_object("blob", $tmpfile), $file1hash, "hash_object: roundtrip"); +$tmpfile = File::Temp->new(); +print $tmpfile my $test_text = "test blob, to be inserted\n"; +like(our $newhash = $r->hash_and_insert_object($tmpfile), qr/[0-9a-fA-F]{40}/, + "hash_and_insert_object: returns hash"); +$tmpfile = File::Temp->new; +is($r->cat_blob($newhash, $tmpfile), length $test_text, "cat_blob: roundtrip size"); +{ local $/; seek $tmpfile, 0, 0; $blobcontents = <$tmpfile>; } +is($blobcontents, $test_text, "cat_blob: roundtrip data"); + +# paths +is($r->repo_path, "./.git", "repo_path"); +is($r->wc_path, $abs_repo_dir . "/", "wc_path"); +is($r->wc_subdir, "", "wc_subdir initial"); +$r->wc_chdir("directory1"); +is($r->wc_subdir, "directory1", "wc_subdir after wc_chdir"); +TODO: { + local $TODO = "commands do not work after wc_chdir"; + # Failure output is active even in non-verbose mode and thus + # annoying. Hence we skip these tests as long as they fail. + todo_skip 'config after wc_chdir', 1; + is($r->config("color.string"), "value", "config after wc_chdir"); +} diff --git a/t/test-lib.sh b/t/test-lib.sh new file mode 100644 index 0000000000..11c027571b --- /dev/null +++ b/t/test-lib.sh @@ -0,0 +1,517 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +# Keep the original TERM for say_color +ORIGINAL_TERM=$TERM + +# For repeatability, reset the environment to known value. +LANG=C +LC_ALL=C +PAGER=cat +TZ=UTC +TERM=dumb +export LANG LC_ALL PAGER TERM TZ +EDITOR=: +VISUAL=: +unset GIT_EDITOR +unset AUTHOR_DATE +unset AUTHOR_EMAIL +unset AUTHOR_NAME +unset COMMIT_AUTHOR_EMAIL +unset COMMIT_AUTHOR_NAME +unset EMAIL +unset GIT_ALTERNATE_OBJECT_DIRECTORIES +unset GIT_AUTHOR_DATE +GIT_AUTHOR_EMAIL=author@example.com +GIT_AUTHOR_NAME='A U Thor' +unset GIT_COMMITTER_DATE +GIT_COMMITTER_EMAIL=committer@example.com +GIT_COMMITTER_NAME='C O Mitter' +unset GIT_DIFF_OPTS +unset GIT_DIR +unset GIT_WORK_TREE +unset GIT_EXTERNAL_DIFF +unset GIT_INDEX_FILE +unset GIT_OBJECT_DIRECTORY +unset GIT_CEILING_DIRECTORIES +unset SHA1_FILE_DIRECTORIES +unset SHA1_FILE_DIRECTORY +GIT_MERGE_VERBOSITY=5 +export GIT_MERGE_VERBOSITY +export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME +export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME +export EDITOR VISUAL +GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u} + +# Protect ourselves from common misconfiguration to export +# CDPATH into the environment +unset CDPATH + +case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in + 1|2|true) + echo "* warning: Some tests will not work if GIT_TRACE" \ + "is set as to trace on STDERR ! *" + echo "* warning: Please set GIT_TRACE to something" \ + "other than 1, 2 or true ! *" + ;; +esac + +# Each test should start with something like this, after copyright notices: +# +# test_description='Description of this test... +# This test checks if command xyzzy does the right thing... +# ' +# . ./test-lib.sh +[ "x$ORIGINAL_TERM" != "xdumb" ] && ( + TERM=$ORIGINAL_TERM && + export TERM && + [ -t 1 ] && + tput bold >/dev/null 2>&1 && + tput setaf 1 >/dev/null 2>&1 && + tput sgr0 >/dev/null 2>&1 + ) && + color=t + +while test "$#" -ne 0 +do + case "$1" in + -d|--d|--de|--deb|--debu|--debug) + debug=t; shift ;; + -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate) + immediate=t; shift ;; + -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests) + export GIT_TEST_LONG=t; shift ;; + -h|--h|--he|--hel|--help) + help=t; shift ;; + -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose) + verbose=t; shift ;; + -q|--q|--qu|--qui|--quie|--quiet) + quiet=t; shift ;; + --no-color) + color=; shift ;; + --no-python) + # noop now... + shift ;; + *) + break ;; + esac +done + +if test -n "$color"; then + say_color () { + ( + TERM=$ORIGINAL_TERM + export TERM + case "$1" in + error) tput bold; tput setaf 1;; # bold red + skip) tput bold; tput setaf 2;; # bold green + pass) tput setaf 2;; # green + info) tput setaf 3;; # brown + *) test -n "$quiet" && return;; + esac + shift + echo "* $*" + tput sgr0 + ) + } +else + say_color() { + test -z "$1" && test -n "$quiet" && return + shift + echo "* $*" + } +fi + +error () { + say_color error "error: $*" + trap - exit + exit 1 +} + +say () { + say_color info "$*" +} + +test "${test_description}" != "" || +error "Test script did not set test_description." + +if test "$help" = "t" +then + echo "$test_description" + exit 0 +fi + +exec 5>&1 +if test "$verbose" = "t" +then + exec 4>&2 3>&1 +else + exec 4>/dev/null 3>/dev/null +fi + +test_failure=0 +test_count=0 +test_fixed=0 +test_broken=0 +test_success=0 + +die () { + echo >&5 "FATAL: Unexpected exit with code $?" + exit 1 +} + +trap 'die' exit + +# The semantics of the editor variables are that of invoking +# sh -c "$EDITOR \"$@\"" files ... +# +# If our trash directory contains shell metacharacters, they will be +# interpreted if we just set $EDITOR directly, so do a little dance with +# environment variables to work around this. +# +# In particular, quoting isn't enough, as the path may contain the same quote +# that we're using. +test_set_editor () { + FAKE_EDITOR="$1" + export FAKE_EDITOR + VISUAL='"$FAKE_EDITOR"' + export VISUAL +} + +test_tick () { + if test -z "${test_tick+set}" + then + test_tick=1112911993 + else + test_tick=$(($test_tick + 60)) + fi + GIT_COMMITTER_DATE="$test_tick -0700" + GIT_AUTHOR_DATE="$test_tick -0700" + export GIT_COMMITTER_DATE GIT_AUTHOR_DATE +} + +# You are not expected to call test_ok_ and test_failure_ directly, use +# the text_expect_* functions instead. + +test_ok_ () { + test_count=$(expr "$test_count" + 1) + test_success=$(expr "$test_success" + 1) + say_color "" " ok $test_count: $@" +} + +test_failure_ () { + test_count=$(expr "$test_count" + 1) + test_failure=$(expr "$test_failure" + 1); + say_color error "FAIL $test_count: $1" + shift + echo "$@" | sed -e 's/^/ /' + test "$immediate" = "" || { trap - exit; exit 1; } +} + +test_known_broken_ok_ () { + test_count=$(expr "$test_count" + 1) + test_fixed=$(($test_fixed+1)) + say_color "" " FIXED $test_count: $@" +} + +test_known_broken_failure_ () { + test_count=$(expr "$test_count" + 1) + test_broken=$(($test_broken+1)) + say_color skip " still broken $test_count: $@" +} + +test_debug () { + test "$debug" = "" || eval "$1" +} + +test_run_ () { + eval >&3 2>&4 "$1" + eval_ret="$?" + return 0 +} + +test_skip () { + this_test=$(expr "./$0" : '.*/\(t[0-9]*\)-[^/]*$') + this_test="$this_test.$(expr "$test_count" + 1)" + to_skip= + for skp in $GIT_SKIP_TESTS + do + case "$this_test" in + $skp) + to_skip=t + esac + done + case "$to_skip" in + t) + say_color skip >&3 "skipping test: $@" + test_count=$(expr "$test_count" + 1) + say_color skip "skip $test_count: $1" + : true + ;; + *) + false + ;; + esac +} + +test_expect_failure () { + test "$#" = 2 || + error "bug in the test script: not 2 parameters to test-expect-failure" + if ! test_skip "$@" + then + say >&3 "checking known breakage: $2" + test_run_ "$2" + if [ "$?" = 0 -a "$eval_ret" = 0 ] + then + test_known_broken_ok_ "$1" + else + test_known_broken_failure_ "$1" + fi + fi + echo >&3 "" +} + +test_expect_success () { + test "$#" = 2 || + error "bug in the test script: not 2 parameters to test-expect-success" + if ! test_skip "$@" + then + say >&3 "expecting success: $2" + test_run_ "$2" + if [ "$?" = 0 -a "$eval_ret" = 0 ] + then + test_ok_ "$1" + else + test_failure_ "$@" + fi + fi + echo >&3 "" +} + +test_expect_code () { + test "$#" = 3 || + error "bug in the test script: not 3 parameters to test-expect-code" + if ! test_skip "$@" + then + say >&3 "expecting exit code $1: $3" + test_run_ "$3" + if [ "$?" = 0 -a "$eval_ret" = "$1" ] + then + test_ok_ "$2" + else + test_failure_ "$@" + fi + fi + echo >&3 "" +} + +# test_external runs external test scripts that provide continuous +# test output about their progress, and succeeds/fails on +# zero/non-zero exit code. It outputs the test output on stdout even +# in non-verbose mode, and announces the external script with "* run +# <n>: ..." before running it. When providing relative paths, keep in +# mind that all scripts run in "trash directory". +# Usage: test_external description command arguments... +# Example: test_external 'Perl API' perl ../path/to/test.pl +test_external () { + test "$#" -eq 3 || + error >&5 "bug in the test script: not 3 parameters to test_external" + descr="$1" + shift + if ! test_skip "$descr" "$@" + then + # Announce the script to reduce confusion about the + # test output that follows. + say_color "" " run $(expr "$test_count" + 1): $descr ($*)" + # Run command; redirect its stderr to &4 as in + # test_run_, but keep its stdout on our stdout even in + # non-verbose mode. + "$@" 2>&4 + if [ "$?" = 0 ] + then + test_ok_ "$descr" + else + test_failure_ "$descr" "$@" + fi + fi +} + +# Like test_external, but in addition tests that the command generated +# no output on stderr. +test_external_without_stderr () { + # The temporary file has no (and must have no) security + # implications. + tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi + stderr="$tmp/git-external-stderr.$$.tmp" + test_external "$@" 4> "$stderr" + [ -f "$stderr" ] || error "Internal error: $stderr disappeared." + descr="no stderr: $1" + shift + say >&3 "expecting no stderr from previous command" + if [ ! -s "$stderr" ]; then + rm "$stderr" + test_ok_ "$descr" + else + if [ "$verbose" = t ]; then + output=`echo; echo Stderr is:; cat "$stderr"` + else + output= + fi + # rm first in case test_failure exits. + rm "$stderr" + test_failure_ "$descr" "$@" "$output" + fi +} + +# This is not among top-level (test_expect_success | test_expect_failure) +# but is a prefix that can be used in the test script, like: +# +# test_expect_success 'complain and die' ' +# do something && +# do something else && +# test_must_fail git checkout ../outerspace +# ' +# +# Writing this as "! git checkout ../outerspace" is wrong, because +# the failure could be due to a segv. We want a controlled failure. + +test_must_fail () { + "$@" + test $? -gt 0 -a $? -le 129 -o $? -gt 192 +} + +# test_cmp is a helper function to compare actual and expected output. +# You can use it like: +# +# test_expect_success 'foo works' ' +# echo expected >expected && +# foo >actual && +# test_cmp expected actual +# ' +# +# This could be written as either "cmp" or "diff -u", but: +# - cmp's output is not nearly as easy to read as diff -u +# - not all diff versions understand "-u" + +test_cmp() { + $GIT_TEST_CMP "$@" +} + +# Most tests can use the created repository, but some may need to create more. +# Usage: test_create_repo <directory> +test_create_repo () { + test "$#" = 1 || + error "bug in the test script: not 1 parameter to test-create-repo" + owd=`pwd` + repo="$1" + mkdir "$repo" + cd "$repo" || error "Cannot setup test environment" + "$GIT_EXEC_PATH/git" init "--template=$GIT_EXEC_PATH/templates/blt/" >&3 2>&4 || + error "cannot run git init -- have you built things yet?" + mv .git/hooks .git/hooks-disabled + cd "$owd" +} + +test_done () { + trap - exit + test_results_dir="$TEST_DIRECTORY/test-results" + mkdir -p "$test_results_dir" + test_results_path="$test_results_dir/${0%-*}-$$" + + echo "total $test_count" >> $test_results_path + echo "success $test_success" >> $test_results_path + echo "fixed $test_fixed" >> $test_results_path + echo "broken $test_broken" >> $test_results_path + echo "failed $test_failure" >> $test_results_path + echo "" >> $test_results_path + + if test "$test_fixed" != 0 + then + say_color pass "fixed $test_fixed known breakage(s)" + fi + if test "$test_broken" != 0 + then + say_color error "still have $test_broken known breakage(s)" + msg="remaining $(($test_count-$test_broken)) test(s)" + else + msg="$test_count test(s)" + fi + case "$test_failure" in + 0) + # We could: + # cd .. && rm -fr 'trash directory' + # but that means we forbid any tests that use their own + # subdirectory from calling test_done without coming back + # to where they started from. + # The Makefile provided will clean this test area so + # we will leave things as they are. + + say_color pass "passed all $msg" + exit 0 ;; + + *) + say_color error "failed $test_failure among $msg" + exit 1 ;; + + esac +} + +# Test the binaries we have just built. The tests are kept in +# t/ subdirectory and are run in 'trash directory' subdirectory. +TEST_DIRECTORY=$(pwd) +PATH=$TEST_DIRECTORY/..:$PATH +GIT_EXEC_PATH=$(pwd)/.. +GIT_TEMPLATE_DIR=$(pwd)/../templates/blt +unset GIT_CONFIG +unset GIT_CONFIG_LOCAL +GIT_CONFIG_NOSYSTEM=1 +GIT_CONFIG_NOGLOBAL=1 +export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL + +GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git +export GITPERLLIB +test -d ../templates/blt || { + error "You haven't built things yet, have you?" +} + +if ! test -x ../test-chmtime; then + echo >&2 'You need to build test-chmtime:' + echo >&2 'Run "make test-chmtime" in the source (toplevel) directory' + exit 1 +fi + +. ../GIT-BUILD-OPTIONS + +# Test repository +test="trash directory" +rm -fr "$test" || { + trap - exit + echo >&5 "FATAL: Cannot prepare test area" + exit 1 +} + +test_create_repo "$test" +# Use -P to resolve symlinks in our working directory so that the cwd +# in subprocesses like git equals our $PWD (for pathname comparisons). +cd -P "$test" || exit 1 + +this_test=$(expr "./$0" : '.*/\(t[0-9]*\)-[^/]*$') +for skp in $GIT_SKIP_TESTS +do + to_skip= + for skp in $GIT_SKIP_TESTS + do + case "$this_test" in + $skp) + to_skip=t + esac + done + case "$to_skip" in + t) + say_color skip >&3 "skipping test $this_test altogether" + say_color skip "skip all tests in $this_test" + test_done + esac +done diff --git a/t/test4012.png b/t/test4012.png Binary files differnew file mode 100644 index 0000000000..7b181d15ce --- /dev/null +++ b/t/test4012.png diff --git a/t/test9200a.png b/t/test9200a.png Binary files differnew file mode 100644 index 0000000000..7b181d15ce --- /dev/null +++ b/t/test9200a.png diff --git a/t/test9200b.png b/t/test9200b.png Binary files differnew file mode 100644 index 0000000000..ac22ccbd3e --- /dev/null +++ b/t/test9200b.png |