如何将分支的内容复制到新的本地分支?

Posted

技术标签:

【中文标题】如何将分支的内容复制到新的本地分支?【英文标题】:How can I copy the content of a branch to a new local branch? 【发布时间】:2013-02-06 13:55:15 【问题描述】:

我在本地分支上工作,并将更改推送到远程。

我想恢复该分支上的更改并对其执行其他操作,但我不想完全失去工作。我正在考虑在本地创建一个新分支并将旧分支复制到那里,然后我可以还原更改并继续在旧分支上工作。

还有比这更好的方法吗?

【问题讨论】:

4 年后,使用 Git 2.15(2017 年第四季度),您将拥有 git branch -c A B。见my answer below 【参考方案1】:

参见第二部分(自 Git 2.23,2019 年第三季度以来):git switch -c newBranch oldBranch


在 Git 2.15(2017 年第四季度)中,“git branch”学会了“-c/-C”通过复制现有分支来创建新分支。

见commit c8b2cec(2017 年 6 月 18 日)Ævar Arnfjörð Bjarmason (avar)。 请参阅 Sahil Dua (sahildua2305) 的 commit 52d59cc、commit 5463caa(2017 年 6 月 18 日)。(由 Junio C Hamano -- gitster -- 合并到 commit 3b48045,2017 年 10 月 3 日)

branch:添加 --copy (-c) 选项以与 --move (-m) 搭配使用

添加--copy 分支及其引用日志和配置的能力, 这使用与--move (-m) 选项相同的底层机制 除了 reflog 和配置被复制而不是被移动。

这对于例如将主题分支复制到新版本, 例如将work 主题提交到列表后,workwork-2,而 保留所有跟踪信息和其他配置 与分支不同,与 --move 保留另一个已经提交的不同 四处转供参考。

注意:复制分支时,您将保留在当前分支上。 作为Junio C Hamano explains,这个新功能的初始实现是修改HEAD,效果不好:

当通过复制分支A 创建新分支B 时,碰巧 成为当前分支,它还会更新 HEAD 以指向新的分支 分支。 它可能是这样制作的,因为“git branch -c A B”在“git branch -m A B”上搭载了它的实现,

这与通常的预期不符。 如果我坐在一张蓝色的椅子上,有人过来把它重新涂成红色,我会接受最终坐在现在是红色的椅子上(我也可以 相反,站起来,因为不再有我最喜欢的蓝色椅子)。

但是如果有人创造了一把新的红色椅子,按照蓝色来建模 我坐在椅子上,我不希望被突然踢掉 椅子,最后坐在新的红色椅子上。


第二部分:使用 git 2.23(2019 年第三季度),无需使用 git 分支或 old confusing git checkout:你有 git switch

git switch -c newBranch oldBranch

【讨论】:

Junio C Hamano 下面引用的解释:'它还更新 HEAD 以指向新分支',似乎与您的说法相矛盾:'注意:复制分支时,您仍保留在当前分支上。正如你所说,在 git 2.17.1 上尝试过之后,我被留在了现有的环境中。因此,这种解释似乎不正确。 @ChrisR 我已将链接添加到原始 Git 邮件列表线程,该语句源自该线程。这是关于 git branch -cinitial 实现,由于 Junio 的评论,该实现正在修复中。 谢谢。编辑也很好,现在对于任何找到自己的方式的人来说都更加清晰,而不必像我一样尝试并看到。【参考方案2】:

鉴于您要求更好的方式选择:

复制分支的一个潜在缺陷是,如果您想合并到同一个父级,或者将更改从副本重新引入原始分支,则必须注意 git 的快进行为。

例如,如果您在“原始”分支中恢复了一些提交,但现在您想重新引入您恢复到原始分支的更改,您不能简单地将复制的分支合并到父分支,因为 git 会看到这些提交已经存在(甚至认为它们稍后会被还原)。

也许cherry-pick [commit-range] 可以在这种情况下工作并且不关心现有的哈希耸耸肩

在我看来,这样做会更好。

    从当前分支 HEAD git branch [archive-branch-name] 创建一个新分支 用git log找到你想回滚的提交 运行git reset --head [commit-hash-from-#2] git push -f origin

请注意,您从“原始”分支开始,在这些步骤中不要更改分支。

或者更简单的是,您可以完全取消分支,只需恢复您想要恢复的提交,如果需要,revert the revert later

【讨论】:

【参考方案3】:
git branch copyOfMyBranch MyBranch

这避免了签出分支的潜在耗时和不必要的行为。回想一下,结帐会修改“工作树”,如果它很大或包含大文件(例如图像或视频),这可能需要很长时间。

【讨论】:

当然,如果你在 git 中有二进制文件,尤其是大文件,那么分析你对这些文件的策略可能是值得的。自然会存在不寻常的情况,并且在 git 中包含二进制文件是完全可以接受的。【参考方案4】:
git checkout old_branch
git branch new_branch

这将为您提供一个与“old_branch”状态相同的新分支“new_branch”。

这个命令可以组合成以下:

git checkout -b new_branch old_branch

【讨论】:

或者更短的git checkout -b new_branch(当你已经在old_branch时)。 这只是创建新分支,但无法将内容从一个分支复制到另一个分支。当我尝试这个命令时,它只显示“名为 **** 的分支已经存在”。 我认为如果创建一个像这样的新分支,不会立即拥有旧分支的副本,而只是旧分支头部的新指针。但是,当你现在做一些类似 rebase 新分支的操作​​时,你应该会看到旧分支仍处于其原始状态,而新分支已被修改。所以我认为这可以满足 OP 的要求。 git checkout old_branch 和 git branch new_branch ....在生产环境中使用上述命令更好,因为下面的命令将创建新分支并将您带到新分支(将分支更改为新分支) .... git checkout -b new_branch old_branch 要覆盖分支,请参阅***.com/questions/26961371/…

以上是关于如何将分支的内容复制到新的本地分支?的主要内容,如果未能解决你的问题,请参考以下文章

如何将分支内容移动到另一个存储库保留历史记录并避免复制原始存储库的完整历史记录?

如何使用 GIT cmd 将远程分支代码的副本复制到本地分支 [重复]

本地 GIT 分支和远程 GITHUB 分支是不是需要相同才能推送代码? [复制]

如何使用Git完全回退到以前的版本并保存到新的分支

如何将 UIView 的光栅化内容复制到新的 UIView 中?

如何在我的 github 上制作分支的本地副本? [复制]