Merge branch 'jn/fast-import-subtree'
* jn/fast-import-subtree: Teach fast-import to import subtrees named by tree id
This commit is contained in:
@ -482,9 +482,11 @@ External data format::
|
|||||||
'M' SP <mode> SP <dataref> SP <path> LF
|
'M' SP <mode> SP <dataref> SP <path> LF
|
||||||
....
|
....
|
||||||
+
|
+
|
||||||
Here `<dataref>` can be either a mark reference (`:<idnum>`)
|
Here usually `<dataref>` must be either a mark reference (`:<idnum>`)
|
||||||
set by a prior `blob` command, or a full 40-byte SHA-1 of an
|
set by a prior `blob` command, or a full 40-byte SHA-1 of an
|
||||||
existing Git blob object.
|
existing Git blob object. If `<mode>` is `040000`` then
|
||||||
|
`<dataref>` 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::
|
Inline data format::
|
||||||
The data content for the file has not been supplied yet.
|
The data content for the file has not been supplied yet.
|
||||||
@ -509,6 +511,8 @@ in octal. Git only supports the following modes:
|
|||||||
* `160000`: A gitlink, SHA-1 of the object refers to a commit in
|
* `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
|
another repository. Git links can only be specified by SHA or through
|
||||||
a commit mark. They are used to implement submodules.
|
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 `<path>` is the complete path of the file to be added
|
In both formats `<path>` is the complete path of the file to be added
|
||||||
(if not already existing) or modified (if already existing).
|
(if not already existing) or modified (if already existing).
|
||||||
|
@ -2131,6 +2131,7 @@ static void file_change_m(struct branch *b)
|
|||||||
case S_IFREG | 0644:
|
case S_IFREG | 0644:
|
||||||
case S_IFREG | 0755:
|
case S_IFREG | 0755:
|
||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
|
case S_IFDIR:
|
||||||
case S_IFGITLINK:
|
case S_IFGITLINK:
|
||||||
/* ok */
|
/* ok */
|
||||||
break;
|
break;
|
||||||
@ -2176,23 +2177,28 @@ static void file_change_m(struct branch *b)
|
|||||||
* another repository.
|
* another repository.
|
||||||
*/
|
*/
|
||||||
} else if (inline_data) {
|
} else if (inline_data) {
|
||||||
|
if (S_ISDIR(mode))
|
||||||
|
die("Directories cannot be specified 'inline': %s",
|
||||||
|
command_buf.buf);
|
||||||
if (p != uq.buf) {
|
if (p != uq.buf) {
|
||||||
strbuf_addstr(&uq, p);
|
strbuf_addstr(&uq, p);
|
||||||
p = uq.buf;
|
p = uq.buf;
|
||||||
}
|
}
|
||||||
read_next_command();
|
read_next_command();
|
||||||
parse_and_store_blob(&last_blob, sha1, 0);
|
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 {
|
} 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)
|
if (type < 0)
|
||||||
die("Blob not found: %s", command_buf.buf);
|
die("%s not found: %s",
|
||||||
if (type != OBJ_BLOB)
|
S_ISDIR(mode) ? "Tree" : "Blob",
|
||||||
die("Not a blob (actually a %s): %s",
|
command_buf.buf);
|
||||||
typename(type), 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);
|
tree_content_set(&b->branch_tree, p, sha1, mode, NULL);
|
||||||
|
@ -853,6 +853,60 @@ test_expect_success \
|
|||||||
'git fast-import <input &&
|
'git fast-import <input &&
|
||||||
test `git rev-parse N2^{tree}` = `git rev-parse N3^{tree}`'
|
test `git rev-parse N2^{tree}` = `git rev-parse N3^{tree}`'
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
'N: copy directory by id' \
|
||||||
|
'cat >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 <<COMMIT
|
||||||
|
copy by tree hash
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
from refs/heads/branch^0
|
||||||
|
M 040000 $subdir file3
|
||||||
|
INPUT_END
|
||||||
|
git fast-import <input &&
|
||||||
|
git diff-tree -C --find-copies-harder -r N4^ N4 >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 <<COMMIT
|
||||||
|
copy by tree hash
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
from refs/heads/branch^0
|
||||||
|
M 040000 $subdir file3
|
||||||
|
|
||||||
|
commit refs/heads/N5
|
||||||
|
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
|
||||||
|
git fast-import <input &&
|
||||||
|
git diff-tree -C --find-copies-harder -r N5^^ N5 >actual &&
|
||||||
|
compare_diff_raw expect actual'
|
||||||
|
|
||||||
###
|
###
|
||||||
### series O
|
### series O
|
||||||
###
|
###
|
||||||
|
Reference in New Issue
Block a user