言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

git でバックポート用のパッチを作る方法。

ようやく何となく git の使い方が分かりかけて来たのでメモ。ドキュメントを細切れに読んで自分で考えただけなので、もっと良い方法があったら教えてください!

目的

  • とあるレポジトリ trunk がある。
  • とあるブランチ experimental がある。
  • experimental に含まれる変更のうち、無難なやつだけのパッチを作りたい。

方針

  • trunk のクローンを作る
  • バックポート用のブランチを作る
  • バックポート用のブランチに、 experimental の内容を読み込む。
  • 実験的すぎる奴を元に戻す。
  • パッチを作成

実際

まず trunk のクローンとバックポート用のブランチを作ります。多分タグを作っておくと便利な気がします。

git clone ssh://example.org/trunk patch/
cd patch/
git checkout -b backport
git tag 適当なタグ名

それから、 experimental レポジトリを読み込みます。この時に git pull では無く、git fetch を使うと変更はすぐに反映されず、FETCH_HEAD と呼ばれる一時領域に保存されます。それから念のために変更点を gitk で眺めます。

git fetch ssh://example.org/experimental master
gitk HEAD..FETCH_HEAD

いよいよ実際にマージ(FETCH_HEAD の内容を反映)しますが、普通にやると勝手にコミットされてしまうので、 --no-commit を付けます。これで変更されたファイルはコミット待ちの状態になります。

git merge --no-commit FETCH_HEAD

それから不要なファイルを元に戻していきます。手順としては、

  • 新しいファイルは git reset HEAD でコミット待ちから外して、rm で削除
  • 変更されたファイルは git reset HEAD でコミット待ちから外して、git checkout で戻す。

次のようなコマンドを使います。

git status # 状態確認。コミット準備中と関係ないファイルに分かれて表示される。
git reset HEAD ファイル名 # コミット準備中から解除
git diff HEAD ファイル名 # コミット準備中のファイルと現在のファイルの差分をみる。
git clean ディレクトリ名 # レポジトリに無いファイルを削除
git checkout ファイル名 # ファイルを元に戻す

最後にビルドして、うまく行かないファイルを修正します。ビルド出来たらコミットします。最初に作ったタグとの diff でパッチを作ります。

git commit -m 'ログ'
git diff 適当なタグ名