Skip to content

Commit 8d737a2

Browse files
committed
Introduce Repository#cherrypick_commit
This is like #cherrypick but we do it in-memory and return an index with the result.
1 parent 79f1a0d commit 8d737a2

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

ext/rugged/rugged_repo.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2530,6 +2530,61 @@ static VALUE rb_git_repo_cherrypick(int argc, VALUE *argv, VALUE self)
25302530
return Qnil;
25312531
}
25322532

2533+
/*
2534+
* call-seq:
2535+
* repo.cherrypick_commit(commit, our_commit, [mainline, options]) -> nil
2536+
*
2537+
* Cherry-pick the given commit on the given base in-memory and
2538+
* return an index with the result.
2539+
*
2540+
* `commit` can be either a string containing a commit id or a
2541+
* `Rugged::Commit` object.
2542+
*
2543+
* `our_commit` is the base commit, can be either a string containing
2544+
* a commit id or a `Rugged::Commit` object.
2545+
*
2546+
* `mainline` when cherry-picking a merge, this is the parent number
2547+
* (starting from 1) which should be considered the mainline.
2548+
*/
2549+
static VALUE rb_git_repo_cherrypick_commit(int argc, VALUE *argv, VALUE self)
2550+
{
2551+
VALUE rb_options, rb_commit, rb_our_commit, rb_mainline;
2552+
2553+
git_repository *repo;
2554+
git_commit *commit, *our_commit;
2555+
git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
2556+
git_index *index;
2557+
int error, mainline;
2558+
2559+
rb_scan_args(argc, argv, "21:", &rb_commit, &rb_our_commit, &rb_mainline, &rb_options);
2560+
2561+
if (TYPE(rb_commit) == T_STRING) {
2562+
rb_commit = rugged_object_rev_parse(self, rb_commit, 1);
2563+
}
2564+
if (TYPE(rb_our_commit) == T_STRING) {
2565+
rb_our_commit = rugged_object_rev_parse(self, rb_our_commit, 1);
2566+
}
2567+
2568+
if (!rb_obj_is_kind_of(rb_commit, rb_cRuggedCommit)) {
2569+
rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
2570+
}
2571+
if (!rb_obj_is_kind_of(rb_our_commit, rb_cRuggedCommit)) {
2572+
rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
2573+
}
2574+
2575+
Data_Get_Struct(self, git_repository, repo);
2576+
Data_Get_Struct(rb_commit, git_commit, commit);
2577+
Data_Get_Struct(rb_our_commit, git_commit, our_commit);
2578+
2579+
rugged_parse_merge_options(&opts, rb_options);
2580+
2581+
mainline = NIL_P(rb_mainline) ? 0 : FIX2UINT(rb_mainline);
2582+
error = git_cherrypick_commit(&index, repo, commit, our_commit, mainline, &opts);
2583+
rugged_exception_check(error);
2584+
2585+
return rugged_index_new(rb_cRuggedIndex, self, index);
2586+
}
2587+
25332588
void Init_rugged_repo(void)
25342589
{
25352590
id_call = rb_intern("call");
@@ -2603,6 +2658,7 @@ void Init_rugged_repo(void)
26032658
rb_define_method(rb_cRuggedRepo, "checkout_head", rb_git_checkout_head, -1);
26042659

26052660
rb_define_method(rb_cRuggedRepo, "cherrypick", rb_git_repo_cherrypick, -1);
2661+
rb_define_method(rb_cRuggedRepo, "cherrypick_commit", rb_git_repo_cherrypick_commit, -1);
26062662
rb_define_method(rb_cRuggedRepo, "fetch_attributes", rb_git_repo_attributes, -1);
26072663

26082664
rb_cRuggedOdbObject = rb_define_class_under(rb_mRugged, "OdbObject", rb_cObject);

test/cherrypick_test.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,35 @@ def test_merge_second_parent
7575
assert_equal "e5183bfd18e3a0a691fadde2f0d5610b73282d31", @repo.index["file2.txt"][:oid]
7676
assert_equal "409a1bec58bf35348e8b62b72bb9c1f45cf5a587", @repo.index["file3.txt"][:oid]
7777
end
78+
79+
def test_cherrypick_commit
80+
index = @repo.cherrypick_commit("cfc4f0999a8367568e049af4f72e452d40828a15",
81+
"d3d77487660ee3c0194ee01dc5eaf478782b1c7e")
82+
83+
assert_equal 0, index.conflicts.size
84+
assert_equal "38c05a857e831a7e759d83778bfc85d003e21c45", index["file1.txt"][:oid]
85+
assert_equal "a661b5dec1004e2c62654ded3762370c27cf266b", index["file2.txt"][:oid]
86+
assert_equal "df6b290e0bd6a89b01d69f66687e8abf385283ca", index["file3.txt"][:oid]
87+
88+
89+
assert_raises(Rugged::CherrypickError) do
90+
@repo.cherrypick_commit("abe4603bc7cd5b8167a267e0e2418fd2348f8cff",
91+
"cfc4f0999a8367568e049af4f72e452d40828a15")
92+
end
93+
94+
index = @repo.cherrypick_commit("abe4603bc7cd5b8167a267e0e2418fd2348f8cff",
95+
"cfc4f0999a8367568e049af4f72e452d40828a15", 1)
96+
97+
assert_equal 0, index.conflicts.size
98+
assert_equal "f90f9dcbdac2cce5cc166346160e19cb693ef4e8", index["file1.txt"][:oid]
99+
assert_equal "563f6473a3858f99b80e5f93c660512ed38e1e6f", index["file2.txt"][:oid]
100+
assert_equal "e233b9ed408a95e9d4b65fec7fc34943a556deb2", index["file3.txt"][:oid]
101+
102+
index = @repo.cherrypick_commit("abe4603bc7cd5b8167a267e0e2418fd2348f8cff",
103+
"cfc4f0999a8367568e049af4f72e452d40828a15", 2)
104+
105+
assert_equal "487434cace79238a7091e2220611d4f20a765690", index["file1.txt"][:oid]
106+
assert_equal "e5183bfd18e3a0a691fadde2f0d5610b73282d31", index["file2.txt"][:oid]
107+
assert_equal "409a1bec58bf35348e8b62b72bb9c1f45cf5a587", index["file3.txt"][:oid]
108+
end
78109
end

0 commit comments

Comments
 (0)