如何从远程分支进行挑选(cherry-pick)操作?

219
我在进行cherry-pick的时候遇到了问题。我当前在本地机器上的"master"分支上。我想从另一个名为"zebra"的分支中挑选一个提交进行 cherry-pick。"zebra"分支是一个远程分支。
所以git状态:
# On branch master
nothing to commit (working directory clean)

好的,现在我尝试挑选我想要的提交记录:

git cherry-pick xyz
fatal: bad object xyz

“xyz”是我感兴趣的分支“zebra”上发生的提交的签名。

那么首先显而易见的问题是,为什么git找不到我引用的提交?说实话,我不太理解这是如何起作用的。Git是否在我的工作目录中为所有其他分支存储类似于提交的数据库?执行cherry-pick命令时,它会去搜索本地数据库以找到我所说的提交吗?

由于“zebra”是一个远程分支,我想我没有它的本地数据。所以我切换了分支:

git checkout zebra
Switched to branch 'zebra'

现在,在我的本地机器上,我可以看到目录中的文件正确地反映了斑马的状态。我切换回主分支,尝试再次挑选(希望现在可用提交数据),但是我仍然遇到同样的问题。

我对这里发生的事情有根本性的误解,任何帮助都会很棒。


4
从概念上看,一切似乎都是正确的。你确定正在使用正确的哈希值(就像你所说的签名)来提交吗?尝试使用“git show <哈希值>”进行验证。 - 0xc0de
1
嗨,是的,没错——我的两个分支都在 Github 上,并且我可以使用它们来找到提交页面。如果我理解正确,我的本地机器状态是这样的,即在“主”上下文中,git 无法找到“斑马”的哈希值。我需要以某种方式告诉它“斑马”也存在于本地吗? - user291701
1
哦,执行“git show xyz”会出现相同的错误“fatal: bad object”。(我正在用正确的哈希替换xyz)。 - user291701
为了澄清,我可以使用我的'xyz'哈希在github上查看提交,例如:"https://github.com/me/test/commit/xyz"。 - user291701
$git fetch 然后再试一次。 - Mauricio Gracia Gutierrez
在这种情况下,git fetch -allgit pull 将会有所帮助。有时我们的本地分支与远程不同步,应该使用 git status 进行检查。执行 git pull 可以解决问题,然后再进行 cherry pick。 - akshay_sushir
13个回答

294

由于“zebra”是一个远程分支,我认为我本地没有它的数据。

您说得对,您确实没有正确的数据,但尝试了错误的解决方法。要从远程源本地收集数据,您需要使用git fetch。当您执行git checkout zebra时,您切换到了上次获取该分支状态的任何内容。因此,请先从远程获取:

# fetch just the one remote
git fetch <remote>
# or fetch from all remotes
git fetch --all
# make sure you're back on the branch you want to cherry-pick to
git cherry-pick xyz

1
存档链接:http://archive.miek.nl/blog/archives/2011/12/13/cherry-picking_remote_branches/index.html - brianpeiris
1
尝试在Github上挑选一个上游修复的方法,结果发现检出的哈希与Github上的不同。因此我不得不先检出并获取哈希,然后再进行挑选。 - DustWolf
6
很遗憾在这里缺少一个选项来传递远程分支到cherry-pick命令中,例如:git cherry-pick <remote> <hash>。请问您需要什么其他帮助吗? - Jared
在获取远程分支后工作得很好。谢谢 :) - Adeel
是的,对我来说获取后也起作用了。有关 Git cherry-pick 的更多信息,请访问 https://www.atlassian.com/git/tutorials/cherry-pick - Satheesh M
很好的解释,感谢您在这里的回答。对我有用。 - AMIC MING

34

作为对原帖已被接受的答案的补充:

如果你在使用中遇到了问题

fatal: bad object xxxxx

这是因为您没有访问该提交的权限。这意味着您没有将那个仓库存储在本地。然后:

git remote add LABEL_FOR_THE_REPO REPO_YOU_WANT_THE_COMMIT_FROM
git fetch LABEL_FOR_THE_REPO
git cherry-pick xxxxxxx

其中 xxxxxxx 是您想要的提交哈希值。


我已经添加了仓库,但没有使用upstream标记? - Gobliins

29

添加远程仓库(名称为“foo”),从中我们想要挑选特定提交记录

$ git remote add foo git://github.com/foo/bar.git

获取他们的分支

$ git fetch foo

列出他们的提交(这应该列出在获取的foo中的所有提交)

$ git log foo/master

选择所需的提交记录

$ git cherry-pick 97fedac

13

在将一个开发分支合并到主分支后,我通常会删除该开发分支。然而,如果我想挑选开发分支中的提交,我必须使用合并提交哈希值以避免“坏对象”错误。


10
需要先将两个分支的数据都拉到本地驱动器上。
正在进行的是从branch-a选择性地挑选提交到branch-b中,但你当前在branch-b上,而branch-a的本地副本尚未更新(你需要首先在两个分支上执行git pull)。
步骤: - git checkout branch-a - git pull origin branch-a - git checkout branch-b - git pull origin branch-b - git cherry-pick 输出: [branch-b ] 日志数据 作者:作者 已更改1个文件,插入1个(+),删除3个(-)

9

只需要两个简单步骤:

  1. git fetch
  2. git cherry-pick ur-commit-hash

4
提交应该存在于本地,可以使用 git log 进行检查。
如果提交不存在,则尝试使用 git fetch 以最新的远程内容更新本地。

3

在使用拉取请求提交ID选项卡中的提交ID后,我遇到了此错误返回。但是该提交被压缩和合并。在github的拉取请求中,寻找这段文本:“merged commit xxxxxxx into...”而不是尝试使用提交选项卡中的提交ID。


2

我通过进入包含我想要挑选的提交的分支来解决了这个问题。

git checkout <branch With Commit To Cherry-Pick>

使用日志查找提交哈希值

git log

当你找到了你的哈希值后,将其复制并粘贴到记事本中。如果使用命令行,请向上滚动以获取哈希值,然后检出你想要放置提交的分支。

git checkout < branch I Want To Place My Cherry-Picked-Hash In>

最后从git中调用cherry-pick(注)-x是将您的cherry-pick消息附加到原始消息中。 “在记录提交时,附加一行内容,其中包含“(cherry picked from commit …​)”以指示此更改是从哪个提交中cherry-picked而来的。”

git cherry-pick -x <your hash commit to add to the current branch>

2
如果你已经拉取了代码,但仍然遇到这个问题,可能是以下原因之一。
有时候你尝试获取的提交已经不再属于任何分支。这可能发生在你进行变基(rebase)操作时。
在这种情况下,在远程仓库中:
1. git checkout xxxxx 2. git checkout -b temp-branch 然后在你的本地仓库中重新拉取代码。新的分支将被获取,包括那个提交。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接