如何讓Git匯出兩個Commit之間更新或新增的檔案

這件事應該常常發生,某人將一包Source交付給你,希望你完成某個任務後將Source交付,而為了安全我們只會交付異動過的檔案。通常我們會用工具或是腦記下自己修改哪些檔案,如果你有使用git做版本控制,那git也可以幫你完成這件事。

使用Git匯出

一般來說Git本身就有匯出的功能,我們可以使用指令來匯出Git的內容。

匯出.tar

git archive --output=files.tar HEAD $(git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT HEAD)

匯出.zip

git archive --format=zip --output=files.zip HEAD $(git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT HEAD)

但這指令太難記,而且我也不需要壓縮,因此要使用Script來協助工作。

Windows 平台

在Windows需要Batch檔完成,

首先需要透過Git指令來取得差異的檔案清單。

git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT <CommitID1> <CommitID2>

接著使用Bat指令執行迴圈輸出的動作。

for /f "usebackq tokens=*" %%A in (`git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT <CommitID1> <CommitID2>`) do echo FA|xcopy "%%~fA" "<ExportFolder>\%%A"

再來使用參數傳入Commite ID,並且動態產生輸出資料夾,這樣會更有效率。

echo Eport GitDiff
set /p input1=Export Start Commit ID: 
set commitIdStart=%input1%
set /p input2=Export End Commit ID: 
if [%input2%] ==[] (set commitIdEnd=HEAD) else (set commitIdEnd=%input2%)
echo Start ID = %commitIdStart%
echo End ID = %commitIdEnd%

for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined DateTime set DateTime=%%x
echo %DateTime%
set exportFolder=%DateTime:~0,4%%DateTime:~4,2%%DateTime:~6,2%_%DateTime:~8,6%
echo %exportFolder%
for /f "usebackq tokens=*" %%A in (`git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT %commitIdStart% %commitIdEnd%`) do echo FA|xcopy "%%~fA" "GitExport\%exportFolder%\%%A"
set /p DUMMY =Hit Enter To Continue....

 

macOS

與Windows相似,只是將使用Shell Script實作。

#!/bin/bash
echo "Export Git Diff"

read -p "Export Start Commit ID: " input1
read -p "Export End Commit ID: " input2

commitIdStart="${input1}"
if [ "${input2}" == "" ]; then
  commitIdEnd="HEAD"
else
  commitIdEnd="${input2}"
fi

echo "Start ID: $commitIdStart"
echo "End ID: $commitIdEnd"

#Create Export Folder
now=$(date +%Y%m%d_%H%M%S)
#echo "Current date: $now"
dirpath="GitExport/$now"
echo "Export Path:$dirpath"
mkdir -p $dirpath


#Get File List
files=$(git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT $commitIdStart $commitIdEnd);
#echo $files;

for item in $files ; do
    echo "Copy: $item"
  # For Linux (Todo Test)
  # cp --parents "$item" "$dirpath/$item"
  # For Mac OS
   ditto "$item" "$dirpath/$item"
done

read -p "Press enter to exit"

 

更詳細的說明可以參考我的github

https://github.com/lulualulu/GitDiffExport

Reference

https://blog.miniasp.com/post/2014/04/01/Git-Export-Only-Added-Modified-Files.aspx