如何将提交从一个分支复制到另一个分支?

Bob*_*lsh 682 git branching-and-merging

我的主人有两个分支:

  • v2.1 :(版本2)我已经工作了几个月
  • wss:我昨天创建的是为我的主人添加一个特定功能(在制作中)

有没有办法将昨天的提交从wss复制到v2.1?

Ben*_*ier 855

使用

git cherry-pick <commit>
Run Code Online (Sandbox Code Playgroud)

申请<commit>当前的分支机构.

我自己可能会交叉检查我选择的提交,gitk然后通过右键单击提交条目来挑选它们.


如果你想更自动(带有所有危险)并假设自昨天以来所有提交都发生在wss上你可以生成使用的提交列表git log(--pretty由Jefromi建议)

git log --reverse --since=yesterday --pretty=%H
Run Code Online (Sandbox Code Playgroud)

所以一切都假设你使用 bash

for commit in $(git log --reverse --since=yesterday --pretty=%H);
do
    git cherry-pick $commit
done
Run Code Online (Sandbox Code Playgroud)

如果这里出现问题(有很多潜力),你就会遇到麻烦,因为这会影响实时结账,所以要么手动挑选,要么像Jefromi建议的那样使用rebase.

  • 一个罕见的视线,一个简单直接的解决方案的"git"答案,而不是通过git的复杂性来蜿蜒来证明回答者对它的了解程度. (6认同)
  • 同意.这就是为什么我从不使用它,而是手动完成它.但樱桃选择仍然是答案,至少在问题标题上.我修改了响应. (2认同)

Cas*_*bel 537

你应该有一个工作流程,让你通过合并完成所有这些:

- x - x - x (v2) - x - x - x (v2.1)
           \
            x - x - x (wss)
Run Code Online (Sandbox Code Playgroud)

所以你要做的就是git checkout v2.1git merge wss.如果由于某种原因你真的不能这样做,并且你不能使用git rebase将你的wss分支移动到正确的位置,从某个地方获取单个提交并将其应用到别处的命令就是git cherry-pick.只需检查要应用它的分支,然后运行即可git cherry-pick <SHA of commit to cherry-pick>.

rebase的一些方法可能会拯救你:

如果您的历史记录如下:

- x - x - x (v2) - x - x - x (v2.1)
           \
            x - x - x (v2-only) - x - x - x (wss)
Run Code Online (Sandbox Code Playgroud)

您可以使用git rebase --onto v2 v2-only wss将wss直接移动到v2:

- x - x - x (v2) - x - x - x (v2.1)
          |\
          |  x - x - x (v2-only)
           \
             x - x - x (wss)
Run Code Online (Sandbox Code Playgroud)

然后你可以合并!如果你真的,真的,真的无法达到你可以合并的程度,你仍然可以使用rebase一次有效地做几个樱桃选择:

# wss-starting-point is the SHA1/branch immediately before the first commit to rebase
git branch wss-to-rebase wss
git rebase --onto v2.1 wss-starting-point wss-to-rebase
git checkout v2.1
git merge wss-to-rebase
Run Code Online (Sandbox Code Playgroud)

注意:为了做到这一点需要额外工作的原因是它在您的存储库中创建了重复的提交.这不是一件好事 - 简单分支和合并的关键在于能够通过将提交放在一个地方并将它们合并到需要的任何地方来完成所有事情.重复提交意味着永远不会合并这两个分支的意图(如果您决定以后再进行,则会产生冲突).

  • 关于如何做到*正确*方式的精湛答案!我希望我也可以两次投票来创建ASCII图表. (12认同)

Lye*_*UKH 64

git cherry-pick :应用某些现有提交引入的更改

假设我们有分支A和(X,Y,Z)提交.我们需要将这些提交加入到分支.我们将使用这些cherry-pick操作.

当我们使用时cherry-pick,我们应该按照提交出现在分支A中的相同时间顺序在分支B上添加提交.

cherry-pick确实支持一系列提交,但如果你在该范围内有合并提交,它会变得非常复杂

git checkout B
git cherry-pick SHA-COMMIT-X
git cherry-pick SHA-COMMIT-Y
git cherry-pick SHA-COMMIT-Z
Run Code Online (Sandbox Code Playgroud)

工作流程示例:

在此输入图像描述

我们可以使用cherry-pick选择

-e或--edit:使用此选项,git cherry-pick将允许您在提交之前编辑提交消息.

-n或--no-commit:通常命令会自动创建一系列提交.此标志应用必要的更改来挑选您的工作树和索引的每个命名提交,而不进行任何提交.此外,使用此选项时,索引不必与HEAD提交匹配.樱桃选择是针对索引的开始状态完成的.

这里一个有趣的文章有关cherry-pick.


Kri*_*rya 26

假设我已经向 master 分支提交了更改。我将获得提交的提交 id(xyz) 现在我必须转到我需要推送提交的分支。

单次提交 ID xyx

git checkout branch-name
git cherry-pick xyz
git push origin branch-name
Run Code Online (Sandbox Code Playgroud)

多个提交 ID 的 xyz abc qwe

git checkout branch-name
git cherry-pick xyz abc qwe
git push origin branch-name
Run Code Online (Sandbox Code Playgroud)


Cha*_* Ma 18

您可以从要复制的提交中创建补丁,并将补丁应用于目标分支.

  • 即使你出于某种原因真的想要使用补丁而不是使用cherry-pick(s)/ rebase,直接的方法是使用`git format-patch <revision range>`和`git am*.patch `. (16认同)

小智 10

或者,如果你在福音传道者身上少一点,你可以做一些我正在使用的丑陋方式.在deploy_template中,我想要在我的主服务器上作为分支部署进行复制

git branch deploy deploy_template
git checkout deploy
git rebase master
Run Code Online (Sandbox Code Playgroud)

这将在deploy_template上创建新的分支部署(我使用-f来覆盖现有的部署分支),然后将这个新分支重新绑定到master上,而不改变deploy_template.


par*_*ver 7

已经提到的答案涵盖了大部分内容,但似乎缺少的一件事是ing的--no-commit功能cherry-pick

假设您在功能分支上有多个提交,并且您想将所有提交“合并”为一个提交并将它们放在您的主分支上。在这种情况下,您需要做的是:

git checkout <branch-on-which-to-add-features>
git cherry-pick --no-commit <commit-hash>
git cherry-pick --no-commit <commit-hash>
.
.
.
Run Code Online (Sandbox Code Playgroud)

最后,一旦您完成了cherry-pick所有必需的功能,您就可以进行最终提交:

git commit -m "Some message for the merge commit"
Run Code Online (Sandbox Code Playgroud)

理想情况下,正如@Cascabel提到的,您应该使用mergerebase。但是,如果您觉得别无选择,则可以使用cherry-picking。


Muh*_*eda 5

这是另一种方法。

git checkout {SOURCE_BRANCH}               # switch to Source branch.
git checkout {COMMIT_HASH}                 # go back to the desired commit.
git checkout -b {temp_branch}              # create a new temporary branch from {COMMIT_HASH} snapshot.
git checkout {TARGET_BRANCH}               # switch to Target branch.
git merge {temp_branch}                    # merge code to your Target branch.
git branch -d {temp_branch}                # delete the temp branch.
Run Code Online (Sandbox Code Playgroud)


Jer*_*yal 5

使用内置的 git gui 来挑选特定的提交会更安全:

例如:将一个提交从一个dev分支复制到main另一个分支:

git checkout main
gitk --all
Run Code Online (Sandbox Code Playgroud)

然后右键单击所需的提交并选择Cherry-pick this commit

在此输入图像描述

gitk对于 Mac:在 Mac 上安装 gitk