Currently fast-import/export cannot be used for repositories with submodules. This patch extends the relevant programs to make them correctly process gitlinks. Signed-off-by: Alexander Gavrilov <angavrilov@xxxxxxxxx> --- I noticed that fast-export & fast-import cannot work with repositories using submodules: import complains about an invalid mode, and export fails while trying to open the SHA as a blob. As I didn't see any particular reason for it to be so, I tried to implement support for gitlinks. What I'm unsure of is, should fast-export try to reuse commit marks for gitlinks where it happened to recognize the object, or always output the SHA as it is stored in the tree? -- Alexander Documentation/git-fast-import.txt | 3 +++ builtin-fast-export.c | 18 +++++++++++++++--- fast-import.c | 12 +++++++++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index 395c055..80c591a 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 implements 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 d0a462f..14b1549 100644 --- a/builtin-fast-export.c +++ b/builtin-fast-export.c @@ -123,8 +123,19 @@ static void show_filemodify(struct diff_queue_struct *q, 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); + int mark = object ? get_object_mark(object) : 0; + + if (mark) + printf("M %06o :%d %s\n", spec->mode, + mark, spec->path); + else { + if (!S_ISGITLINK(spec->mode)) + die("Unknown object added: %s at %s", + sha1_to_hex(spec->sha1), spec->path); + + printf("M %06o %s %s\n", spec->mode, + sha1_to_hex(spec->sha1), spec->path); + } } } } @@ -183,7 +194,8 @@ static void handle_commit(struct commit *commit, struct rev_info *rev) "", &rev->diffopt); 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_object(&commit->object); if (!is_encoding_utf8(encoding)) diff --git a/fast-import.c b/fast-import.c index e72b286..e7977c1 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,16 @@ 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); + } + } else if (inline_data) { static struct strbuf buf = STRBUF_INIT; if (p != uq.buf) { -- 1.5.6.3.18.gfe82 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html