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:

committed by
Junio C Hamano

parent
4211e4d10c
commit
8e87ca6615
@ -29,6 +29,12 @@ OPTIONS
|
|||||||
Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on
|
Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on
|
||||||
the local end after the transfer is complete.
|
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
|
Author
|
||||||
------
|
------
|
||||||
Written by Junio C Hamano <junkio@cox.net>
|
Written by Junio C Hamano <junkio@cox.net>
|
||||||
|
40
fetch.c
40
fetch.c
@ -7,6 +7,7 @@
|
|||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
#include "blob.h"
|
#include "blob.h"
|
||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
int get_tree = 0;
|
int get_tree = 0;
|
||||||
int get_history = 0;
|
int get_history = 0;
|
||||||
@ -210,6 +211,45 @@ static int mark_complete(const char *path, const unsigned char *sha1)
|
|||||||
return 0;
|
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,
|
int pull(int targets, char **target, const char **write_ref,
|
||||||
const char *write_ref_log_details)
|
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 */
|
/* Report what we got under get_verbosely */
|
||||||
extern void pull_say(const char *, const char *);
|
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 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. */
|
/* 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,
|
extern int pull(int targets, char **target, const char **write_ref,
|
||||||
|
@ -8,8 +8,9 @@
|
|||||||
static int use_link = 0;
|
static int use_link = 0;
|
||||||
static int use_symlink = 0;
|
static int use_symlink = 0;
|
||||||
static int use_filecopy = 1;
|
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)
|
void prefetch(unsigned char *sha1)
|
||||||
{
|
{
|
||||||
@ -194,7 +195,7 @@ int fetch_ref(char *ref, unsigned char *sha1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char local_pull_usage[] =
|
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.
|
* 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 -s is specified, then a symlink is attempted.
|
||||||
* If -n is _not_ specified, then a regular file-to-file copy is done.
|
* 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;
|
int commits;
|
||||||
char *commit_id;
|
const char **write_ref = NULL;
|
||||||
|
char **commit_id;
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
|
|
||||||
setup_git_directory();
|
setup_git_directory();
|
||||||
@ -230,20 +232,30 @@ int main(int argc, char **argv)
|
|||||||
else if (argv[arg][1] == 'v')
|
else if (argv[arg][1] == 'v')
|
||||||
get_verbosely = 1;
|
get_verbosely = 1;
|
||||||
else if (argv[arg][1] == 'w')
|
else if (argv[arg][1] == 'w')
|
||||||
write_ref = argv[++arg];
|
write_ref = &argv[++arg];
|
||||||
else if (!strcmp(argv[arg], "--recover"))
|
else if (!strcmp(argv[arg], "--recover"))
|
||||||
get_recover = 1;
|
get_recover = 1;
|
||||||
|
else if (!strcmp(argv[arg], "--stdin"))
|
||||||
|
commits_on_stdin = 1;
|
||||||
else
|
else
|
||||||
usage(local_pull_usage);
|
usage(local_pull_usage);
|
||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
if (argc < arg + 2)
|
if (argc < arg + 2 - commits_on_stdin)
|
||||||
usage(local_pull_usage);
|
usage(local_pull_usage);
|
||||||
commit_id = argv[arg];
|
if (commits_on_stdin) {
|
||||||
path = argv[arg + 1];
|
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;
|
return 1;
|
||||||
|
|
||||||
|
if (commits_on_stdin)
|
||||||
|
pull_targets_free(commits, commit_id, write_ref);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user