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