Browse Source

Merge branch 'master' of git://repo.or.cz/git/fastimport

* 'master' of git://repo.or.cz/git/fastimport:
  Allow fast-import frontends to reload the marks table
  Use atomic updates to the fast-import mark file
  Preallocate memory earlier in fast-import
maint
Junio C Hamano 18 years ago
parent
commit
f45fa2a073
  1. 13
      Documentation/git-fast-import.txt
  2. 85
      fast-import.c
  3. 8
      t/t9300-fast-import.sh

13
Documentation/git-fast-import.txt

@ -62,7 +62,18 @@ OPTIONS
Dumps the internal marks table to <file> when complete. Dumps the internal marks table to <file> when complete.
Marks are written one per line as `:markid SHA-1`. Marks are written one per line as `:markid SHA-1`.
Frontends can use this file to validate imports after they 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 <file> is only opened and truncated
at checkpoint (or completion) the same path can also be
safely given to \--import-marks.

--import-marks=<file>::
Before processing any input, load the marks specified in
<file>. 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=<file>:: --export-pack-edges=<file>::
After creating a packfile, print a line of data to After creating a packfile, print a line of data to

85
fast-import.c

@ -1371,16 +1371,33 @@ static void dump_marks_helper(FILE *f,


static void dump_marks(void) static void dump_marks(void)
{ {
if (mark_file) static struct lock_file mark_lock;
{ int mark_fd;
FILE *f = fopen(mark_file, "w"); FILE *f;
if (f) {
dump_marks_helper(f, 0, marks); if (!mark_file)
fclose(f); return;
} else
failure |= error("Unable to write marks file %s: %s", mark_fd = hold_lock_file_for_update(&mark_lock, mark_file, 0);
mark_file, strerror(errno)); if (mark_fd < 0) {
failure |= error("Unable to write marks file %s: %s",
mark_file, strerror(errno));
return;
}

f = fdopen(mark_fd, "w");
if (!f) {
rollback_lock_file(&mark_lock);
failure |= error("Unable to write marks file %s: %s",
mark_file, strerror(errno));
return;
} }

dump_marks_helper(f, 0, marks);
fclose(f);
if (commit_lock_file(&mark_lock))
failure |= error("Unable to write marks file %s: %s",
mark_file, strerror(errno));
} }


static void read_next_command(void) static void read_next_command(void)
@ -1976,6 +1993,40 @@ static void cmd_checkpoint(void)
read_next_command(); 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[] = 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]"; "git-fast-import [--date-format=f] [--max-pack-size=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]";


@ -1984,6 +2035,12 @@ int main(int argc, const char **argv)
int i, show_stats = 1; int i, show_stats = 1;


git_config(git_default_config); git_config(git_default_config);
alloc_objects(object_entry_alloc);
strbuf_init(&command_buf);
atom_table = xcalloc(atom_table_sz, sizeof(struct atom_str*));
branch_table = xcalloc(branch_table_sz, sizeof(struct branch*));
avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*));
marks = pool_calloc(1, sizeof(struct mark_set));


for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
const char *a = argv[i]; const char *a = argv[i];
@ -2007,6 +2064,8 @@ int main(int argc, const char **argv)
max_depth = strtoul(a + 8, NULL, 0); max_depth = strtoul(a + 8, NULL, 0);
else if (!prefixcmp(a, "--active-branches=")) else if (!prefixcmp(a, "--active-branches="))
max_active_branches = strtoul(a + 18, NULL, 0); max_active_branches = strtoul(a + 18, NULL, 0);
else if (!prefixcmp(a, "--import-marks="))
import_marks(a + 15);
else if (!prefixcmp(a, "--export-marks=")) else if (!prefixcmp(a, "--export-marks="))
mark_file = a + 15; mark_file = a + 15;
else if (!prefixcmp(a, "--export-pack-edges=")) { else if (!prefixcmp(a, "--export-pack-edges=")) {
@ -2027,14 +2086,6 @@ int main(int argc, const char **argv)
if (i != argc) if (i != argc)
usage(fast_import_usage); usage(fast_import_usage);


alloc_objects(object_entry_alloc);
strbuf_init(&command_buf);

atom_table = xcalloc(atom_table_sz, sizeof(struct atom_str*));
branch_table = xcalloc(branch_table_sz, sizeof(struct branch*));
avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*));
marks = pool_calloc(1, sizeof(struct mark_set));

start_packfile(); start_packfile();
for (;;) { for (;;) {
read_next_command(); read_next_command();

8
t/t9300-fast-import.sh

@ -111,6 +111,14 @@ test_expect_success \
'A: verify marks output' \ 'A: verify marks output' \
'diff -u expect marks.out' 'diff -u expect marks.out'


test_expect_success \
'A: verify marks import' \
'git-fast-import \
--import-marks=marks.out \
--export-marks=marks.new \
</dev/null &&
diff -u expect marks.new'

### ###
### series B ### series B
### ###

Loading…
Cancel
Save