2013-01-09 37 views
5

我進口巴扎庫到GIT中(使用git bzr),但所得到的庫包含雜散提交父鏈接:取出雜散提交父指針

Spurious parent link

注意,提交標記1.02-6是基於離1.02-3提交,但1.02-1被不必要地也標記爲母體。 (注:在回購的這部分所有提交的標籤;還有所示的那些之間沒有提交。)

我曾嘗試在幾個方面基礎重建(在master分支:git rebase 1.02-3git rebase -i upstream-1.02git rebase --onto 1.02-1 1.02-3git rebase --root upstream-1.02 --onto=other_branch) ,但在每種情況下都會因合併衝突而失敗。這似乎是企圖超過必要的;歷史是正確除了一個額外的父指針被記錄在提交標記1.02-6

你如何刪除,以線性的歷史聯繫?有沒有比手工按順序挑選所有提交更好的方法?

+1

是真的「假」?或者是否修正了1.02-1的'1.02-1',但是沒有將它變成'1.02-3'(或者通過其他路徑)?不熟悉'bzr',我假設上面的圖只是簡化爲標籤發佈(即其他目前沒有顯示的提交/更改集)。 – twalberg

+0

@twalberg:不簡單。這些都是承諾。 –

+0

可能會有用:http://git-scm.com/docs/git-commit-tree,'git cat-file -p 1.02-6' –

回答

5

可以使用git commit-tree內部命令做手工。

我們想要編輯標記爲1.02-6的提交,以刪除虛假父指針(至56a2f3b5948ab54c9239c2b384a6ea9eb1f410c4)。

首先,閱讀從現有的提交對象的信息:

[email protected]:/path/repo.git$ git cat-file -p 1.02-6 
tree c658aa1ebcf2bf2a607696c7868b875be72fb01f 
parent 56a2f3b5948ab54c9239c2b384a6ea9eb1f410c4 
parent 4e671bf1d2298729c9e5cfd8229051cfe2c40831 
author James Damour (Suvarov454) <[email protected]> 1146319620 -0400 
committer Bazaar Package Importer <[email protected]> 1146319620 -0400 

The "main/" in the Section line of debian/control should be assumed. 

Extract the commit message using git log --format=%B -n 1 1.02-6.

現在創建一個具有相同內容的新的提交(不包括假父鏈接,並提交者信息):

git log --format=%B -n 1 1.02-6 | \ 
    GIT_AUTHOR_NAME="James Damour (Suvarov454)" \ 
    GIT_AUTHOR_EMAIL="[email protected]" \ 
    GIT_AUTHOR_DATE="1146319620 -0400" \ 
    git commit-tree c658aa1ebcf2bf2a607696c7868b875be72fb01f \ 
     -p 4e671bf1d2298729c9e5cfd8229051cfe2c40831 

這創建了一個新的提交,並打印了其散列(cc32e66 ...)。現在把它變成一個新的分支:

git checkout -b fixed_commit cc32e66 

和重訂master到新的分支:

git checkout master 
git rebase fixed_commit 

,我們就大功告成了:

Finished

你可能想要刪除舊的分支並重新標記適當的提交。


其實使用git filter-branch --parent-filter它可能會更容易。我沒有嘗試過。

1

你可以嘗試rebase。有一個例子有點下降(搜索 - onto),我認爲這與你的情況類似。

認爲你需要做的

git rebase --onto 1.02-1 1.02-3 

1.02-3之後,應該把一切都在1.02-1那可能是你想要的東西。

記住哈希將在一切不同於第一改變提交,但我認爲你這樣做是在從BZR移動的第一步所以沒有其他人應該還沒有克隆這一點。

+0

這給了一堆合併衝突。似乎試圖做超過必要的事情。 –

1

這會糾正父母在不改變任何東西(如提交者日期):

git filter-branch --tag-name-filter cat --parent-filter 'test $GIT_COMMIT = [sha of 1.02-6] && echo "-p [sha of 1.02-3]" || cat' -- 1.02-1..master

你將有相應的承諾ID來替換括號中的文字。如果您有更多需要重寫的下游分支,請將1.02-1..master更改爲--all並準備等待。

當然,如果其他人從你想編輯的任何提交後分支出來,請不要使用這個或任何其他解決方案。他們會恨你。

+0

如果你不需要關心其他人(例如,在從svn或bzr轉換到git之後,以及在你推送到你的git服務器之前進行清理),那麼這真的是最好的答案。我嘗試了所有這些。 –

10

最簡單的方法來做到這一點(在GIT中> = 1.6.5)是使用:

git replace --edit <sha> 

和刪除/添加/改變親:行。

一旦你感到高興的改變是正確的,你可以修改的提交,使更改永久有效:

git filter-branch --tag-name-filter cat -- --all 
+1

簡單而直接,沒有多個容易出錯的命令。這應該是被接受的答案! –

+2

注意我們可以運行第二個命令作爲'git filter-branch --tag-name-filter cat - ..head',所以我們只重寫所需的提交,而不是每一次提交。支持的參數記錄在這裏https://www.kernel.org/pub/software/scm/git/docs/git-rev-list.html – Michael

+0

要小心,不知何故,這在mac上永久崩潰sourcetree – HopefullyHelpful