2014-06-06 82 views
16

我希望能夠做到這一點:混帳:獲得的git的'好處底墊--interactive`櫻桃挑選

git cherry-pick --interactive hash-0..hash-n-1 # fantasy command 

,並獲得相同的工作流程互動變基:編輯緩衝區來起來,包含:

pick hash-0 
pick hash-1 
pick hash-2 
... 
pick hash-n-1 

在那裏我可以刪除任何不需要提交,squash在一起,或edit的選秀權之間的停頓做一些手工修正(如commit --amend)和所有。

注互動變基pick是怎麼樣tanalizingly cherry-pick

現在上述操作可以通過首先執行櫻桃挑選來完成,然後交互式變基,這是不方便的。那就是:

$ git tag old-head # mark starting point for later rebase 
$ git cherry-pick hash-0..hash-n-1 # get everything first 
$ git rebase --interactive old-head # okay now rebase "in-branch" to fix it up 

這不僅是不方便的,因爲這兩個步驟,而是因爲它可能需要解決衝突的承諾,你甚至不想將在底墊階段被丟棄。

+2

是不是'git的重訂 - 那就是嗎? –

+0

@CarlNorum我不知道;如果是這樣,它可以擴展爲答案嗎? – Kaz

+0

你是否真的試圖挑選提交範圍'hash-0..hash-n-1',或者你在尋找一個可以推廣到不一定是祖先/後代的任意提交的答案? –

回答

1

也許一個更好的答案就在那裏,但是這可能爲你工作

git cherry | awk '$0=$2' > cherry.txt 
"$EDITOR" cherry.txt 
git cherry-pick --stdin < cherry.txt 

Example

+2

嗯,不是真的,但是感謝'$ 0 = $ 2' awk技巧:比'{print $ 2}'更清晰。 – Kaz

4

好吧,卡爾Norum時的建議下,我看着的git rebase--onto說法。

用例可以像這樣得到滿足,這是一種改進,雖然仍然涉及到多少步驟。

的主要問題是,底墊需要一個當前分支的,所以我們對我們的座標轉移到一個臨時的分支,然後後來操縱我們原來的分支頭和刪除臨時黨支部挑選。

流動看起來像這樣:

# We are originally on "mybranch" 
# We create a temp-branch pointing to the last commit to be picked: hash-n-1 

$ git checkout -b temp-branch hash-n-1 # create branch at last hash 

# Then we rebase from the point before the first hash, onto our original branch 

$ git rebase --interactive hash-0^ --onto mybranch 

# The above rebase should make "temp-branch" into the very object that 
# we want "mybranch" to be. If it looks that way, then all that is left is 
# make it so: 

$ git checkout mybranch   
$ git reset --hard temp-branch 
$ git branch -D temp-branch 

git rebase --interactive hash-0^ --onto mybranch使用hash-0爲「上游」之前提交的底墊,把所有的提交從當前分支(基於hash-n-1),它們是不上游。那些提交當然是hash-0hash-n-1。他們被重新綁定到mybranch頭上,但它是當前的temp-branch,即reset --hard來跟蹤結果。所以我們只需將該指針分配給mybranch並刪除temp-branch

這是相當笨拙,但消除重複挑肥揀瘦,而且很容易在任何時候恢復只是git reset --hard mybranch

(這還可以改進嗎?)

+0

據我所知,這與Git的本土瓷器命令一樣好。您可能會構建一個簡單易用的別名,它使用管道命令來實現您最初想要的內容,但我對這些管道命令不太熟悉。 –

+0

@Cupcake如果我們開始一個交互式底圖,會發生什麼,但是然後添加提交('pick'線)到原來不是最初的提交?它會採取他們還是採取?我必須嘗試一下。 – Kaz

+0

其實,現在你已經提到過了,我聽說'rebase'確實只是在引擎蓋下運行'cherry-pick',但我不知道這是否是真的。我認爲'rebase'只是一個shell腳本,讓我檢查一下... –

22

好的,想出了一個很好的黑客。

開始一個微不足道的rebase --interactive HEAD^了一個提交當前分支。你喜歡的東西:

pick 1efd396b * Fixed a bug in frob function 

現在,只需粘貼要挑更多的哈希值:

pick 1efd396b * Fixed a bug in frob function 
pick f01934db * Awesome feature added 
pick 6fd109c1 * Refactored the widgets layer 
squash 3900fd77 * Refactored the widgets layer s'more 

保存並退出,凌晨:在rebase騾子乖乖把你裝上額外的克魯夫特它的後面,並根據命令將其合併到當前分支中。

實際上,你可以做一個空的底墊:

git rebase --interactive HEAD 

你得到含有

noop 

您不必刪除緩衝區;在此之後添加你的選擇。

附錄:要產生選擇列表,此方法,使用git log --oneline --reverse from..to,然後修整所需要的輸出,並在前面加上底墊命令的每一行:picksquash,...

+0

如果有人願意查看源代碼,'git rebase'目前只是一個Bash shell腳本,可能會或可能不會在引擎蓋下采摘櫻桃,但如果將它轉化爲更快的C實現,未來可能會發生變化。 –

+0

@Cupcake是否意味着每次執行'git pull'(即配置了'--rebase'語義,或者顯式地使用該選項),它都運行shell代碼? – Kaz

+0

嗯,'git pull'本身實際上只是一個[shell腳本](https://github.com/git/git/glob/v2.0.0/git-pull.sh),目前。 –