Merge branch 'jn/fast-import-fix'
authorJunio C Hamano <gitster@pobox.com>
Tue, 30 Nov 2010 01:52:32 +0000 (17:52 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 30 Nov 2010 01:52:32 +0000 (17:52 -0800)
* 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

1  2 
fast-import.c
t/t9300-fast-import.sh
diff --combined fast-import.c
index 77549ebd6fbfbea051901d4ab474eebc8e2dbdbd,d881630b012db0c19760d5e362cf19490546bdc1..8263dbe841a6ac738c3a5a31006f3fdffcbc7e77
@@@ -1437,6 -1437,20 +1437,20 @@@ static void store_tree(struct tree_entr
        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,
        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;
                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 +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;
        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 +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;
        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 +2232,10 @@@ static void file_change_m(struct branc
                                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 +2294,13 @@@ static void file_change_cr(struct branc
                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,
@@@ -2893,7 -2918,7 +2918,7 @@@ static int git_pack_config(const char *
  }
  
  static const char fast_import_usage[] =
 -"git fast-import [--date-format=f] [--max-pack-size=n] [--big-file-threshold=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]";
 +"git fast-import [--date-format=<f>] [--max-pack-size=<n>] [--big-file-threshold=<n>] [--depth=<n>] [--active-branches=<n>] [--export-marks=<marks.file>]";
  
  static void parse_argv(void)
  {
diff --combined t/t9300-fast-import.sh
index 14d17691b1c48e2b3211812a16d6dda7e83ad31a,dd90a0933e3e7b6f74795f12bbf7e7dc96214b00..e8034d410fe50a770c3122c98967d80937bb1943
@@@ -321,7 -321,7 +321,7 @@@ test_expect_success 
        'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done'
  test_expect_success \
        'C: validate reuse existing blob' \
 -      'test $newf = `git rev-parse --verify branch:file2/newf`
 +      'test $newf = `git rev-parse --verify branch:file2/newf` &&
         test $oldf = `git rev-parse --verify branch:file2/oldf`'
  
  cat >expect <<EOF
@@@ -928,6 -928,114 +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
  ###