我在2個分支中工作,混淆了一切。針對分支A的一些更改在分支B中,而相反。一些提交包含更改正確的分支和錯誤的錯誤的同時。我對這個組合做了幾次提交。git:混淆分支 - 如何清理
之後我再次在正確的分支中做了更改。 所以我結束了正確分支的所有更改,但每個分支也都屬於另一個分支。 然後對於我推送的分支A和分支B,我已經提出了請求。
問題1:如何從每個分支中刪除不屬於此處的更改? 我確切地知道我需要恢復到原始狀態的分支中的哪些文件。
問題2:如何更改已經發出的拉請求?
我在2個分支中工作,混淆了一切。針對分支A的一些更改在分支B中,而相反。一些提交包含更改正確的分支和錯誤的錯誤的同時。我對這個組合做了幾次提交。git:混淆分支 - 如何清理
之後我再次在正確的分支中做了更改。 所以我結束了正確分支的所有更改,但每個分支也都屬於另一個分支。 然後對於我推送的分支A和分支B,我已經提出了請求。
問題1:如何從每個分支中刪除不屬於此處的更改? 我確切地知道我需要恢復到原始狀態的分支中的哪些文件。
問題2:如何更改已經發出的拉請求?
爲了將來的參考,在推送之前清理它會更安全。在這一點上,你有兩個選擇:
您可以創建新的分支機構(新名稱)和遷移所需的更改他們每個人。現有的分支將最終被放棄。
您可以「重寫歷史記錄」來修復現有分支。任何取回/拉動現有分支的人都必須執行恢復程序(請參閱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
這些改變 - 你可以改變命令從pick
到drop
如果任何承諾有變化的組合(有些屬於上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
選項)。
Tkx ,,這很清楚。我們在分支中也有不止一個功能,您的解決方案我認爲可以爲每個功能創建一個新的分支並從RootA開始,只需選擇該功能的更改即可。然後爲特徵2創建一個分支,從RootA開始,再次只選擇屬於特徵2的更改。如果所有功能都拆分刪除brancheA。它是否正確? –
@JacJac是的,這是正確的。 –
如果您還沒有推開這些分支的是,你可以:
tmpA
和tmpB
(例如從origin/A
和origin/B
)git cherry-pick
你需要從A
到tmpA
的提交,和從B
到tmpB
;如果你需要編輯提交使用選項--no-commit
,然後git reset
清除指數,其次是git add -p
只添加需要進行修改,然後提交結果A
到tmpA
(git branch -f A tmpA
),同樣爲B
。tmpA
和tmpB
。Tkx,與櫻桃挑選是可能分裂一個承諾?在一次提交中,我們有時會更改brancheA和nrancheB。我認爲櫻桃採取整個承諾? –
@JacJac是的,但你可以使用'git cherry-pick'和'--no-commit'選項。然後做一個'git reset',你現在可以用'git add -p'只添加你需要的東西。一旦你添加了你需要的文件(或文件的一部分),提交併執行'git clean -fd'。 – VonC
是那個已經被接收器合併的請求了嗎? – quetzalcoatl
不,他們沒有合併它 –
如果他們還沒有合併它,然後**拉請求**是沒有意義的。基本上它只記得一個「註釋」,說「請將我的公共回購分支FOOBAR合併到你的BARFOO」。當你清理一些事情然後發佈/推送那些清理時,pull請求將不會改變。它**仍然會告訴相同的**:「請將我的foobar合併到您的barfoo中」。但是,現在,顯然,您的foobar將在清理後=>因此,您可以認爲「拉取請求」是自動自我更新。當然,它很方便,但只要它們尚未合併即可。 – quetzalcoatl