sequencer (rebase -i): update refs after a successful rebase
An interactive rebase operates on a detached HEAD (to keep the reflog of the original branch relatively clean), and updates the branch only at the end. Now that the sequencer learns to perform interactive rebases, it also needs to learn the trick to update the branch before removing the directory containing the state of the interactive rebase. We introduce a new head_ref variable in a wider scope than necessary at the moment, to allow for a later patch that prints out "Successfully rebased and updated <ref>". Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Jan 2, 2017 at 16:27 UTC
4b83ce9f6772451d4582dc1f0891790acbdf4eb1
1 file changed
+45
-1
sequencer.c
+45
-1
@@ -102,6 +102,8 @@ static GIT_PATH_FUNC(rebase_path_stopped_sha, "rebase-merge/stopped-sha")
102
static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, "rebase-merge/gpg_sign_opt")
103
static GIT_PATH_FUNC(rebase_path_orig_head, "rebase-merge/orig-head")
104
static GIT_PATH_FUNC(rebase_path_verbose, "rebase-merge/verbose")
105
+static GIT_PATH_FUNC(rebase_path_head_name, "rebase-merge/head-name")
106
+static GIT_PATH_FUNC(rebase_path_onto, "rebase-merge/onto")
107
108
static inline int is_rebase_i(const struct replay_opts *opts)
109
{
@@ -1784,12 +1786,53 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
1786
}
1787
1788
if (is_rebase_i(opts)) {
1787
- struct strbuf buf = STRBUF_INIT;
1789
+ struct strbuf head_ref = STRBUF_INIT, buf = STRBUF_INIT;
1790
1791
/* Stopped in the middle, as planned? */
1792
if (todo_list->current < todo_list->nr)
1793
return 0;
1794
1795
+ if (read_oneliner(&head_ref, rebase_path_head_name(), 0) &&
1796
+ starts_with(head_ref.buf, "refs/")) {
1797
+ unsigned char head[20], orig[20];
1798
+ int res;
1799
+
1800
+ if (get_sha1("HEAD", head)) {
1801
+ res = error(_("cannot read HEAD"));
1802
+cleanup_head_ref:
1803
+ strbuf_release(&head_ref);
1804
+ strbuf_release(&buf);
1805
+ return res;
1806
+ }
1807
+ if (!read_oneliner(&buf, rebase_path_orig_head(), 0) ||
1808
+ get_sha1_hex(buf.buf, orig)) {
1809
+ res = error(_("could not read orig-head"));
1810
+ goto cleanup_head_ref;
1811
+ }
1812
+ strbuf_addf(&buf, "rebase -i (finish): %s onto ",
1813
+ head_ref.buf);
1814
+ if (!read_oneliner(&buf, rebase_path_onto(), 0)) {
1815
+ res = error(_("could not read 'onto'"));
1816
+ goto cleanup_head_ref;
1817
+ }
1818
+ if (update_ref(buf.buf, head_ref.buf, head, orig,
1819
+ REF_NODEREF, UPDATE_REFS_MSG_ON_ERR)) {
1820
+ res = error(_("could not update %s"),
1821
+ head_ref.buf);
1822
+ goto cleanup_head_ref;
1823
+ }
1824
+ strbuf_reset(&buf);
1825
+ strbuf_addf(&buf,
1826
+ "rebase -i (finish): returning to %s",
1827
+ head_ref.buf);
1828
+ if (create_symref("HEAD", head_ref.buf, buf.buf)) {
1829
+ res = error(_("could not update HEAD to %s"),
1830
+ head_ref.buf);
1831
+ goto cleanup_head_ref;
1832
+ }
1833
+ strbuf_reset(&buf);
1834
+ }
1835
+
1836
if (opts->verbose) {
1837
struct rev_info log_tree_opt;
1838
struct object_id orig, head;
@@ -1810,6 +1853,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
1853
}
1854
}
1855
strbuf_release(&buf);
1856
+ strbuf_release(&head_ref);
1857
}
1858
1859
/*