fast-import: tighten M 040000 syntax
When tree_content_set() is asked to modify the path "foo/bar/", it first recurses like so: tree_content_set(root, "foo/bar/", sha1, S_IFDIR) -> tree_content_set(root:foo, "bar/", ...) -> tree_content_set(root:foo/bar, "", ...) And as a side-effect of 2794ad5 (fast-import: Allow filemodify to set the root, 2010-10-10), this last call is accepted and changes the tree entry for root:foo/bar to refer to the specified tree. That seems safe enough but let's reject the new syntax (we never meant to support it) and make it harder for frontends to introduce pointless incompatibilities with git fast-import 1.7.3. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jonathan Nieder committed
Oct 17, 2010 at 20:08 UTC
3421578393a5983db6fa76a203c9dee95c74801d
2 files changed
+55
-9
fast-import.c
+25
-9
@@ -1437,6 +1437,20 @@ static void store_tree(struct tree_entry *root)
1437
t->entry_count -= del;
1438
}
1439
1440
+static void tree_content_replace(
1441
+ struct tree_entry *root,
1442
+ const unsigned char *sha1,
1443
+ const uint16_t mode,
1444
+ struct tree_content *newtree)
1445
+{
1446
+ if (!S_ISDIR(mode))
1447
+ die("Root cannot be a non-directory");
1448
+ hashcpy(root->versions[1].sha1, sha1);
1449
+ if (root->tree)
1450
+ release_tree_content_recursive(root->tree);
1451
+ root->tree = newtree;
1452
+}
1453
+
1454
static int tree_content_set(
1455
struct tree_entry *root,
1456
const char *p,
@@ -1454,15 +1468,6 @@ static int tree_content_set(
1468
n = slash1 - p;
1469
else
1470
n = strlen(p);
1457
- if (!slash1 && !n) {
1458
- if (!S_ISDIR(mode))
1459
- die("Root cannot be a non-directory");
1460
- hashcpy(root->versions[1].sha1, sha1);
1461
- if (root->tree)
1462
- release_tree_content_recursive(root->tree);
1463
- root->tree = subtree;
1464
- return 1;
1465
- }
1471
if (!n)
1472
die("Empty path component found in input");
1473
if (!slash1 && !S_ISDIR(mode) && subtree)
@@ -2230,6 +2235,10 @@ static void file_change_m(struct branch *b)
2235
command_buf.buf);
2236
}
2237
2238
+ if (!*p) {
2239
+ tree_content_replace(&b->branch_tree, sha1, mode, NULL);
2240
+ return;
2241
+ }
2242
tree_content_set(&b->branch_tree, p, sha1, mode, NULL);
2243
}
2244
@@ -2288,6 +2297,13 @@ static void file_change_cr(struct branch *b, int rename)
2297
tree_content_get(&b->branch_tree, s, &leaf);
2298
if (!leaf.versions[1].mode)
2299
die("Path %s not in branch", s);
2300
+ if (!*d) { /* C "path/to/subdir" "" */
2301
+ tree_content_replace(&b->branch_tree,
2302
+ leaf.versions[1].sha1,
2303
+ leaf.versions[1].mode,
2304
+ leaf.tree);
2305
+ return;
2306
+ }
2307
tree_content_set(&b->branch_tree, d,
2308
leaf.versions[1].sha1,
2309
leaf.versions[1].mode,
t/t9300-fast-import.sh
+30
@@ -928,6 +928,20 @@ test_expect_success \
928
git diff-tree -C --find-copies-harder -r N5^^ N5 >actual &&
929
compare_diff_raw expect actual'
930
931
+test_expect_success \
932
+ 'N: reject foo/ syntax' \
933
+ 'subdir=$(git rev-parse refs/heads/branch^0:file2) &&
934
+ test_must_fail git fast-import <<-INPUT_END
935
+ commit refs/heads/N5B
936
+ committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
937
+ data <<COMMIT
938
+ copy with invalid syntax
939
+ COMMIT
940
+
941
+ from refs/heads/branch^0
942
+ M 040000 $subdir file3/
943
+ INPUT_END'
944
+
945
test_expect_success \
946
'N: copy to root by id and modify' \
947
'echo "hello, world" >expect.foo &&
@@ -965,6 +979,22 @@ test_expect_success \
979
test_cmp expect.foo actual.foo &&
980
test_cmp expect.bar actual.bar'
981
982
+test_expect_success \
983
+ 'N: extract subtree' \
984
+ 'branch=$(git rev-parse --verify refs/heads/branch^{tree}) &&
985
+ cat >input <<-INPUT_END &&
986
+ commit refs/heads/N9
987
+ committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
988
+ data <<COMMIT
989
+ extract subtree branch:newdir
990
+ COMMIT
991
+
992
+ M 040000 $branch ""
993
+ R "newdir" ""
994
+ INPUT_END
995
+ git fast-import <input &&
996
+ git diff --exit-code branch:newdir N9'
997
+
998
###
999
### series O
1000
###