Skip to content

Commit 4e46a8d

Browse files
dschogitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6727524 commit 4e46a8d

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

Documentation/git-fast-export.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ If the backend uses a similar \--import-marks file, this allows for
6565
incremental bidirectional exporting of the repository by keeping the
6666
marks the same across runs.
6767

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+
6874

6975
EXAMPLES
7076
--------

builtin-fast-export.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ static const char *fast_export_usage[] = {
2424

2525
static int progress;
2626
static enum { VERBATIM, WARN, STRIP, ABORT } signed_tag_mode = ABORT;
27+
static int fake_missing_tagger;
2728

2829
static int parse_opt_signed_tag_mode(const struct option *opt,
2930
const char *arg, int unset)
@@ -297,10 +298,17 @@ static void handle_tag(const char *name, struct tag *tag)
297298
message_size = strlen(message);
298299
}
299300
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+
}
304312

305313
/* handle signed tags */
306314
if (message) {
@@ -326,9 +334,10 @@ static void handle_tag(const char *name, struct tag *tag)
326334

327335
if (!prefixcmp(name, "refs/tags/"))
328336
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",
330338
name, get_object_mark(tag->tagged),
331339
(int)(tagger_end - tagger), tagger,
340+
tagger == tagger_end ? "" : "\n",
332341
(int)message_size, (int)message_size, message ? message : "");
333342
}
334343

@@ -483,6 +492,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
483492
"Dump marks to this file"),
484493
OPT_STRING(0, "import-marks", &import_filename, "FILE",
485494
"Import marks from this file"),
495+
OPT_BOOLEAN(0, "fake-missing-tagger", &fake_missing_tagger,
496+
"Fake a tagger when tags lack one"),
486497
OPT_END()
487498
};
488499

t/t9301-fast-export.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,4 +239,24 @@ test_expect_success 'fast-export | fast-import when master is tagged' '
239239
240240
'
241241

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+
242262
test_done

0 commit comments

Comments
 (0)