summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fast-import.c35
-rwxr-xr-xt/t9300-fast-import.sh4
2 files changed, 24 insertions, 15 deletions
diff --git a/fast-import.c b/fast-import.c
index ea1b3217fe..5da07e83e5 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1629,7 +1629,8 @@ del_entry:
static int tree_content_get(
struct tree_entry *root,
const char *p,
- struct tree_entry *leaf)
+ struct tree_entry *leaf,
+ int allow_root)
{
struct tree_content *t;
const char *slash1;
@@ -1641,31 +1642,39 @@ static int tree_content_get(
n = slash1 - p;
else
n = strlen(p);
- if (!n)
+ if (!n && !allow_root)
die("Empty path component found in input");
if (!root->tree)
load_tree(root);
+
+ if (!n) {
+ e = root;
+ goto found_entry;
+ }
+
t = root->tree;
for (i = 0; i < t->entry_count; i++) {
e = t->entries[i];
if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
- if (!slash1) {
- memcpy(leaf, e, sizeof(*leaf));
- if (e->tree && is_null_sha1(e->versions[1].sha1))
- leaf->tree = dup_tree_content(e->tree);
- else
- leaf->tree = NULL;
- return 1;
- }
+ if (!slash1)
+ goto found_entry;
if (!S_ISDIR(e->versions[1].mode))
return 0;
if (!e->tree)
load_tree(e);
- return tree_content_get(e, slash1 + 1, leaf);
+ return tree_content_get(e, slash1 + 1, leaf, 0);
}
}
return 0;
+
+found_entry:
+ memcpy(leaf, e, sizeof(*leaf));
+ if (e->tree && is_null_sha1(e->versions[1].sha1))
+ leaf->tree = dup_tree_content(e->tree);
+ else
+ leaf->tree = NULL;
+ return 1;
}
static int update_branch(struct branch *b)
@@ -2415,7 +2424,7 @@ static void file_change_cr(struct branch *b, int rename)
if (rename)
tree_content_remove(&b->branch_tree, s, &leaf);
else
- tree_content_get(&b->branch_tree, s, &leaf);
+ tree_content_get(&b->branch_tree, s, &leaf, 1);
if (!leaf.versions[1].mode)
die("Path %s not in branch", s);
if (!*d) { /* C "path/to/subdir" "" */
@@ -3067,7 +3076,7 @@ static void parse_ls(struct branch *b)
die("Garbage after path in: %s", command_buf.buf);
p = uq.buf;
}
- tree_content_get(root, p, &leaf);
+ tree_content_get(root, p, &leaf, 1);
/*
* A directory in preparation would have a sha1 of zero
* until it is saved. Save, for simplicity.
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index f4b93557a6..04385a7250 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -1253,7 +1253,7 @@ test_expect_success \
git diff-tree -C --find-copies-harder -r N4 N6 >actual &&
compare_diff_raw expect actual'
-test_expect_failure \
+test_expect_success \
'N: copy root by path' \
'cat >expect <<-\EOF &&
:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf oldroot/file2/newf
@@ -2988,7 +2988,7 @@ test_expect_success 'S: ls with garbage after sha1 must fail' '
###
# Setup is carried over from series S.
-test_expect_failure 'T: ls root tree' '
+test_expect_success 'T: ls root tree' '
sed -e "s/Z\$//" >expect <<-EOF &&
040000 tree $(git rev-parse S^{tree}) Z
EOF