在git中使用分支进行还原还原,并且易于阅读

在git中使用分支进行还原还原,并且易于阅读,git,version-control,Git,Version Control,这个问题是关于如何在git中还原还原,并且以一种对未来读者有意义的方式进行还原,并且永远不会使存储库处于不好的状态 我的git存储库有一段时间头(在master上)指向一个非常好的提交: HEAD | G 然后在分支上进行了一些开发,这些提交看起来不错,所以它们被合并到master中 HEAD | G -- C1 -- ... -- Ck 但后来我们在这些提交中发现了一个微妙的bug。很明显,我们可以回到G,然后花

这个问题是关于如何在git中还原还原,并且以一种对未来读者有意义的方式进行还原,并且永远不会使存储库处于不好的状态

我的git存储库有一段时间头(在master上)指向一个非常好的提交:

HEAD
   |
   G
然后在分支上进行了一些开发,这些提交看起来不错,所以它们被合并到master中

               HEAD
                  |
G -- C1 -- ... -- Ck
但后来我们在这些提交中发现了一个微妙的bug。很明显,我们可以回到G,然后花一些时间来考虑这个问题。所以我们做到了。Commit R是通过键入以下内容实现的还原

$ git checkout -b B
$ git checkout master
$ git revert --no-commit G..HEAD
这使我的存储库处于这样一种状态,除了历史之外,在R和G处看起来是一样的:

                     HEAD
                        |
G -- C1 -- ... -- Ck -- R
                  |
                  B
然后又有了一些新的发展:在master(E1,E2)上进行了一些紧急提交,在B(D1,…,Dj)上进行了一些额外的发展,纠正了我们在Ck上遇到的问题,并继续了一些其他重要的工作。现在,存储库如下所示:

                                HEAD
                                   |
G -- C1 -- ... -- Ck -- R -- E1 -- E2
                  |
                   \ -- D1 -- ... -- Dj
                                     |
                                     B
                                                           HEAD
                                                              |
G -- C1 -- ... -- Ck -- R -- E1 -- E2 -- (-R) -- D1 -- ... -- Dj
很好,才过了一天,但现在是时候把事情安排好了。我想要的是一个如下所示的存储库:

                                HEAD
                                   |
G -- C1 -- ... -- Ck -- R -- E1 -- E2
                  |
                   \ -- D1 -- ... -- Dj
                                     |
                                     B
                                                           HEAD
                                                              |
G -- C1 -- ... -- Ck -- R -- E1 -- E2 -- (-R) -- D1 -- ... -- Dj
其中(-R)是一个撤销R的commit。我想以某种合理的方式来做这件事,以便将来的读者清楚发生了什么

我想到的最好的方法是:

$ git checkout B
$ git rebase master
$ git revert R
# Use the rebase -i to change ordering so that R happens before D1:
$ git rebase -i master
$ git checkout master
$ git merge --ff-only B
$ git push

我有理由相信这会奏效,但我觉得我错过了一些东西。有什么建议可以帮助我提高我的git fu吗?

我也很肯定它会奏效。这是另一条路-

D1
之前,使用
rebase-i
进行樱桃式拾取
E1和E2

                                   HEAD
                                   |
G -- C1 -- ... -- Ck -- R -- E1 -- E2
                  |
                   \ -- E1 -- E2 -- D1 -- ... -- Dj
                                                 |
                                                 B
然后将
master
分支替换为
B
分支

$ git checkout B
$ git branch -D master                   # delete master
$ git checkout -b master                 # create master from B
$ git push -f origin master              # force(-f) push and replace remote master's history by local master  

另外,还有两种方法,步骤很少

1:

git checkout B
git rebase -i master
git branch -D master
git branch -m B master
git rebase --onto Ck R E2
git rebase --onto <current SHA-1> Ck Dj
git checkout -b temp
git branch -D master
git branch -m temp master
2:

git checkout B
git rebase -i master
git branch -D master
git branch -m B master
git rebase --onto Ck R E2
git rebase --onto <current SHA-1> Ck Dj
git checkout -b temp
git branch -D master
git branch -m temp master
最后,我使用rebase(或者可能是cherry pick)来解决缺少的提交,然后(我不知道的关键思想)我使用
git branch-m
将master移到master old,然后将B移到master,然后将两者都推。我很快就会删除老主人。(是的,reflog还提供了恢复路径,但这更容易记住。)