2

私のレポにはいくつかのサブツリー (例: ./sub1/./sub2/..) があり、それらを別のレポに抽出して、コミット履歴と同じディレクトリ構造を維持したいと考えています。つまり、新しいレポにはメイン レポのサブツリーがsub1必要です。./sub1/これどうやってするの?

4

1 に答える 1

5

サブツリーフィルターでgitのフィルターブランチを使用できます。

手順は次のとおりです。

  1. 作業コピーを複製します。この操作はローカル リポジトリを変更するため、最初に作業コピーが必要です。以下のように git clone を実行するか、単にコピーすることができます。

    git clone --no-hardlinks <original repository> <working copy>
    
  2. サブツリー フィルタを使用します。

    cd <working copy>
    
    git filter-branch --subdirectory-filter <subdir path to be splited> --prune-empty --tag-name-filter cat -- --all
    
    # reset current working directory
    git reset --hard
    
  3. 多くの古いオブジェクトが到達不能になったため、クリーニング作業を行う方がよいでしょう。

    1. 古いリモコンを削除する

      git remote rm origin
      
    2. 古いリログを削除

      # clean unneeded reflog in order to free space
      refbak=$(git for-each-ref --format="%(refname)" refs/original/)
      if [ -n "$refbak" ];then
          echo -n $refbak | xargs -n 1 git update-ref -d
      fi
      git reflog expire --expire=now --all
      
    3. レポを再パックして圧縮する

      # prune loose objects
      git gc --aggressive --prune=now
      

これにより、リポジトリ構造がから変更されます

repo/
    |-- sub1/
        |-- sub11
        |-- sub12
    |-- sub2

repo/
    |-- sub11
    |-- sub12

でも、こうなりたいらしい

repo/
    |-- sub1/
        |-- sub11
        |-- sub12

次に、もう 1 つの手順を実行する必要があります。git コミット履歴を index-filter で書き換えます。

# replace <subdir path> with the actual subdir path, for this case, it should be "sub1"
git filter-branch --index-filter 'git ls-files -s | sed "s-\t-&<subdir path>/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD
于 2012-10-10T11:41:06.327 に答える