aboutsummaryrefslogtreecommitdiff
path: root/builtin-revert.c
diff options
context:
space:
mode:
authorJohannes Schindelin <Johannes.Schindelin@gmx.de>2008-07-04 16:19:52 +0100
committerJunio C Hamano <gitster@pobox.com>2008-07-07 13:23:42 -0700
commitf95ebf74296077d5fdccaa2668edc527841db521 (patch)
treeb3744edcbc4ee2fdad99c93ad2f161ebd7a38ed4 /builtin-revert.c
parent44701c67fd1d5d771b440c8646b7b268d4f1402d (diff)
downloadgit-f95ebf74296077d5fdccaa2668edc527841db521.tar.gz
git-f95ebf74296077d5fdccaa2668edc527841db521.tar.xz
Allow cherry-picking root commits
A root commit couldn't be cherry-picked. But its semantics can be defined as simply merging two trees by overlaying disjoint parts and merging overlapping files without any common ancestor. You should be able to rebase originally independent branches on top of another branch by using this. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-revert.c')
-rw-r--r--builtin-revert.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/builtin-revert.c b/builtin-revert.c
index 0270f9b85..f3d452418 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -206,6 +206,7 @@ static int merge_recursive(const char *base_sha1,
{
char buffer[256];
const char *argv[6];
+ int i = 0;
sprintf(buffer, "GITHEAD_%s", head_sha1);
setenv(buffer, head_name, 1);
@@ -218,12 +219,13 @@ static int merge_recursive(const char *base_sha1,
* and $prev on top of us (when reverting), or the change between
* $prev and $commit on top of us (when cherry-picking or replaying).
*/
- argv[0] = "merge-recursive";
- argv[1] = base_sha1;
- argv[2] = "--";
- argv[3] = head_sha1;
- argv[4] = next_sha1;
- argv[5] = NULL;
+ argv[i++] = "merge-recursive";
+ if (base_sha1)
+ argv[i++] = base_sha1;
+ argv[i++] = "--";
+ argv[i++] = head_sha1;
+ argv[i++] = next_sha1;
+ argv[i++] = NULL;
return run_command_v_opt(argv, RUN_COMMAND_NO_STDIN | RUN_GIT_CMD);
}
@@ -297,9 +299,12 @@ static int revert_or_cherry_pick(int argc, const char **argv)
discard_cache();
}
- if (!commit->parents)
- die ("Cannot %s a root commit", me);
- if (commit->parents->next) {
+ if (!commit->parents) {
+ if (action == REVERT)
+ die ("Cannot revert a root commit");
+ parent = NULL;
+ }
+ else if (commit->parents->next) {
/* Reverting or cherry-picking a merge commit */
int cnt;
struct commit_list *p;
@@ -368,7 +373,8 @@ static int revert_or_cherry_pick(int argc, const char **argv)
}
}
- if (merge_recursive(sha1_to_hex(base->object.sha1),
+ if (merge_recursive(base == NULL ?
+ NULL : sha1_to_hex(base->object.sha1),
sha1_to_hex(head), "HEAD",
sha1_to_hex(next->object.sha1), oneline) ||
write_cache_as_tree(head, 0, NULL)) {