@matheusbsbs / matheus-bagliano / commits / ae7c5dcef9
Fork 0

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>

Alexander Gavrilov committed Jul 27, 2008 at 00:52 UTC ae7c5dcef92d46cfc8987fde2c264614fe475bd1
3 files changed +81 -2
Documentation/git-fast-export.txt
+9
@@ -36,6 +36,15 @@ when encountering a signed tag. With 'strip', the tags will be made
36 unsigned, with 'verbatim', they will be silently exported
37 and with 'warn', they will be exported, but you will see a warning.
38
39 +-M::
40 +-C::
41 + Perform move and/or copy detection, as described in the
42 + linkgit:git-diff[1] manual page, and use it to generate
43 + rename and copy commands in the output dump.
44 ++
45 +Note that earlier versions of this command did not complain and
46 +produced incorrect results if you gave these options.
47 +
48 --export-marks=<file>::
49 Dumps the internal marks table to <file> when complete.
50 Marks are written one per line as `:markid SHA-1`. Only marks
builtin-fast-export.c
+26 -2
@@ -132,10 +132,27 @@ static void show_filemodify(struct diff_queue_struct *q,
132 {
133 int i;
134 for (i = 0; i < q->nr; i++) {
135 + struct diff_filespec *ospec = q->queue[i]->one;
136 struct diff_filespec *spec = q->queue[i]->two;
136 - if (is_null_sha1(spec->sha1))
137 +
138 + switch (q->queue[i]->status) {
139 + case DIFF_STATUS_DELETED:
140 printf("D %s\n", spec->path);
138 - else {
141 + break;
142 +
143 + case DIFF_STATUS_COPIED:
144 + case DIFF_STATUS_RENAMED:
145 + printf("%c \"%s\" \"%s\"\n", q->queue[i]->status,
146 + ospec->path, spec->path);
147 +
148 + if (!hashcmp(ospec->sha1, spec->sha1) &&
149 + ospec->mode == spec->mode)
150 + break;
151 + /* fallthrough */
152 +
153 + case DIFF_STATUS_TYPE_CHANGED:
154 + case DIFF_STATUS_MODIFIED:
155 + case DIFF_STATUS_ADDED:
156 /*
157 * Links refer to objects in another repositories;
158 * output the SHA-1 verbatim.
@@ -148,6 +165,13 @@ static void show_filemodify(struct diff_queue_struct *q,
165 printf("M %06o :%d %s\n", spec->mode,
166 get_object_mark(object), spec->path);
167 }
168 + break;
169 +
170 + default:
171 + die("Unexpected comparison status '%c' for %s, %s",
172 + q->queue[i]->status,
173 + ospec->path ? ospec->path : "none",
174 + spec->path ? spec->path : "none");
175 }
176 }
177 }
t/t9301-fast-export.sh
+46
@@ -185,4 +185,50 @@ test_expect_success 'submodule fast-export | fast-import' '
185
186 '
187
188 +export GIT_AUTHOR_NAME='A U Thor'
189 +export GIT_COMMITTER_NAME='C O Mitter'
190 +
191 +test_expect_success 'setup copies' '
192 +
193 + git config --unset i18n.commitencoding &&
194 + git checkout -b copy rein &&
195 + git mv file file3 &&
196 + git commit -m move1 &&
197 + test_tick &&
198 + cp file2 file4 &&
199 + git add file4 &&
200 + git mv file2 file5 &&
201 + git commit -m copy1 &&
202 + test_tick &&
203 + cp file3 file6 &&
204 + git add file6 &&
205 + git commit -m copy2 &&
206 + test_tick &&
207 + echo more text >> file6 &&
208 + echo even more text >> file6 &&
209 + git add file6 &&
210 + git commit -m modify &&
211 + test_tick &&
212 + cp file6 file7 &&
213 + echo test >> file7 &&
214 + git add file7 &&
215 + git commit -m copy_modify
216 +
217 +'
218 +
219 +test_expect_success 'fast-export -C -C | fast-import' '
220 +
221 + ENTRY=$(git rev-parse --verify copy) &&
222 + rm -rf new &&
223 + mkdir new &&
224 + git --git-dir=new/.git init &&
225 + git fast-export -C -C --signed-tags=strip --all > output &&
226 + grep "^C \"file6\" \"file7\"\$" output &&
227 + cat output |
228 + (cd new &&
229 + git fast-import &&
230 + test $ENTRY = $(git rev-parse --verify refs/heads/copy))
231 +
232 +'
233 +
234 test_done