git cherry-pick简介

本文编辑整理自:
git cherry-pick 用于把另一个本地分支的commit修改应用到当前分支。
实际问题
在本地 master 分支上做了一个 commit ( 38361a68138140827b31b72f8bbfd88b3705d77a ) , 如何把它放到 本地 old_cc 分支上?
办法之一: 使用 cherry-pick . 根据git 文档:
Apply the changes introduced by some existing commits
就是对已经存在的commit 进行apply (可以理解为再次提交)
简单用法
git cherry-pick <commit id>
例如:
$ git checkout old_cc
$ git cherry-pick 38361a68
1.如果顺利,就会正常提交。结果:
Finished one cherry-pick.
# On branch old_cc
# Your branch is ahead of 'origin/old_cc' by 3 commits.
2. 如果在cherry-pick 的过程中出现了冲突
Automatic cherry-pick failed. After resolving the conflicts,
mark the corrected paths with 'git add <paths>' or 'git rm <paths>'
and commit the result with:

git commit -c 15a2b6c61927e5aed6718de89ad9dafba939a90b

就跟普通的冲突一样,手工解决:
执行git status 看哪些文件出现冲突
$ git status
both modified: app/models/user.rb
接着手动解决冲突的文件,然后通过git add把改到添加到索引,最后执行git commit提交修改。
$ vim app/models/user.rb
$ git add app/models/user.rb
git commit -c < 原commit号 >
git-cherry-pick(1)
==================

NAME
----
git-cherry-pick - Apply the changes introduced by some existing commits

SYNOPSIS
--------
'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...

DESCRIPTION
-----------

Given one or more existing commits, apply the change each one
introduces, recording a new commit for each. This requires your
working tree to be clean (no modifications from the HEAD commit).

When it is not obvious how to apply a change, the following
happens:

1. The current branch and `HEAD` pointer stay at the last commit
successfully made.
2. The `CHERRY_PICK_HEAD` ref is set to point at the commit that
introduced the change that is difficult to apply.
3. Paths in which the change applied cleanly are updated both
in the index file and in your working tree.
4. For conflicting paths, the index file records up to three
versions, as described in the "TRUE MERGE" section of
linkgit:git-merge[1]. The working tree files will include
a description of the conflict bracketed by the usual
conflict markers `<<<<<<<` and `>>>>>>>`.
5. No other modifications are made.

See linkgit:git-merge[1] for some hints on resolving such
conflicts.

OPTIONS
-------
<commit>...::
Commits to cherry-pick.
For a more complete list of ways to spell commits, see
linkgit:gitrevisions[7].
Sets of commits can be passed but no traversal is done by
default, as if the '--no-walk' option was specified, see
linkgit:git-rev-list[1].

-e::
--edit::
With this option, 'git cherry-pick' will let you edit the commit
message prior to committing.

-x::
When recording the commit, append to the original commit
message a note that indicates which commit this change
was cherry-picked from. Append the note only for cherry
picks without conflicts. Do not use this option if
you are cherry-picking from your private branch because
the information is useless to the recipient. If on the
other hand you are cherry-picking between two publicly
visible branches (e.g. backporting a fix to a
maintenance branch for an older release from a
development branch), adding this information can be
useful.

-r::
It used to be that the command defaulted to do `-x`
described above, and `-r` was to disable it. Now the
default is not to do `-x` so this option is a no-op.

-m parent-number::
--mainline parent-number::
Usually you cannot cherry-pick a merge because you do not know which
side of the merge should be considered the mainline. This
option specifies the parent number (starting from 1) of
the mainline and allows cherry-pick to replay the change
relative to the specified parent.

-n::
--no-commit::
Usually the command automatically creates a sequence of commits.
This flag applies the changes necessary to cherry-pick
each named commit to your working tree and the index,
without making any commit. In addition, when this
option is used, your index does not have to match the
HEAD commit. The cherry-pick is done against the
beginning state of your index.
+
This is useful when cherry-picking more than one commits'
effect to your index in a row.

-s::
--signoff::
Add Signed-off-by line at the end of the commit message.

--ff::
If the current HEAD is the same as the parent of the
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::

Apply the change introduced by the commit at the tip of the
master branch and create a new commit with this change.

git cherry-pick ..master::
git cherry-pick ^HEAD master::

Apply the changes introduced by all commits that are ancestors
of master but not of HEAD to produce new commits.

git cherry-pick master{tilde}4 master{tilde}2::

Apply the changes introduced by the fifth and third last
commits pointed to by master and create 2 new commits with
these changes.

git cherry-pick -n master~1 next::

Apply to the working tree and the index the changes introduced
by the second last commit pointed to by master and by the last
commit pointed to by next, but do not create any commit with
these changes.

git cherry-pick --ff ..next::

If history is linear and HEAD is an ancestor of next, update
the working tree and advance the HEAD pointer to match next.
Otherwise, apply the changes introduced by those commits that
are in next but not HEAD to the current branch, creating a new
commit for each new change.

git rev-list --reverse master \-- README | git cherry-pick -n --stdin::

Apply the changes introduced by all commits on the master
branch that touched README to the working tree and index,
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.

### Git Cherry-Pick 的基本概念 `git cherry-pick` 是一种用于将单个或多个特定提交应用到当前分支的操作工具。它允许开发者从其他分支挑选某些提交并将其应用于另一个分支,而无需合并整个分支。 通过 `git cherry-pick` 命令可以实现以下功能: - 将某个分支中的单独提交引入到另一分支中。 - 解决跨分支开发时的代码同步需求。 此操作的核心在于指定要复制的具体提交哈希值(commit hash),从而仅提取该提交的内容及其更改[^5]。 --- ### 使用方法 #### 单次提交的应用 假设有一个提交记录为 `abc1234`,可以通过如下方式将其应用至当前分支: ```bash git cherry-pick abc1234 ``` 执行上述命令后,Git 会尝试重现目标提交所涉及的所有修改,并创建一个新的提交对象于当前分支上[^5]。 #### 多次连续提交的选择性应用 如果希望选取一系列连续的提交,比如从 `abc1234` 到 `def5678`,则可采用范围形式调用: ```bash git cherry-pick abc1234..def5678 ``` 注意这里的两个点号表示包含起始不包含结束;如果是三个点号,则意味着两端均被纳入考虑范围内[^5]。 对于非线性的历史结构或者复杂的场景下可能引发冲突的情况,请参阅下一节关于常见问题的部分处理办法。 --- ### 常见问题及解决方案 当运行 `cherry-pick` 过程遇到文件级别的差异无法自动解析时,会出现所谓的“merge conflict”。此时需手动编辑受影响区域直至消除矛盾之处后再继续流程: ```bash # 编辑完成后标记已解决状态 git add . # 继续完成剩余部分 git cherry-pick --continue ``` 另外,在中途决定放弃正在进行的任务时也可以随时中断过程并通过清理工作区来恢复原状: ```bash git cherry-pick --abort ``` 还有就是要注意的是,频繁使用 `cherry-pick` 可能会造成重复的历史条目累积,影响仓库整洁度以及后续维护成本增加等问题[^6]。 --- ### 示例代码展示 下面给出一个完整的例子演示如何利用 `git cherry-pick` 把远程服务器上的修复补丁快速拉取下来并集成进本地特性版本之中去。 假定存在这样的情况:远端 master 上已经包含了重要的错误修正但是尚未发布正式版;与此同时我们正在 feature-x 分支上面紧张忙碌着新特性的研发活动。为了尽早享受到这些改进成果而不必等待整体更新周期完毕,我们可以这样做: ```bash # 首先切换回主干以便定位确切位置 git checkout main git pull origin main # 查看日志找到那个关键修补程序对应的 commit id ,比如说 'a1b2c3d' git log --oneline # 跳转回到自己的专题线路 git checkout feature-x # 执行摘果子动作把那笔调整拿过来 git cherry-pick a1b2c3d ``` 这样就成功地让我们的私人项目享受到了公共主线里的最新优化进展啦! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值