Support copy and rename detection in fast-export.

Although it does not matter for Git itself, tools that
export to systems that explicitly track copies and
renames can benefit from such information.

This patch makes fast-export output correct action
logs when -M or -C are enabled.

Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Alexander Gavrilov 2008-07-27 00:52:54 +04:00 коммит произвёл Junio C Hamano
Родитель 6b2fbaaffc
Коммит ae7c5dcef9
3 изменённых файлов: 81 добавлений и 2 удалений

Просмотреть файл

@ -36,6 +36,15 @@ when encountering a signed tag. With 'strip', the tags will be made
unsigned, with 'verbatim', they will be silently exported unsigned, with 'verbatim', they will be silently exported
and with 'warn', they will be exported, but you will see a warning. and with 'warn', they will be exported, but you will see a warning.
-M::
-C::
Perform move and/or copy detection, as described in the
linkgit:git-diff[1] manual page, and use it to generate
rename and copy commands in the output dump.
+
Note that earlier versions of this command did not complain and
produced incorrect results if you gave these options.
--export-marks=<file>:: --export-marks=<file>::
Dumps the internal marks table to <file> when complete. Dumps the internal marks table to <file> when complete.
Marks are written one per line as `:markid SHA-1`. Only marks Marks are written one per line as `:markid SHA-1`. Only marks

Просмотреть файл

@ -132,10 +132,27 @@ static void show_filemodify(struct diff_queue_struct *q,
{ {
int i; int i;
for (i = 0; i < q->nr; i++) { for (i = 0; i < q->nr; i++) {
struct diff_filespec *ospec = q->queue[i]->one;
struct diff_filespec *spec = q->queue[i]->two; struct diff_filespec *spec = q->queue[i]->two;
if (is_null_sha1(spec->sha1))
switch (q->queue[i]->status) {
case DIFF_STATUS_DELETED:
printf("D %s\n", spec->path); printf("D %s\n", spec->path);
else { break;
case DIFF_STATUS_COPIED:
case DIFF_STATUS_RENAMED:
printf("%c \"%s\" \"%s\"\n", q->queue[i]->status,
ospec->path, spec->path);
if (!hashcmp(ospec->sha1, spec->sha1) &&
ospec->mode == spec->mode)
break;
/* fallthrough */
case DIFF_STATUS_TYPE_CHANGED:
case DIFF_STATUS_MODIFIED:
case DIFF_STATUS_ADDED:
/* /*
* Links refer to objects in another repositories; * Links refer to objects in another repositories;
* output the SHA-1 verbatim. * output the SHA-1 verbatim.
@ -148,6 +165,13 @@ static void show_filemodify(struct diff_queue_struct *q,
printf("M %06o :%d %s\n", spec->mode, printf("M %06o :%d %s\n", spec->mode,
get_object_mark(object), spec->path); get_object_mark(object), spec->path);
} }
break;
default:
die("Unexpected comparison status '%c' for %s, %s",
q->queue[i]->status,
ospec->path ? ospec->path : "none",
spec->path ? spec->path : "none");
} }
} }
} }

Просмотреть файл

@ -185,4 +185,50 @@ test_expect_success 'submodule fast-export | fast-import' '
' '
export GIT_AUTHOR_NAME='A U Thor'
export GIT_COMMITTER_NAME='C O Mitter'
test_expect_success 'setup copies' '
git config --unset i18n.commitencoding &&
git checkout -b copy rein &&
git mv file file3 &&
git commit -m move1 &&
test_tick &&
cp file2 file4 &&
git add file4 &&
git mv file2 file5 &&
git commit -m copy1 &&
test_tick &&
cp file3 file6 &&
git add file6 &&
git commit -m copy2 &&
test_tick &&
echo more text >> file6 &&
echo even more text >> file6 &&
git add file6 &&
git commit -m modify &&
test_tick &&
cp file6 file7 &&
echo test >> file7 &&
git add file7 &&
git commit -m copy_modify
'
test_expect_success 'fast-export -C -C | fast-import' '
ENTRY=$(git rev-parse --verify copy) &&
rm -rf new &&
mkdir new &&
git --git-dir=new/.git init &&
git fast-export -C -C --signed-tags=strip --all > output &&
grep "^C \"file6\" \"file7\"\$" output &&
cat output |
(cd new &&
git fast-import &&
test $ENTRY = $(git rev-parse --verify refs/heads/copy))
'
test_done test_done