トップ «前の日記(2009-03-24) 最新 次の日記(2009-04-01)» 編集 RDF

雄也の?日坊主日記


2009-03-28

_ [git] 自分管理でないソフトウェアを変更する際のワークフロー

自分管理でない既存のソフトウェアについて,不具合修正あるいは新機能追加を提案する際に,gitを使って効率よく作業する一連の作業手順を考えてみた.

ブランチの運用方針

本エントリで最も重要なことはブランチの運用方針を明確にすることである.

この作業手順では以下のような方針でブランチを運用する.

  • master

    行った修正や改良を普段使用するために用意する.

    upstreamとこのリポジトリで行った全ての作業を適用したもの. すなわち,後述するupstreamとchanges/*,localを全てマージしたもの.

  • upstream

    upstreamの変更点を各ブランチにマージするために使用する.

    upstreamの最新ソースコードを入れるブランチ.

    • SCMがある場合はオリジナルのSCMからpullするコード.
    • SCMがない場合はtarballなどから展開したコード.
  • changes/*

    このリポジトリで機能追加あるいは不具合修正を行うブランチ.

    変更ごとにブランチを別にする.

  • local

    リポジトリ固有のupstreamには有益でないと思われる変更を行うブランチ.

    例えば以下のようなものをこのブランチで作業する.

    • リポジトリ固有の運用方針を書いたドキュメント
    • changes/*の各ブランチでの変更内容を書いたドキュメント
    • 俺Toolsによる自動生成ファイルのファイル名を書いた.gitignore

作業可能になるまでの初期設定

最新のソースコードをインポートする.

% tar xfz ZenTest-3.11.1.tgz
% mv ZenTest-3.11.1 ZenTest
% cd ZenTest
% git init
% git add .
% git commit -m 'imported release 3.11.1.'

upstreamブランチを作ってそのブランチに移動する.

% git checkout -b upstream

リリースされたファイルをインポートした場合は必要に応じてタグを打つ.

% git tag upstream-release-3.11.1

localブランチを作る.

% git branch local

機能追加あるいは不具合修正するとき

upstreamブランチからブランチを作って移る.

% git checkout upstream
% git checkout -b changes/some-change

いろいろ作業してgit commitする.

作業が終わったら,masterに反映させる.

% git checkout master
% git merge changes/some-change

公開用リポジトリに反映させる. git push時に--allオプションを付けることで作った全てのブランチを反映できる.

% git remote add github git@github.com:nishidayuya/zentest.git
% git push --all github

反映したくないブランチがある場合は以下のように直接指定する.

% git push github changes/some-change
% git push github master
余談

「いろいろ作業してgit commitする」の間は必要に応じてさらにブランチを作って作業してもいい.

% git checkout -b changes/some-change-01
<いろいろ作業,いろいろgit commit>
% git checkout changes/some-change-01
% git merge --squash changes/some-change-01
% git commit -m 'some log.'
% git branch -D changes/some-change-01

リポジトリ固有の変更をするとき

localブランチに移る.

% git checkout local

いろいろ作業してgit commitする.

作業が終わったら,masterに反映させる.

% git checkout master
% git merge local

公開用リポジトリにも反映させる.

% git push --all github

upstreamの更新を受け入れるとき

upstreamブランチに移る.

% git checkout upstream

tarballの場合は一度全て消してから展開し,必要に応じてgit add,git commitする. 全て消してからでないとupstreamで削除されたファイルが反映できないためである.

% rm -rf *
% tar xfz ZenTest-4.0.0.tgz
% mv ZenTest-4.0.0/* .
% mv ZenTest-4.0.0/.autotest .
% rmdir ZenTest-4.0.0
% git add .
% git commit -m 'imported release 4.0.0.' -a
% git tag upstream-release-4.0.0

upstreamの変更をmaster以外の各ブランチに反映させる.

% for b in `git branch \
            | sed -e 's/\*/ /g' -e 's/^ *//g' \
                  -e '/^master$/ d' -e '/^upstream$/ d'`
  do
    git checkout $b
    git merge upstream || break
  done

上記をコンフリクトがなくなるまで繰返し行う.

masterにupstreamの変更をマージする.

  • 先の作業でコンフリクトが発生しなければ以下の<from-branch>はupstreamでいい.
  • コンフリクトが発生したブランチがあれば, <from-branch>はコンフリクトが発生したブランチにすると都合がいい.

    % git checkout master
    % git merge <from-branch>

このリポジトリで行った変更がupstreamにマージされている場合は, 作業を行ったブランチを削除する.

% git branch -D changes/some-change

公開用リポジトリにも反映させる.

% git push --all github

書いてみて気づいたこと

  1. 実行するコマンドはあくまで例示であり他の方法も考えられるだろう.
  2. SCMも必ずしもgitである必要はない. MercurialやDARCS,やりやすさはあるだろうがSubversionやCVSでも 同様のことはできるのではないだろうか.

4/10追記

  • 作業可能になるまでの初期設定段階ではなにも変更を加えてないので公開リポジトリに反映する必要はないんじゃないかと考えて変更した.

2004|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|
2006|05|
2007|04|05|09|10|11|
2008|04|05|08|10|11|
2009|02|03|04|05|06|07|08|09|10|11|
2010|02|03|04|07|10|
2011|04|08|
2012|02|10|
2014|05|06|08|
2018|03|
楽天で探す
楽天市場
キーワードから探す
楽天トラベル