From e8438420bb7d368bec3647b90c557b9931582267 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 7 Mar 2007 18:07:26 -0500 Subject: [PATCH] Allow fast-import frontends to reload the marks table I'm giving fast-import a lesson on how to reload the marks table using the same format it outputs with --export-marks. This way a frontend can reload the marks table from a prior import, making incremental imports less painful. Signed-off-by: Shawn O. Pearce --- Documentation/git-fast-import.txt | 13 ++++++++++- fast-import.c | 36 +++++++++++++++++++++++++++++++ t/t9300-fast-import.sh | 8 +++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index 77a14bb07..7e3d2b1a9 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -62,7 +62,18 @@ OPTIONS Dumps the internal marks table to when complete. Marks are written one per line as `:markid SHA-1`. Frontends can use this file to validate imports after they - have been completed. + have been completed, or to save the marks table across + incremental runs. As is only opened and truncated + at checkpoint (or completion) the same path can also be + safely given to \--import-marks. + +--import-marks=:: + Before processing any input, load the marks specified in + . The input file must exist, must be readable, and + must use the same format as produced by \--export-marks. + Multiple options may be supplied to import more than one + set of marks. If a mark is defined to different values, + the last file wins. --export-pack-edges=:: After creating a packfile, print a line of data to diff --git a/fast-import.c b/fast-import.c index a09221242..fbed8e4e8 100644 --- a/fast-import.c +++ b/fast-import.c @@ -1997,6 +1997,40 @@ static void cmd_checkpoint(void) read_next_command(); } +static void import_marks(const char *input_file) +{ + char line[512]; + FILE *f = fopen(input_file, "r"); + if (!f) + die("cannot read %s: %s", input_file, strerror(errno)); + while (fgets(line, sizeof(line), f)) { + uintmax_t mark; + char *end; + unsigned char sha1[20]; + struct object_entry *e; + + end = strchr(line, '\n'); + if (line[0] != ':' || !end) + die("corrupt mark line: %s", line); + *end = 0; + mark = strtoumax(line + 1, &end, 10); + if (!mark || end == line + 1 + || *end != ' ' || get_sha1(end + 1, sha1)) + die("corrupt mark line: %s", line); + e = find_object(sha1); + if (!e) { + enum object_type type = sha1_object_info(sha1, NULL); + if (type < 0) + die("object not found: %s", sha1_to_hex(sha1)); + e = insert_object(sha1); + e->type = type; + e->pack_id = MAX_PACK_ID; + } + insert_mark(mark, e); + } + fclose(f); +} + static const char fast_import_usage[] = "git-fast-import [--date-format=f] [--max-pack-size=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]"; @@ -2034,6 +2068,8 @@ int main(int argc, const char **argv) max_depth = strtoul(a + 8, NULL, 0); else if (!prefixcmp(a, "--active-branches=")) max_active_branches = strtoul(a + 18, NULL, 0); + else if (!prefixcmp(a, "--import-marks=")) + import_marks(a + 15); else if (!prefixcmp(a, "--export-marks=")) mark_file = a + 15; else if (!prefixcmp(a, "--export-pack-edges=")) { diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 970d68365..2e1a09ff2 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -111,6 +111,14 @@ test_expect_success \ 'A: verify marks output' \ 'diff -u expect marks.out' +test_expect_success \ + 'A: verify marks import' \ + 'git-fast-import \ + --import-marks=marks.out \ + --export-marks=marks.new \ +