update-ref --stdin: reimplement using reference transactions

This change is mostly clerical: the parse_cmd_*() functions need to use local variables rather than a struct ref_update to collect the arguments needed for each update, and then call ref_transaction_*() to queue the change rather than building up the list of changes at the caller side. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael Haggerty committed Apr 7, 2014 at 15:48 UTC aebfc13337e503b5a7d064cb1e9c9916f24c2baf
1 file changed +75 -67
builtin/update-ref.c
+75 -67
@@ -12,29 +12,11 @@ static const char * const git_update_ref_usage[] = {
12 NULL
13 };
14
15 -static int updates_alloc;
16 -static int updates_count;
17 -static struct ref_update **updates;
15 +static struct ref_transaction *transaction;
16
17 static char line_termination = '\n';
18 static int update_flags;
19
22 -static struct ref_update *update_alloc(void)
23 -{
24 - struct ref_update *update;
25 -
26 - /* Allocate and zero-init a struct ref_update */
27 - update = xcalloc(1, sizeof(*update));
28 - ALLOC_GROW(updates, updates_count + 1, updates_alloc);
29 - updates[updates_count++] = update;
30 -
31 - /* Store and reset accumulated options */
32 - update->flags = update_flags;
33 - update_flags = 0;
34 -
35 - return update;
36 -}
37 -
20 /*
21 * Parse one whitespace- or NUL-terminated, possibly C-quoted argument
22 * and append the result to arg. Return a pointer to the terminator.
@@ -196,97 +178,119 @@ static int parse_next_sha1(struct strbuf *input, const char **next,
178
179 static const char *parse_cmd_update(struct strbuf *input, const char *next)
180 {
199 - struct ref_update *update;
200 -
201 - update = update_alloc();
181 + char *refname;
182 + unsigned char new_sha1[20];
183 + unsigned char old_sha1[20];
184 + int have_old;
185
203 - update->ref_name = parse_refname(input, &next);
204 - if (!update->ref_name)
186 + refname = parse_refname(input, &next);
187 + if (!refname)
188 die("update: missing <ref>");
189
207 - if (parse_next_sha1(input, &next, update->new_sha1,
208 - "update", update->ref_name,
190 + if (parse_next_sha1(input, &next, new_sha1, "update", refname,
191 PARSE_SHA1_ALLOW_EMPTY))
210 - die("update %s: missing <newvalue>", update->ref_name);
192 + die("update %s: missing <newvalue>", refname);
193
212 - update->have_old = !parse_next_sha1(input, &next, update->old_sha1,
213 - "update", update->ref_name,
214 - PARSE_SHA1_OLD);
194 + have_old = !parse_next_sha1(input, &next, old_sha1, "update", refname,
195 + PARSE_SHA1_OLD);
196
197 if (*next != line_termination)
217 - die("update %s: extra input: %s", update->ref_name, next);
198 + die("update %s: extra input: %s", refname, next);
199 +
200 + ref_transaction_update(transaction, refname, new_sha1, old_sha1,
201 + update_flags, have_old);
202 +
203 + update_flags = 0;
204 + free(refname);
205
206 return next;
207 }
208
209 static const char *parse_cmd_create(struct strbuf *input, const char *next)
210 {
224 - struct ref_update *update;
225 -
226 - update = update_alloc();
211 + char *refname;
212 + unsigned char new_sha1[20];
213
228 - update->ref_name = parse_refname(input, &next);
229 - if (!update->ref_name)
214 + refname = parse_refname(input, &next);
215 + if (!refname)
216 die("create: missing <ref>");
217
232 - if (parse_next_sha1(input, &next, update->new_sha1,
233 - "create", update->ref_name, 0))
234 - die("create %s: missing <newvalue>", update->ref_name);
218 + if (parse_next_sha1(input, &next, new_sha1, "create", refname, 0))
219 + die("create %s: missing <newvalue>", refname);
220
236 - if (is_null_sha1(update->new_sha1))
237 - die("create %s: zero <newvalue>", update->ref_name);
221 + if (is_null_sha1(new_sha1))
222 + die("create %s: zero <newvalue>", refname);
223
224 if (*next != line_termination)
240 - die("create %s: extra input: %s", update->ref_name, next);
225 + die("create %s: extra input: %s", refname, next);
226 +
227 + ref_transaction_create(transaction, refname, new_sha1, update_flags);
228 +
229 + update_flags = 0;
230 + free(refname);
231
232 return next;
233 }
234
235 static const char *parse_cmd_delete(struct strbuf *input, const char *next)
236 {
247 - struct ref_update *update;
237 + char *refname;
238 + unsigned char old_sha1[20];
239 + int have_old;
240
249 - update = update_alloc();
250 -
251 - update->ref_name = parse_refname(input, &next);
252 - if (!update->ref_name)
241 + refname = parse_refname(input, &next);
242 + if (!refname)
243 die("delete: missing <ref>");
244
255 - if (parse_next_sha1(input, &next, update->old_sha1,
256 - "delete", update->ref_name, PARSE_SHA1_OLD)) {
257 - update->have_old = 0;
245 + if (parse_next_sha1(input, &next, old_sha1, "delete", refname,
246 + PARSE_SHA1_OLD)) {
247 + have_old = 0;
248 } else {
259 - if (is_null_sha1(update->old_sha1))
260 - die("delete %s: zero <oldvalue>", update->ref_name);
261 - update->have_old = 1;
249 + if (is_null_sha1(old_sha1))
250 + die("delete %s: zero <oldvalue>", refname);
251 + have_old = 1;
252 }
253
254 if (*next != line_termination)
265 - die("delete %s: extra input: %s", update->ref_name, next);
255 + die("delete %s: extra input: %s", refname, next);
256 +
257 + ref_transaction_delete(transaction, refname, old_sha1,
258 + update_flags, have_old);
259 +
260 + update_flags = 0;
261 + free(refname);
262
263 return next;
264 }
265
266 static const char *parse_cmd_verify(struct strbuf *input, const char *next)
267 {
272 - struct ref_update *update;
273 -
274 - update = update_alloc();
268 + char *refname;
269 + unsigned char new_sha1[20];
270 + unsigned char old_sha1[20];
271 + int have_old;
272
276 - update->ref_name = parse_refname(input, &next);
277 - if (!update->ref_name)
273 + refname = parse_refname(input, &next);
274 + if (!refname)
275 die("verify: missing <ref>");
276
280 - if (parse_next_sha1(input, &next, update->old_sha1,
281 - "verify", update->ref_name, PARSE_SHA1_OLD)) {
282 - update->have_old = 0;
277 + if (parse_next_sha1(input, &next, old_sha1, "verify", refname,
278 + PARSE_SHA1_OLD)) {
279 + hashclr(new_sha1);
280 + have_old = 0;
281 } else {
284 - hashcpy(update->new_sha1, update->old_sha1);
285 - update->have_old = 1;
282 + hashcpy(new_sha1, old_sha1);
283 + have_old = 1;
284 }
285
286 if (*next != line_termination)
289 - die("verify %s: extra input: %s", update->ref_name, next);
287 + die("verify %s: extra input: %s", refname, next);
288 +
289 + ref_transaction_update(transaction, refname, new_sha1, old_sha1,
290 + update_flags, have_old);
291 +
292 + update_flags = 0;
293 + free(refname);
294
295 return next;
296 }
@@ -355,13 +359,17 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
359 die("Refusing to perform update with empty message.");
360
361 if (read_stdin) {
362 + int ret;
363 + transaction = ref_transaction_begin();
364 +
365 if (delete || no_deref || argc > 0)
366 usage_with_options(git_update_ref_usage, options);
367 if (end_null)
368 line_termination = '\0';
369 update_refs_stdin();
363 - return update_refs(msg, updates, updates_count,
364 - UPDATE_REFS_DIE_ON_ERR);
370 + ret = ref_transaction_commit(transaction, msg,
371 + UPDATE_REFS_DIE_ON_ERR);
372 + return ret;
373 }
374
375 if (end_null)