[筆記]Copy git commited changed files into new directory
有時候,會需要只取得變更的程式檔案,再做打包
列出 commit 的變更
可在 Git Bash 使用git-diff
指令
(列出時,若超過目前 console 高度,按ENTER往下瀏覽,按q結束離開)
使用--name-only
列出檔案名稱
- 兩個 commit 間差異的變更
SHA1
與SHA2
分別為你要比對的兩個 commit
1 | git diff --name-only SHA1 SHA2 |
- 取得 not staged 的變更 (也就是尚未
git add
):
1 | git diff --name-only |
- 比對取得最後一個 commit 之後的變更
1 | git diff --name-only HEAD |
- 比對取得最後一個 commit 之前 與最後一個 commit 之間的變更
1 | git diff --name-only HEAD^ HEAD |
Q: 如果改成
git diff --name-only HEAD^
會是甚麼?
A: 就是比對最後一個 commit 之前,與最後一個 commit 之後的變更
就像是
git diff --name-only HEAD^ HEAD
加上
git diff --name-only HEAD
的結果
僅取得狀態為新增與修改的變更
以上的指令,會列出所有的變更,包含已刪除的檔案。
因此,當要進行複製,若列表包含已刪除的檔案,便會出現問題。
則可加上使用--diff-filter
參數
- 新增(Added) : A
- 修改(Modified) : M
- 刪除(Deleted) : D
… 等等
大寫表示 include,小寫表示 exclude
若僅需列出新增(Added)、修改(Modified):
1 | git diff --name-only --diff-filter=AM HEAD^ HEAD |
相對的,若僅須排除刪除的:1
git diff --name-only --diff-filter=d HEAD^ HEAD
複製列出的檔案到新的資料夾
複製的指令,可使用 cp
若要讓複製的檔案在新的根目錄中,維持原本的檔案夾結構
須加上參數 --parents
有關$()
的說明,可參考這篇unix.stackchange
意思大概是,將$()
內的指令,執行的結果,帶入$()
所在指令的位置
所以可以利用$()
結合如下:
(其中out-dir
須為已存在之資料夾)
1 | cp --parents $(git diff --name-only --diff-filter=d HEAD^ HEAD) out-dir |
建立新資料夾存放複製的檔案
若要一併於指令執行時建立存放的資料夾,可使用mkdir
然而,若資料夾已存在,直接使用mkdir
會丟出錯誤
加上-p
便不會丟出錯誤(並不會取代)
若要取代,則需先將現有資料夾含所有內容刪除 (使用rm -r
)
但是,若刪除時資料夾不存在,仍會丟出錯誤
則須加上-f
忽略不存在的情形,變成
1 | rm -rf dirname |
因此,可再修改成:
(;
表示前方指令的結束,因此,會依序刪除、建立資料夾,再進行複製檔案搬移)
1 | rm -rf out-dir; mkdir out-dir; cp --parents $(git diff --name-only --diff-filter=d HEAD^ HEAD) out-dir |