問題: 由于項目的版本線混亂, 導致可能需要在不同分支上切換, 而且某些功能也可能在不同分支上移動.
一個版本可能有多個功能點, 一個版本又對應于一個分支, 如果一個功能點有多個提交, 那么當其他分支需要這個功能點時怎么辦? cherry-pick或patch都可以實現(xiàn), 但是都各有麻煩的地方: cherry-pick需要找出要移動的功能點相關的提交記錄, 而patch需要功能點的提交記錄都是連續(xù)的. 實際開發(fā)中不同功能點之間的提交記錄往往是穿插的. 如果某個功能點相關的改動只生成一個commit,這將極大的簡化功能點在分支間的移動工作. 那么是否可以實現(xiàn)改動某次提交和將現(xiàn)有改動追加到某次提交上呢?
下面是cherry將某個功能點從一個分支移動到其他分支的示意圖:

如上圖, 可以使用cherry-pick將某個功能點從branchA移動到branchB上, 步驟如下:
- 切到branchB分支上
- 執(zhí)行命令
git cherry-pick 0096b95 7bfbaaa 326d7d8
那么問題來了, 如果某個功能點提交了很多次且log信息不規(guī)范, 那我們找commit-hash的時候就得費一番功夫了, 可不可以將后來的改動追加到以前的某個commit上呢? 或者直接更改改以前的某次提交?
答案是: 可以! (git中將當前改動追加到上一次提交上可以使用命令git commit --amend實現(xiàn), 下面介紹的兩種解決方案都使用了這樣命令)
<一> 下面是直接更改某次提交的操作步驟:
- 將HEAD移到需要更改的commit上:
git rebase f744c32cf74454a74bb2f80e5e38b120cb475af1^ --interactive
找到需要更改的commit, 將行首的pick改成edit, 按esc, 輸入:wq退出 - 更改文件
- 使用
git add 改動的文件添加改動文件到暫存 - 使用
git commit --amend追加改動到第一步中指定的commit上 - 使用
git rebase --continue移動HEAD到最新的commit處
這里會有沖突, 需要解決:- 編輯沖突文件, 解決沖突
git add .git commit --amend
解決沖突之后再執(zhí)行git rebase --continue
上述方法, 是改動某個指定的commit, 如果我要將工作空間中已經改動的東西追加到某個commit上, 那么改如何做呢?
<二>將工作空間中的改動追加到某次提交上的步驟如下:
- 保存工作空間中的改動
git stash - 后面的步驟就和上面的決絕方案的步驟差不多, 只是第2步的
更改文件改成執(zhí)行命令git stash pop, 其他步驟都一樣
這樣處理之后, 如果branchB分支需要branchA分支上的某個功能, 只需要找到這個功能的惟一的一個提交記錄即可, 就不需要在很多commit之中尋找這個功能點的相關提交記錄. 更改合并之后再移動功能點, 就簡單了許多, 執(zhí)行找到功能點的惟一一個提交記錄, 讓后使用git cherry-pick commit-hash即可, 操作示意圖如下:

總結: 上述更改摸個提交記錄/將現(xiàn)有改動追加到某個commit之上的方案在實際開發(fā)環(huán)境中的需求并不多, 而且實現(xiàn)起來有相當?shù)木窒扌? 原因如下:
- 如果版本規(guī)劃比較清晰, 就不會出現(xiàn)某個功能在不同版本之間穿梭的情形, 出現(xiàn)這種情況的大部分原因是:
多個版本的開發(fā)并發(fā)進行(產品你TMD當我們是電腦么, 有多個cpu同時運行啊?! 不好意思, 忍不住爆粗口了-_-!) - 實際開發(fā)中一次提交中的改動不可能只改動一個功能點 (如果模塊或者功能點的邊界劃分的十分清晰, 是可以做到每次只改動一個功能點的)