Teach git-local-fetch the --stdin switch
This makes it possible to fetch many commits (refs) at once, greatly speeding up cg-clone. Signed-off-by: Petr Baudis <pasky@suse.cz> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
4211e4d10c
commit
8e87ca6615
@ -29,6 +29,12 @@ OPTIONS
|
||||
Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on
|
||||
the local end after the transfer is complete.
|
||||
|
||||
--stdin::
|
||||
Instead of a commit id on the commandline (which is not expected in this
|
||||
case), 'git-local-fetch' expects lines on stdin in the format
|
||||
|
||||
<commit-id>['\t'<filename-as-in--w>]
|
||||
|
||||
Author
|
||||
------
|
||||
Written by Junio C Hamano <junkio@cox.net>
|
||||
|
40
fetch.c
40
fetch.c
@ -7,6 +7,7 @@
|
||||
#include "tag.h"
|
||||
#include "blob.h"
|
||||
#include "refs.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
int get_tree = 0;
|
||||
int get_history = 0;
|
||||
@ -210,6 +211,45 @@ static int mark_complete(const char *path, const unsigned char *sha1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pull_targets_stdin(char ***target, const char ***write_ref)
|
||||
{
|
||||
int targets = 0, targets_alloc = 0;
|
||||
struct strbuf buf;
|
||||
*target = NULL; *write_ref = NULL;
|
||||
strbuf_init(&buf);
|
||||
while (1) {
|
||||
char *rf_one = NULL;
|
||||
char *tg_one;
|
||||
|
||||
read_line(&buf, stdin, '\n');
|
||||
if (buf.eof)
|
||||
break;
|
||||
tg_one = buf.buf;
|
||||
rf_one = strchr(tg_one, '\t');
|
||||
if (rf_one)
|
||||
*rf_one++ = 0;
|
||||
|
||||
if (targets >= targets_alloc) {
|
||||
targets_alloc = targets_alloc ? targets_alloc * 2 : 64;
|
||||
*target = xrealloc(*target, targets_alloc * sizeof(**target));
|
||||
*write_ref = xrealloc(*write_ref, targets_alloc * sizeof(**write_ref));
|
||||
}
|
||||
(*target)[targets] = strdup(tg_one);
|
||||
(*write_ref)[targets] = rf_one ? strdup(rf_one) : NULL;
|
||||
targets++;
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
void pull_targets_free(int targets, char **target, const char **write_ref)
|
||||
{
|
||||
while (targets--) {
|
||||
free(target[targets]);
|
||||
if (write_ref[targets])
|
||||
free((char *) write_ref[targets]);
|
||||
}
|
||||
}
|
||||
|
||||
int pull(int targets, char **target, const char **write_ref,
|
||||
const char *write_ref_log_details)
|
||||
{
|
||||
|
6
fetch.h
6
fetch.h
@ -40,6 +40,12 @@ extern int get_recover;
|
||||
/* Report what we got under get_verbosely */
|
||||
extern void pull_say(const char *, const char *);
|
||||
|
||||
/* Load pull targets from stdin */
|
||||
extern int pull_targets_stdin(char ***target, const char ***write_ref);
|
||||
|
||||
/* Free up loaded targets */
|
||||
extern void pull_targets_free(int targets, char **target, const char **write_ref);
|
||||
|
||||
/* If write_ref is set, the ref filename to write the target value to. */
|
||||
/* If write_ref_log_details is set, additional text will appear in the ref log. */
|
||||
extern int pull(int targets, char **target, const char **write_ref,
|
||||
|
@ -8,8 +8,9 @@
|
||||
static int use_link = 0;
|
||||
static int use_symlink = 0;
|
||||
static int use_filecopy = 1;
|
||||
static int commits_on_stdin = 0;
|
||||
|
||||
static char *path; /* "Remote" git repository */
|
||||
static const char *path; /* "Remote" git repository */
|
||||
|
||||
void prefetch(unsigned char *sha1)
|
||||
{
|
||||
@ -194,7 +195,7 @@ int fetch_ref(char *ref, unsigned char *sha1)
|
||||
}
|
||||
|
||||
static const char local_pull_usage[] =
|
||||
"git-local-fetch [-c] [-t] [-a] [-v] [-w filename] [--recover] [-l] [-s] [-n] commit-id path";
|
||||
"git-local-fetch [-c] [-t] [-a] [-v] [-w filename] [--recover] [-l] [-s] [-n] [--stdin] commit-id path";
|
||||
|
||||
/*
|
||||
* By default we only use file copy.
|
||||
@ -202,10 +203,11 @@ static const char local_pull_usage[] =
|
||||
* If -s is specified, then a symlink is attempted.
|
||||
* If -n is _not_ specified, then a regular file-to-file copy is done.
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
const char *write_ref = NULL;
|
||||
char *commit_id;
|
||||
int commits;
|
||||
const char **write_ref = NULL;
|
||||
char **commit_id;
|
||||
int arg = 1;
|
||||
|
||||
setup_git_directory();
|
||||
@ -230,20 +232,30 @@ int main(int argc, char **argv)
|
||||
else if (argv[arg][1] == 'v')
|
||||
get_verbosely = 1;
|
||||
else if (argv[arg][1] == 'w')
|
||||
write_ref = argv[++arg];
|
||||
write_ref = &argv[++arg];
|
||||
else if (!strcmp(argv[arg], "--recover"))
|
||||
get_recover = 1;
|
||||
else if (!strcmp(argv[arg], "--stdin"))
|
||||
commits_on_stdin = 1;
|
||||
else
|
||||
usage(local_pull_usage);
|
||||
arg++;
|
||||
}
|
||||
if (argc < arg + 2)
|
||||
if (argc < arg + 2 - commits_on_stdin)
|
||||
usage(local_pull_usage);
|
||||
commit_id = argv[arg];
|
||||
path = argv[arg + 1];
|
||||
if (commits_on_stdin) {
|
||||
commits = pull_targets_stdin(&commit_id, &write_ref);
|
||||
} else {
|
||||
commit_id = (char **) &argv[arg++];
|
||||
commits = 1;
|
||||
}
|
||||
path = argv[arg];
|
||||
|
||||
if (pull(1, &commit_id, &write_ref, path))
|
||||
if (pull(commits, commit_id, write_ref, path))
|
||||
return 1;
|
||||
|
||||
if (commits_on_stdin)
|
||||
pull_targets_free(commits, commit_id, write_ref);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user