Skip to content

Commit b3025e3

Browse files
committed
Add git-cherry-pick recipes
Add the way that worked for me. Not sure if it is idiomatic. When doing the convenience-mode cherry-pick, the repo remains in cherry-picking mode afterwards. I've already added an issue for this.
1 parent f923e20 commit b3025e3

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

docs/recipes.rst

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Main porcelain commands
1717
.. toctree::
1818
:maxdepth: 1
1919

20+
git-cherry-pick (Apply the changes introduced by some existing commits.) <recipes/git-cherry-pick>
2021
git-init (Create an empty git repository or reinitialize an existing one.) <recipes/git-init>
2122
git-log (Show commit logs.) <recipes/git-log>
2223
git-show (Show various types of objects.) <recipes/git-show>

docs/recipes/git-cherry-pick.rst

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
**********************************************************************
2+
git-cherry-pick
3+
**********************************************************************
4+
5+
The convenient way to cherry-pick a commit is to use
6+
:py:meth:`.Repository.cherrypick()`. It is limited to cherry-picking with a
7+
working copy and on-disk index.
8+
9+
.. code-block:: bash
10+
11+
$> cd /path/to/repo
12+
$> git checkout basket
13+
$> git cherry-pick 9e044d03c
14+
15+
.. code-block:: python
16+
17+
repo = pygit2.Repository('/path/to/repo')
18+
repo.checkout('basket')
19+
20+
cherry_id = pygit2.Oid('9e044d03c')
21+
repo.cherrypick(cherry_id)
22+
23+
if repo.index.conflicts is None:
24+
tree_id = repo.index.write_tree()
25+
26+
cherry = repo.get(cherry_id)
27+
committer = pygit2.Signature('Archimedes', '[email protected]')
28+
29+
repo.create_commit(basket.name, cherry.author, committer,
30+
cherry.message, tree_id, [basket.target])
31+
del basket # outdated, prevent from accidentally using it
32+
33+
34+
----------------------------------------------------------------------
35+
Cherry-picking a commit without a working copy
36+
----------------------------------------------------------------------
37+
38+
This way of cherry-picking gives you more control over the process and works
39+
on bare repositories as well as repositories with a working copy.
40+
:py:meth:`~.Repository.merge_trees()` can also be used for other tasks, for
41+
example `three-argument rebases`_.
42+
43+
.. _`three-argument rebases`: https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html
44+
45+
.. code-block:: python
46+
47+
repo = pygit2.Repository('/path/to/repo')
48+
49+
cherry = repo.revparse_single('9e044d03c')
50+
basket = repo.lookup_branch('basket')
51+
52+
base = repo.merge_base(cherry.oid, basket.target)
53+
base_tree = cherry.parents[0].tree
54+
55+
index = repo.merge_trees(base_tree, basket, cherry)
56+
tree_id = index.write_tree(repo)
57+
58+
author = cherry.author
59+
committer = pygit2.Signature('Archimedes', '[email protected]')
60+
61+
repo.create_commit(basket.name, author, committer, cherry.message,
62+
tree_id, [basket.target])
63+
del None # outdated, prevent from accidentally using it
64+
65+
----------------------------------------------------------------------
66+
References
67+
----------------------------------------------------------------------
68+
69+
- git-cherry-pick_.
70+
71+
.. _git-cherry-pick: https://www.kernel.org/pub/software/scm/git/docs/git-cherry-pick.html

0 commit comments

Comments
 (0)