Merge branch 'jn/fast-import-fix'
* jn/fast-import-fix: fast-import: do not clear notes in do_change_note_fanout() t9300 (fast-import): another test for the "replace root" feature fast-import: tighten M 040000 syntax fast-import: filemodify after M 040000 <tree> "" crashes
This commit is contained in:
commit
ed8298dc34
@ -1437,6 +1437,20 @@ static void store_tree(struct tree_entry *root)
|
||||
t->entry_count -= del;
|
||||
}
|
||||
|
||||
static void tree_content_replace(
|
||||
struct tree_entry *root,
|
||||
const unsigned char *sha1,
|
||||
const uint16_t mode,
|
||||
struct tree_content *newtree)
|
||||
{
|
||||
if (!S_ISDIR(mode))
|
||||
die("Root cannot be a non-directory");
|
||||
hashcpy(root->versions[1].sha1, sha1);
|
||||
if (root->tree)
|
||||
release_tree_content_recursive(root->tree);
|
||||
root->tree = newtree;
|
||||
}
|
||||
|
||||
static int tree_content_set(
|
||||
struct tree_entry *root,
|
||||
const char *p,
|
||||
@ -1444,7 +1458,7 @@ static int tree_content_set(
|
||||
const uint16_t mode,
|
||||
struct tree_content *subtree)
|
||||
{
|
||||
struct tree_content *t = root->tree;
|
||||
struct tree_content *t;
|
||||
const char *slash1;
|
||||
unsigned int i, n;
|
||||
struct tree_entry *e;
|
||||
@ -1454,20 +1468,14 @@ static int tree_content_set(
|
||||
n = slash1 - p;
|
||||
else
|
||||
n = strlen(p);
|
||||
if (!slash1 && !n) {
|
||||
if (!S_ISDIR(mode))
|
||||
die("Root cannot be a non-directory");
|
||||
hashcpy(root->versions[1].sha1, sha1);
|
||||
if (root->tree)
|
||||
release_tree_content_recursive(root->tree);
|
||||
root->tree = subtree;
|
||||
return 1;
|
||||
}
|
||||
if (!n)
|
||||
die("Empty path component found in input");
|
||||
if (!slash1 && !S_ISDIR(mode) && subtree)
|
||||
die("Non-directories cannot have subtrees");
|
||||
|
||||
if (!root->tree)
|
||||
load_tree(root);
|
||||
t = root->tree;
|
||||
for (i = 0; i < t->entry_count; i++) {
|
||||
e = t->entries[i];
|
||||
if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
|
||||
@ -1523,7 +1531,7 @@ static int tree_content_remove(
|
||||
const char *p,
|
||||
struct tree_entry *backup_leaf)
|
||||
{
|
||||
struct tree_content *t = root->tree;
|
||||
struct tree_content *t;
|
||||
const char *slash1;
|
||||
unsigned int i, n;
|
||||
struct tree_entry *e;
|
||||
@ -1534,6 +1542,9 @@ static int tree_content_remove(
|
||||
else
|
||||
n = strlen(p);
|
||||
|
||||
if (!root->tree)
|
||||
load_tree(root);
|
||||
t = root->tree;
|
||||
for (i = 0; i < t->entry_count; i++) {
|
||||
e = t->entries[i];
|
||||
if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
|
||||
@ -1581,7 +1592,7 @@ static int tree_content_get(
|
||||
const char *p,
|
||||
struct tree_entry *leaf)
|
||||
{
|
||||
struct tree_content *t = root->tree;
|
||||
struct tree_content *t;
|
||||
const char *slash1;
|
||||
unsigned int i, n;
|
||||
struct tree_entry *e;
|
||||
@ -1592,6 +1603,9 @@ static int tree_content_get(
|
||||
else
|
||||
n = strlen(p);
|
||||
|
||||
if (!root->tree)
|
||||
load_tree(root);
|
||||
t = root->tree;
|
||||
for (i = 0; i < t->entry_count; i++) {
|
||||
e = t->entries[i];
|
||||
if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
|
||||
@ -2218,6 +2232,10 @@ static void file_change_m(struct branch *b)
|
||||
command_buf.buf);
|
||||
}
|
||||
|
||||
if (!*p) {
|
||||
tree_content_replace(&b->branch_tree, sha1, mode, NULL);
|
||||
return;
|
||||
}
|
||||
tree_content_set(&b->branch_tree, p, sha1, mode, NULL);
|
||||
}
|
||||
|
||||
@ -2276,6 +2294,13 @@ static void file_change_cr(struct branch *b, int rename)
|
||||
tree_content_get(&b->branch_tree, s, &leaf);
|
||||
if (!leaf.versions[1].mode)
|
||||
die("Path %s not in branch", s);
|
||||
if (!*d) { /* C "path/to/subdir" "" */
|
||||
tree_content_replace(&b->branch_tree,
|
||||
leaf.versions[1].sha1,
|
||||
leaf.versions[1].mode,
|
||||
leaf.tree);
|
||||
return;
|
||||
}
|
||||
tree_content_set(&b->branch_tree, d,
|
||||
leaf.versions[1].sha1,
|
||||
leaf.versions[1].mode,
|
||||
|
@ -928,6 +928,114 @@ test_expect_success \
|
||||
git diff-tree -C --find-copies-harder -r N5^^ N5 >actual &&
|
||||
compare_diff_raw expect actual'
|
||||
|
||||
test_expect_success \
|
||||
'N: reject foo/ syntax' \
|
||||
'subdir=$(git rev-parse refs/heads/branch^0:file2) &&
|
||||
test_must_fail git fast-import <<-INPUT_END
|
||||
commit refs/heads/N5B
|
||||
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
|
||||
data <<COMMIT
|
||||
copy with invalid syntax
|
||||
COMMIT
|
||||
|
||||
from refs/heads/branch^0
|
||||
M 040000 $subdir file3/
|
||||
INPUT_END'
|
||||
|
||||
test_expect_success \
|
||||
'N: copy to root by id and modify' \
|
||||
'echo "hello, world" >expect.foo &&
|
||||
echo hello >expect.bar &&
|
||||
git fast-import <<-SETUP_END &&
|
||||
commit refs/heads/N7
|
||||
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
|
||||
data <<COMMIT
|
||||
hello, tree
|
||||
COMMIT
|
||||
|
||||
deleteall
|
||||
M 644 inline foo/bar
|
||||
data <<EOF
|
||||
hello
|
||||
EOF
|
||||
SETUP_END
|
||||
|
||||
tree=$(git rev-parse --verify N7:) &&
|
||||
git fast-import <<-INPUT_END &&
|
||||
commit refs/heads/N8
|
||||
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
|
||||
data <<COMMIT
|
||||
copy to root by id and modify
|
||||
COMMIT
|
||||
|
||||
M 040000 $tree ""
|
||||
M 644 inline foo/foo
|
||||
data <<EOF
|
||||
hello, world
|
||||
EOF
|
||||
INPUT_END
|
||||
git show N8:foo/foo >actual.foo &&
|
||||
git show N8:foo/bar >actual.bar &&
|
||||
test_cmp expect.foo actual.foo &&
|
||||
test_cmp expect.bar actual.bar'
|
||||
|
||||
test_expect_success \
|
||||
'N: extract subtree' \
|
||||
'branch=$(git rev-parse --verify refs/heads/branch^{tree}) &&
|
||||
cat >input <<-INPUT_END &&
|
||||
commit refs/heads/N9
|
||||
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
|
||||
data <<COMMIT
|
||||
extract subtree branch:newdir
|
||||
COMMIT
|
||||
|
||||
M 040000 $branch ""
|
||||
C "newdir" ""
|
||||
INPUT_END
|
||||
git fast-import <input &&
|
||||
git diff --exit-code branch:newdir N9'
|
||||
|
||||
test_expect_success \
|
||||
'N: modify subtree, extract it, and modify again' \
|
||||
'echo hello >expect.baz &&
|
||||
echo hello, world >expect.qux &&
|
||||
git fast-import <<-SETUP_END &&
|
||||
commit refs/heads/N10
|
||||
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
|
||||
data <<COMMIT
|
||||
hello, tree
|
||||
COMMIT
|
||||
|
||||
deleteall
|
||||
M 644 inline foo/bar/baz
|
||||
data <<EOF
|
||||
hello
|
||||
EOF
|
||||
SETUP_END
|
||||
|
||||
tree=$(git rev-parse --verify N10:) &&
|
||||
git fast-import <<-INPUT_END &&
|
||||
commit refs/heads/N11
|
||||
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
|
||||
data <<COMMIT
|
||||
copy to root by id and modify
|
||||
COMMIT
|
||||
|
||||
M 040000 $tree ""
|
||||
M 100644 inline foo/bar/qux
|
||||
data <<EOF
|
||||
hello, world
|
||||
EOF
|
||||
R "foo" ""
|
||||
C "bar/qux" "bar/quux"
|
||||
INPUT_END
|
||||
git show N11:bar/baz >actual.baz &&
|
||||
git show N11:bar/qux >actual.qux &&
|
||||
git show N11:bar/quux >actual.quux &&
|
||||
test_cmp expect.baz actual.baz &&
|
||||
test_cmp expect.qux actual.qux &&
|
||||
test_cmp expect.qux actual.quux'
|
||||
|
||||
###
|
||||
### series O
|
||||
###
|
||||
|
Loading…
Reference in New Issue
Block a user