18
#include "wt-status.h"
19
20
#define GIT_HISTORY_REWORD_USAGE \
21
- N_("git history reword <commit> [--ref-action=(branches|head|print)]")
21
+ N_("git history reword <commit> [--dry-run] [--ref-action=(branches|head)]")
22
23
static void change_data_free(void *util, const char *str UNUSED)
24
{
155
REF_ACTION_DEFAULT,
156
REF_ACTION_BRANCHES,
157
REF_ACTION_HEAD,
158
- REF_ACTION_PRINT,
158
};
159
160
static int parse_ref_action(const struct option *opt, const char *value, int unset)
166
*action = REF_ACTION_BRANCHES;
167
} else if (!strcmp(value, "head")) {
168
*action = REF_ACTION_HEAD;
170
- } else if (!strcmp(value, "print")) {
171
- *action = REF_ACTION_PRINT;
169
} else {
173
- return error(_("%s expects one of 'branches', 'head' or 'print'"),
170
+ return error(_("%s expects one of 'branches' or 'head'"),
171
opt->long_name);
172
}
173
283
return ret;
284
}
285
286
+static int handle_ref_update(struct ref_transaction *transaction,
287
+ const char *refname,
288
+ const struct object_id *new_oid,
289
+ const struct object_id *old_oid,
290
+ const char *reflog_msg,
291
+ struct strbuf *err)
292
+{
293
+ if (!transaction) {
294
+ printf("update %s %s %s\n",
295
+ refname, oid_to_hex(new_oid), oid_to_hex(old_oid));
296
+ return 0;
297
+ }
298
+
299
+ return ref_transaction_update(transaction, refname, new_oid, old_oid,
300
+ NULL, NULL, 0, reflog_msg, err);
301
+}
302
+
303
static int handle_reference_updates(struct rev_info *revs,
304
enum ref_action action,
305
struct commit *original,
306
struct commit *rewritten,
293
- const char *reflog_msg)
307
+ const char *reflog_msg,
308
+ int dry_run)
309
{
310
const struct name_decoration *decoration;
311
struct replay_revisions_options opts = { 0 };
327
if (ret)
328
goto out;
329
315
- switch (action) {
316
- case REF_ACTION_BRANCHES:
317
- case REF_ACTION_HEAD:
330
+ if (action != REF_ACTION_BRANCHES && action != REF_ACTION_HEAD)
331
+ BUG("unsupported ref action %d", action);
332
+
333
+ if (!dry_run) {
334
transaction = ref_store_transaction_begin(get_main_ref_store(revs->repo), 0, &err);
335
if (!transaction) {
336
ret = error(_("failed to begin ref transaction: %s"), err.buf);
337
goto out;
338
}
339
+ }
340
324
- for (size_t i = 0; i < result.updates_nr; i++) {
325
- ret = ref_transaction_update(transaction,
326
- result.updates[i].refname,
327
- &result.updates[i].new_oid,
328
- &result.updates[i].old_oid,
329
- NULL, NULL, 0, reflog_msg, &err);
330
- if (ret) {
331
- ret = error(_("failed to update ref '%s': %s"),
332
- result.updates[i].refname, err.buf);
333
- goto out;
334
- }
341
+ for (size_t i = 0; i < result.updates_nr; i++) {
342
+ ret = handle_ref_update(transaction,
343
+ result.updates[i].refname,
344
+ &result.updates[i].new_oid,
345
+ &result.updates[i].old_oid,
346
+ reflog_msg, &err);
347
+ if (ret) {
348
+ ret = error(_("failed to update ref '%s': %s"),
349
+ result.updates[i].refname, err.buf);
350
+ goto out;
351
}
352
+ }
353
+
354
+ /*
355
+ * `replay_revisions()` only updates references that are
356
+ * ancestors of `rewritten`, so we need to manually
357
+ * handle updating references that point to `original`.
358
+ */
359
+ for (decoration = get_name_decoration(&original->object);
360
+ decoration;
361
+ decoration = decoration->next)
362
+ {
363
+ if (decoration->type != DECORATION_REF_LOCAL &&
364
+ decoration->type != DECORATION_REF_HEAD)
365
+ continue;
366
+
367
+ if (action == REF_ACTION_HEAD &&
368
+ decoration->type != DECORATION_REF_HEAD)
369
+ continue;
370
371
/*
338
- * `replay_revisions()` only updates references that are
339
- * ancestors of `rewritten`, so we need to manually
340
- * handle updating references that point to `original`.
372
+ * We only need to update HEAD separately in case it's
373
+ * detached. If it's not we'd already update the branch
374
+ * it is pointing to.
375
*/
342
- for (decoration = get_name_decoration(&original->object);
343
- decoration;
344
- decoration = decoration->next)
345
- {
346
- if (decoration->type != DECORATION_REF_LOCAL &&
347
- decoration->type != DECORATION_REF_HEAD)
348
- continue;
349
-
350
- if (action == REF_ACTION_HEAD &&
351
- decoration->type != DECORATION_REF_HEAD)
352
- continue;
353
-
354
- /*
355
- * We only need to update HEAD separately in case it's
356
- * detached. If it's not we'd already update the branch
357
- * it is pointing to.
358
- */
359
- if (action == REF_ACTION_BRANCHES &&
360
- decoration->type == DECORATION_REF_HEAD &&
361
- !detached_head)
362
- continue;
363
-
364
- ret = ref_transaction_update(transaction,
365
- decoration->name,
366
- &rewritten->object.oid,
367
- &original->object.oid,
368
- NULL, NULL, 0, reflog_msg, &err);
369
- if (ret) {
370
- ret = error(_("failed to update ref '%s': %s"),
371
- decoration->name, err.buf);
372
- goto out;
373
- }
374
- }
375
-
376
- if (ref_transaction_commit(transaction, &err)) {
377
- ret = error(_("failed to commit ref transaction: %s"), err.buf);
376
+ if (action == REF_ACTION_BRANCHES &&
377
+ decoration->type == DECORATION_REF_HEAD &&
378
+ !detached_head)
379
+ continue;
380
+
381
+ ret = handle_ref_update(transaction,
382
+ decoration->name,
383
+ &rewritten->object.oid,
384
+ &original->object.oid,
385
+ reflog_msg, &err);
386
+ if (ret) {
387
+ ret = error(_("failed to update ref '%s': %s"),
388
+ decoration->name, err.buf);
389
goto out;
390
}
391
+ }
392
381
- break;
382
- case REF_ACTION_PRINT:
383
- for (size_t i = 0; i < result.updates_nr; i++)
384
- printf("update %s %s %s\n",
385
- result.updates[i].refname,
386
- oid_to_hex(&result.updates[i].new_oid),
387
- oid_to_hex(&result.updates[i].old_oid));
388
- break;
389
- default:
390
- BUG("unsupported ref action %d", action);
393
+ if (transaction && ref_transaction_commit(transaction, &err)) {
394
+ ret = error(_("failed to commit ref transaction: %s"), err.buf);
395
+ goto out;
396
}
397
398
ret = 0;
414
NULL,
415
};
416
enum ref_action action = REF_ACTION_DEFAULT;
417
+ int dry_run = 0;
418
struct option options[] = {
419
OPT_CALLBACK_F(0, "ref-action", &action, N_("<action>"),
414
- N_("control ref update behavior (branches|head|print)"),
420
+ N_("control ref update behavior (branches|head)"),
421
PARSE_OPT_NONEG, parse_ref_action),
422
+ OPT_BOOL('n', "dry-run", &dry_run,
423
+ N_("perform a dry-run without updating any refs")),
424
OPT_END(),
425
};
426
struct strbuf reflog_msg = STRBUF_INIT;
457
strbuf_addf(&reflog_msg, "reword: updating %s", argv[0]);
458
459
ret = handle_reference_updates(&revs, action, original, rewritten,
452
- reflog_msg.buf);
460
+ reflog_msg.buf, dry_run);
461
if (ret < 0) {
462
ret = error(_("failed replaying descendants"));
463
goto out;