Skip to content

Commit e0eb6b9

Browse files
johnkeepinggitster
authored andcommitted
fast-import: allow ls or filecopy of the root tree
Commit 178e1de (fast-import: don't allow 'ls' of path with empty components, 2012-03-09) restricted paths which: . contain an empty directory component (e.g. foo//bar is invalid), . end with a directory separator (e.g. foo/ is invalid), . start with a directory separator (e.g. /foo is invalid). However, the implementation also caught the empty path, which should represent the root tree. Relax this restriction so that the empty path is explicitly allowed and refers to the root tree. Reported-by: Dave Abrahams <[email protected]> Signed-off-by: John Keeping <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent adefdba commit e0eb6b9

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

fast-import.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,7 +1629,8 @@ static int tree_content_remove(
16291629
static int tree_content_get(
16301630
struct tree_entry *root,
16311631
const char *p,
1632-
struct tree_entry *leaf)
1632+
struct tree_entry *leaf,
1633+
int allow_root)
16331634
{
16341635
struct tree_content *t;
16351636
const char *slash1;
@@ -1641,31 +1642,39 @@ static int tree_content_get(
16411642
n = slash1 - p;
16421643
else
16431644
n = strlen(p);
1644-
if (!n)
1645+
if (!n && !allow_root)
16451646
die("Empty path component found in input");
16461647

16471648
if (!root->tree)
16481649
load_tree(root);
1650+
1651+
if (!n) {
1652+
e = root;
1653+
goto found_entry;
1654+
}
1655+
16491656
t = root->tree;
16501657
for (i = 0; i < t->entry_count; i++) {
16511658
e = t->entries[i];
16521659
if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
1653-
if (!slash1) {
1654-
memcpy(leaf, e, sizeof(*leaf));
1655-
if (e->tree && is_null_sha1(e->versions[1].sha1))
1656-
leaf->tree = dup_tree_content(e->tree);
1657-
else
1658-
leaf->tree = NULL;
1659-
return 1;
1660-
}
1660+
if (!slash1)
1661+
goto found_entry;
16611662
if (!S_ISDIR(e->versions[1].mode))
16621663
return 0;
16631664
if (!e->tree)
16641665
load_tree(e);
1665-
return tree_content_get(e, slash1 + 1, leaf);
1666+
return tree_content_get(e, slash1 + 1, leaf, 0);
16661667
}
16671668
}
16681669
return 0;
1670+
1671+
found_entry:
1672+
memcpy(leaf, e, sizeof(*leaf));
1673+
if (e->tree && is_null_sha1(e->versions[1].sha1))
1674+
leaf->tree = dup_tree_content(e->tree);
1675+
else
1676+
leaf->tree = NULL;
1677+
return 1;
16691678
}
16701679

16711680
static int update_branch(struct branch *b)
@@ -2415,7 +2424,7 @@ static void file_change_cr(struct branch *b, int rename)
24152424
if (rename)
24162425
tree_content_remove(&b->branch_tree, s, &leaf);
24172426
else
2418-
tree_content_get(&b->branch_tree, s, &leaf);
2427+
tree_content_get(&b->branch_tree, s, &leaf, 1);
24192428
if (!leaf.versions[1].mode)
24202429
die("Path %s not in branch", s);
24212430
if (!*d) { /* C "path/to/subdir" "" */
@@ -3067,7 +3076,7 @@ static void parse_ls(struct branch *b)
30673076
die("Garbage after path in: %s", command_buf.buf);
30683077
p = uq.buf;
30693078
}
3070-
tree_content_get(root, p, &leaf);
3079+
tree_content_get(root, p, &leaf, 1);
30713080
/*
30723081
* A directory in preparation would have a sha1 of zero
30733082
* until it is saved. Save, for simplicity.

t/t9300-fast-import.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,7 +1253,7 @@ test_expect_success \
12531253
git diff-tree -C --find-copies-harder -r N4 N6 >actual &&
12541254
compare_diff_raw expect actual'
12551255

1256-
test_expect_failure \
1256+
test_expect_success \
12571257
'N: copy root by path' \
12581258
'cat >expect <<-\EOF &&
12591259
: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' '
29882988
###
29892989
# Setup is carried over from series S.
29902990

2991-
test_expect_failure 'T: ls root tree' '
2991+
test_expect_success 'T: ls root tree' '
29922992
sed -e "s/Z\$//" >expect <<-EOF &&
29932993
040000 tree $(git rev-parse S^{tree}) Z
29942994
EOF

0 commit comments

Comments
 (0)