git リポジトリの分岐

サブディレクトリを新しいリポジトリへ分岐させる (シンプルな場合)

git clone --no-hardlinks --branch master originalRepoURL childRepo
cd childRepo
git filter-branch --prune-empty --subdirectory-filter path/to/keep master
git remote remove origin
git prune
git gc --aggressive

originalRepoURLmasterpath/to/keep などは適当な値に変える。全てのブランチを処理したい場合は -- --all を使う。

サブディレクトリを新しいリポジトリへ分岐させる (複雑な場合)

複数のパスをフィルターしたい場合は、--index-filterbrew install gnu-sed findutils によってインストールできる GNU xargs と GNU sed を使う必要がある。

git clone --no-hardlinks --branch master originalRepoURL childRepo
cd childRepo
git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- path1/to/keep path2/to/keep' --prune-empty master
git filter-branch --prune-empty --parent-filter 'gsed "s/-p //g" | gxargs git show-branch --independent | gsed "s/\</-p /g"'
git remote remove origin
git prune
git gc --aggressive

originalRepoURLmasterpath1/to/keeppath2/to/keep などは適当な値に変える。全てのブランチを処理したい場合は -- --all を使う。

src を path/to/keep に戻す

--subdirectory-filterpath/to/keep 以下の src/ などをルートに移動してしまうので、元のパス (もしくは別のパス) に戻したい場合は移動させてコミットを 1つ追加する必要がある。

mkdir -p path/to/keep
git mv src path/to/keep
git commit -m "move files"

タグの削除

元リポの全てのタグを削除したい場合は、以下を deltags.sh という名前で保存して、実行する。

#!/bin/bash
 
for t in `git tag`
do
  git tag -d $t
done
chmod +x deltags.sh
./deltags.sh

既存のリポジトリへと merge する

オプションとして、このテクニックを応用して既存のリポへと履歴を接ぎ木をすることができる。
念の為 wip/graft というブランチを作ってそこに接ぎ木する。

cd ..
git clone someotherRepo
cd someotherRepo
git remote add childRepo ../childRepo
git checkout -b wip/graft
git pull childRepo master --allow-unrelated-histories
git remote remove childRepo

これでプルリクなどを送ることができる。

参照