ローカルファイルをmasterブランチと同じ状態にしたままで、別ブランチに切り替えたい
Gitのブランチ管理を正面から否定するような要望ですが、Gitのリポジトリと、Subversion のリポジトリを下記のように同期運用するために、このような動作が必要なのです。
- 社内サーバー上には git のリポジトリ、VPNの先のサーバ上には Subversion のリポジトリが存在します
- ワークツリーは .git/ と .svn/ の両方があります(両方でチェックアウトしています)
- importブランチは、Subversion のリポジトリの内容を取り込む専用ブランチとします
- masterブランチの内容を Subversion にコミットします(masterとimportの差分がコミットされる)
- Subversion のリポジトリ内容を svn update によりワークツリーへマージして取り込み、それをimportブランチにコミットし、masterブランチへ適宜マージします
Subversion 側からみて 3. から 4. の間でワークツリーを変更せずに、git のブランチをmasterからimportへ切り替えたいのです。
git-svn を使えば良いのでは?
サーバー上は Subversion で管理し、ローカルにgitを使うケースには適しているようですが、サーバー上に git リポジトリがあるケースについての事例が見つからず不安でした。また Subversion のリポジトリ全体ではなくブランチの一部を選択的にチェックアウトしていますし、将来のある時点で追いかけるブランチを切り替える必要もありますが、それを git-svn で運用できるか不安です。
※「このようなケースでも、git-svn で上手く運用できますよ」という情報があればぜひコメントください。
importブランチをチェックアウトして、masterブランチの内容をmergeすれば良いのでは?
マージは import から master への一方向にしたいのです。
というわけで、ローカルファイル(ワークツリー)を変更せずに Git のブランチを切り替える方法です
## masterブランチへ切り替える.
git checkout master
## ローカルファイルを変更せずに、masterブランチの先端を import ブランチの先端と同じ場所へ移動する.
# このとき、変更前の masterブランチ先端は ORIG_HEAD としてラベル付けされる.
# --softオプションによりimportブランチ先端とローカルファイルの間の変更はステージングされる.
git reset --soft import
## importブランチへ切り替える.
# checkout とは 指定ブランチの先端をローカルファイルに取り出す動作である.
# master と import の先端が同じなので、ローカルファイルは変更されない.
# importブランチ先端とローカルファイルの間の変更はステージングされたままである.
git checkout import
## masterブランチの先端をreset前の元の位置(ORIG_HEAD)に戻しておく.
# 見慣れないコマンドだが、これで上手くいくのだ.
git update-ref refs/heads/master ORIG_HEAD
後は svn update でSubversionリポジトリの内容をワークツリーにマージし、git commit で importブランチへ取り込みます.