一般執行git cherry-pick只會套用到專案下的相同資料夾的相同檔案,
若是要將提交套到不同資料夾下的檔案,需先將提交內容轉成patch檔案,
再視情況使用git am 或 patch
產生patch
git format-patch [--relative=<path>] <committish> [--stdout > <patch-file>]
其中
- –relative是為限制patch範圍在某個子資料夾下,例如僅針對專案下的images的修改,就設定–relative=images 或 –relative images,而抽出的patch檔裡,原始提交的images路徑就會被移除。
- <committish>是提交的範圍,例如head^或hash1..hash2
- –stdout是為了將提交內容顯示在螢幕上,然後再透過 > <patch-file>將標準輸出轉成指定的patch檔案,若不指定 –stdout ,git format-patch則會將每個提交產生個別的patch檔案
套用PATCH到不同資料夾的不同檔案
patch [--directory=<dir>] < <patch-file>
上述指令會將<patch-file>套到指定的<dir>下,如果是同層資料夾可省略–directory。如果<patch-file>套到的是相同檔名的檔案,則會直接套用,若不存在與patch同名的檔案,patch會等待輸入檔名套用,見下圖紅框處,請自行指定要套用的檔名。
套用PATCH到不同資料夾的相同檔案
git am [--3way] [--directory=<dir>] <patch-file>
git am可指定不同資料夾套用patch,但必須是相同檔名,而且檔案的狀態必須與patch前的狀態一模一樣,否則預設狀態下是不會套用patch。如果檔案狀態不一樣,可以加上–3way參數,git會嘗試將提交套到指定檔案。
差異
patch指令會將patch檔套到檔案,但不會直接建立提交,git am則在套用patch之後直接建立提交。
結論
無論patch 或 git am,若是要將 patch檔套到現存檔案,檔案的內容必須和patch檔的裡的結構相似,不然是套不過去的,雖然兩者都可以加上–reject,套用適用的patch並將不適用的patch輸出成.rej檔案,並放在目的專案下,但若要套用的patch絕大部份都不相容,上述的操作應該也無法帶來什麼好處,直接用比對工具來處理可能還比較適合。
不過如果需要套用patch的檔案數量很多,也許試試看也無妨,反正也沒有更有效的方法了。
新增於2023/08/03
今天終於注意到git am還有個–3way選項可以用,這樣一來,其他資料夾下的檔案就不需要維持相同狀態了(就是提交修改處的前後三行的範圍要一模一樣)。