Skip to content

Commit 01aedc9

Browse files
committed
Merge branch 'cc/cherry-pick-stdin'
* cc/cherry-pick-stdin: revert: do not rebuild argv on heap revert: accept arbitrary rev-list options t3508 (cherry-pick): futureproof against unmerged files
2 parents a76b208 + e0ef849 commit 01aedc9

File tree

4 files changed

+61
-25
lines changed

4 files changed

+61
-25
lines changed

Documentation/git-cherry-pick.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,13 @@ git cherry-pick --ff ..next::
113113
are in next but not HEAD to the current branch, creating a new
114114
commit for each new change.
115115

116+
git rev-list --reverse master \-- README | git cherry-pick -n --stdin::
117+
118+
Apply the changes introduced by all commits on the master
119+
branch that touched README to the working tree and index,
120+
so the result can be inspected and made into a single new
121+
commit if suitable.
122+
116123
Author
117124
------
118125
Written by Junio C Hamano <[email protected]>

builtin/revert.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,14 @@ static const char *strategy;
5050

5151
static char *get_encoding(const char *message);
5252

53+
static const char * const *revert_or_cherry_pick_usage(void)
54+
{
55+
return action == REVERT ? revert_usage : cherry_pick_usage;
56+
}
57+
5358
static void parse_args(int argc, const char **argv)
5459
{
55-
const char * const * usage_str =
56-
action == REVERT ? revert_usage : cherry_pick_usage;
60+
const char * const * usage_str = revert_or_cherry_pick_usage();
5761
int noop;
5862
struct option options[] = {
5963
OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"),
@@ -78,8 +82,10 @@ static void parse_args(int argc, const char **argv)
7882
die("program error");
7983
}
8084

81-
commit_argc = parse_options(argc, argv, NULL, options, usage_str, 0);
82-
if (commit_argc < 1)
85+
commit_argc = parse_options(argc, argv, NULL, options, usage_str,
86+
PARSE_OPT_KEEP_ARGV0 |
87+
PARSE_OPT_KEEP_UNKNOWN);
88+
if (commit_argc < 2)
8389
usage_with_options(usage_str, options);
8490

8591
commit_argv = argv;
@@ -525,27 +531,22 @@ static int do_pick_commit(void)
525531

526532
static void prepare_revs(struct rev_info *revs)
527533
{
528-
int argc = 0;
529-
int i;
530-
const char **argv = xmalloc((commit_argc + 4) * sizeof(*argv));
534+
int argc;
531535

532-
argv[argc++] = NULL;
533-
argv[argc++] = "--no-walk";
536+
init_revisions(revs, NULL);
537+
revs->no_walk = 1;
534538
if (action != REVERT)
535-
argv[argc++] = "--reverse";
536-
for (i = 0; i < commit_argc; i++)
537-
argv[argc++] = commit_argv[i];
538-
argv[argc++] = NULL;
539+
revs->reverse = 1;
540+
541+
argc = setup_revisions(commit_argc, commit_argv, revs, NULL);
542+
if (argc > 1)
543+
usage(*revert_or_cherry_pick_usage());
539544

540-
init_revisions(revs, NULL);
541-
setup_revisions(argc - 1, argv, revs, NULL);
542545
if (prepare_revision_walk(revs))
543546
die("revision walk setup failed");
544547

545548
if (!revs->commits)
546549
die("empty commit set passed");
547-
548-
free(argv);
549550
}
550551

551552
static int revert_or_cherry_pick(int argc, const char **argv)

t/t3501-revert-cherry-pick.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,24 @@ test_expect_success setup '
4141
git tag rename2
4242
'
4343

44+
test_expect_success 'cherry-pick --nonsense' '
45+
46+
pos=$(git rev-parse HEAD) &&
47+
git diff --exit-code HEAD &&
48+
test_must_fail git cherry-pick --nonsense 2>msg &&
49+
git diff --exit-code HEAD "$pos" &&
50+
grep '[Uu]sage:' msg
51+
'
52+
53+
test_expect_success 'revert --nonsense' '
54+
55+
pos=$(git rev-parse HEAD) &&
56+
git diff --exit-code HEAD &&
57+
test_must_fail git revert --nonsense 2>msg &&
58+
git diff --exit-code HEAD "$pos" &&
59+
grep '[Uu]sage:' msg
60+
'
61+
4462
test_expect_success 'cherry-pick after renaming branch' '
4563
4664
git checkout rename2 &&

t/t3508-cherry-pick-many-commits.sh

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ test_expect_success setup '
2323
'
2424

2525
test_expect_success 'cherry-pick first..fourth works' '
26-
git checkout master &&
26+
git checkout -f master &&
2727
git reset --hard first &&
2828
test_tick &&
2929
git cherry-pick first..fourth &&
@@ -33,7 +33,7 @@ test_expect_success 'cherry-pick first..fourth works' '
3333
'
3434

3535
test_expect_success 'cherry-pick --ff first..fourth works' '
36-
git checkout master &&
36+
git checkout -f master &&
3737
git reset --hard first &&
3838
test_tick &&
3939
git cherry-pick --ff first..fourth &&
@@ -43,7 +43,7 @@ test_expect_success 'cherry-pick --ff first..fourth works' '
4343
'
4444

4545
test_expect_success 'cherry-pick -n first..fourth works' '
46-
git checkout master &&
46+
git checkout -f master &&
4747
git reset --hard first &&
4848
test_tick &&
4949
git cherry-pick -n first..fourth &&
@@ -53,7 +53,7 @@ test_expect_success 'cherry-pick -n first..fourth works' '
5353
'
5454

5555
test_expect_success 'revert first..fourth works' '
56-
git checkout master &&
56+
git checkout -f master &&
5757
git reset --hard fourth &&
5858
test_tick &&
5959
git revert first..fourth &&
@@ -63,7 +63,7 @@ test_expect_success 'revert first..fourth works' '
6363
'
6464

6565
test_expect_success 'revert ^first fourth works' '
66-
git checkout master &&
66+
git checkout -f master &&
6767
git reset --hard fourth &&
6868
test_tick &&
6969
git revert ^first fourth &&
@@ -73,7 +73,7 @@ test_expect_success 'revert ^first fourth works' '
7373
'
7474

7575
test_expect_success 'revert fourth fourth~1 fourth~2 works' '
76-
git checkout master &&
76+
git checkout -f master &&
7777
git reset --hard fourth &&
7878
test_tick &&
7979
git revert fourth fourth~1 fourth~2 &&
@@ -82,8 +82,8 @@ test_expect_success 'revert fourth fourth~1 fourth~2 works' '
8282
git diff --quiet HEAD first
8383
'
8484

85-
test_expect_failure 'cherry-pick -3 fourth works' '
86-
git checkout master &&
85+
test_expect_success 'cherry-pick -3 fourth works' '
86+
git checkout -f master &&
8787
git reset --hard first &&
8888
test_tick &&
8989
git cherry-pick -3 fourth &&
@@ -92,4 +92,14 @@ test_expect_failure 'cherry-pick -3 fourth works' '
9292
test "$(git rev-parse --verify HEAD)" != "$(git rev-parse --verify fourth)"
9393
'
9494

95+
test_expect_success 'cherry-pick --stdin works' '
96+
git checkout -f master &&
97+
git reset --hard first &&
98+
test_tick &&
99+
git rev-list --reverse first..fourth | git cherry-pick --stdin &&
100+
git diff --quiet other &&
101+
git diff --quiet HEAD other &&
102+
test "$(git rev-parse --verify HEAD)" != "$(git rev-parse --verify fourth)"
103+
'
104+
95105
test_done

0 commit comments

Comments
 (0)