1

現在のブランチの先頭だけがそのまま残り、他のすべてが押しつぶされるように git リポジトリをリベースする最も簡単な方法は何ですか? できれば、さまざまなリポジトリに適用できる非対話型のソリューションです。

背景: 以前のバージョンからの多くのレガシー コードを追跡しているため、リポジトリが大きすぎます。興味がなくなったブランチを削除しました。残りのブランチについては、アーカイブのために最終バージョンを保持したいと思いますが、中間の変更はすべてクリーンアップします。

4

1 に答える 1

2

私はこの質問が興味深いと思ったので、あなたが望むこと (のようなもの) を行う小さな bash スクリプトを書きました。

ファイルとしてダウンロードして(またはGithub のレポをチェックして)、以下のソースを見つけることができます。ここに少し議論があります:

使用法:

./start_git_repo_fresh.sh [-r] [<path to git repo>]
where-rは共通のルート コミットの作成を有効にし、パスは別の場所からスクリプトを使用できるようにします。パスを省略すると、現在のディレクトリ (CWD) が使用されます

このスクリプトの主なタスクは、最新のコミットを使用するだけで、現在存在するブランチを移植することです (Git コミットは完全なリポジトリのスナップショットなので、簡単です)。

フラグを指定する-rと、新しい空のルート コミットが作成され、すべてのブランチがそのルート コミットの直接の子孫として作成されます。フラグを指定しない場合、すべての新しいブランチには独自のルートがあり (孤立したブランチになります)、それぞれに 1 つのコミットが含まれます。

これは、既存のローカル ブランチのブランチを取得し、それらの上を歩くことによって行われます。各ブランチ (call it BR) に対して、スクリプトは次のことを行います。

  • いつ-r指定されるか
    • (a) 新しい共通ルート コミットから新しいブランチを作成する
    • (b) からファイルをチェックアウトします。BR
  • 指定-rない場合
    • (a) チェックアウトBR
    • (b) から新しい孤立ブランチを作成するBR
  • (c) からBRのコミット メッセージを使用して、からファイルをコミットします。BR
  • (d) 古いブランチを削除するBR
  • (e) 新しく作成したブランチの名前を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
于 2013-04-17T19:56:48.020 に答える