Skip to content

Commit

Permalink
fast-import: allow moving the root tree
Browse files Browse the repository at this point in the history
Because fast-import.c::tree_content_remove does not check for the empty
path, it is not possible to move the root tree to a subdirectory.
Instead the error "Path  not in branch" is produced (note the double
space where the empty path has been inserted).

Fix this by explicitly checking for the empty path and handling it.

Signed-off-by: John Keeping <john@keeping.me.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
John Keeping authored and Junio C Hamano committed Jun 23, 2013
1 parent e0eb6b9 commit 62bfa11
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 8 deletions.
21 changes: 14 additions & 7 deletions fast-import.c
Original file line number Diff line number Diff line change
Expand Up @@ -1568,7 +1568,8 @@ static int tree_content_set(
static int tree_content_remove(
struct tree_entry *root,
const char *p,
struct tree_entry *backup_leaf)
struct tree_entry *backup_leaf,
int allow_root)
{
struct tree_content *t;
const char *slash1;
Expand All @@ -1583,6 +1584,12 @@ static int tree_content_remove(

if (!root->tree)
load_tree(root);

if (!*p && allow_root) {
e = root;
goto del_entry;
}

t = root->tree;
for (i = 0; i < t->entry_count; i++) {
e = t->entries[i];
Expand All @@ -1599,7 +1606,7 @@ static int tree_content_remove(
goto del_entry;
if (!e->tree)
load_tree(e);
if (tree_content_remove(e, slash1 + 1, backup_leaf)) {
if (tree_content_remove(e, slash1 + 1, backup_leaf, 0)) {
for (n = 0; n < e->tree->entry_count; n++) {
if (e->tree->entries[n]->versions[1].mode) {
hashclr(root->versions[1].sha1);
Expand Down Expand Up @@ -2188,7 +2195,7 @@ static uintmax_t do_change_note_fanout(
}

/* Rename fullpath to realpath */
if (!tree_content_remove(orig_root, fullpath, &leaf))
if (!tree_content_remove(orig_root, fullpath, &leaf, 0))
die("Failed to remove path %s", fullpath);
tree_content_set(orig_root, realpath,
leaf.versions[1].sha1,
Expand Down Expand Up @@ -2323,7 +2330,7 @@ static void file_change_m(struct branch *b)

/* Git does not track empty, non-toplevel directories. */
if (S_ISDIR(mode) && !memcmp(sha1, EMPTY_TREE_SHA1_BIN, 20) && *p) {
tree_content_remove(&b->branch_tree, p, NULL);
tree_content_remove(&b->branch_tree, p, NULL, 0);
return;
}

Expand Down Expand Up @@ -2384,7 +2391,7 @@ static void file_change_d(struct branch *b)
die("Garbage after path in: %s", command_buf.buf);
p = uq.buf;
}
tree_content_remove(&b->branch_tree, p, NULL);
tree_content_remove(&b->branch_tree, p, NULL, 1);
}

static void file_change_cr(struct branch *b, int rename)
Expand Down Expand Up @@ -2422,7 +2429,7 @@ static void file_change_cr(struct branch *b, int rename)

memset(&leaf, 0, sizeof(leaf));
if (rename)
tree_content_remove(&b->branch_tree, s, &leaf);
tree_content_remove(&b->branch_tree, s, &leaf, 1);
else
tree_content_get(&b->branch_tree, s, &leaf, 1);
if (!leaf.versions[1].mode)
Expand Down Expand Up @@ -2530,7 +2537,7 @@ static void note_change_n(struct branch *b, unsigned char *old_fanout)
}

construct_path_with_fanout(sha1_to_hex(commit_sha1), *old_fanout, path);
if (tree_content_remove(&b->branch_tree, path, NULL))
if (tree_content_remove(&b->branch_tree, path, NULL, 0))
b->num_notes--;

if (is_null_sha1(sha1))
Expand Down
2 changes: 1 addition & 1 deletion t/t9300-fast-import.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,7 @@ cat >expect <<EOF
:100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 R100 newdir/exec.sh sub/newdir/exec.sh
:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100 newdir/interesting sub/newdir/interesting
EOF
test_expect_failure \
test_expect_success \
'M: rename root to subdirectory' \
'git fast-import <input &&
git diff-tree -M -r M4^ M4 >actual &&
Expand Down

0 comments on commit 62bfa11

Please sign in to comment.