diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2018-05-03 23:01:23 (GMT) |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2018-05-06 04:21:58 (GMT) |
commit | ebddf393964120628f60f6f5e435cde87cc209c6 (patch) | |
tree | 30f61534d92bd5915894064bf083097ee01cfc70 /sequencer.c | |
parent | 21d0764c823bdca78b99dae562ca9e5c2a121738 (diff) | |
download | git-ebddf393964120628f60f6f5e435cde87cc209c6.zip git-ebddf393964120628f60f6f5e435cde87cc209c6.tar.gz git-ebddf393964120628f60f6f5e435cde87cc209c6.tar.bz2 |
sequencer: allow introducing new root commits
In the context of the new --rebase-merges mode, which was designed
specifically to allow for changing the existing branch topology
liberally, a user may want to extract commits into a completely fresh
branch that starts with a newly-created root commit.
This is now possible by inserting the command `reset [new root]` before
`pick`ing the commit that wants to become a root commit. Example:
reset [new root]
pick 012345 a commit that is about to become a root commit
pick 234567 this commit will have the previous one as parent
This does not conflict with other uses of the `reset` command because
`[new root]` is not (part of) a valid ref name: both the opening bracket
as well as the space are illegal in ref names.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'sequencer.c')
-rw-r--r-- | sequencer.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/sequencer.c b/sequencer.c index 8eddda6..a783239 100644 --- a/sequencer.c +++ b/sequencer.c @@ -2747,18 +2747,34 @@ static int do_reset(const char *name, int len, struct replay_opts *opts) if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0) return -1; - /* Determine the length of the label */ - for (i = 0; i < len; i++) - if (isspace(name[i])) - len = i; - - strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name); - if (get_oid(ref_name.buf, &oid) && - get_oid(ref_name.buf + strlen("refs/rewritten/"), &oid)) { - error(_("could not read '%s'"), ref_name.buf); - rollback_lock_file(&lock); - strbuf_release(&ref_name); - return -1; + if (len == 10 && !strncmp("[new root]", name, len)) { + if (!opts->have_squash_onto) { + const char *hex; + if (commit_tree("", 0, the_hash_algo->empty_tree, + NULL, &opts->squash_onto, + NULL, NULL)) + return error(_("writing fake root commit")); + opts->have_squash_onto = 1; + hex = oid_to_hex(&opts->squash_onto); + if (write_message(hex, strlen(hex), + rebase_path_squash_onto(), 0)) + return error(_("writing squash-onto")); + } + oidcpy(&oid, &opts->squash_onto); + } else { + /* Determine the length of the label */ + for (i = 0; i < len; i++) + if (isspace(name[i])) + len = i; + + strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name); + if (get_oid(ref_name.buf, &oid) && + get_oid(ref_name.buf + strlen("refs/rewritten/"), &oid)) { + error(_("could not read '%s'"), ref_name.buf); + rollback_lock_file(&lock); + strbuf_release(&ref_name); + return -1; + } } memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts)); |