strbuf: add strbuf_add*_urlencode
[gitweb.git] / t / t9300-fast-import.sh
index 986bc14d58c30201e75f3d95d9b8245e997b99e9..438aaf6b14b8ae0cb35739d6006eaf646876107c 100755 (executable)
@@ -42,6 +42,14 @@ echo "$@"'
 
 >empty
 
+test_expect_success 'setup: have pipes?' '
+       rm -f frob &&
+       if mkfifo frob
+       then
+               test_set_prereq PIPE
+       fi
+'
+
 ###
 ### series A
 ###
@@ -86,6 +94,12 @@ data <<EOF
 An annotated tag without a tagger
 EOF
 
+tag series-A-blob
+from :3
+data <<EOF
+An annotated tag that annotates a blob.
+EOF
+
 INPUT_END
 test_expect_success \
     'A: create pack from stdin' \
@@ -143,6 +157,18 @@ test_expect_success 'A: verify tag/series-A' '
        test_cmp expect actual
 '
 
+cat >expect <<EOF
+object $(git rev-parse refs/heads/master:file3)
+type blob
+tag series-A-blob
+
+An annotated tag that annotates a blob.
+EOF
+test_expect_success 'A: verify tag/series-A-blob' '
+       git cat-file tag tags/series-A-blob >actual &&
+       test_cmp expect actual
+'
+
 cat >expect <<EOF
 :2 `git rev-parse --verify master:file2`
 :3 `git rev-parse --verify master:file3`
@@ -161,6 +187,55 @@ test_expect_success \
                </dev/null &&
        test_cmp expect marks.new'
 
+test_tick
+new_blob=$(echo testing | git hash-object --stdin)
+cat >input <<INPUT_END
+tag series-A-blob-2
+from $(git rev-parse refs/heads/master:file3)
+data <<EOF
+Tag blob by sha1.
+EOF
+
+blob
+mark :6
+data <<EOF
+testing
+EOF
+
+commit refs/heads/new_blob
+committer  <> 0 +0000
+data 0
+M 644 :6 new_blob
+#pretend we got sha1 from fast-import
+ls "new_blob"
+
+tag series-A-blob-3
+from $new_blob
+data <<EOF
+Tag new_blob.
+EOF
+INPUT_END
+
+cat >expect <<EOF
+object $(git rev-parse refs/heads/master:file3)
+type blob
+tag series-A-blob-2
+
+Tag blob by sha1.
+object $new_blob
+type blob
+tag series-A-blob-3
+
+Tag new_blob.
+EOF
+
+test_expect_success \
+       'A: tag blob by sha1' \
+       'git fast-import <input &&
+       git cat-file tag tags/series-A-blob-2 >actual &&
+       git cat-file tag tags/series-A-blob-3 >>actual &&
+       test_cmp expect actual'
+
 test_tick
 cat >input <<INPUT_END
 commit refs/heads/verify--import-marks
@@ -316,6 +391,105 @@ test_expect_success \
         test `git rev-parse master` = `git rev-parse TEMP_TAG^`'
 rm -f .git/TEMP_TAG
 
+git gc 2>/dev/null >/dev/null
+git prune 2>/dev/null >/dev/null
+
+cat >input <<INPUT_END
+commit refs/heads/empty-committer-1
+committer  <> $GIT_COMMITTER_DATE
+data <<COMMIT
+empty commit
+COMMIT
+INPUT_END
+test_expect_success 'B: accept empty committer' '
+       git fast-import <input &&
+       out=$(git fsck) &&
+       echo "$out" &&
+       test -z "$out"
+'
+git update-ref -d refs/heads/empty-committer-1 || true
+
+git gc 2>/dev/null >/dev/null
+git prune 2>/dev/null >/dev/null
+
+cat >input <<INPUT_END
+commit refs/heads/empty-committer-2
+committer <a@b.com> $GIT_COMMITTER_DATE
+data <<COMMIT
+empty commit
+COMMIT
+INPUT_END
+test_expect_success 'B: accept and fixup committer with no name' '
+       git fast-import <input &&
+       out=$(git fsck) &&
+       echo "$out" &&
+       test -z "$out"
+'
+git update-ref -d refs/heads/empty-committer-2 || true
+
+git gc 2>/dev/null >/dev/null
+git prune 2>/dev/null >/dev/null
+
+cat >input <<INPUT_END
+commit refs/heads/invalid-committer
+committer Name email> $GIT_COMMITTER_DATE
+data <<COMMIT
+empty commit
+COMMIT
+INPUT_END
+test_expect_success 'B: fail on invalid committer (1)' '
+       test_must_fail git fast-import <input
+'
+git update-ref -d refs/heads/invalid-committer || true
+
+cat >input <<INPUT_END
+commit refs/heads/invalid-committer
+committer Name <e<mail> $GIT_COMMITTER_DATE
+data <<COMMIT
+empty commit
+COMMIT
+INPUT_END
+test_expect_success 'B: fail on invalid committer (2)' '
+       test_must_fail git fast-import <input
+'
+git update-ref -d refs/heads/invalid-committer || true
+
+cat >input <<INPUT_END
+commit refs/heads/invalid-committer
+committer Name <email>> $GIT_COMMITTER_DATE
+data <<COMMIT
+empty commit
+COMMIT
+INPUT_END
+test_expect_success 'B: fail on invalid committer (3)' '
+       test_must_fail git fast-import <input
+'
+git update-ref -d refs/heads/invalid-committer || true
+
+cat >input <<INPUT_END
+commit refs/heads/invalid-committer
+committer Name <email $GIT_COMMITTER_DATE
+data <<COMMIT
+empty commit
+COMMIT
+INPUT_END
+test_expect_success 'B: fail on invalid committer (4)' '
+       test_must_fail git fast-import <input
+'
+git update-ref -d refs/heads/invalid-committer || true
+
+cat >input <<INPUT_END
+commit refs/heads/invalid-committer
+committer Name<email> $GIT_COMMITTER_DATE
+data <<COMMIT
+empty commit
+COMMIT
+INPUT_END
+test_expect_success 'B: fail on invalid committer (5)' '
+       test_must_fail git fast-import <input
+'
+git update-ref -d refs/heads/invalid-committer || true
+
 ###
 ### series C
 ###
@@ -646,6 +820,18 @@ test_expect_success \
        'test 1 = `git rev-list J | wc -l` &&
         test 0 = `git ls-tree J | wc -l`'
 
+cat >input <<INPUT_END
+reset refs/heads/J2
+
+tag wrong_tag
+from refs/heads/J2
+data <<EOF
+Tag branch that was reset.
+EOF
+INPUT_END
+test_expect_success \
+       'J: tag must fail on empty branch' \
+       'test_must_fail git fast-import <input'
 ###
 ### series K
 ###
@@ -726,6 +912,47 @@ test_expect_success \
         git diff-tree --abbrev --raw L^ L >output &&
         test_cmp expect output'
 
+cat >input <<INPUT_END
+blob
+mark :1
+data <<EOF
+the data
+EOF
+
+commit refs/heads/L2
+committer C O Mitter <committer@example.com> 1112912473 -0700
+data <<COMMIT
+init L2
+COMMIT
+M 644 :1 a/b/c
+M 644 :1 a/b/d
+M 644 :1 a/e/f
+
+commit refs/heads/L2
+committer C O Mitter <committer@example.com> 1112912473 -0700
+data <<COMMIT
+update L2
+COMMIT
+C a g
+C a/e g/b
+M 644 :1 g/b/h
+INPUT_END
+
+cat <<EOF >expect
+g/b/f
+g/b/h
+EOF
+
+test_expect_success \
+    'L: nested tree copy does not corrupt deltas' \
+       'git fast-import <input &&
+       git ls-tree L2 g/b/ >tmp &&
+       cat tmp | cut -f 2 >actual &&
+       test_cmp expect actual &&
+       git fsck `git rev-parse L2`'
+
+git update-ref -d refs/heads/L2
+
 ###
 ### series M
 ###
@@ -898,6 +1125,77 @@ test_expect_success \
         git diff-tree -C --find-copies-harder -r N4^ N4 >actual &&
         compare_diff_raw expect actual'
 
+test_expect_success PIPE 'N: read and copy directory' '
+       cat >expect <<-\EOF
+       :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      file3/newf
+       :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100   file2/oldf      file3/oldf
+       EOF
+       git update-ref -d refs/heads/N4 &&
+       rm -f backflow &&
+       mkfifo backflow &&
+       (
+               exec <backflow &&
+               cat <<-EOF &&
+               commit refs/heads/N4
+               committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+               data <<COMMIT
+               copy by tree hash, part 2
+               COMMIT
+
+               from refs/heads/branch^0
+               ls "file2"
+               EOF
+               read mode type tree filename &&
+               echo "M 040000 $tree file3"
+       ) |
+       git fast-import --cat-blob-fd=3 3>backflow &&
+       git diff-tree -C --find-copies-harder -r N4^ N4 >actual &&
+       compare_diff_raw expect actual
+'
+
+test_expect_success PIPE 'N: empty directory reads as missing' '
+       cat <<-\EOF >expect &&
+       OBJNAME
+       :000000 100644 OBJNAME OBJNAME A        unrelated
+       EOF
+       echo "missing src" >expect.response &&
+       git update-ref -d refs/heads/read-empty &&
+       rm -f backflow &&
+       mkfifo backflow &&
+       (
+               exec <backflow &&
+               cat <<-EOF &&
+               commit refs/heads/read-empty
+               committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+               data <<COMMIT
+               read "empty" (missing) directory
+               COMMIT
+
+               M 100644 inline src/greeting
+               data <<BLOB
+               hello
+               BLOB
+               C src/greeting dst1/non-greeting
+               C src/greeting unrelated
+               # leave behind "empty" src directory
+               D src/greeting
+               ls "src"
+               EOF
+               read -r line &&
+               printf "%s\n" "$line" >response &&
+               cat <<-\EOF
+               D dst1
+               D dst2
+               EOF
+       ) |
+       git fast-import --cat-blob-fd=3 3>backflow &&
+       test_cmp expect.response response &&
+       git rev-list read-empty |
+       git diff-tree -r --root --stdin |
+       sed "s/$_x40/OBJNAME/g" >actual &&
+       test_cmp expect actual
+'
+
 test_expect_success \
        'N: copy root directory by tree hash' \
        'cat >expect <<-\EOF &&
@@ -1689,6 +1987,23 @@ test_expect_success \
        'Q: verify second note for second commit' \
        'git cat-file blob refs/notes/foobar:$commit2 >actual && test_cmp expect actual'
 
+cat >input <<EOF
+reset refs/heads/Q0
+
+commit refs/heads/note-Q0
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+Note for an empty branch.
+COMMIT
+
+N inline refs/heads/Q0
+data <<NOTE
+some note
+NOTE
+EOF
+test_expect_success \
+       'Q: deny note on empty branch' \
+       'test_must_fail git fast-import <input'
 ###
 ### series R (feature and option)
 ###
@@ -1748,6 +2063,108 @@ test_expect_success \
     'cat input | git fast-import --export-marks=other.marks &&
     grep :1 other.marks'
 
+test_expect_success 'R: catch typo in marks file name' '
+       test_must_fail git fast-import --import-marks=nonexistent.marks </dev/null &&
+       echo "feature import-marks=nonexistent.marks" |
+       test_must_fail git fast-import
+'
+
+test_expect_success 'R: import and output marks can be the same file' '
+       rm -f io.marks &&
+       blob=$(echo hi | git hash-object --stdin) &&
+       cat >expect <<-EOF &&
+       :1 $blob
+       :2 $blob
+       EOF
+       git fast-import --export-marks=io.marks <<-\EOF &&
+       blob
+       mark :1
+       data 3
+       hi
+
+       EOF
+       git fast-import --import-marks=io.marks --export-marks=io.marks <<-\EOF &&
+       blob
+       mark :2
+       data 3
+       hi
+
+       EOF
+       test_cmp expect io.marks
+'
+
+test_expect_success 'R: --import-marks=foo --output-marks=foo to create foo fails' '
+       rm -f io.marks &&
+       test_must_fail git fast-import --import-marks=io.marks --export-marks=io.marks <<-\EOF
+       blob
+       mark :1
+       data 3
+       hi
+
+       EOF
+'
+
+test_expect_success 'R: --import-marks-if-exists' '
+       rm -f io.marks &&
+       blob=$(echo hi | git hash-object --stdin) &&
+       echo ":1 $blob" >expect &&
+       git fast-import --import-marks-if-exists=io.marks --export-marks=io.marks <<-\EOF &&
+       blob
+       mark :1
+       data 3
+       hi
+
+       EOF
+       test_cmp expect io.marks
+'
+
+test_expect_success 'R: feature import-marks-if-exists' '
+       rm -f io.marks &&
+       >expect &&
+
+       git fast-import --export-marks=io.marks <<-\EOF &&
+       feature import-marks-if-exists=not_io.marks
+       EOF
+       test_cmp expect io.marks &&
+
+       blob=$(echo hi | git hash-object --stdin) &&
+
+       echo ":1 $blob" >io.marks &&
+       echo ":1 $blob" >expect &&
+       echo ":2 $blob" >>expect &&
+
+       git fast-import --export-marks=io.marks <<-\EOF &&
+       feature import-marks-if-exists=io.marks
+       blob
+       mark :2
+       data 3
+       hi
+
+       EOF
+       test_cmp expect io.marks &&
+
+       echo ":3 $blob" >>expect &&
+
+       git fast-import --import-marks=io.marks \
+                       --export-marks=io.marks <<-\EOF &&
+       feature import-marks-if-exists=not_io.marks
+       blob
+       mark :3
+       data 3
+       hi
+
+       EOF
+       test_cmp expect io.marks &&
+
+       >expect &&
+
+       git fast-import --import-marks-if-exists=not_io.marks \
+                       --export-marks=io.marks <<-\EOF
+       feature import-marks-if-exists=io.marks
+       EOF
+       test_cmp expect io.marks
+'
+
 cat >input << EOF
 feature import-marks=marks.out
 feature export-marks=marks.new
@@ -1759,7 +2176,7 @@ test_expect_success \
     test_cmp marks.out marks.new'
 
 cat >input <<EOF
-feature import-marks=nonexistant.marks
+feature import-marks=nonexistent.marks
 feature export-marks=marks.new
 EOF
 
@@ -1770,7 +2187,7 @@ test_expect_success \
 
 
 cat >input <<EOF
-feature import-marks=nonexistant.marks
+feature import-marks=nonexistent.marks
 feature export-marks=combined.marks
 EOF
 
@@ -1806,6 +2223,11 @@ test_expect_success 'R: feature no-relative-marks should be honoured' '
     test_cmp marks.new non-relative.out
 '
 
+test_expect_success 'R: feature ls supported' '
+       echo "feature ls" |
+       git fast-import
+'
+
 test_expect_success 'R: feature cat-blob supported' '
        echo "feature cat-blob" |
        git fast-import
@@ -1815,7 +2237,7 @@ test_expect_success 'R: cat-blob-fd must be a nonnegative integer' '
        test_must_fail git fast-import --cat-blob-fd=-1 </dev/null
 '
 
-test_expect_success 'R: print old blob' '
+test_expect_success NOT_MINGW 'R: print old blob' '
        blob=$(echo "yes it can" | git hash-object -w --stdin) &&
        cat >expect <<-EOF &&
        ${blob} blob 11
@@ -1827,7 +2249,7 @@ test_expect_success 'R: print old blob' '
        test_cmp expect actual
 '
 
-test_expect_success 'R: in-stream cat-blob-fd not respected' '
+test_expect_success NOT_MINGW 'R: in-stream cat-blob-fd not respected' '
        echo hello >greeting &&
        blob=$(git hash-object -w greeting) &&
        cat >expect <<-EOF &&
@@ -1848,7 +2270,7 @@ test_expect_success 'R: in-stream cat-blob-fd not respected' '
        test_cmp expect actual.1
 '
 
-test_expect_success 'R: print new blob' '
+test_expect_success NOT_MINGW 'R: print new blob' '
        blob=$(echo "yep yep yep" | git hash-object --stdin) &&
        cat >expect <<-EOF &&
        ${blob} blob 12
@@ -1866,7 +2288,7 @@ test_expect_success 'R: print new blob' '
        test_cmp expect actual
 '
 
-test_expect_success 'R: print new blob by sha1' '
+test_expect_success NOT_MINGW 'R: print new blob by sha1' '
        blob=$(echo "a new blob named by sha1" | git hash-object --stdin) &&
        cat >expect <<-EOF &&
        ${blob} blob 25
@@ -1931,14 +2353,6 @@ test_expect_success 'R: print two blobs to stdout' '
        test_cmp expect actual
 '
 
-test_expect_success 'setup: have pipes?' '
-       rm -f frob &&
-       if mkfifo frob
-       then
-               test_set_prereq PIPE
-       fi
-'
-
 test_expect_success PIPE 'R: copy using cat-file' '
        expect_id=$(git hash-object big) &&
        expect_len=$(wc -c <big) &&
@@ -2066,6 +2480,48 @@ test_expect_success 'R: quiet option results in no stats being output' '
     test_cmp empty output
 '
 
+test_expect_success 'R: feature done means terminating "done" is mandatory' '
+       echo feature done | test_must_fail git fast-import &&
+       test_must_fail git fast-import --done </dev/null
+'
+
+test_expect_success 'R: terminating "done" with trailing gibberish is ok' '
+       git fast-import <<-\EOF &&
+       feature done
+       done
+       trailing gibberish
+       EOF
+       git fast-import <<-\EOF
+       done
+       more trailing gibberish
+       EOF
+'
+
+test_expect_success 'R: terminating "done" within commit' '
+       cat >expect <<-\EOF &&
+       OBJID
+       :000000 100644 OBJID OBJID A    hello.c
+       :000000 100644 OBJID OBJID A    hello2.c
+       EOF
+       git fast-import <<-EOF &&
+       commit refs/heads/done-ends
+       committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+       data <<EOT
+       Commit terminated by "done" command
+       EOT
+       M 100644 inline hello.c
+       data <<EOT
+       Hello, world.
+       EOT
+       C hello.c hello2.c
+       done
+       EOF
+       git rev-list done-ends |
+       git diff-tree -r --stdin --root --always |
+       sed -e "s/$_x40/OBJID/g" >actual &&
+       test_cmp expect actual
+'
+
 cat >input <<EOF
 option git non-existing-option
 EOF