2017-05-08 62 views
2

我在2個分支中工作,混淆了一切。針對分支A的一些更改在分支B中,而相反。一些提交包含更改正確的分支和錯誤的錯誤的同時。我對這個組合做了幾次提交。git:混淆分支 - 如何清理

之後我再次在正確的分支中做了更改。 所以我結束了正確分支的所有更改,但每個分支也都屬於另一個分支。 然後對於我推送的分支A和分支B,我已經提出了請求。

問題1:如何從每個分支中刪除不屬於此處的更改? 我確切地知道我需要恢復到原始狀態的分支中的哪些文件。

問題2:如何更改已經發出的拉請求?

+0

是那個已經被接收器合併的請求了嗎? – quetzalcoatl

+0

不,他們沒有合併它 –

+0

如果他們還沒有合併它,然後**拉請求**是沒有意義的。基本上它只記得一個「註釋」,說「請將我的公共回購分支FOOBAR合併到你的BARFOO」。當你清理一些事情然後發佈/推送那些清理時,pull請求將不會改變。它**仍然會告訴相同的**:「請將我的foobar合併到您的barfoo中」。但是,現在,顯然,您的foobar將在清理後=>因此,您可以認爲「拉取請求」是自動自我更新。當然,它很方便,但只要它們尚未合併即可。 – quetzalcoatl

回答

1

爲了將來的參考,在推送之前清理它會更安全。在這一點上,你有兩個選擇:

  • 您可以創建新的分支機構(新名稱)和遷移所需的更改他們每個人。現有的分支將最終被放棄。

  • 您可以「重寫歷史記錄」來修復現有分支。任何取回/拉動現有分支的人都必須執行恢復程序(請參閱git rebase文檔中的「從上游重新分配中恢復」以獲得對此問題的一般性討論)。

我會寫出此過程假設第一個選項,因爲它在某些方面更安全。如果您想使用歷史重寫,我會提供一些關於如何調整過程的說明。我將展示如何執行branchA,並且branchB的過程基本相同。我將假設分支是從master創建的(因此如果不是,則用相應的「父分支」替換對master的所有引用)。

檢出現有分支。

git checkout branchA 

假設你不希望新的分支將被移動到master小費,你需要找到分支點。爲了簡化說明,我們在那裏創建一個臨時標記(儘管從技術上講,您可以使用SHA1 ID來代替此提交)。

所以,你必須

x --- A --- x <--(master) 
     \ 
     A1 --- B1 --- AB1 --- A2 <--(branchA) 

,你需要找到A。如果您知道有(在這個例子中)在branchA 4個提交後,從master分裂,你可以說

git tag rootA branchA~4 

如果你不知道電話號碼,你可以從一個GUI前端它眼珠子或者從git log --graph master branchA(如果提交歷史就足夠,這是實用的小),如果還是不行:

git rev-list master..branchA 

輸出的最後一行是SHA1爲第一承諾在你的分支,所以假設這是31337c0d3你會

git tag rootA 31337c0d3^ 

(注意末尾的^)。

的一種方式或其他,你現在應該有

[rootA] 
     | 
x --- A --- x <--(master) 
     \ 
     A1 --- B1 --- AB1 --- A2 <--(branchA) 

現在,創建新的分支(但你可以如使用「改寫歷史」選項,跳過此步驟)。

git checkout -b new_branchA 

現在開始交互式衍合會議

git rebase -i --onto rootA master 

你會得到一個文本編輯器以「待辦事項」列表中,代表提交每行。

對於上branchA屬於提交,保留線路不變(pick命令)

對於上branchB屬於提交 - 考慮到你已經有branchB這些改變 - 你可以改變命令從pickdrop

如果任何承諾有變化的組合(有些屬於上branchA,也有人認爲在branchB屬於),從pick命令更改爲edit

保存並退出文本編輯器,git將啓動rebase。如果你用edit標記了任何提交,那麼git會暫停並提示你進行編輯,然後告訴它恢復rebase。

當底墊完成後,你將有

[rootA] 
     | 
x --- A --- x <--(master) 
     |\ 
     | A1 --- B1 --- AB1 --- A2 <--(branchA) 
     \ 
     A1' --- Ab1' --- A2' <--(new_branchA) 

(其中Ab1'AB1編輯的更換隻意味着BranchA變化保持)。

如果您將其作爲歷史重寫,那麼branchA將指向A2',當然不會有new_branchA

您可以清理temp標籤。

git tag --delete rootA 

,除非你是一個歷史的改寫,你不再需要的舊branchA

git branch --delete branchA 

最後,你可以把遠程

git push 

(在該情況下,的歷史重寫,將需要-f選項)。

+0

Tkx ,,這很清楚。我們在分支中也有不止一個功能,您的解決方案我認爲可以爲每個功能創建一個新的分支並從RootA開始,只需選擇該功能的更改即可。然後爲特徵2創建一個分支,從RootA開始,再次只選擇屬於特徵2的更改。如果所有功能都拆分刪除brancheA。它是否正確? –

+0

@JacJac是的,這是正確的。 –

0

如果您還沒有推開這些分支的是,你可以:

  • 創建分支tmpAtmpB(例如從origin/Aorigin/B
  • git cherry-pick你需要從AtmpA的提交,和從BtmpB;如果你需要編輯提交使用選項--no-commit,然後git reset清除指數,其次是git add -p只添加需要進行修改,然後提交結果
  • 重置這些地方分行AtmpAgit branch -f A tmpA),同樣爲B
  • 刪除tmpAtmpB
+0

Tkx,與櫻桃挑選是可能分裂一個承諾?在一次提交中,我們有時會更改brancheA和nrancheB。我認爲櫻桃採取整個承諾? –

+0

@JacJac是的,但你可以使用'git cherry-pick'和'--no-commit'選項。然後做一個'git reset',你現在可以用'git add -p'只添加你需要的東西。一旦你添加了你需要的文件(或文件的一部分),提交併執行'git clean -fd'。 – VonC