summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 73e7b2e)
raw | patch | inline | side by side (parent: 73e7b2e)
author | Jonathan Nieder <jrnieder@gmail.com> | |
Sat, 11 Dec 2010 00:51:44 +0000 (18:51 -0600) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Tue, 28 Dec 2010 19:27:56 +0000 (11:27 -0800) |
For example, this would allow cherry-picking or reverting patches from
a piece of history with a different end-of-line style, like so:
$ git revert -Xrenormalize old-problematic-commit
Currently that is possible with manual use of merge-recursive but the
cherry-pick/revert porcelain does not expose the functionality.
While at it, document the existing support for --strategy.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
a piece of history with a different end-of-line style, like so:
$ git revert -Xrenormalize old-problematic-commit
Currently that is possible with manual use of merge-recursive but the
cherry-pick/revert porcelain does not expose the functionality.
While at it, document the existing support for --strategy.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
index 73008705ebe304c8d2a2d089e9328be369c50fc6..749d68a72bf720d82260fe175be0824f7ad069eb 100644 (file)
cherry-pick'ed commit, then a fast forward to this commit will
be performed.
+--strategy=<strategy>::
+ Use the given merge strategy. Should only be used once.
+ See the MERGE STRATEGIES section in linkgit:git-merge[1]
+ for details.
+
+-X<option>::
+--strategy-option=<option>::
+ Pass the merge strategy-specific option through to the
+ merge strategy. See linkgit:git-merge[1] for details.
+
EXAMPLES
--------
git cherry-pick master::
so the result can be inspected and made into a single new
commit if suitable.
+The following sequence attempts to backport a patch, bails out because
+the code the patch applies to has changed too much, and then tries
+again, this time exercising more care about matching up context lines.
+
+------------
+$ git cherry-pick topic^ <1>
+$ git diff <2>
+$ git reset --merge ORIG_HEAD <3>
+$ git cherry-pick -Xpatience topic^ <4>
+------------
+<1> apply the change that would be shown by `git show topic^`.
+In this example, the patch does not apply cleanly, so
+information about the conflict is written to the index and
+working tree and no new commit results.
+<2> summarize changes to be reconciled
+<3> cancel the cherry-pick. In other words, return to the
+pre-cherry-pick state, preserving any local modifications you had in
+the working tree.
+<4> try to apply the change introduced by `topic^` again,
+spending extra time to avoid mistakes based on incorrectly matching
+context lines.
+
Author
------
Written by Junio C Hamano <gitster@pobox.com>
index 752fc88e768e4b8e1afddad4bdd7833cf20978c7..45be851750c2ce81500765f6dfbd23578c68abda 100644 (file)
--signoff::
Add Signed-off-by line at the end of the commit message.
+--strategy=<strategy>::
+ Use the given merge strategy. Should only be used once.
+ See the MERGE STRATEGIES section in linkgit:git-merge[1]
+ for details.
+
+-X<option>::
+--strategy-option=<option>::
+ Pass the merge strategy-specific option through to the
+ merge strategy. See linkgit:git-merge[1] for details.
+
EXAMPLES
--------
git revert HEAD~3::
diff --git a/builtin/merge.c b/builtin/merge.c
index 42fff387e69d9b5412e8e776aed3272b78ebe758..9403747b6afeb89a9079e7203f5a027014411495 100644 (file)
--- a/builtin/merge.c
+++ b/builtin/merge.c
die("git write-tree failed to write a tree");
}
-int try_merge_command(const char *strategy, struct commit_list *common,
+int try_merge_command(const char *strategy, size_t xopts_nr,
+ const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes)
{
const char **args;
rollback_lock_file(lock);
return clean ? 0 : 1;
} else {
- return try_merge_command(strategy, common, head_arg, remoteheads);
+ return try_merge_command(strategy, xopts_nr, xopts,
+ common, head_arg, remoteheads);
}
}
diff --git a/builtin/revert.c b/builtin/revert.c
index bb6e9e83b756b47dae449064ca7762fe3558fc0e..dc1b702edc6b4bd95ebf41c12bf1da6fe9d6850d 100644 (file)
--- a/builtin/revert.c
+++ b/builtin/revert.c
static int allow_rerere_auto;
static const char *me;
+
+/* Merge strategy. */
static const char *strategy;
+static const char **xopts;
+static size_t xopts_nr, xopts_alloc;
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
return action == REVERT ? revert_usage : cherry_pick_usage;
}
+static int option_parse_x(const struct option *opt,
+ const char *arg, int unset)
+{
+ if (unset)
+ return 0;
+
+ ALLOC_GROW(xopts, xopts_nr + 1, xopts_alloc);
+ xopts[xopts_nr++] = xstrdup(arg);
+ return 0;
+}
+
static void parse_args(int argc, const char **argv)
{
const char * const * usage_str = revert_or_cherry_pick_usage();
OPT_INTEGER('m', "mainline", &mainline, "parent number"),
OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
OPT_STRING(0, "strategy", &strategy, "strategy", "merge strategy"),
+ OPT_CALLBACK('X', "strategy-option", &xopts, "option",
+ "option for merge strategy", option_parse_x),
OPT_END(),
OPT_END(),
OPT_END(),
struct merge_options o;
struct tree *result, *next_tree, *base_tree, *head_tree;
int clean, index_fd;
+ const char **xopt;
static struct lock_file index_lock;
index_fd = hold_locked_index(&index_lock, 1);
read_cache();
- /*
- * NEEDSWORK: cherry-picking between branches with
- * different end-of-line normalization is a pain;
- * plumb in an option to set o.renormalize?
- * (or better: arbitrary -X options)
- */
init_merge_options(&o);
o.ancestor = base ? base_label : "(empty tree)";
o.branch1 = "HEAD";
next_tree = next ? next->tree : empty_tree();
base_tree = base ? base->tree : empty_tree();
+ for (xopt = xopts; xopt != xopts + xopts_nr; xopt++)
+ parse_merge_opt(&o, *xopt);
+
clean = merge_trees(&o,
head_tree,
next_tree, base_tree, &result);
commit_list_insert(base, &common);
commit_list_insert(next, &remotes);
- res = try_merge_command(strategy, common,
+ res = try_merge_command(strategy, xopts_nr, xopts, common,
sha1_to_hex(head), remotes);
free_commit_list(common);
free_commit_list(remotes);
index 60a05a8b978345224c0313edb8060f5a7c2ccb54..6bf155cbdb61498bdaf84712a2dea6fb05361ce2 100755 (executable)
cd_to_toplevel
no_commit=
+xopt=
while case "$#" in 0) break ;; esac
do
case "$1" in
-x|--i-really-want-to-expose-my-private-commit-object-name)
replay=
;;
+ -X?*)
+ xopt="$xopt$(git rev-parse --sq-quote "--${1#-X}")"
+ ;;
+ --strategy-option=*)
+ xopt="$xopt$(git rev-parse --sq-quote "--${1#--strategy-option=}")"
+ ;;
+ -X|--strategy-option)
+ shift
+ xopt="$xopt$(git rev-parse --sq-quote "--$1")"
+ ;;
-*)
usage
;;
# and $prev on top of us (when reverting), or the change between
# $prev and $commit on top of us (when cherry-picking or replaying).
-git-merge-recursive $base -- $head $next &&
+eval "git merge-recursive $xopt $base -- $head $next" &&
result=$(git-write-tree 2>/dev/null) || {
mv -f .msg "$GIT_DIR/MERGE_MSG"
{
diff --git a/merge-recursive.h b/merge-recursive.h
index c8135b0ec70cc2eb92e5a6fd9353a134fda6b7bf..981ed6ac94b5ed73f15a3b0dca723586374ca0b8 100644 (file)
--- a/merge-recursive.h
+++ b/merge-recursive.h
int parse_merge_opt(struct merge_options *out, const char *s);
/* builtin/merge.c */
-int try_merge_command(const char *strategy, struct commit_list *common, const char *head_arg, struct commit_list *remotes);
+int try_merge_command(const char *strategy, size_t xopts_nr,
+ const char **xopts, struct commit_list *common,
+ const char *head_arg, struct commit_list *remotes);
#endif
index 2293797553d49c5221da10ca17f97eeba1f5d29d..796f616abf17f40e59212b7abb80867f851baa55 100755 (executable)
git merge-recursive --ignore-space-change HEAD^ -- HEAD remote
'
+test_expect_success 'naive cherry-pick fails' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git cherry-pick --no-commit remote &&
+ git read-tree --reset -u HEAD &&
+ test_must_fail git cherry-pick remote &&
+ test_must_fail git update-index --refresh &&
+ grep "<<<<<<" text.txt
+'
+
+test_expect_success '-Xignore-space-change makes cherry-pick succeed' '
+ git read-tree --reset -u HEAD &&
+ git cherry-pick --no-commit -Xignore-space-change remote
+'
+
test_expect_success '--ignore-space-change: our w/s-only change wins' '
q_to_cr <<-\EOF >expected &&
justice and holiness and is the nurse of his age and theQ