Browse Source

fast-import: Allow filemodify to set the root

v1.7.3-rc0~75^2 (Teach fast-import to import subtrees named by tree id,
2010-06-30) has a shortcoming - it doesn't allow the root to be set.
Extend this behaviour by allowing the root to be referenced as the
empty path, "".

For a command (like filter-branch --subdirectory-filter) that wants
to commit a lot of trees that already exist in the object db, writing
undeltified objects as loose files only to repack them later can
involve a significant amount of overhead.
(23% slow-down observed on Linux 2.6.35, worse on Mac OS X 10.6)

Fortunately we have fast-import (which is one of the only git commands
that will write to a pack directly) but there is not an advertised way
to tell fast-import to commit a given tree without unpacking it.

This patch changes that, by allowing

	M 040000 <tree id> ""

as a filemodify line in a commit to reset to a particular tree without
any need to parse it.  For example,

	M 040000 4b825dc642 ""

is a synonym for the deleteall command and the fast-import equivalent of

	git read-tree 4b825dc642

Signed-off-by: David Barr <david.barr@cordelta.com>
Commit-message-by: Jonathan Nieder <jrnieder@gmail.com>
Acked-by: Sverre Rabbelier <srabbelier@gmail.com>
Tested-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
David Barr 14 years ago committed by Junio C Hamano
parent
commit
2794ad5244
  1. 3
      Documentation/git-fast-import.txt
  2. 9
      fast-import.c
  3. 21
      t/t9300-fast-import.sh

3
Documentation/git-fast-import.txt

@ -524,6 +524,9 @@ start with double quote (`"`). @@ -524,6 +524,9 @@ start with double quote (`"`).
If an `LF` or double quote must be encoded into `<path>` shell-style
quoting should be used, e.g. `"path/with\n and \" in it"`.

Additionally, in `040000` mode, `<path>` may also be an empty string
(`""`) to specify the root of the tree.

The value of `<path>` must be in canonical form. That is it must not:

* contain an empty directory component (e.g. `foo//bar` is invalid),

9
fast-import.c

@ -1454,6 +1454,15 @@ static int tree_content_set( @@ -1454,6 +1454,15 @@ static int tree_content_set(
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)

21
t/t9300-fast-import.sh

@ -874,6 +874,27 @@ test_expect_success \ @@ -874,6 +874,27 @@ test_expect_success \
git diff-tree -C --find-copies-harder -r N4^ N4 >actual &&
compare_diff_raw expect actual'

test_expect_success \
'N: copy root directory by tree hash' \
'cat >expect <<-\EOF &&
:100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D file3/newf
:100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D file3/oldf
EOF
root=$(git rev-parse refs/heads/branch^0^{tree}) &&
cat >input <<-INPUT_END &&
commit refs/heads/N6
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
copy root directory by tree hash
COMMIT

from refs/heads/branch^0
M 040000 $root ""
INPUT_END
git fast-import <input &&
git diff-tree -C --find-copies-harder -r N4 N6 >actual &&
compare_diff_raw expect actual'

test_expect_success \
'N: modify copied tree' \
'cat >expect <<-\EOF &&

Loading…
Cancel
Save