2013-04-17 36 views
1

將git存儲庫重新綁定成最簡單的方法是什麼?只有當前分支的頭部保持機密,其他所有分支都被壓扁?最好是我可以應用於各種存儲庫的非交互式解決方案。非交互式的git squash/rebase全部轉化爲當前分支頭

背景:我的存儲庫太大了,因爲它正在跟蹤以前版本中的很多遺留代碼。我刪除了我不再感興趣的分支機構。對於其餘分支機構,我想保留最終版本用於歸檔目的,但要清理所有中間變更。

回答

2

因爲我發現這個問題很有趣,所以我寫了一個小小的bash腳本,它可以提供你想要的東西。

您可以download it as a file(或查看its repo on Github)並找到下面的來源。這裏有一個小的討論:

用法:

./start_git_repo_fresh.sh [-r] [<path to git repo>]
其中-r使公共根的創建提交和路徑讓我們使用來自不同位置的腳本;如果路徑被省略,則使用當前目錄(CWD)

此腳本的主要任務是移植現有的分支,通過簡單地使用他們最新的承諾(因爲Git修訂是完整的信息庫的快照,這很容易)。

如果您指定-r標誌,則會創建一個新的空根提交,並且將所有分支創建爲該根提交的直接後代。如果你沒有指定標誌,那麼每個新分支都有它自己的根(它們將是孤兒分支)並且每個都包含一個提交。

這是通過獲得一個現有的本地分支分支並走過它們;每個分支(稱之爲BR),腳本將:

  • -r指定
    • (一)創建新的共同的根新枝犯
    • (二)檢查出從BR
  • 文件時指定
    -r
    • (a)中檢查出BR
    • (b)中創建從BR一個新的孤兒分支
  • (c)使用從BR提交消息從BR提交文件
  • (d)刪除老枝BR
  • (五)重命名新創建的分支BR

如果分支在腳本啓動時簽出(回購不在分離的HEAD狀態中),則在最後檢出該分支的新版本;如果回購是在分離的HEAD上,則最後創建的分支將被退出。


腳本來源:

#!/bin/bash 

COMMON_ROOT=0 
TEMP_ROOT_BRANCH="NEW_ROOT_COMMIT" 

if [ "$1" == "-r" ]; then 
    COMMON_ROOT=1 
    shift 1 
fi 

if [ "$#" -eq 1 ]; then 
    cd "$1" 
fi 

branches=$(git branch --color=never) 
orig_branch=$(echo "$branches" | grep --color=never "^\* " | sed "s/^\* //") 

if [ "$COMMON_ROOT" -eq 1 ]; then 
    echo "Creating new (empty) common root commit" 
    git checkout --orphan "$TEMP_ROOT_BRANCH" 2> /dev/null 
    git rm -r --cached . >/dev/null 
    git clean -dfx > /dev/null 
    git commit --allow-empty -m "Initial commit" > /dev/null 
fi 

echo "$branches" | sed "s/^\* //" | while read branch; do 
    echo "Transplanting branch $branch" 
    newbranch="${branch}_new" 
    if [ "$COMMON_ROOT" -eq 1 ]; then 
     git checkout -b "$newbranch" "$TEMP_ROOT_BRANCH" > /dev/null 2>/dev/null 
     git checkout "$branch" -- . > /dev/null 2>/dev/null 
    else 
     git checkout "$branch" > /dev/null 2>/dev/null 
     git checkout --orphan "$newbranch" > /dev/null 2>/dev/null 
    fi 
    git commit -C "$branch" > /dev/null 
    git branch -D "$branch" > /dev/null 
    git branch -m "$newbranch" "$branch" > /dev/null 
done 

if [ "$COMMON_ROOT" -eq 1 ]; then 
    git branch -D "$TEMP_ROOT_BRANCH" > /dev/null 
fi 

if [ -n "$orig_branch" ]; then 
    git checkout "$orig_branch" 2>/dev/null 
fi