Browse Source

fast-import: treat SIGUSR1 as a request to access objects early

It can be tedious to wait for a multi-million-revision import.
Unfortunately it is hard to spy on the import because fast-import
works by continuously streaming out objects, without updating the pack
index or refs until a checkpoint command or the end of the stream.

So allow the impatient operator to request checkpoints by sending a
signal, like so:

	killall -USR1 git-fast-import

When receiving such a signal, fast-import would schedule a checkpoint
to take place after the current top-level command (usually a "commit"
or "blob" request) finishes.

Caveats: just like ordinary checkpoint commands, such requests slow
down the import.  Switching to a new pack at a suboptimal moment is
also likely to result in a less dense initial collection of packs.
That's the price.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Jonathan Nieder 14 years ago committed by Junio C Hamano
parent
commit
dc01f59d21
  1. 7
      Documentation/git-fast-import.txt
  2. 41
      fast-import.c

7
Documentation/git-fast-import.txt

@ -1233,6 +1233,13 @@ and lazy loading of subtrees, allows fast-import to efficiently import @@ -1233,6 +1233,13 @@ and lazy loading of subtrees, allows fast-import to efficiently import
projects with 2,000+ branches and 45,114+ files in a very limited
memory footprint (less than 2.7 MiB per active branch).

Signals
-------
Sending *SIGUSR1* to the 'git fast-import' process ends the current
packfile early, simulating a `checkpoint` command. The impatient
operator can use this facility to peek at the objects and refs from an
import in progress, at the cost of some added running time and worse
compression.

Author
------

41
fast-import.c

@ -361,6 +361,9 @@ static uintmax_t next_mark; @@ -361,6 +361,9 @@ static uintmax_t next_mark;
static struct strbuf new_data = STRBUF_INIT;
static int seen_data_command;

/* Signal handling */
static volatile sig_atomic_t checkpoint_requested;

static void parse_argv(void);

static void write_branch_report(FILE *rpt, struct branch *b)
@ -500,6 +503,32 @@ static NORETURN void die_nicely(const char *err, va_list params) @@ -500,6 +503,32 @@ static NORETURN void die_nicely(const char *err, va_list params)
exit(128);
}

#ifndef SIGUSR1 /* Windows, for example */

static void set_checkpoint_signal(void)
{
}

#else

static void checkpoint_signal(int signo)
{
checkpoint_requested = 1;
}

static void set_checkpoint_signal(void)
{
struct sigaction sa;

memset(&sa, 0, sizeof(sa));
sa.sa_handler = checkpoint_signal;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sigaction(SIGUSR1, &sa, NULL);
}

#endif

static void alloc_objects(unsigned int cnt)
{
struct object_entry_pool *b;
@ -2689,14 +2718,20 @@ static void parse_reset_branch(void) @@ -2689,14 +2718,20 @@ static void parse_reset_branch(void)
unread_command_buf = 1;
}

static void parse_checkpoint(void)
static void checkpoint(void)
{
checkpoint_requested = 0;
if (object_count) {
cycle_packfile();
dump_branches();
dump_tags();
dump_marks();
}
}

static void parse_checkpoint(void)
{
checkpoint_requested = 1;
skip_optional_lf();
}

@ -2953,6 +2988,7 @@ int main(int argc, const char **argv) @@ -2953,6 +2988,7 @@ int main(int argc, const char **argv)
prepare_packed_git();
start_packfile();
set_die_routine(die_nicely);
set_checkpoint_signal();
while (read_next_command() != EOF) {
if (!strcmp("blob", command_buf.buf))
parse_new_blob();
@ -2974,6 +3010,9 @@ int main(int argc, const char **argv) @@ -2974,6 +3010,9 @@ int main(int argc, const char **argv)
/* ignore non-git options*/;
else
die("Unsupported command: %s", command_buf.buf);

if (checkpoint_requested)
checkpoint();
}

/* argv hasn't been parsed yet, do so */

Loading…
Cancel
Save