我曾在本地分公司工作过,也将更改推到远程。

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

有没有比这更好的办法?


git checkout old_branch
git branch new_branch

这将给你一个新分支“new_branch”,其状态与“old_branch”相同。

该命令可与以下命令组合:

git checkout -b new_branch old_branch

git branch copyOfMyBranch MyBranch

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


参见第二部分(自Git 2.23, Q3 2019): Git switch -c newBranch oldBranch


在Git 2.15(2017年Q4)中,“Git分支”学习了“-c/ -c”来通过复制现有分支来创建新分支。

C commit 8b2c(2017年1月18日)b on edge of arnfmason(梅森) 参见Sahil Dua (sahildua2305)的commit 52d59cc, commit 5463caa(2017年6月18日)。 (由Junio C Hamano—gitster—在commit 3b48045中合并,2017年10月3日)

branch: add a --copy (-c) option to go with --move (-m) Add the ability to --copy a branch and its reflog and configuration, this uses the same underlying machinery as the --move (-m) option except the reflog and configuration is copied instead of being moved. This is useful for e.g. copying a topic branch to a new version, e.g. work to work-2 after submitting the work topic to the list, while preserving all the tracking info and other configuration that goes with the branch, and unlike --move keeping the other already-submitted branch around for reference.

注意:当复制一个分支时,您将保持在当前的分支上。 正如Junio C Hamano解释的那样,这个新功能的最初实现是修改HEAD,这并不好:

When creating a new branch B by copying the branch A that happens to be the current branch, it also updates HEAD to point at the new branch. It probably was made this way because "git branch -c A B" piggybacked its implementation on "git branch -m A B", This does not match the usual expectation. If I were sitting on a blue chair, and somebody comes and repaints it to red, I would accept ending up sitting on a chair that is now red (I am also OK to stand, instead, as there no longer is my favourite blue chair). But if somebody creates a new red chair, modelling it after the blue chair I am sitting on, I do not expect to be booted off of the blue chair and ending up on sitting on the new red one.


第二部分:使用git 2.23(2019年Q3),不需要使用git分支或旧的令人困惑的git checkout:你有git开关。

git switch -c newBranch oldBranch

在Git 2.40 (Q1 2023)中,' Git branch -c'(man)更加健壮,可以检测到无操作的情况。

参见Rubén Justo (rjusto)提交cfbd173(2022年11月17日)。 (由Junio C Hamano - gitster -在commit 963f8d3中合并,2022年12月19日)

分支:通过@{-1}强制复制一个分支到它自己是没有操作的 署名:Rubén Justo 署名:泰勒·布劳

Since 52d59cc ("branch: add a --copy (-c) option to go with --move (-m)", 2017-06-18, Git v2.15.0-rc0 -- merge listed in batch #12) we can copy a branch to make a new branch with the '-c' (copy) option or to overwrite an existing branch using the '-C' (force copy) option. A no-op possibility is considered when we are asked to copy a branch to itself, to follow the same no-op introduced for the rename (-M) operation in 3f59481 (branch: allow a no-op , 2011-11-25, Git v1.7.9-rc0 -- merge) (branch: allow a no-op "branch -M <current-branch> HEAD", 2011-11-25). To check for this, in 52d59cc we compared the branch names provided by the user, source (HEAD if omitted) and destination, and a match is considered as this no-op. Since ae5a6c3 (checkout: implement , 2009-01-17, Git v1.6.2-rc0 -- merge) (checkout: implement "@{-N}" shortcut name for N-th last branch, 2009-01-17) a branch can be specified using shortcuts like @{-1}. This allows this usage: $ git checkout -b test $ git checkout - $ git branch -C test test # no-op $ git branch -C test @{-1} # oops $ git branch -C @{-1} test # oops As we are using the branch name provided by the user to do the comparison, if one of the branches is provided using a shortcut we are not going to have a match and a call to git_config_copy_section() will happen. This will make a duplicate of the configuration for that branch, and with this progression the second call will produce four copies of the configuration, and so on. Let's use the interpreted branch name instead for this comparison. The rename operation is not affected.


如果你要求更好的方式选择:

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

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

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

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

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

请注意,您从“原始”分支开始,并没有在步骤中更改分支。

或者更简单地说,你可以完全取消分支,只恢复你想恢复的提交,如果需要的话,以后再恢复


签出到要复制的分支。然后,一旦你在那个分支运行: Git checkout -b new_branch_name