重置/恢复整个分支到另一个分支状态?

dan*_*451 14 git merge revert reset

我有一个分支A和一个分支B(以及其他一些分支).

让我们说A的提交历史如下:

  • 承诺5
  • 承诺4
  • 提交3
  • ...

B的承诺历史:

  • 其他一些提交
  • 承诺4
  • 从分支C合并其他东西(进入分支B)
  • 提交3
  • ...

基本上我想要的是"删除"提交所做的所有更改,其他一些提交以及从分支C到分支B 的其他内容的合并.

我想分支的工作树是完全一样的像支的工作树.

我该如何实现这一目标?

Rüd*_*ann 19

实现这一目标的一种方法是通过git reset.在分支B执行时

git reset --hard A
Run Code Online (Sandbox Code Playgroud)

此后,分支B指向了头部提交A.该--hard选项重置索引和工作树,以便将所有跟踪的文件重置为分支中的版本A.A复制旧的head-commit .git/ORIG_HEAD以允许撤消更改.

或者 - 虽然不在分支上B- 您可以删除分支B并重新创建它,如下所示:

git branch -d B     # delete branch B
git branch B A      # re-create branch B and let it point to the commit of branch A
Run Code Online (Sandbox Code Playgroud)

除了第一个建议,这将使索引和工作树保持不变.

  • 您可以在`push`命令中添加`--force`选项以覆盖远程分支.但是你应该很清楚后果,例如[这里](http://stackoverflow.com/questions/21259585/other-consequences-of-git-push-force)或[here](http:// stackoverflow) .COM /问题/ 23432788 /混帐推力背后的场景). (3认同)

Tri*_*tan 13

正如其他人所表明的那样,git 确实reset --hard会使分支 B 看起来与分支 A 完全相同。但是,这将删除 B 的历史记录。避免此问题的另一种方法是创建并应用补丁文件:

git checkout A
git diff B > /tmp/AtoB.patch # Generate changes needed to make B match the current branch A
git checkout B
git apply /tmp/AtoB.patch # Update files to match the state of A
git add -A # Track any deleted or newly created files
git commit -a -m "Make B match A" # Commit the changes
Run Code Online (Sandbox Code Playgroud)

现在我们不是在“重写历史”,所以当你推到原点时不会有争议。这种方法的优点是同步是 B 历史记录中的离散提交,可以随时恢复。但请注意,分支 A 的提交历史记录在转换中丢失。

顺便说一句:如果您收到有关二进制文件的错误,请将 --binary 标志添加到 diff 命令中,如下所示git diff --binary B > /tmp/AtoB.patch


pra*_*atZ 9

如果你希望你的分支B看起来像分支A.你可以做一个reset --hard

git checkout branch-B

git reset --hard branch-A
Run Code Online (Sandbox Code Playgroud)

在这种情况下,请注意您将丢失提交.您的分支-B看起来酷似分支-A,无论提交作了分支-B,是不存在的分支-A,将丢失.此外,如果branch-B与其他人共享,则不建议执行此操作.

在这种情况下,您可以尝试恢复分支-B中不需要的提交

git revert <sha-of-"some other commit">
git revert <sha-of-"merge of other stuff from branch C (into branch B)"> 
Run Code Online (Sandbox Code Playgroud)

第二个提交看起来像一个合并提交,所以你可能也必须传递父.

 git revert <sha-of-"merge of other stuff from branch C (into branch B)"> -m1
Run Code Online (Sandbox Code Playgroud)


Rom*_*eri 7

For completion, let's add this very simple way to achieve it :

git branch -f branchB branchA
Run Code Online (Sandbox Code Playgroud)

It takes advantage of the fact that branches in git are mere pointers. This command just replaces the ref to the tip commit of one branch with another. No need to go into complex structure changes to build something you already have.

(See the doc)