2016-12-02 59 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