[PATCH/RFC 1/2] fetch-pack: new option to read refs from stdin
>From c4bb55f9f27569faa368d823ca6fe4b236e37cd6 Mon Sep 17 00:00:00 2001
From: Ivan Todoroski <grnch@gmx.net>
Date: Sat, 24 Mar 2012 15:13:05 +0100
Subject: [PATCH/RFC 1/2] fetch-pack: new option to read refs from stdin
---
Documentation/git-fetch-pack.txt | 9 ++++++++
builtin/fetch-pack.c | 44 ++++++++++++++++++++++++++++++++++++--
fetch-pack.h | 3 ++-
3 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt
index ed1bdaacd1..7cd7c785bc 100644
--- a/Documentation/git-fetch-pack.txt
+++ b/Documentation/git-fetch-pack.txt
@@ -32,6 +32,15 @@ OPTIONS
--all::
Fetch all remote refs.
+--stdin::
+ Take the list of refs from stdin, one per line. If there
+ are refs specified on the command line in addition to this
+ option, then the refs from stdin are processed after those
+ on the command line.
+ If '--stateless-rpc' is specified together with this option
+ then the list of refs must be in packet format (pkt-line)
+ with a flush packet terminating the list.
+
-q::
--quiet::
Pass '-q' flag to 'git unpack-objects'; this makes the
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index a4d3e90a86..3c4c193e45 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -23,7 +23,7 @@ static struct fetch_pack_args args = {
};
static const char fetch_pack_usage[] =
-"git fetch-pack [--all] [--quiet|-q] [--keep|-k] [--thin] [--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] [--no-progress] [-v] [<host>:]<directory> [<refs>...]";
+"git fetch-pack [--all] [--stdin] [--quiet|-q] [--keep|-k] [--thin] [--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] [--no-progress] [-v] [<host>:]<directory> [<refs>...]";
#define COMPLETE (1U << 0)
#define COMMON (1U << 1)
@@ -896,7 +896,7 @@ static void fetch_pack_setup(void)
int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
{
- int i, ret, nr_heads;
+ int i, ret, nr_heads, alloc_heads;
struct ref *ref = NULL;
char *dest = NULL, **heads;
int fd[2];
@@ -941,6 +941,10 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
args.fetch_all = 1;
continue;
}
+ if (!strcmp("--stdin", arg)) {
+ args.refs_from_stdin = 1;
+ continue;
+ }
if (!strcmp("-v", arg)) {
args.verbose = 1;
continue;
@@ -972,6 +976,42 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
if (!dest)
usage(fetch_pack_usage);
+ if (args.refs_from_stdin) {
+ char ref[1000];
+ /* copy refs from cmdline to new growable list */
+ int size = nr_heads * sizeof(*heads);
+ heads = memcpy(xmalloc(size), heads, size);
+ alloc_heads = nr_heads;
+ /* append refs from stdin to ones from cmdline */
+ for (;;) {
+ if (args.stateless_rpc) {
+ /* read using pkt-line in stateless RPC mode,
+ flush packet signifies end of refs */
+ int n = packet_read_line(0, ref, sizeof(ref));
+ if (!n)
+ break;
+ if (ref[n-1] == '\n')
+ ref[n-1] = '\0';
+ }
+ else {
+ int n;
+ if (!fgets(ref, sizeof(ref), stdin)) {
+ if (ferror(stdin))
+ die_errno("cannot read ref");
+ if (feof(stdin))
+ break;
+ }
+ n = strlen(ref);
+ if (ref[n-1] == '\n')
+ ref[n-1] = '\0';
+ else if (!feof(stdin))
+ die("ref too long on stdin");
+ }
+ ALLOC_GROW(heads, nr_heads + 1, alloc_heads);
+ heads[nr_heads++] = xstrdup(ref);
+ }
+ }
+
if (args.stateless_rpc) {
conn = NULL;
fd[0] = 0;
diff --git a/fetch-pack.h b/fetch-pack.h
index 0608edae3f..292d69389e 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -13,7 +13,8 @@ struct fetch_pack_args {
verbose:1,
no_progress:1,
include_tag:1,
- stateless_rpc:1;
+ stateless_rpc:1,
+ refs_from_stdin:1;
};
struct ref *fetch_pack(struct fetch_pack_args *args,
--
1.7.9.4.16.gd24fa.dirty