Git 批次刪除某段時間前的遠端分支

  1. 前言
  2. 前置作業 修改 Powershell 輸出 UTF-8 (避免輸出中文字亂碼)
  3. 操作流程
  4. DeleteGitRemoteBranch.ps1 原始檔
  5. 參考連結

前言

在使用 Git 作為版控開發專案時,若以 Gitflow 來執行時
開發人員從 master 拉出 feature/* 分支進行開發後,當 feature 分支 開發完成合進 master 後
該 feature 分支 是否要直接刪除,則依照各開發團隊的規格即可,有些 Pull Request 機制也可勾選 Merge 後自動刪除分支。
合併進主線後,立即刪除 feature 分支的好處是,遠端分支看起來相對乾淨
但缺點是若要退版 or 重新併版時,就有一點麻煩,因為 feature 分支被刪除了
而不立即刪除 feature 分支,則彈性會多一點,但也會造成遠端分支繁雜,需要固定清理維護。

因目前開發團隊是選擇 不立即刪除 feature 分支,導致遠端分支 甚至有超過3、4年的分支還存在,所以寫了批次腳本來做刪除

Git Flow 是什麼?為什麼需要這種東西?

前置作業 修改 Powershell 輸出 UTF-8 (避免輸出中文字亂碼)

  1. 查詢 Powershell profile 所在路徑

    $profile
    

  2. 若該路徑無該檔案 則自行新增

    $OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
    

操作流程

  1. 將 DeleteGitRemoteBranch.ps1 放在專案 git 目錄下

  2. 設定腳本參數 提供了三個參數可設定
    保護分支($protectedBranch) = 刪除分支時略過保護分支 (判斷遠端分支名稱包含保護分支名稱)
    檢查 Commit 日期($checkDate) = 刪除該時間之前的分支 (判斷分支最後Commit時間)
    保護特定 Commit 人員的分支($protectedCommiter) = 不刪除該人員的分支 (判斷該分支最後的Commiter)

  3. 執行腳本
    $checkDate 設為 2022-03-01 (刪除 2022-03-01 以前的分支)
    $protectedBranch 設為 master、20220125_z、20220126_z (刪除時略過這三個分支)
    $protectedCommiter 設為 w4560000

  4. 確認列出的遠端儲存庫路徑、待刪除的遠端分支是否正確 ($protectedCommiter 的分支也會列出,但會註記不刪除)

    若確認發現有異常 不刪除時 則程式直接結束

    確認沒問題 則輸入 y or yes

    成功刪除 develop、分支測試兩個分支

DeleteGitRemoteBranch.ps1 原始檔

# 參數定義
# 保護的分支 無法刪除
$protectedBranch = 'master', '20220125_z', '20220126_z'

# 檢查Commit日期
$checkDate = "2022-03-01"

# 保護特定Commit人員的分支
$protectedCommiter = 'w4560000'

Write-Host "刪除" $checkDate "之前分支 Start~`n"
Write-Host "遠端儲存庫:"
foreach ($remote in $(git remote -v)) {
    Write-Host $remote
}
Write-Host

Write-Host '已排除保護分支 ' $protectedBranch

Write-Host

$branchCount = $(git branch -ar | Select-String $protectedBranch -NotMatch | % { $_.ToString().Trim() }).count

if ($branchCount -eq 0) {
    Write-Host "無分支可刪除"
    Write-Host "請輸入任意鍵 結束程式"
    $anykey = [System.Console]::ReadKey($true)
    return;
}

$deleteFlag = $false;
$deleteBranchList = @()

foreach ($branch in $(git branch -ar | Select-String $protectedBranch -NotMatch | % { $_.ToString().Trim() })) {

    # 列出 無異動 commit 的分支
    if (!$(git log $branch -1 --since=$checkDate  --pretty=format:"%H")) {

        $author = $(git log $branch -1 --pretty=format:"%an")
        $lastCommitDate = $(git log $branch -1 --pretty=format:"%ad" --date=format:'%Y-%m-%d %H:%M:%S')

        # 處理中文排版對齊
        $count = $branch.Length - $($branch -replace '[\u4E00-\u9FFF]', '').Length
        $branch = $branch.PadRight(80 - $count)

        # 保護特定Commit人員的分支先不刪
        if ($author.Contains($protectedCommiter)) { 
            Write-Host $branch
            Write-Host ' - 分支最後異動人員' $author.PadRight(30) $lastCommitDate '(' $protectedCommiter '的分支先不刪)'
            Write-Host
            continue;
        }

        Write-Host $branch
        Write-Host ' - 分支最後異動人員' $author.PadRight(30) $lastCommitDate
        Write-Host
        $deleteBranchList += $branch | % { $_.trim().replace('origin/', '') };
        $deleteFlag = $true;
    }
}

if ($deleteFlag -eq $false) {
    Write-Host "無分支可刪除"
    Write-Host "請輸入任意鍵 結束程式"
    $anykey = [System.Console]::ReadKey($true)
    return;
}

$confirmation = Read-Host "`n是否要刪除以上分支? [Y] Yes [N] No" 

if ($confirmation.ToLower() -eq 'y' -or $confirmation.ToLower() -eq 'yes') {
    Write-Host "`n開始刪除...`n"

    foreach ($branch in $deleteBranchList) {
        git push $(git remote) --delete $branch
    }
}

Write-Host "`n請輸入任意鍵 結束程式"
$anykey = [System.Console]::ReadKey($true)
return;

參考連結

Alan Tsai 的學習筆記 - [git]如何快速清理已經合並(merged)的分支(branch) - local及remote


轉載請註明來源,若有任何錯誤或表達不清楚的地方,歡迎在下方評論區留言,也可以來信至 leozheng0621@gmail.com
如果文章對您有幫助,歡迎斗內(donate),請我喝杯咖啡

斗內💰

×

歡迎斗內

github