2016-11-07 69 views
1

尋找壓扁提交,以便面向公衆的項目不會有像「temp」或「temp123」這樣沒有意義的提交消息。使用git reset --soft,標記一個提交,以便以後可以壓縮*向下*

我正在尋找一種方法來使用git reset --soft HEAD~5,但不是隨機選擇數字5,我想回到Git日誌並找到所有不匹配模式的提交,並且一旦我點擊我停止了模式。所以我們可以說我git log提交信息是這樣的:

temp123 
fooGit 
temp 
fml 
temp24 
tmp69 
tttoday 
publish/release:xyz 

,所以我會壓扁前7最近的提交,但放棄一切「的」 publish/release:xyz

由於相當複雜的原因,git merge --squash從公共分支發佈將不會爲我工作,因爲我最終刪除或重命名私人分支上的項目相當多的文件,所以有太多的合併衝突。在我看來,在嘗試了幾種方法後,最好用-f推向面向公衆的分支機構,而不是以這種方式擔心衝突。

我想在我的情況下,更好的方法是南瓜承諾,像這樣:

# on private "dev" branch 
# make a bunch of changes, rename files, yadda yadda 
git add . && git add -A && git commit -am "temp" && 
git checkout -b squash_branch # we do squashing on this branch to be safer 
git reset --soft head~15 # apparently this undoes commits for the last 15 commits 
git commit -am "A serious commit message" 
git push -u public master -f # overwrite public master 

這種方式,我從來沒有解決公衆面臨的分支和私人發展分支,它可以超之間的衝突從我的經驗中毫無意義和煩人。

但是,我試圖解決的問題與上面的數字15有關。我只是猜測有多少承諾「擠壓」。我寧願知道確切的數字來壓扁。

也許我可以做一個沒有適合某種模式的Git提交消息的所有提交的壓縮?所以當我運行壁球時,我創建了一個具有特定模式的提交消息,假設它是「XYZ」。我可以運行git reset --soft HEAD~(some git commit pattern matching to find the count)嗎?

還有一個問題。在squash_branch上執行壁球(git reset --soft)後,我應該將該分支合併回專用dev分支嗎?

+0

的Dev分支不跟蹤公共/主,在Dev分支跟蹤私人的/ dev –

回答

2

可以找到數,但這是有點危險的,因爲這將是錯號碼如果有合併提交存在於鏈(這裏未示出):

git rev-list --count HEAD^{/publish/release:xyz}..HEAD 

符號rev^{/text}的意思是「從給定rev開始,搜索給定的文本的每個提交消息(a la git log --grep)」。因此,第一個表達式在提交消息中與提交publish/release:xyz相匹配。 ..語法然後使用該提交的ID到刪除提交併提交從名稱HEAD選擇的提交的集合之前。 --count然後給我們剩餘的提交數。因此,如果你的圖形看起來是這樣的:

...--o--*--o--o--o--o <-- HEAD 

其中*是在它與文本提交,這會放棄提交*和其他進一步的左承諾,留下四名決賽o提交節點到HEAD點。 --count然後對這四次提交進行計數並打印4

總的來說,這是一個糟糕的策略。以分支或標記名稱標記點開始要好得多。分支或標籤名稱標識指向它的提交。而不是試圖找到模式提交*,只是標誌着它的時候你讓它:

git tag xyz 

現在你有這樣的:

 tag:xyz 
     | 
     v 
...--o--*--o--o--o <-- HEAD -> dev 

xyz..HEAD讓你正確的一組提交的,你可以git reset --soft xyz使分支標籤dev點回犯*

 tag:xyz 
     | 
     v 
...--o--* <-- HEAD -> dev 
     \ 
      o--o--o [only findable via reflogs] 

一旦你完成有了這個,只需刪除標籤即可。

(同樣,你可以使用一個分支或標記名稱;使用你喜歡哪個,我說明了這一個標籤,因爲標籤名稱不應該移動,而分支名稱動他們。移動自動,其實,只要你git checkout分支,然後進行提交,或使用git reset。標籤名稱指向一個特定的承諾,只是呆在那裏。)


注意,順便說一下,你可以不使用搜索通貨膨脹在創建標籤:

git tag xyz HEAD^{/publish/release:xyz} 

也就是說,你確定其呈交標記創建標籤名稱時。 (實際上對於分支名稱也是如此。)然後,您可以使用git log --decorate查看此標記,圖形查看器(如gitk)通常會向您顯示哪些提交具有哪些標記。

(搜索和標記是過渡到這更好的,至少在理論上,習慣的好辦法。)

+0

這是有點超過我的頭 - 基本上你說要使用標記,而不是統計提交消息日誌? –

+0

你是對的,並不是所有的開發都會發生在開發......未來將有功能分支將被合併到開發中,雖然現在我直接在開發分支上進行所有開發 –

+1

@AlexanderMills:「基本上你說的是使用標籤而不是統計提交消息日誌?「是的,它更簡單,並且在'git log --graph --decorate --oneline'輸出(或其他圖形瀏覽器)中很好地顯示出來。 – torek

1

我假設您的dev分支在開始工作之前跟蹤master。如果沒有,請在進行臨時提交之前創建一個新的分支。

要確定從master分支點(從而重置回點),這樣做:

git merge-base master HEAD 

可以表明這一點,並HEAD之間的所有承諾(這應該包括所有的臨時提交,只有那些提交)有:

git log --oneline $(git merge-base master HEAD)..HEAD 

可以通過管道將命令的輸出wc -l並獲得提交的數目,這是你需要爲你的git reset命令數量。

或者,你可以得到這個數字直接:

git rev-list --count $(git merge-base master HEAD)..HEAD 

全部放在一起:

git reset --soft HEAD~$(git log --oneline $(git merge-base master HEAD)..HEAD | wc -l) 

或者:

git reset --soft HEAD~$(git rev-list --count $(git merge-base master HEAD)..HEAD) 

做復位後,而不是合併squash_branch轉換爲dev,則可以更好地進行硬重置(船尾呃您確認沒有被打破,當然):

git checkout dev 
git reset --hard squash_branch 

此外,合併衝突往往發生是有原因的,所以我會警惕盲目強行推到遠端。如果您必須力量推動,然後做這個:

git push origin master --force-with-lease 

--force-with-lease標誌將導致Git的覆蓋,你已經獲取的任何承諾,但如果遙控器有新提交的命令將失敗,你不知道。

+0

感謝這看起來好,所以你在說我應該把squash分支合併回dev ..我還在原始問題中加了一條評論來澄清,你對toreks的回答是什麼? –

+0

@AlexanderMills如果你對'dev'沒有任何改變(如果你馬上做這個,你不會做任何改動),如果你不關心「 temp123「提交。如果您對工作流有更多疑問,請隨時[問一個新問題](// stackoverflow.com/questions/ask)。 torek的回答看起來也不錯(我已經提高了);標籤建議是我也有過的一個想法,所以如果您的分支工作流程阻止您使用我的解決方案,我會採取這種做法。 –

+0

是的,我認爲從長遠來看,會有分支機構脫離開發,所以是可能很好的嘗試標記方法 –

相關問題