2016-12-02 57 views
2

这个问题是关于如何在git中恢复回复,并以对未来读者有意义的方式执行,并且永远不会使存储库处于不良状态。在分支中恢复git的回复,并且可读

我的git仓库拥有一段时间的HEAD(上主)指着一个很好的承诺:

HEAD 
    | 
    G 

再有所发展发生了,树枝上,而这些提交看起来很不错,所以他们得到了合并成主。

   HEAD 
        | 
G -- C1 -- ... -- Ck 

但是后来我们在那些提交中发现了一个微妙的错误。很显然,我们可以回滚到G,然后花一些时间来思考。所以我们做到了。提交R为来到约键入类似

$ git checkout -b B 
$ git checkout master 
$ git revert --no-commit G..HEAD 

那把我的仓库在这样的状态,其中处于R和是在g看起来是一样的,除了历史上的复归:

     HEAD 
         | 
G -- C1 -- ... -- Ck -- R 
        | 
        B 

然后又发生了一些事情:有些紧急提交了主(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 

其中(-R)是新的commit撤销R.我想做到这一点在一些合理的方式,以便它清楚未来的读者发生了什么。

我认为要做到这一点,最好的办法是这样的:

$ 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?

回答

1

另外,还有另外两种方法,只有几个步骤。

1:

git checkout B 
git rebase -i master 
git branch -D master 
git branch -m B master 

2:

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 

所以主分支将看起来像:

G -- C1 -- ... -- Ck -- E1 -- E2 -- D1 -- ... -- Dj  master 
+0

最后,我用底垫(或可能这是樱桃选择),以拉拢失踪的承诺,然后(我的主要想法迪不知道)我使用'git branch -m'将master移到master-master,然后B移到master,然后push both。我很快就会删除master-old。 (是的,reflog还提供了恢复路径,但这更容易记住。) – jma

1

我也很确定它会工作。这里是其他的方式 -

Cherry-pick E1 & E2之前D1使用rebase -i

        HEAD 
            | 
G -- C1 -- ... -- Ck -- R -- E1 -- E2 
        | 
        \ -- E1 -- E2 -- D1 -- ... -- Dj 
               | 
               B 

然后用B分支取代master分支。

$ 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