125
static GIT_PATH_FUNC(rebase_path_rewritten_pending,
126
"rebase-merge/rewritten-pending")
127
128
+/*
129
+ * The path of the file containig the OID of the "squash onto" commit, i.e.
130
+ * the dummy commit used for `reset [new root]`.
131
+ */
132
+static GIT_PATH_FUNC(rebase_path_squash_onto, "rebase-merge/squash-onto")
133
+
134
/*
135
* The path of the file listing refs that need to be deleted after the rebase
136
* finishes. This is used by the `label` command to record the need for cleanup.
476
transaction = ref_transaction_begin(&err);
477
if (!transaction ||
478
ref_transaction_update(transaction, "HEAD",
473
- to, unborn ? &null_oid : from,
479
+ to, unborn && !is_rebase_i(opts) ?
480
+ &null_oid : from,
481
0, sb.buf, &err) ||
482
ref_transaction_commit(transaction, &err)) {
483
ref_transaction_free(transaction);
699
return NULL;
700
}
701
702
+/* Read author-script and return an ident line (author <email> timestamp) */
703
+static const char *read_author_ident(struct strbuf *buf)
704
+{
705
+ const char *keys[] = {
706
+ "GIT_AUTHOR_NAME=", "GIT_AUTHOR_EMAIL=", "GIT_AUTHOR_DATE="
707
+ };
708
+ char *in, *out, *eol;
709
+ int i = 0, len;
710
+
711
+ if (strbuf_read_file(buf, rebase_path_author_script(), 256) <= 0)
712
+ return NULL;
713
+
714
+ /* dequote values and construct ident line in-place */
715
+ for (in = out = buf->buf; i < 3 && in - buf->buf < buf->len; i++) {
716
+ if (!skip_prefix(in, keys[i], (const char **)&in)) {
717
+ warning("could not parse '%s' (looking for '%s'",
718
+ rebase_path_author_script(), keys[i]);
719
+ return NULL;
720
+ }
721
+
722
+ eol = strchrnul(in, '\n');
723
+ *eol = '\0';
724
+ sq_dequote(in);
725
+ len = strlen(in);
726
+
727
+ if (i > 0) /* separate values by spaces */
728
+ *(out++) = ' ';
729
+ if (i == 1) /* email needs to be surrounded by <...> */
730
+ *(out++) = '<';
731
+ memmove(out, in, len);
732
+ out += len;
733
+ if (i == 1) /* email needs to be surrounded by <...> */
734
+ *(out++) = '>';
735
+ in = eol + 1;
736
+ }
737
+
738
+ if (i < 3) {
739
+ warning("could not parse '%s' (looking for '%s')",
740
+ rebase_path_author_script(), keys[i]);
741
+ return NULL;
742
+ }
743
+
744
+ buf->len = out - buf->buf;
745
+ return buf->buf;
746
+}
747
+
748
static const char staged_changes_advice[] =
749
N_("you have staged changes in your working tree\n"
750
"If these changes are meant to be squashed into the previous commit, run:\n"
764
#define AMEND_MSG (1<<2)
765
#define CLEANUP_MSG (1<<3)
766
#define VERIFY_MSG (1<<4)
767
+#define CREATE_ROOT_COMMIT (1<<5)
768
769
/*
770
* If we are cherry-pick, and if the merge did not result in
784
struct child_process cmd = CHILD_PROCESS_INIT;
785
const char *value;
786
787
+ if (flags & CREATE_ROOT_COMMIT) {
788
+ struct strbuf msg = STRBUF_INIT, script = STRBUF_INIT;
789
+ const char *author = is_rebase_i(opts) ?
790
+ read_author_ident(&script) : NULL;
791
+ struct object_id root_commit, *cache_tree_oid;
792
+ int res = 0;
793
+
794
+ if (!defmsg)
795
+ BUG("root commit without message");
796
+
797
+ if (!(cache_tree_oid = get_cache_tree_oid()))
798
+ res = -1;
799
+
800
+ if (!res)
801
+ res = strbuf_read_file(&msg, defmsg, 0);
802
+
803
+ if (res <= 0)
804
+ res = error_errno(_("could not read '%s'"), defmsg);
805
+ else
806
+ res = commit_tree(msg.buf, msg.len, cache_tree_oid,
807
+ NULL, &root_commit, author,
808
+ opts->gpg_sign);
809
+
810
+ strbuf_release(&msg);
811
+ strbuf_release(&script);
812
+ if (!res) {
813
+ update_ref(NULL, "CHERRY_PICK_HEAD", &root_commit, NULL,
814
+ REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR);
815
+ res = update_ref(NULL, "HEAD", &root_commit, NULL, 0,
816
+ UPDATE_REFS_MSG_ON_ERR);
817
+ }
818
+ return res < 0 ? error(_("writing root commit")) : 0;
819
+ }
820
+
821
cmd.git_cmd = 1;
822
823
if (is_rebase_i(opts)) {
1304
{
1305
int res = 1;
1306
1219
- if (!(flags & EDIT_MSG) && !(flags & VERIFY_MSG)) {
1307
+ if (!(flags & EDIT_MSG) && !(flags & VERIFY_MSG) &&
1308
+ !(flags & CREATE_ROOT_COMMIT)) {
1309
struct object_id oid;
1310
struct strbuf sb = STRBUF_INIT;
1311
1458
return command == TODO_FIXUP || command == TODO_SQUASH;
1459
}
1460
1461
+/* Does this command create a (non-merge) commit? */
1462
+static int is_pick_or_similar(enum todo_command command)
1463
+{
1464
+ switch (command) {
1465
+ case TODO_PICK:
1466
+ case TODO_REVERT:
1467
+ case TODO_EDIT:
1468
+ case TODO_REWORD:
1469
+ case TODO_FIXUP:
1470
+ case TODO_SQUASH:
1471
+ return 1;
1472
+ default:
1473
+ return 0;
1474
+ }
1475
+}
1476
+
1477
static int update_squash_messages(enum todo_command command,
1478
struct commit *commit, struct replay_opts *opts)
1479
{
1628
return error(_("your index file is unmerged."));
1629
} else {
1630
unborn = get_oid("HEAD", &head);
1526
- if (unborn)
1631
+ /* Do we want to generate a root commit? */
1632
+ if (is_pick_or_similar(command) && opts->have_squash_onto &&
1633
+ !oidcmp(&head, &opts->squash_onto)) {
1634
+ if (is_fixup(command))
1635
+ return error(_("cannot fixup root commit"));
1636
+ flags |= CREATE_ROOT_COMMIT;
1637
+ unborn = 1;
1638
+ } else if (unborn)
1639
oidcpy(&head, the_hash_algo->empty_tree);
1640
if (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : "HEAD",
1641
NULL, 0))
2248
read_strategy_opts(opts, &buf);
2249
strbuf_release(&buf);
2250
2251
+ if (read_oneliner(&buf, rebase_path_squash_onto(), 0)) {
2252
+ if (get_oid_hex(buf.buf, &opts->squash_onto) < 0)
2253
+ return error(_("unusable squash-onto"));
2254
+ opts->have_squash_onto = 1;
2255
+ }
2256
+
2257
return 0;
2258
}
2259