mirror of
https://github.com/git-for-windows/git.git
synced 2026-06-14 05:33:00 -05:00
builtin/history: split handling of ref updates into two phases
The function `handle_reference_updates()` is used by git-history(1) to
update all references that refer to commits that have been rewritten. As
such, it performs two steps:
- It gathers the references that need to be updated in the first
place.
- It prepares and commits the reference transaction.
In a subsequent commit we'll want to handle those two steps separately.
Prepare for this by splitting up the function into two.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
033db05809
commit
fa07f7efbd
@@ -333,21 +333,17 @@ static int handle_ref_update(struct ref_transaction *transaction,
|
||||
NULL, NULL, 0, reflog_msg, err);
|
||||
}
|
||||
|
||||
static int handle_reference_updates(struct rev_info *revs,
|
||||
enum ref_action action,
|
||||
struct commit *original,
|
||||
struct commit *rewritten,
|
||||
const char *reflog_msg,
|
||||
int dry_run,
|
||||
enum replay_empty_commit_action empty)
|
||||
static int compute_pending_ref_updates(struct rev_info *revs,
|
||||
enum ref_action action,
|
||||
struct commit *original,
|
||||
struct commit *rewritten,
|
||||
enum replay_empty_commit_action empty,
|
||||
struct replay_result *result)
|
||||
{
|
||||
const struct name_decoration *decoration;
|
||||
struct replay_revisions_options opts = {
|
||||
.empty = empty,
|
||||
};
|
||||
struct replay_result result = { 0 };
|
||||
struct ref_transaction *transaction = NULL;
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
char hex[GIT_MAX_HEXSZ + 1];
|
||||
bool detached_head;
|
||||
int head_flags = 0;
|
||||
@@ -359,34 +355,13 @@ static int handle_reference_updates(struct rev_info *revs,
|
||||
|
||||
opts.onto = oid_to_hex_r(hex, &rewritten->object.oid);
|
||||
|
||||
ret = replay_revisions(revs, &opts, &result);
|
||||
ret = replay_revisions(revs, &opts, result);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ret;
|
||||
|
||||
if (action != REF_ACTION_BRANCHES && action != REF_ACTION_HEAD)
|
||||
BUG("unsupported ref action %d", action);
|
||||
|
||||
if (!dry_run) {
|
||||
transaction = ref_store_transaction_begin(get_main_ref_store(revs->repo), 0, &err);
|
||||
if (!transaction) {
|
||||
ret = error(_("failed to begin ref transaction: %s"), err.buf);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < result.updates_nr; i++) {
|
||||
ret = handle_ref_update(transaction,
|
||||
result.updates[i].refname,
|
||||
&result.updates[i].new_oid,
|
||||
&result.updates[i].old_oid,
|
||||
reflog_msg, &err);
|
||||
if (ret) {
|
||||
ret = error(_("failed to update ref '%s': %s"),
|
||||
result.updates[i].refname, err.buf);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* `replay_revisions()` only updates references that are
|
||||
* ancestors of `rewritten`, so we need to manually
|
||||
@@ -414,14 +389,43 @@ static int handle_reference_updates(struct rev_info *revs,
|
||||
!detached_head)
|
||||
continue;
|
||||
|
||||
ALLOC_GROW(result->updates, result->updates_nr + 1, result->updates_alloc);
|
||||
result->updates[result->updates_nr].refname = xstrdup(decoration->name);
|
||||
result->updates[result->updates_nr].old_oid = original->object.oid;
|
||||
result->updates[result->updates_nr].new_oid = rewritten->object.oid;
|
||||
result->updates_nr++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apply_pending_ref_updates(struct repository *repo,
|
||||
const struct replay_result *result,
|
||||
const char *reflog_msg,
|
||||
int dry_run)
|
||||
{
|
||||
struct ref_transaction *transaction = NULL;
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
int ret;
|
||||
|
||||
if (!dry_run) {
|
||||
transaction = ref_store_transaction_begin(get_main_ref_store(repo),
|
||||
0, &err);
|
||||
if (!transaction) {
|
||||
ret = error(_("failed to begin ref transaction: %s"), err.buf);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < result->updates_nr; i++) {
|
||||
ret = handle_ref_update(transaction,
|
||||
decoration->name,
|
||||
&rewritten->object.oid,
|
||||
&original->object.oid,
|
||||
result->updates[i].refname,
|
||||
&result->updates[i].new_oid,
|
||||
&result->updates[i].old_oid,
|
||||
reflog_msg, &err);
|
||||
if (ret) {
|
||||
ret = error(_("failed to update ref '%s': %s"),
|
||||
decoration->name, err.buf);
|
||||
result->updates[i].refname, err.buf);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -435,11 +439,33 @@ static int handle_reference_updates(struct rev_info *revs,
|
||||
|
||||
out:
|
||||
ref_transaction_free(transaction);
|
||||
replay_result_release(&result);
|
||||
strbuf_release(&err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int handle_reference_updates(struct rev_info *revs,
|
||||
enum ref_action action,
|
||||
struct commit *original,
|
||||
struct commit *rewritten,
|
||||
const char *reflog_msg,
|
||||
int dry_run,
|
||||
enum replay_empty_commit_action empty)
|
||||
{
|
||||
struct replay_result result = { 0 };
|
||||
int ret;
|
||||
|
||||
ret = compute_pending_ref_updates(revs, action, original, rewritten,
|
||||
empty, &result);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = apply_pending_ref_updates(revs->repo, &result, reflog_msg, dry_run);
|
||||
|
||||
out:
|
||||
replay_result_release(&result);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int commit_became_empty(struct repository *repo,
|
||||
struct commit *original,
|
||||
struct tree *result)
|
||||
|
||||
Reference in New Issue
Block a user