@@ -6,17 +6,13 @@
#include "git-compat-util.h"
#include "builtin.h"
-#include "cache-tree.h"
-#include "commit.h"
#include "hex.h"
#include "lockfile.h"
#include "merge-ort.h"
#include "parse-options.h"
#include "refs.h"
#include "revision.h"
-#include "sequencer.h"
#include "strvec.h"
-#include "tree.h"
static const char *short_commit_name(struct commit *commit)
{
@@ -93,6 +89,7 @@ static struct commit *pick_regular_commit(struct commit *pickme,
pickme_tree = get_commit_tree(pickme);
base_tree = get_commit_tree(base);
+ merge_opt->branch1 = short_commit_name(last_commit);
merge_opt->branch2 = short_commit_name(pickme);
merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2);
@@ -113,15 +110,12 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
{
struct commit *onto;
const char *onto_name = NULL;
- struct commit *last_commit = NULL, *last_picked_commit = NULL;
- struct lock_file lock = LOCK_INIT;
+ struct commit *last_commit = NULL;
struct strvec rev_walk_args = STRVEC_INIT;
struct rev_info revs;
struct commit *commit;
struct merge_options merge_opt;
- struct tree *head_tree;
struct merge_result result;
- struct strbuf reflog_msg = STRBUF_INIT;
struct strbuf branch_name = STRBUF_INIT;
int ret = 0;
@@ -177,20 +171,19 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
init_merge_options(&merge_opt, the_repository);
memset(&result, 0, sizeof(result));
merge_opt.show_rename_progress = 0;
- merge_opt.branch1 = "HEAD";
- head_tree = get_commit_tree(onto);
- result.tree = head_tree;
+ result.tree = get_commit_tree(onto);
last_commit = onto;
while ((commit = get_revision(&revs))) {
- struct commit *pick;
+ const struct name_decoration *decoration;
if (!commit->parents)
die(_("replaying down to root commit is not supported yet!"));
if (commit->parents->next)
die(_("replaying merge commits is not supported yet!"));
- pick = pick_regular_commit(commit, last_commit, &merge_opt, &result);
- if (!pick) {
+ last_commit = pick_regular_commit(commit, last_commit, &merge_opt, &result);
+
+ if (!last_commit) {
/* TODO: handle conflicts in sparse worktree instead */
struct object_id head;
struct tree *head_tree;
@@ -215,54 +208,31 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
oid_to_hex(&commit->object.oid));
}
- last_commit = pick;
- last_picked_commit = commit;
- }
-
- repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
- if (repo_read_index(the_repository) < 0)
- BUG("Could not read index");
-
- merge_switch_to_result(&merge_opt, head_tree, &result, 1, !result.clean);
-
- if (result.clean < 0)
- exit(128);
-
- if (result.clean) {
- strbuf_addf(&reflog_msg, "finish rebase %s onto %s",
- oid_to_hex(&last_picked_commit->object.oid),
- oid_to_hex(&last_commit->object.oid));
- if (update_ref(reflog_msg.buf, branch_name.buf,
- &last_commit->object.oid,
- &last_picked_commit->object.oid,
- REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) {
- error(_("could not update %s"), argv[2]);
- die("Failed to update %s", argv[2]);
- }
- if (create_symref("HEAD", branch_name.buf, reflog_msg.buf) < 0)
- die(_("unable to update HEAD"));
-
- prime_cache_tree(the_repository, the_repository->index,
- result.tree);
- } else {
- strbuf_addf(&reflog_msg, "rebase progress up to %s",
- oid_to_hex(&last_picked_commit->object.oid));
- if (update_ref(reflog_msg.buf, "HEAD",
- &last_commit->object.oid,
- &onto->object.oid,
- REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) {
- error(_("could not update %s"), argv[2]);
- die("Failed to update %s", argv[2]);
+ decoration = get_name_decoration(&commit->object);
+ if (!decoration)
+ continue;
+
+ while (decoration) {
+ if (decoration->type == DECORATION_REF_LOCAL) {
+ printf("update %s %s %s\n",
+ decoration->name,
+ oid_to_hex(&last_commit->object.oid),
+ oid_to_hex(&commit->object.oid));
+ }
+ decoration = decoration->next;
}
}
- if (write_locked_index(&the_index, &lock,
- COMMIT_LOCK | SKIP_IF_UNCHANGED))
- die(_("unable to write %s"), get_index_file());
- ret = (result.clean == 0);
+ /* Cleanup */
+ merge_finalize(&merge_opt, &result);
+ ret = result.clean;
+
cleanup:
- strbuf_release(&reflog_msg);
strbuf_release(&branch_name);
release_revisions(&revs);
- return ret;
+
+ /* Return */
+ if (ret < 0)
+ exit(128);
+ return ret ? 0 : 1;
}
@@ -71,7 +71,9 @@ test_expect_success 'caching renames does not preclude finding new ones' '
git switch upstream &&
- git replay --onto HEAD upstream~1 topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
git ls-files >tracked-files &&
test_line_count = 2 tracked-files &&
@@ -139,7 +141,9 @@ test_expect_success 'cherry-pick both a commit and its immediate revert' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
grep region_enter.*diffcore_rename trace.output >calls &&
test_line_count = 1 calls
@@ -197,7 +201,9 @@ test_expect_success 'rename same file identically, then reintroduce it' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
git ls-files >tracked &&
test_line_count = 2 tracked &&
@@ -273,7 +279,9 @@ test_expect_success 'rename same file identically, then add file to old dir' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
git ls-files >tracked &&
test_line_count = 4 tracked &&
@@ -450,7 +458,9 @@ test_expect_success 'dir rename unneeded, then add new file to old dir' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
grep region_enter.*diffcore_rename trace.output >calls &&
test_line_count = 2 calls &&
@@ -515,7 +525,9 @@ test_expect_success 'dir rename unneeded, then rename existing file into old dir
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
grep region_enter.*diffcore_rename trace.output >calls &&
test_line_count = 3 calls &&
@@ -616,7 +628,9 @@ test_expect_success 'caching renames only on upstream side, part 1' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
grep region_enter.*diffcore_rename trace.output >calls &&
test_line_count = 1 calls &&
@@ -673,7 +687,9 @@ test_expect_success 'caching renames only on upstream side, part 2' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
grep region_enter.*diffcore_rename trace.output >calls &&
test_line_count = 2 calls &&