Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2008-07-19 16:21:24 +0400
committerJunio C Hamano <gitster@pobox.com>2008-07-19 22:25:51 +0400
commit03db4525d38119f7778d6e9117f27c47db8466d4 (patch)
treeee8126cbb922debfe445a54658c5a57dca4cc3ca
parent4a3fedd5976ae9175cc418876d17ca568278b426 (diff)
Support gitlinks in fast-import.
Currently fast-import/export cannot be used for repositories with submodules. This patch extends the relevant programs to make them correctly process gitlinks. Links can be represented by two forms of the Modify command: M 160000 SHA1 some/path which sets the link target explicitly, or M 160000 :mark some/path where the mark refers to a commit. The latter form can be used by importing tools to build all submodules simultaneously in one physical repository, and then simply fetch them apart. Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--Documentation/git-fast-import.txt3
-rw-r--r--builtin-fast-export.c19
-rw-r--r--fast-import.c16
-rwxr-xr-xt/t9300-fast-import.sh152
-rwxr-xr-xt/t9301-fast-export.sh42
5 files changed, 227 insertions, 5 deletions
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index 2d01d0d100..c2f483a8d2 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -481,6 +481,9 @@ in octal. Git only supports the following modes:
what you want.
* `100755` or `755`: A normal, but executable, file.
* `120000`: A symlink, the content of the file will be the link target.
+* `160000`: A gitlink, SHA-1 of the object refers to a commit in
+ another repository. Git links can only be specified by SHA or through
+ a commit mark. They are used to implement submodules.
In both formats `<path>` is the complete path of the file to be added
(if not already existing) or modified (if already existing).
diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index 76f3167276..a443d59460 100644
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -136,9 +136,18 @@ static void show_filemodify(struct diff_queue_struct *q,
if (is_null_sha1(spec->sha1))
printf("D %s\n", spec->path);
else {
- struct object *object = lookup_object(spec->sha1);
- printf("M %06o :%d %s\n", spec->mode,
- get_object_mark(object), spec->path);
+ /*
+ * Links refer to objects in another repositories;
+ * output the SHA-1 verbatim.
+ */
+ if (S_ISGITLINK(spec->mode))
+ printf("M %06o %s %s\n", spec->mode,
+ sha1_to_hex(spec->sha1), spec->path);
+ else {
+ struct object *object = lookup_object(spec->sha1);
+ printf("M %06o :%d %s\n", spec->mode,
+ get_object_mark(object), spec->path);
+ }
}
}
}
@@ -196,8 +205,10 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)
diff_root_tree_sha1(commit->tree->object.sha1,
"", &rev->diffopt);
+ /* Export the referenced blobs, and remember the marks. */
for (i = 0; i < diff_queued_diff.nr; i++)
- handle_object(diff_queued_diff.queue[i]->two->sha1);
+ if (!S_ISGITLINK(diff_queued_diff.queue[i]->two->mode))
+ handle_object(diff_queued_diff.queue[i]->two->sha1);
mark_next_object(&commit->object);
if (!is_encoding_utf8(encoding))
diff --git a/fast-import.c b/fast-import.c
index c4d054ecc7..7089e6f9e6 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1868,6 +1868,7 @@ static void file_change_m(struct branch *b)
case S_IFREG | 0644:
case S_IFREG | 0755:
case S_IFLNK:
+ case S_IFGITLINK:
case 0644:
case 0755:
/* ok */
@@ -1900,7 +1901,20 @@ static void file_change_m(struct branch *b)
p = uq.buf;
}
- if (inline_data) {
+ if (S_ISGITLINK(mode)) {
+ if (inline_data)
+ die("Git links cannot be specified 'inline': %s",
+ command_buf.buf);
+ else if (oe) {
+ if (oe->type != OBJ_COMMIT)
+ die("Not a commit (actually a %s): %s",
+ typename(oe->type), command_buf.buf);
+ }
+ /*
+ * Accept the sha1 without checking; it expected to be in
+ * another repository.
+ */
+ } else if (inline_data) {
static struct strbuf buf = STRBUF_INIT;
if (p != uq.buf) {
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index e17afa8c30..1fc06c5a23 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -918,4 +918,156 @@ test_expect_success \
grep "progress " <input >expect &&
test_cmp expect actual'
+###
+### series P (gitlinks)
+###
+
+cat >input <<INPUT_END
+blob
+mark :1
+data 10
+test file
+
+reset refs/heads/sub
+commit refs/heads/sub
+mark :2
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data 12
+sub_initial
+M 100644 :1 file
+
+blob
+mark :3
+data <<DATAEND
+[submodule "sub"]
+ path = sub
+ url = "`pwd`/sub"
+DATAEND
+
+commit refs/heads/subuse1
+mark :4
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data 8
+initial
+from refs/heads/master
+M 100644 :3 .gitmodules
+M 160000 :2 sub
+
+blob
+mark :5
+data 20
+test file
+more data
+
+commit refs/heads/sub
+mark :6
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data 11
+sub_second
+from :2
+M 100644 :5 file
+
+commit refs/heads/subuse1
+mark :7
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data 7
+second
+from :4
+M 160000 :6 sub
+
+INPUT_END
+
+test_expect_success \
+ 'P: supermodule & submodule mix' \
+ 'git-fast-import <input &&
+ git checkout subuse1 &&
+ rm -rf sub && mkdir sub && cd sub &&
+ git init &&
+ git fetch .. refs/heads/sub:refs/heads/master &&
+ git checkout master &&
+ cd .. &&
+ git submodule init &&
+ git submodule update'
+
+SUBLAST=$(git-rev-parse --verify sub)
+SUBPREV=$(git-rev-parse --verify sub^)
+
+cat >input <<INPUT_END
+blob
+mark :1
+data <<DATAEND
+[submodule "sub"]
+ path = sub
+ url = "`pwd`/sub"
+DATAEND
+
+commit refs/heads/subuse2
+mark :2
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data 8
+initial
+from refs/heads/master
+M 100644 :1 .gitmodules
+M 160000 $SUBPREV sub
+
+commit refs/heads/subuse2
+mark :3
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data 7
+second
+from :2
+M 160000 $SUBLAST sub
+
+INPUT_END
+
+test_expect_success \
+ 'P: verbatim SHA gitlinks' \
+ 'git branch -D sub &&
+ git gc && git prune &&
+ git-fast-import <input &&
+ test $(git-rev-parse --verify subuse2) = $(git-rev-parse --verify subuse1)'
+
+test_tick
+cat >input <<INPUT_END
+commit refs/heads/subuse3
+mark :1
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+corrupt
+COMMIT
+
+from refs/heads/subuse2
+M 160000 inline sub
+data <<DATA
+$SUBPREV
+DATA
+
+INPUT_END
+
+test_expect_success 'P: fail on inline gitlink' '
+ ! git-fast-import <input'
+
+test_tick
+cat >input <<INPUT_END
+blob
+mark :1
+data <<DATA
+$SUBPREV
+DATA
+
+commit refs/heads/subuse3
+mark :2
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+corrupt
+COMMIT
+
+from refs/heads/subuse2
+M 160000 :1 sub
+
+INPUT_END
+
+test_expect_success 'P: fail on blob mark in gitlink' '
+ ! git-fast-import <input'
+
test_done
diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh
index 0959f2f815..8324f6e3bd 100755
--- a/t/t9301-fast-export.sh
+++ b/t/t9301-fast-export.sh
@@ -143,4 +143,46 @@ test_expect_success 'signed-tags=strip' '
'
+test_expect_success 'setup submodule' '
+
+ git checkout -f master &&
+ mkdir sub &&
+ cd sub &&
+ git init &&
+ echo test file > file &&
+ git add file &&
+ git commit -m sub_initial &&
+ cd .. &&
+ git submodule add "`pwd`/sub" sub &&
+ git commit -m initial &&
+ test_tick &&
+ cd sub &&
+ echo more data >> file &&
+ git add file &&
+ git commit -m sub_second &&
+ cd .. &&
+ git add sub &&
+ git commit -m second
+
+'
+
+test_expect_success 'submodule fast-export | fast-import' '
+
+ SUBENT1=$(git ls-tree master^ sub) &&
+ SUBENT2=$(git ls-tree master sub) &&
+ rm -rf new &&
+ mkdir new &&
+ git --git-dir=new/.git init &&
+ git fast-export --signed-tags=strip --all |
+ (cd new &&
+ git fast-import &&
+ test "$SUBENT1" = "$(git ls-tree refs/heads/master^ sub)" &&
+ test "$SUBENT2" = "$(git ls-tree refs/heads/master sub)" &&
+ git checkout master &&
+ git submodule init &&
+ git submodule update &&
+ cmp sub/file ../sub/file)
+
+'
+
test_done