提交 8e87ca66 编写于 作者: P Petr Baudis 提交者: Junio C Hamano

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: NPetr Baudis <pasky@suse.cz>
Signed-off-by: NJunio C Hamano <junkio@cox.net>
上级 4211e4d1
......@@ -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>
......
......@@ -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)
{
......
......@@ -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;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册