<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cherry-Pick on Grayson blog :smile:</title><link>https://blog.grayson.work/tags/cherry-pick/</link><description>Recent content in Cherry-Pick on Grayson blog :smile:</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>blog.grayson.work</copyright><lastBuildDate>Fri, 26 Jun 2026 17:30:00 +0800</lastBuildDate><atom:link href="https://blog.grayson.work/tags/cherry-pick/index.xml" rel="self" type="application/rss+xml"/><item><title>git cherry-pick -m 1 Explained: How to Pick a Merge Commit</title><link>https://blog.grayson.work/p/git-cherry-pick-merge-commit/</link><pubDate>Fri, 26 Jun 2026 17:30:00 +0800</pubDate><guid>https://blog.grayson.work/p/git-cherry-pick-merge-commit/</guid><description>&lt;h2 id="why-you-need--m-1"&gt;Why You Need &lt;code&gt;-m 1&lt;/code&gt;
&lt;/h2&gt;&lt;p&gt;Cherry-picking a merge commit directly fails: it has two parents, and Git doesn&amp;rsquo;t know which one to diff against. &lt;code&gt;-m 1&lt;/code&gt; tells Git to &amp;ldquo;use the first parent (usually the mainline) as the base.&amp;rdquo;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git cherry-pick 8865ad0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;error: commit 8865ad060c1c64fbc3c0196e12302b1d96e8bf30 is a merge but no -m option was given.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;fatal: cherry-pick failed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The most common scenario: the &lt;code&gt;feature&lt;/code&gt; branch has already landed in &lt;code&gt;main&lt;/code&gt; through a merge commit, and now you need the same feature on a maintained &lt;code&gt;release&lt;/code&gt; branch, without dragging along the other commits on &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You could cherry-pick each commit from &lt;code&gt;feature&lt;/code&gt; one by one, but that gets tedious as the commit count grows, and any conflicts you resolved by hand during the merge won&amp;rsquo;t come along. Picking the merge commit itself gets you the feature&amp;rsquo;s complete change in one command.&lt;/p&gt;
&lt;h2 id="core-concept-a-merge-commit-has-two-parents"&gt;Core Concept: A Merge Commit Has Two Parents
&lt;/h2&gt;&lt;p&gt;A regular commit has one parent; a merge commit has two. &lt;strong&gt;Parent 1&lt;/strong&gt; is the branch you were on when you ran the merge, and &lt;strong&gt;parent 2&lt;/strong&gt; is the branch that was merged in.&lt;/p&gt;
&lt;p&gt;When you run &lt;code&gt;git merge feature&lt;/code&gt; on &lt;code&gt;main&lt;/code&gt;, the tip of &lt;code&gt;main&lt;/code&gt; at that moment becomes parent 1 and the tip of &lt;code&gt;feature&lt;/code&gt; becomes parent 2. Merging a PR on GitHub or GitLab with &amp;ldquo;Create a merge commit&amp;rdquo; uses the same order: the target branch comes first.&lt;/p&gt;
&lt;figure class="cpm-fig"&gt;
&lt;style&gt;
.cpm-fig{margin:1.5em 0;text-align:center}
.cpm-fig svg{width:100%;max-width:640px;height:auto;--cpm-p1:#2563eb;--cpm-p2:#b45309;--cpm-ink:var(--card-text-color-main);--cpm-muted:var(--card-text-color-secondary);--cpm-bg:var(--card-background)}
:root[data-scheme="dark"] .cpm-fig svg{--cpm-p1:#60a5fa;--cpm-p2:#fbbf24}
.cpm-fig figcaption{margin-top:.6em;font-size:.9em;color:var(--card-text-color-secondary)}
.cpm-node{fill:var(--cpm-bg);stroke:var(--cpm-ink);stroke-width:2}
.cpm-edge{fill:none;stroke:var(--cpm-muted);stroke-width:2}
.cpm-panel{fill:none;stroke:var(--cpm-muted);stroke-opacity:.4}
.cpm-box{fill:var(--cpm-bg);stroke:var(--cpm-ink);stroke-width:1.5}
.cpm-t,.cpm-h,.cpm-f,.cpm-m,.cpm-r,.cpm-lbl{text-anchor:middle;dominant-baseline:central}
.cpm-t{fill:var(--cpm-ink);font-size:16px;font-weight:700}
.cpm-s{font-size:12px}
.cpm-h{font-size:15px;font-weight:700}
.cpm-f{fill:var(--cpm-ink);font-size:13px;font-family:var(--code-font-family,ui-monospace,monospace)}
.cpm-lbl{fill:var(--cpm-muted);font-size:13px;font-family:var(--code-font-family,ui-monospace,monospace)}
.cpm-m{fill:var(--cpm-muted);font-size:13px}
.cpm-r{font-size:16px;font-weight:700;font-family:var(--code-font-family,ui-monospace,monospace)}
.cpm-ah{fill:var(--cpm-muted)}
.cpm-e1,.cpm-b1{stroke:var(--cpm-p1);stroke-width:2.5}
.cpm-e2,.cpm-b2{stroke:var(--cpm-p2);stroke-width:2.5}
.cpm-c1{fill:var(--cpm-p1)}
.cpm-c2{fill:var(--cpm-p2)}
.cpm-bold{font-weight:700}
&lt;/style&gt;
&lt;svg viewBox="0 0 640 240" role="img" aria-labelledby="cpm-g1-t" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;title id="cpm-g1-t"&gt;Merge commit M has two parents: C is parent 1, B is parent 2&lt;/title&gt;
&lt;defs&gt;
&lt;marker id="cpm-g1-a" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="10" markerHeight="10" markerUnits="userSpaceOnUse" orient="auto"&gt;&lt;path class="cpm-ah" d="M0,0 L10,5 L0,10 z"/&gt;&lt;/marker&gt;
&lt;marker id="cpm-g1-a1" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="11" markerHeight="11" markerUnits="userSpaceOnUse" orient="auto"&gt;&lt;path class="cpm-c1" d="M0,0 L10,5 L0,10 z"/&gt;&lt;/marker&gt;
&lt;marker id="cpm-g1-a2" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="11" markerHeight="11" markerUnits="userSpaceOnUse" orient="auto"&gt;&lt;path class="cpm-c2" d="M0,0 L10,5 L0,10 z"/&gt;&lt;/marker&gt;
&lt;/defs&gt;
&lt;line class="cpm-edge" x1="77" y1="155" x2="202" y2="80" marker-end="url(#cpm-g1-a)"/&gt;
&lt;line class="cpm-edge" x1="240" y1="70" x2="339" y2="70" marker-end="url(#cpm-g1-a)"/&gt;
&lt;line class="cpm-edge" x1="80" y1="165" x2="269" y2="165" marker-end="url(#cpm-g1-a)"/&gt;
&lt;line class="cpm-edge cpm-e1" x1="310" y1="165" x2="499" y2="165" marker-end="url(#cpm-g1-a1)"/&gt;
&lt;line class="cpm-edge cpm-e2" x1="377" y1="80" x2="502" y2="154" marker-end="url(#cpm-g1-a2)"/&gt;
&lt;circle class="cpm-node" cx="60" cy="165" r="20"/&gt;&lt;text class="cpm-t cpm-s" x="60" y="165"&gt;init&lt;/text&gt;
&lt;circle class="cpm-node" cx="220" cy="70" r="20"/&gt;&lt;text class="cpm-t" x="220" y="70"&gt;A&lt;/text&gt;
&lt;circle class="cpm-node cpm-b2" cx="360" cy="70" r="20"/&gt;&lt;text class="cpm-t" x="360" y="70"&gt;B&lt;/text&gt;
&lt;circle class="cpm-node cpm-b1" cx="290" cy="165" r="20"/&gt;&lt;text class="cpm-t" x="290" y="165"&gt;C&lt;/text&gt;
&lt;circle class="cpm-node" cx="520" cy="165" r="22" style="stroke-width:3"/&gt;&lt;text class="cpm-t" x="520" y="165"&gt;M&lt;/text&gt;
&lt;text class="cpm-h cpm-c1" x="404" y="150"&gt;parent 1&lt;/text&gt;
&lt;text class="cpm-h cpm-c2" x="478" y="100"&gt;parent 2&lt;/text&gt;
&lt;text class="cpm-lbl" x="60" y="203"&gt;release&lt;/text&gt;
&lt;text class="cpm-lbl" x="360" y="36"&gt;feature&lt;/text&gt;
&lt;text class="cpm-lbl" x="572" y="165"&gt;main&lt;/text&gt;
&lt;text class="cpm-m" x="600" y="226"&gt;time →&lt;/text&gt;
&lt;/svg&gt;
&lt;figcaption&gt;Arrows follow the direction of time: two colored arrows lead into M, one from C (parent 1) and one from B (parent 2).&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To confirm the order, look at the &lt;code&gt;Merge:&lt;/code&gt; line in the output of &lt;code&gt;git log -1 &amp;lt;sha&amp;gt;&lt;/code&gt;. The first hash listed is parent 1:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git log -1 8865ad0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;commit 8865ad060c1c64fbc3c0196e12302b1d96e8bf30
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Merge: 06233b4 d9b8793
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Author: Demo &amp;lt;demo@example.com&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Date: Fri Jun 26 17:56:50 2026 +0800
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; M: merge feature
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;You can also print each parent with &lt;code&gt;git rev-parse &amp;lt;sha&amp;gt;^1 &amp;lt;sha&amp;gt;^2&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git rev-parse 8865ad0^1 8865ad0^2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;06233b41967aea22699e607028a268615027526c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;d9b87938de6bd17532f3156c05e7cfd0b475a787
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="what--m-1-and--m-2-actually-compute"&gt;What &lt;code&gt;-m 1&lt;/code&gt; and &lt;code&gt;-m 2&lt;/code&gt; Actually Compute
&lt;/h2&gt;&lt;p&gt;At its core, cherry-pick applies &amp;ldquo;the diff between a commit and its parent&amp;rdquo; to the current branch. &lt;code&gt;-m&lt;/code&gt; (long form &lt;code&gt;--mainline&lt;/code&gt;) just picks one of the two parents as the base. Whichever parent you pick, you take the changes from the other side.&lt;/p&gt;
&lt;figure class="cpm-fig"&gt;
&lt;svg viewBox="0 0 640 290" role="img" aria-labelledby="cpm-g2-t" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;title id="cpm-g2-t"&gt;-m 1 diffs C against M and gets login.txt; -m 2 diffs B against M and gets README.md&lt;/title&gt;
&lt;defs&gt;
&lt;marker id="cpm-g2-a" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="10" markerHeight="10" markerUnits="userSpaceOnUse" orient="auto"&gt;&lt;path class="cpm-ah" d="M0,0 L10,5 L0,10 z"/&gt;&lt;/marker&gt;
&lt;/defs&gt;
&lt;rect class="cpm-panel" x="6" y="6" width="306" height="278" rx="10"/&gt;
&lt;text class="cpm-h cpm-c1" x="159" y="34"&gt;-m 1: base is parent 1 (C)&lt;/text&gt;
&lt;rect class="cpm-box cpm-b1" x="26" y="58" width="112" height="112" rx="8"/&gt;
&lt;text class="cpm-t" x="82" y="80"&gt;C&lt;/text&gt;
&lt;text class="cpm-f" x="82" y="110"&gt;app.txt&lt;/text&gt;
&lt;text class="cpm-f" x="82" y="132"&gt;README.md&lt;/text&gt;
&lt;text class="cpm-m" x="159" y="98"&gt;diff&lt;/text&gt;
&lt;line class="cpm-edge" x1="142" y1="114" x2="176" y2="114" marker-end="url(#cpm-g2-a)"/&gt;
&lt;rect class="cpm-box" x="180" y="58" width="112" height="112" rx="8"/&gt;
&lt;text class="cpm-t" x="236" y="80"&gt;M&lt;/text&gt;
&lt;text class="cpm-f" x="236" y="110"&gt;app.txt&lt;/text&gt;
&lt;text class="cpm-f" x="236" y="132"&gt;README.md&lt;/text&gt;
&lt;text class="cpm-f cpm-c1 cpm-bold" x="236" y="154"&gt;+ login.txt&lt;/text&gt;
&lt;text class="cpm-m" x="159" y="204"&gt;lands on the current branch&lt;/text&gt;
&lt;text class="cpm-r cpm-c1" x="159" y="230"&gt;+ login.txt&lt;/text&gt;
&lt;text class="cpm-m" x="159" y="256"&gt;feature's changes (A, B)&lt;/text&gt;
&lt;rect class="cpm-panel" x="328" y="6" width="306" height="278" rx="10"/&gt;
&lt;text class="cpm-h cpm-c2" x="481" y="34"&gt;-m 2: base is parent 2 (B)&lt;/text&gt;
&lt;rect class="cpm-box cpm-b2" x="348" y="58" width="112" height="112" rx="8"/&gt;
&lt;text class="cpm-t" x="404" y="80"&gt;B&lt;/text&gt;
&lt;text class="cpm-f" x="404" y="110"&gt;app.txt&lt;/text&gt;
&lt;text class="cpm-f" x="404" y="132"&gt;login.txt&lt;/text&gt;
&lt;text class="cpm-m" x="481" y="98"&gt;diff&lt;/text&gt;
&lt;line class="cpm-edge" x1="464" y1="114" x2="498" y2="114" marker-end="url(#cpm-g2-a)"/&gt;
&lt;rect class="cpm-box" x="502" y="58" width="112" height="112" rx="8"/&gt;
&lt;text class="cpm-t" x="558" y="80"&gt;M&lt;/text&gt;
&lt;text class="cpm-f" x="558" y="110"&gt;app.txt&lt;/text&gt;
&lt;text class="cpm-f" x="558" y="132"&gt;login.txt&lt;/text&gt;
&lt;text class="cpm-f cpm-c2 cpm-bold" x="558" y="154"&gt;+ README.md&lt;/text&gt;
&lt;text class="cpm-m" x="481" y="204"&gt;lands on the current branch&lt;/text&gt;
&lt;text class="cpm-r cpm-c2" x="481" y="230"&gt;+ README.md&lt;/text&gt;
&lt;text class="cpm-m" x="481" y="256"&gt;main-side changes (C)&lt;/text&gt;
&lt;/svg&gt;
&lt;figcaption&gt;On the left is the usual -m 1: diffing C against M yields exactly what feature brought in.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Base&lt;/th&gt;
&lt;th&gt;Diff computed&lt;/th&gt;
&lt;th&gt;What lands on the current branch&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-m 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;parent 1 (C, main side)&lt;/td&gt;
&lt;td&gt;C → M&lt;/td&gt;
&lt;td&gt;Everything from feature (A, B, plus any conflict resolution done during the merge)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-m 2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;parent 2 (B, feature side)&lt;/td&gt;
&lt;td&gt;B → M&lt;/td&gt;
&lt;td&gt;Changes on main since feature branched off (C)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;When the job is &amp;ldquo;move an already-merged feature to another branch,&amp;rdquo; you almost always want &lt;code&gt;-m 1&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="hands-on-build-a-demo-repository"&gt;Hands-On: Build a Demo Repository
&lt;/h2&gt;&lt;p&gt;You can copy and run the commands below as-is. They build the repository from the diagrams: &lt;code&gt;release&lt;/code&gt; stays at &lt;code&gt;init&lt;/code&gt;, &lt;code&gt;feature&lt;/code&gt; has two commits, &lt;code&gt;main&lt;/code&gt; has one unrelated commit, and merge commit M brings &lt;code&gt;feature&lt;/code&gt; into &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll go in four steps and check the commit graph with &lt;code&gt;git log --oneline --graph --all&lt;/code&gt; after each one. The output shown is real (your SHAs will differ).&lt;/p&gt;
&lt;h3 id="step-1-initial-commit-branch-off-release"&gt;Step 1: Initial commit, branch off release
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git init -b main demo &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; demo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;v1&amp;#34;&lt;/span&gt; &amp;gt; app.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add app.txt &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git commit -m &lt;span class="s2"&gt;&amp;#34;init&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Branch release off here (we won&amp;#39;t touch it again)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch release
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git log --oneline --graph --all
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* f643d1c (HEAD -&amp;gt; main, release) init
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;There&amp;rsquo;s only one commit, and both &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;release&lt;/code&gt; point to it.&lt;/p&gt;
&lt;h3 id="step-2-two-commits-on-the-feature-branch"&gt;Step 2: Two commits on the feature branch
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git checkout -b feature
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;login&amp;#34;&lt;/span&gt; &amp;gt; login.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add login.txt &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git commit -m &lt;span class="s2"&gt;&amp;#34;A: add login&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;logout&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; login.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -am &lt;span class="s2"&gt;&amp;#34;B: add logout&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git log --oneline --graph --all
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* d9b8793 (HEAD -&amp;gt; feature) B: add logout
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* f7858bc A: add login
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* f643d1c (release, main) init
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;feature&lt;/code&gt; has moved two commits ahead; &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;release&lt;/code&gt; are still at &lt;code&gt;init&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="step-3-an-unrelated-commit-on-main"&gt;Step 3: An unrelated commit on main
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git checkout main
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;readme&amp;#34;&lt;/span&gt; &amp;gt; README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add README.md &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git commit -m &lt;span class="s2"&gt;&amp;#34;C: add readme&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git log --oneline --graph --all
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* d9b8793 (feature) B: add logout
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* f7858bc A: add login
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;| * 06233b4 (HEAD -&amp;gt; main) C: add readme
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;|/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* f643d1c (release) init
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;History forks after &lt;code&gt;init&lt;/code&gt;: &lt;code&gt;feature&lt;/code&gt;&amp;rsquo;s A and B on one side, &lt;code&gt;main&lt;/code&gt;&amp;rsquo;s C on the other.&lt;/p&gt;
&lt;h3 id="step-4-merge-feature-into-main-with-a-merge-commit"&gt;Step 4: Merge feature into main with a merge commit
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git merge --no-ff feature -m &lt;span class="s2"&gt;&amp;#34;M: merge feature&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;--no-ff&lt;/code&gt; guarantees that a merge commit is created.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git merge --no-ff feature -m &lt;span class="s2"&gt;&amp;#34;M: merge feature&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Merge made by the &amp;#39;ort&amp;#39; strategy.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; login.txt | 2 ++
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 1 file changed, 2 insertions(+)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; create mode 100644 login.txt
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git log --oneline --graph --all
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* 8865ad0 (HEAD -&amp;gt; main) M: merge feature
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;|\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;| * d9b8793 (feature) B: add logout
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;| * f7858bc A: add login
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* | 06233b4 C: add readme
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;|/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* f643d1c (release) init
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Two lines lead into M (&lt;code&gt;8865ad0&lt;/code&gt;): the vertical one from C (&lt;code&gt;06233b4&lt;/code&gt;, parent 1) and the one on the right from B (&lt;code&gt;d9b8793&lt;/code&gt;, parent 2). That&amp;rsquo;s the same order as &lt;code&gt;Merge: 06233b4 d9b8793&lt;/code&gt; earlier.&lt;/p&gt;
&lt;h2 id="run-the-cherry-pick-and-verify"&gt;Run the Cherry-Pick and Verify
&lt;/h2&gt;&lt;p&gt;Switch to &lt;code&gt;release&lt;/code&gt; and pick M with &lt;code&gt;-m 1&lt;/code&gt;. Since &lt;code&gt;main&lt;/code&gt; currently points at M, you can use the branch name directly:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git checkout release
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick -m &lt;span class="m"&gt;1&lt;/span&gt; main &lt;span class="c1"&gt;# same as git cherry-pick -m 1 8865ad0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Running it and checking the result in the terminal:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git checkout release
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Switched to branch &amp;#39;release&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git cherry-pick -m &lt;span class="m"&gt;1&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;[release 20de01d] M: merge feature
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Date: Fri Jun 26 17:56:50 2026 +0800
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 1 file changed, 2 insertions(+)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; create mode 100644 login.txt
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; ls
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;app.txt login.txt
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git log --oneline --graph --all
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* 8865ad0 (main) M: merge feature
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;|\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;| * d9b8793 (feature) B: add logout
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;| * f7858bc A: add login
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* | 06233b4 C: add readme
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;|/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;| * 20de01d (HEAD -&amp;gt; release) M: merge feature
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;|/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* f643d1c init
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git log -1 --format&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%h parents: %p&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;20de01d parents: f643d1c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;release&lt;/code&gt; got &lt;code&gt;feature&lt;/code&gt;&amp;rsquo;s &lt;code&gt;login.txt&lt;/code&gt;, and &lt;code&gt;main&lt;/code&gt;&amp;rsquo;s &lt;code&gt;README.md&lt;/code&gt; did not come along. Note that the new &lt;code&gt;20de01d&lt;/code&gt; is an ordinary single-parent commit (its only parent is &lt;code&gt;f643d1c&lt;/code&gt;), not a merge commit. It just reuses M&amp;rsquo;s commit message.&lt;/p&gt;
&lt;h2 id="comparison-what-happens-with--m-2"&gt;Comparison: What Happens with &lt;code&gt;-m 2&lt;/code&gt;
&lt;/h2&gt;&lt;p&gt;With &lt;code&gt;-m 2&lt;/code&gt; you get &lt;code&gt;main&lt;/code&gt;&amp;rsquo;s &lt;code&gt;README.md&lt;/code&gt; instead, and none of &lt;code&gt;feature&lt;/code&gt;&amp;rsquo;s changes. Try it on a fresh branch from &lt;code&gt;init&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git checkout -b release-m2 release~1 &lt;span class="c1"&gt;# back to init, before the cherry-pick&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick -m &lt;span class="m"&gt;2&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git checkout -b release-m2 release~1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Switched to a new branch &amp;#39;release-m2&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git cherry-pick -m &lt;span class="m"&gt;2&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;[release-m2 220b106] M: merge feature
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Date: Fri Jun 26 17:56:50 2026 +0800
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 1 file changed, 1 insertion(+)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; create mode 100644 README.md
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; ls
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;README.md app.txt
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The base is now B. B already contains &lt;code&gt;login.txt&lt;/code&gt;, so the diff from B to M is only the &lt;code&gt;README.md&lt;/code&gt; that C introduced.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-m 2&lt;/code&gt; still has its uses. If someone first ran &lt;code&gt;git merge main&lt;/code&gt; on &lt;code&gt;feature&lt;/code&gt; and then fast-forwarded &lt;code&gt;main&lt;/code&gt; to that merge, the parent order is reversed, and you&amp;rsquo;d need &lt;code&gt;-m 2&lt;/code&gt; to get &lt;code&gt;feature&lt;/code&gt;&amp;rsquo;s changes.&lt;/p&gt;
&lt;h2 id="common-pitfalls-and-best-practices"&gt;Common Pitfalls and Best Practices
&lt;/h2&gt;&lt;p&gt;The biggest pitfall is assuming parent 1 is the mainline. Confirm the parent order before you act, and the rest is easy to handle.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Check the order first.&lt;/strong&gt; Use the &lt;code&gt;Merge:&lt;/code&gt; line from &lt;code&gt;git log -1 &amp;lt;sha&amp;gt;&lt;/code&gt; to confirm which one is parent 1, especially for merges someone else made.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add &lt;code&gt;-x&lt;/code&gt; to record the source.&lt;/strong&gt; &lt;code&gt;git cherry-pick -x -m 1 &amp;lt;sha&amp;gt;&lt;/code&gt; appends &lt;code&gt;(cherry picked from commit ...)&lt;/code&gt; to the commit message, so you can find where a change came from later.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Handle conflicts as usual.&lt;/strong&gt; Fix the conflicted files, &lt;code&gt;git add&lt;/code&gt; them, then run &lt;code&gt;git cherry-pick --continue&lt;/code&gt;. To give up, &lt;code&gt;git cherry-pick --abort&lt;/code&gt; puts the branch back where it was.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Watch out for later merges.&lt;/strong&gt; Cherry-pick creates new SHAs, and Git doesn&amp;rsquo;t remember that these changes are already in &lt;code&gt;release&lt;/code&gt;. If you later merge &lt;code&gt;feature&lt;/code&gt; or &lt;code&gt;main&lt;/code&gt; into &lt;code&gt;release&lt;/code&gt;, identical changes usually merge cleanly, but anything &lt;code&gt;feature&lt;/code&gt; changed afterwards may conflict.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reverting works differently.&lt;/strong&gt; A cherry-picked commit is a regular commit, so &lt;code&gt;git revert &amp;lt;new sha&amp;gt;&lt;/code&gt; is enough. Reverting the original merge commit M needs &lt;code&gt;git revert -m 1 M&lt;/code&gt; too.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You can apply &lt;code&gt;-m 1&lt;/code&gt; to a whole batch.&lt;/strong&gt; Since Git 2.21, &lt;code&gt;-m&lt;/code&gt; also works on regular commits, so a range that includes merge commits can be picked with one command.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With &lt;code&gt;-x&lt;/code&gt;, the last line of the commit message records the full SHA of the source merge commit:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git checkout -b release-x release~1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick -x -m &lt;span class="m"&gt;1&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; git log -1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;commit bd76f2d148bac366ad55b388915292d25daead59
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Author: Demo &amp;lt;demo@example.com&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Date: Fri Jun 26 17:56:50 2026 +0800
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; M: merge feature
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; (cherry picked from commit 8865ad060c1c64fbc3c0196e12302b1d96e8bf30)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="cheat-sheet"&gt;Cheat Sheet
&lt;/h2&gt;&lt;p&gt;The one thing to remember: &lt;strong&gt;&lt;code&gt;-m N&lt;/code&gt; uses the Nth parent as the base and takes the changes from the other side. To move a merged feature, use &lt;code&gt;-m 1&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick -m 1 &amp;lt;M&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apply M&amp;rsquo;s diff against parent 1 (the merged-in branch&amp;rsquo;s changes) to the current branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick -m 2 &amp;lt;M&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apply M&amp;rsquo;s diff against parent 2 (the mainline side&amp;rsquo;s changes) to the current branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick -x -m 1 &amp;lt;M&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same as above, and record the source SHA in the commit message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log -1 &amp;lt;M&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show the &lt;code&gt;Merge:&lt;/code&gt; line to confirm the parent order&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git rev-parse &amp;lt;M&amp;gt;^1 &amp;lt;M&amp;gt;^2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Print parent 1 and parent 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick --continue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Continue after resolving conflicts and running &lt;code&gt;git add&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick --abort&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Abandon this cherry-pick and return to the previous state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git revert -m 1 &amp;lt;M&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Revert everything the merge brought in&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description></item></channel></rss>