2015-06-20 120 views
5

我試圖壓扁許多提交到一個單一的問題是,我需要做的作者(姓名或電子郵件)。Git Squash按作者 - 所有作者提交到一個提交

的情況:

可以說我有一個分支叫功能一,在這個部門我有很多很多的作者提交。如何將作者的所有提交(例如電子郵件)壓縮爲單個提交。我想這樣做是爲了能夠將所有作者提交合併到master中。

這裏有什麼幫助嗎?

在此先感謝

+0

聽起來好像它會導致大量不必要的工作。也就是說,如果特定作者的提交不是連續的,那麼壓縮它們將需要大量的手動干預。你最好讓你的許多作者各自在自己的分支上工作。 – larsks

回答

1

Be careful rewriting history

最終的結果你想可能是可能的,如果你對每個作者創建分支,cherry-pick從每個作者適當的分支的提交,然後壓扁這些變化。但是,如果這些提交有意義地相互依賴,我認爲這不會起作用。

如果你有一系列提交:

  Author1    Author2    Author1 
version1 ---commit---> version2 ---commit---> version3 ---commit--->... 

如果你嘗試從中提取Author2的變化,並將其應用於版本1,有一個很好的機會,它將沒有任何意義(例如,如果Author2修改Author1創建的代碼)。

1

考慮到Kenkroncaveats,你可以做:

SORTED_GIT_LOGS=$(git log --pretty="format:%an %H" master..feature_a | sort -g | cut -d' ' -f2); \ 
IFS=$(echo -en "\n\b"); for LOG in $SORTED_GIT_LOGS; do \ 
    git cherry-pick $LOG; \ 
done | less 

git log --pretty="format:%an %H" master..feature_a | sort -g將在feature_a提交(不是那些從master因爲master..feature_a語法)

的日誌分類您仍然需要進行交互式重新分版來壓扁master(現在由作者訂購)提交。

+0

交互式底座示例:http://denniskubes.com/2012/08/22/honey-i-squashed-the-commits/ – VonC

+0

如果作者完成,'git reset'也可以工作:http:// makandracards .com/makandra/527-squash-several-git-commits-into-a-single-commit – VonC

1

我需要在回收處於脫機狀態時對不必要的大型存儲庫進行類似的重寫。我採用的方法是使用GIT_SEQUENCE_EDITOR嘗試自動「交互式」rebase,this answer由@ james-foucar & @pfalcon覆蓋。

爲了更好地工作,我發現最好先從被重寫的歷史記錄中刪除合併。對於我自己的情況,這是使用大量的git rebase --onto完成的,這在StackOverflow的其他問題中得到了充分的說明。

我創建了一個small script generate-similiar-commit-squashes.sh生成pick & squash命令,這樣連續的相似提交會被壓扁。我使用author-date-and-shortlog來匹配類似的提交,但你只需要作者(我的要點有關如何使其僅匹配作者的評論)。

$ generate-similiar-commit-squashes.sh > /tmp/git-rebase-todo-list 

輸出看起來與同風格的「更新XYZ」提交信息像

... 
pick aaff1c556004539a54a7a33ce2fb859af0c4238c [email protected] 
squash aa190ea2323ece42f1cd212041bf61b94d751d5c [email protected] 
pick aab8c98981a8d824d2bc0d5278d59bc1a22cc7b0 [email protected]_config.yml 

的倉庫也充滿了自我恢復。當被壓扁時,他們導致空的承諾。

我正在合併的提交具有相同的提交消息。 git rebase -i提供了修改後的提交消息,並附加了所有壓縮的提交消息,這些消息將會重複。爲了解決這個問題,我使用了一個來自this answer的小Perl腳本來刪除git rebase提供的提交消息中的重複行。它在文件中更好,因爲它將用在shell變量中。

$ echo 'print if ! $x{$_}++' > /tmp/strip-seen-lines.pl 

現在的最後一步:

$ GIT_EDITOR='perl -i -n -f /tmp/strip-seen-lines.pl ' \ 
    GIT_SEQUENCE_EDITOR='cat /tmp/git-rebase-todo-list >' \ 
    git rebase --keep-empty -i $(git rev-list --max-parents=0 HEAD) 

儘管使用--keep-emptygit通過關於空提交這個過程中抱怨幾次。它會將我傾倒到控制檯上,但不完整git rebase。爲了跳過空的提交併恢復處理,需要以下兩個命令(在我的情況下相當頻繁)。

$ git reset HEAD^ 
$ GIT_EDITOR='perl -i -n -f /tmp/strip-seen-lines.pl ' git rebase --continue 

再次儘管--keep-empty,我發現我在最後提交歷史had no empty commits,所以上面的重置已經刪除它們。我認爲我的git版本2.14.1有問題。處理~100萬次這樣的提交在蹩腳的筆記本電腦上花了超過10分鐘。

+0

有趣的方法,比我的答案更完整。 +1。不知道你的'--keep-empty'問題。 – VonC

+0

重寫歷史記錄也值得注意,如果您不希望重寫過程將您自己(重寫器)作爲每次提交的提交者,您可能需要通過重置提交者來完成重寫。最簡單的方法是[設置提交者=作者](https://stackoverflow.com/a/32944640/5037965),但如果原始提交者信息實際上很重要並且需要保留,則需要更詳細的方法。 –

+0

我已經添加到https://gist.github.com/jayvdb/9b41677f00065dbd94cc02446fc5ba34一個腳本'generate-multiple-new-file-squashes.sh'來合併僅包含連續添加的提交(即提交者使用GitHub/GitLab/BitBucket Web UI「上傳文件」) –