Add support for "import" helper command
This command, supported if the "import" capability is advertized, allows a helper to support fetching by outputting a git-fast-import stream. If both "fetch" and "import" are advertized, git itself will use "fetch" (although other users may use "import" in this case). Signed-off-by: Daniel Barkalow <barkalow@iabervon.org> Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Daniel Barkalow committed
Nov 18, 2009 at 02:42 UTC
e65e91ed4af5ed9c5c810a2cd77b8648a0287e66
2 files changed
+62
Documentation/git-remote-helpers.txt
+10
@@ -43,6 +43,13 @@ Commands are given by the caller on the helper's standard input, one per line.
43
+
44
Supported if the helper has the "fetch" capability.
45
46
+'import' <name>::
47
+ Produces a fast-import stream which imports the current value
48
+ of the named ref. It may additionally import other refs as
49
+ needed to construct the history efficiently.
50
++
51
+Supported if the helper has the "import" capability.
52
+
53
If a fatal error occurs, the program writes the error message to
54
stderr and exits. The caller should expect that a suitable error
55
message has been printed if the child closes the connection without
@@ -57,6 +64,9 @@ CAPABILITIES
64
'fetch'::
65
This helper supports the 'fetch' command.
66
67
+'import'::
68
+ This helper supports the 'import' command.
69
+
70
REF LIST ATTRIBUTES
71
-------------------
72
transport-helper.c
+52
@@ -11,6 +11,7 @@ struct helper_data
11
const char *name;
12
struct child_process *helper;
13
unsigned fetch : 1;
14
+ unsigned import : 1;
15
};
16
17
static struct child_process *get_helper(struct transport *transport)
@@ -48,6 +49,8 @@ static struct child_process *get_helper(struct transport *transport)
49
break;
50
if (!strcmp(buf.buf, "fetch"))
51
data->fetch = 1;
52
+ if (!strcmp(buf.buf, "import"))
53
+ data->import = 1;
54
}
55
return data->helper;
56
}
@@ -98,6 +101,52 @@ static int fetch_with_fetch(struct transport *transport,
101
return 0;
102
}
103
104
+static int get_importer(struct transport *transport, struct child_process *fastimport)
105
+{
106
+ struct child_process *helper = get_helper(transport);
107
+ memset(fastimport, 0, sizeof(*fastimport));
108
+ fastimport->in = helper->out;
109
+ fastimport->argv = xcalloc(5, sizeof(*fastimport->argv));
110
+ fastimport->argv[0] = "fast-import";
111
+ fastimport->argv[1] = "--quiet";
112
+
113
+ fastimport->git_cmd = 1;
114
+ return start_command(fastimport);
115
+}
116
+
117
+static int fetch_with_import(struct transport *transport,
118
+ int nr_heads, struct ref **to_fetch)
119
+{
120
+ struct child_process fastimport;
121
+ struct child_process *helper = get_helper(transport);
122
+ int i;
123
+ struct ref *posn;
124
+ struct strbuf buf = STRBUF_INIT;
125
+
126
+ if (get_importer(transport, &fastimport))
127
+ die("Couldn't run fast-import");
128
+
129
+ for (i = 0; i < nr_heads; i++) {
130
+ posn = to_fetch[i];
131
+ if (posn->status & REF_STATUS_UPTODATE)
132
+ continue;
133
+
134
+ strbuf_addf(&buf, "import %s\n", posn->name);
135
+ write_in_full(helper->in, buf.buf, buf.len);
136
+ strbuf_reset(&buf);
137
+ }
138
+ disconnect_helper(transport);
139
+ finish_command(&fastimport);
140
+
141
+ for (i = 0; i < nr_heads; i++) {
142
+ posn = to_fetch[i];
143
+ if (posn->status & REF_STATUS_UPTODATE)
144
+ continue;
145
+ read_ref(posn->name, posn->old_sha1);
146
+ }
147
+ return 0;
148
+}
149
+
150
static int fetch(struct transport *transport,
151
int nr_heads, struct ref **to_fetch)
152
{
@@ -115,6 +164,9 @@ static int fetch(struct transport *transport,
164
if (data->fetch)
165
return fetch_with_fetch(transport, nr_heads, to_fetch);
166
167
+ if (data->import)
168
+ return fetch_with_import(transport, nr_heads, to_fetch);
169
+
170
return -1;
171
}
172