ChatGPT解决这个技术问题 Extra ChatGPT

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

我的主人有两个分支:

v2.1:(版本2)我已经工作了几个月

wss:我昨天创建的用于向我的主人添加一个特定功能(在生产中)

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

要简单地将提交(或一系列提交)从一个分支复制到另一个分支,这个答案对我的帮助最大:stackoverflow.com/questions/1994463/…

J
JakeRobb

利用

git cherry-pick <commit>

<commit> 应用于您的当前分支

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

如果您想更加自动化(具有所有危险)并假设自昨天以来的所有提交都发生在 wss 上,您可以使用 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。


--pretty 选项的所有占位符都在 git-log 手册页中。您可以获得所需的任何格式 - 对于以易于解析的形式获取脚本所需的字段特别有用。
我还想指出,假设您确实想要创建重复提交,在我的答案中使用 git rebase 的方法更健壮。特别是,使用这样的 for 循环,如果其中一个选择失败,它仍然会尝试执行其余所有操作。这是...非常非常不好,让我们说。
同意。这就是为什么我从不使用它,而是手动进行。但是cherry-pick仍然是答案,至少对于问题标题。我修改了响应。
有人提交了一个旧的/不正确的分支,然后cherry-pick让我把那个提交放到正确的分支中(同时仍然让他们作为提交者)。完美的。
一个罕见的景象,一个简单而直接的解决方案的 git 答案,而不是通过 git 的复杂性来证明回答者对它的了解程度。
C
Cascabel

你真的应该有一个工作流程,让你通过合并来完成这一切:

- x - x - x (v2) - x - x - x (v2.1)
           \
            x - x - x (wss)

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

变基可能会为您节省的一些方法:

如果您的历史记录如下所示:

- 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 一次有效地做几个樱桃挑选:

# 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

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


不能更同意这个答案。 +1。另请参阅我的旧答案,以说明挑选樱桃的后果:stackoverflow.com/questions/881092/…
@VonC:感谢您的支持,以及有关为什么不挑选樱桃的额外信息-我知道我在那里略过了一点。 @gotgenes:谢谢!我认为这完全值得付出努力 - 只需查看 git-rebase 手册页。没有更好的方法来解释它。
至于为什么您可能无法合并 - Git 合并与 git-svn 不兼容。要将一系列提交从一个 SVN 分支复制到另一个,我最终选择了它们,然后执行交互式 rebase/reword 以在再次 dcommit 之前删除不正确的 git-svn-id 引用。尽管我可能已经省略了挑选樱桃的步骤,而只是单独使用了一个变基。
感谢 jefromi,此信息帮助我理解并编写了此问题/答案 - stackoverflow.com/questions/32600066/…
这是我的用例:关键错误修复已提交到功能分支。我现在需要它在master中投入生产。这将节省我的屁股。
S
Shiridish

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

假设我们有带有 (X, Y, Z) 提交的分支 A。我们需要将这些提交添加到分支 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

工作流程示例:

https://i.stack.imgur.com/wEpJz.png

我们可以将 cherry-pickoptions 一起使用

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

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

这里有一个关于 cherry-pick 的有趣 article


a
anilbey

假设我已经提交了对 master 分支的更改。我现在将获得提交的提交 ID (xyz)。然后我必须去我需要推送我的提交的分支。

单个提交 ID 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

C
Charles Ma

您可以从要复制的提交中create a patch apply the patch 到目标分支。


即使您出于某种原因真的想使用 patch(es) 而不是 cherry-pick(s)/rebase,直接的方法是使用 git format-patch <revision range>git am *.patch
它需要 checkout 到另一个分支。
p
paradocslover

已经提到的答案涵盖了大部分内容,但似乎缺少的一件事是 cherry-picking 的 --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 所述,您应该使用 mergerebase。但是,如果您觉得没有其他选择,您可以使用 cherry-picking。


P
Petr Sykora

或者,如果你在传道者方面少了一点,你可以做一些我正在使用的丑陋的方式。在 deploy_template 中,我想将提交复制到我的 master 作为分支部署

git branch deploy deploy_template
git checkout deploy
git rebase master

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


M
Muhammad Reda

这是另一种方法。

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.

感觉这是一个非常好的方法,以防您通过重置进度并拥有一个单独的分支(在我的情况下为测试环境)来恢复您的提交。
G
Gebb

cherry-pick 命令可以从标准输入中读取提交列表。

以下命令cherry-picks 用户 John 编写的存在于“develop”分支但不存在于“release”分支中的提交,并按时间顺序执行。

git log develop --not release --format=%H --reverse --author John | git cherry-pick --stdin

z
zeroimpl

对于将最后一次提交从分支 wss 复制到 v2.1 的简单情况,您可以简单地获取提交 id (git log --oneline | head -n 1) 并执行以下操作:

git checkout v2.1
git merge <commit>

这需要签出到另一个分支。
G
GorvGoyl

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

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

git checkout main
gitk --all

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

https://i.stack.imgur.com/V5gcA.png

gitk 对于 Mac:Install gitk on Mac


此答案假定安装了特定的操作系统和应用程序。你能让它更通用吗?
gitk 可用于多个操作系统。对于 Mac:stackoverflow.com/q/17582685