@matheusbsbs / matheus-bagliano / commits / 4e46a8d62c
Fork 0

fast-export: deal with tag objects that do not have a tagger

When no tagger was found (old Git produced tags like this), no "tagger" line is printed (but this is incompatible with the current git fast-import). Alternatively, you can pass the option --fake-missing-tagger, forcing fast-export to fake a tagger Unspecified Tagger <no-tagger> with a tag date of the beginning of (Unix) time in the case of a missing tagger, so that fast-import is still able to import the result. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Dec 20, 2008 at 01:00 UTC 4e46a8d62c551e11e21bd04e059e9ae3cdcfd029
3 files changed +42 -5
Documentation/git-fast-export.txt
+6
@@ -65,6 +65,12 @@ If the backend uses a similar \--import-marks file, this allows for
65 incremental bidirectional exporting of the repository by keeping the
66 marks the same across runs.
67
68 +--fake-missing-tagger::
69 + Some old repositories have tags without a tagger. The
70 + fast-import protocol was pretty strict about that, and did not
71 + allow that. So fake a tagger to be able to fast-import the
72 + output.
73 +
74
75 EXAMPLES
76 --------
builtin-fast-export.c
+16 -5
@@ -24,6 +24,7 @@ static const char *fast_export_usage[] = {
24
25 static int progress;
26 static enum { VERBATIM, WARN, STRIP, ABORT } signed_tag_mode = ABORT;
27 +static int fake_missing_tagger;
28
29 static int parse_opt_signed_tag_mode(const struct option *opt,
30 const char *arg, int unset)
@@ -297,10 +298,17 @@ static void handle_tag(const char *name, struct tag *tag)
298 message_size = strlen(message);
299 }
300 tagger = memmem(buf, message ? message - buf : size, "\ntagger ", 8);
300 - if (!tagger)
301 - die ("No tagger for tag %s", sha1_to_hex(tag->object.sha1));
302 - tagger++;
303 - tagger_end = strchrnul(tagger, '\n');
301 + if (!tagger) {
302 + if (fake_missing_tagger)
303 + tagger = "tagger Unspecified Tagger "
304 + "<unspecified-tagger> 0 +0000";
305 + else
306 + tagger = "";
307 + tagger_end = tagger + strlen(tagger);
308 + } else {
309 + tagger++;
310 + tagger_end = strchrnul(tagger, '\n');
311 + }
312
313 /* handle signed tags */
314 if (message) {
@@ -326,9 +334,10 @@ static void handle_tag(const char *name, struct tag *tag)
334
335 if (!prefixcmp(name, "refs/tags/"))
336 name += 10;
329 - printf("tag %s\nfrom :%d\n%.*s\ndata %d\n%.*s\n",
337 + printf("tag %s\nfrom :%d\n%.*s%sdata %d\n%.*s\n",
338 name, get_object_mark(tag->tagged),
339 (int)(tagger_end - tagger), tagger,
340 + tagger == tagger_end ? "" : "\n",
341 (int)message_size, (int)message_size, message ? message : "");
342 }
343
@@ -483,6 +492,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
492 "Dump marks to this file"),
493 OPT_STRING(0, "import-marks", &import_filename, "FILE",
494 "Import marks from this file"),
495 + OPT_BOOLEAN(0, "fake-missing-tagger", &fake_missing_tagger,
496 + "Fake a tagger when tags lack one"),
497 OPT_END()
498 };
499
t/t9301-fast-export.sh
+20
@@ -239,4 +239,24 @@ test_expect_success 'fast-export | fast-import when master is tagged' '
239
240 '
241
242 +cat > tag-content << EOF
243 +object $(git rev-parse HEAD)
244 +type commit
245 +tag rosten
246 +EOF
247 +
248 +test_expect_success 'cope with tagger-less tags' '
249 +
250 + TAG=$(git hash-object -t tag -w tag-content) &&
251 + git update-ref refs/tags/sonnenschein $TAG &&
252 + git fast-export -C -C --signed-tags=strip --all > output &&
253 + test $(grep -c "^tag " output) = 4 &&
254 + ! grep "Unspecified Tagger" output &&
255 + git fast-export -C -C --signed-tags=strip --all \
256 + --fake-missing-tagger > output &&
257 + test $(grep -c "^tag " output) = 4 &&
258 + grep "Unspecified Tagger" output
259 +
260 +'
261 +
262 test_done