我从我的主分支获得了两个分支:
- v2.1:(第二版)我已经工作了几个月
- wss:我昨天创建的,为了给我的主分支(在生产中)添加一个特定的功能
有没有办法将昨天在 wss 上提交的更改复制到 v2.1 中?
我从我的主分支获得了两个分支:
有没有办法将昨天在 wss 上提交的更改复制到 v2.1 中?
git cherry-pick <commit>
<commit>
到您的当前分支。我自己会在gitk
中交叉检查我选择的提交,并使用右键单击其中的提交条目来挑选它们。git log
生成提交列表(使用Jefromi建议的--pretty
)。git log --reverse --since=yesterday --pretty=%H
假设您使用bash
,则所有内容都可以放在一起。
for commit in $(git log --reverse --since=yesterday --pretty=%H);
do
git cherry-pick $commit
done
如果这里出现了问题(有很多潜在的问题),你就会陷入麻烦,因为这是在实时结账时运行的,所以要么手动挑选要提交的代码,要么像Jefromi建议的那样使用rebase。
git cherry-pick A^..B
从 A 到 B 进行操作。A 应该比 B 更旧。 - bitsandgit
答案,直接简洁地给出解决方案,而不是在 git 的复杂性中绕来绕去以证明回答者对其了解有多深。 - Przemek D你应该确实有一个工作流程,让你通过合并完成所有这些操作:
- x - x - x (v2) - x - x - x (v2.1)
\
x - x - x (wss)
所以您需要做的就是 git checkout v2.1
和 git 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)
你可以使用 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)
那么你就可以合并!如果你真的,真的,真的无法达到可以合并的地步,你仍然可以使用rebase来有效地一次性进行多个cherry-pick:
# 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
注意:之所以需要额外的工作才能做到这一点,是因为这将在您的存储库中创建重复提交。这并不是一个好事情——轻松分支和合并的整个重点是通过在一个地方进行提交并将它们合并到需要它们的任何位置来完成所有操作。重复提交意味着从未打算将这两个分支合并(如果您决定以后想要合并它们,您会遇到冲突)。git cherry-pick
:应用现有提交引入的更改。
假设我们有一个分支A,其中有(X, Y, Z)个提交。我们需要将这些提交添加到分支B中。我们将使用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
工作流程示例:
我们可以使用 cherry-pick
命令,并结合选项。
-e 或者 --edit:使用此选项,git cherry-pick 命令将允许您在提交之前编辑提交信息。
-n 或者 --no-commit:通常该命令会自动创建一系列的提交。这个标志将应用必要的更改来将每个命名提交挑选到您的工作树和索引中,而不进行任何提交。此外,当使用此选项时,您的索引不必与 HEAD 提交匹配。挑选是针对您的索引初始状态执行的。
这里有一篇有趣的文章,关于使用 cherry-pick
命令。
xyz
)。
然后我必须进入需要推送我的提交的分支。xyz
。git checkout branch-name
git cherry-pick xyz
git push origin branch-name
多个提交ID:xyz
abc
qwe
git checkout branch-name
git cherry-pick xyz abc qwe
git push origin branch-name
之前提到的回答已经覆盖了大部分内容,但是似乎缺少的一件事是cherry-pick
的--no-commit
特性。
假设您在功能分支上有多个提交,并且希望将它们全部合并为一个提交并放入主分支中。在这种情况下,您需要执行以下操作:
git checkout <branch-on-which-to-add-features>
git cherry-pick --no-commit <commit-hash>
git cherry-pick --no-commit <commit-hash>
.
.
.
最后,一旦你cherry-pick
了所有需要的功能,你可以进行最终提交:
git commit -m "Some message for the merge commit"
理想情况下,正如@Cascabel所提到的,你应该使用merge
或rebase
。但如果你感觉没有其他选择,你可以使用cherry-pick
。git format-patch <修订范围>
和 git am *.patch
。 - Cascabelcheckout
命令切换到另一个分支。 - CoolMind如果你不太喜欢"布道者"的方式,你可以使用一个比较丑陋的方法。在deploy_template中有一些我想要复制到我的主分支deploy的提交。
或者,如果您对布道者的说法不太认同,您可以采取我正在使用的另一种有些不太好看的方式。在deploy_template中,有一些提交,我想将它们复制到我的主分支deploy中。
git branch deploy deploy_template
git checkout deploy
git rebase master
这将在deploy_template上创建一个新的分支deploy(我使用-f覆盖现有的deploy分支),然后将该新分支rebase到master,保持deploy_template不变。
这里有另一种方法。
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.
使用内置的git gui更安全地进行挑选特定提交:
例如:从dev
分支复制一个提交到main
分支:
git checkout main
gitk --all
接着右键单击所需提交,选择挑选此次提交
cherry-pick 命令可以从标准输入中读取提交列表。
以下命令按时间顺序挑选用户John在"develop"分支上存在但在"release"分支上不存在的提交。
git log develop --not release --format=%H --reverse --author John | git cherry-pick --stdin