Skip to content

Commit e843842

Browse files
committed
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 <[email protected]>
1 parent 60b9004 commit e843842

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

Documentation/git-fast-import.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,18 @@ OPTIONS
6262
Dumps the internal marks table to <file> when complete.
6363
Marks are written one per line as `:markid SHA-1`.
6464
Frontends can use this file to validate imports after they
65-
have been completed.
65+
have been completed, or to save the marks table across
66+
incremental runs. As <file> is only opened and truncated
67+
at checkpoint (or completion) the same path can also be
68+
safely given to \--import-marks.
69+
70+
--import-marks=<file>::
71+
Before processing any input, load the marks specified in
72+
<file>. The input file must exist, must be readable, and
73+
must use the same format as produced by \--export-marks.
74+
Multiple options may be supplied to import more than one
75+
set of marks. If a mark is defined to different values,
76+
the last file wins.
6677

6778
--export-pack-edges=<file>::
6879
After creating a packfile, print a line of data to

fast-import.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1997,6 +1997,40 @@ static void cmd_checkpoint(void)
19971997
read_next_command();
19981998
}
19991999

2000+
static void import_marks(const char *input_file)
2001+
{
2002+
char line[512];
2003+
FILE *f = fopen(input_file, "r");
2004+
if (!f)
2005+
die("cannot read %s: %s", input_file, strerror(errno));
2006+
while (fgets(line, sizeof(line), f)) {
2007+
uintmax_t mark;
2008+
char *end;
2009+
unsigned char sha1[20];
2010+
struct object_entry *e;
2011+
2012+
end = strchr(line, '\n');
2013+
if (line[0] != ':' || !end)
2014+
die("corrupt mark line: %s", line);
2015+
*end = 0;
2016+
mark = strtoumax(line + 1, &end, 10);
2017+
if (!mark || end == line + 1
2018+
|| *end != ' ' || get_sha1(end + 1, sha1))
2019+
die("corrupt mark line: %s", line);
2020+
e = find_object(sha1);
2021+
if (!e) {
2022+
enum object_type type = sha1_object_info(sha1, NULL);
2023+
if (type < 0)
2024+
die("object not found: %s", sha1_to_hex(sha1));
2025+
e = insert_object(sha1);
2026+
e->type = type;
2027+
e->pack_id = MAX_PACK_ID;
2028+
}
2029+
insert_mark(mark, e);
2030+
}
2031+
fclose(f);
2032+
}
2033+
20002034
static const char fast_import_usage[] =
20012035
"git-fast-import [--date-format=f] [--max-pack-size=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]";
20022036

@@ -2034,6 +2068,8 @@ int main(int argc, const char **argv)
20342068
max_depth = strtoul(a + 8, NULL, 0);
20352069
else if (!prefixcmp(a, "--active-branches="))
20362070
max_active_branches = strtoul(a + 18, NULL, 0);
2071+
else if (!prefixcmp(a, "--import-marks="))
2072+
import_marks(a + 15);
20372073
else if (!prefixcmp(a, "--export-marks="))
20382074
mark_file = a + 15;
20392075
else if (!prefixcmp(a, "--export-pack-edges=")) {

t/t9300-fast-import.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,14 @@ test_expect_success \
111111
'A: verify marks output' \
112112
'diff -u expect marks.out'
113113

114+
test_expect_success \
115+
'A: verify marks import' \
116+
'git-fast-import \
117+
--import-marks=marks.out \
118+
--export-marks=marks.new \
119+
</dev/null &&
120+
diff -u expect marks.new'
121+
114122
###
115123
### series B
116124
###

0 commit comments

Comments
 (0)