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:
Junio C Hamano 2010-11-29 17:52:32 -08:00
commit ed8298dc34
2 changed files with 145 additions and 12 deletions

View File

@ -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,

View File

@ -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
###