From: Junio C Hamano Date: Wed, 18 Aug 2010 19:14:41 +0000 (-0700) Subject: Merge branch 'jn/fast-import-subtree' X-Git-Tag: v1.7.3-rc0~75 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/ebb561bcfc7f04b3122150821dde7aca0356f00c?hp=-c Merge branch 'jn/fast-import-subtree' * jn/fast-import-subtree: Teach fast-import to import subtrees named by tree id --- ebb561bcfc7f04b3122150821dde7aca0356f00c diff --combined Documentation/git-fast-import.txt index 77a0a2481a,f4d9aeb137..966ba4f213 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@@ -439,7 -439,7 +439,7 @@@ Marks must be declared (via `mark`) bef * A complete 40 byte or abbreviated commit SHA-1 in hex. * Any valid Git SHA-1 expression that resolves to a commit. See - ``SPECIFYING REVISIONS'' in linkgit:git-rev-parse[1] for details. + ``SPECIFYING REVISIONS'' in linkgit:gitrevisions[1] for details. The special case of restarting an incremental import from the current branch value should be written as: @@@ -482,9 -482,11 +482,11 @@@ External data format: 'M' SP SP SP LF .... + - Here `` can be either a mark reference (`:`) + Here usually `` must be either a mark reference (`:`) set by a prior `blob` command, or a full 40-byte SHA-1 of an - existing Git blob object. + existing Git blob object. If `` is `040000`` then + `` must be the full 40-byte SHA-1 of an existing + Git tree object or a mark reference set with `--import-marks`. Inline data format:: The data content for the file has not been supplied yet. @@@ -509,6 -511,8 +511,8 @@@ in octal. Git only supports the follow * `160000`: A gitlink, SHA-1 of the object refers to a commit in another repository. Git links can only be specified by SHA or through a commit mark. They are used to implement submodules. + * `040000`: A subdirectory. Subdirectories can only be specified by + SHA or through a tree mark set with `--import-marks`. In both formats `` is the complete path of the file to be added (if not already existing) or modified (if already existing). diff --combined fast-import.c index ddad289dae,ad6843a8b6..dd51ac48b6 --- a/fast-import.c +++ b/fast-import.c @@@ -1666,7 -1666,7 +1666,7 @@@ static void dump_marks_helper(FILE *f if (m->shift) { for (k = 0; k < 1024; k++) { if (m->data.sets[k]) - dump_marks_helper(f, (base + k) << m->shift, + dump_marks_helper(f, base + (k << m->shift), m->data.sets[k]); } } else { @@@ -2131,6 -2131,7 +2131,7 @@@ static void file_change_m(struct branc case S_IFREG | 0644: case S_IFREG | 0755: case S_IFLNK: + case S_IFDIR: case S_IFGITLINK: /* ok */ break; @@@ -2176,23 -2177,28 +2177,28 @@@ * another repository. */ } else if (inline_data) { + if (S_ISDIR(mode)) + die("Directories cannot be specified 'inline': %s", + command_buf.buf); if (p != uq.buf) { strbuf_addstr(&uq, p); p = uq.buf; } read_next_command(); parse_and_store_blob(&last_blob, sha1, 0); - } else if (oe) { - if (oe->type != OBJ_BLOB) - die("Not a blob (actually a %s): %s", - typename(oe->type), command_buf.buf); } else { - enum object_type type = sha1_object_info(sha1, NULL); + enum object_type expected = S_ISDIR(mode) ? + OBJ_TREE: OBJ_BLOB; + enum object_type type = oe ? oe->type : + sha1_object_info(sha1, NULL); if (type < 0) - die("Blob not found: %s", command_buf.buf); - if (type != OBJ_BLOB) - die("Not a blob (actually a %s): %s", - typename(type), command_buf.buf); + die("%s not found: %s", + S_ISDIR(mode) ? "Tree" : "Blob", + command_buf.buf); + if (type != expected) + die("Not a %s (actually a %s): %s", + typename(expected), typename(type), + command_buf.buf); } tree_content_set(&b->branch_tree, p, sha1, mode, NULL); diff --combined t/t9300-fast-import.sh index 2aeed7bd06,50d5913cc1..96d07f1833 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@@ -166,63 -166,6 +166,63 @@@ test_expect_success test `git rev-parse --verify master:file2` \ = `git rev-parse --verify verify--import-marks:copy-of-file2`' +test_tick +mt=$(git hash-object --stdin < /dev/null) +: >input.blob +: >marks.exp +: >tree.exp + +cat >input.commit < $GIT_COMMITTER_DATE +data <>input.blob <>input.commit + echo "M 100644 :$m m$i" >>input.commit + echo "M 100644 :$n n$i" >>input.commit + + echo ":$l $mt" >>marks.exp + echo ":$m $mt" >>marks.exp + echo ":$n $mt" >>marks.exp + + printf "100644 blob $mt\tl$i\n" >>tree.exp + printf "100644 blob $mt\tm$i\n" >>tree.exp + printf "100644 blob $mt\tn$i\n" >>tree.exp + + l=$(($l + $l)) + m=$(($m + $m)) + n=$(($l + $n)) + + i=$((1 + $i)) +done + +sort tree.exp > tree.exp_s + +test_expect_success 'A: export marks with large values' ' + cat input.blob input.commit | git fast-import --export-marks=marks.large && + git ls-tree refs/heads/verify--dump-marks >tree.out && + test_cmp tree.exp_s tree.out && + test_cmp marks.exp marks.large' + ### ### series B ### @@@ -853,6 -796,60 +853,60 @@@ test_expect_success 'git fast-import expect <<-\EOF && + :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf + :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf + EOF + subdir=$(git rev-parse refs/heads/branch^0:file2) && + cat >input <<-INPUT_END && + commit refs/heads/N4 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <actual && + compare_diff_raw expect actual' + + test_expect_success \ + 'N: modify copied tree' \ + '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 + subdir=$(git rev-parse refs/heads/branch^0:file2) && + cat >input <<-INPUT_END && + commit refs/heads/N5 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data < $GIT_COMMITTER_DATE + data <actual && + compare_diff_raw expect actual' + ### ### series O ###