きよくらの備忘録

「三日坊主と呼ばせない!日記」改め。主にソフトウェア開発関連の話題。

Visual Studio Team Serviceで別のチームプロジェクトにリポジトリをforkして運用するメモ

Visual Studio Team Service(以下VSTS)で 別のチームプロジェクトにリポジトリをforkして運用してみよう と試行錯誤中です。とりあえず今やり始めたことをメモがてら。

 

実現したいこと

実現したいのはgithubでよくあるような『手元で修正してpull requestを送るためのfork』では無く。どちらかと逆で。『forkしてカスタマイズしたソースに、適宜分岐元の修正やバージョンアップを取り込む』という運用です。

有体に言うと、

  • パッケージ販売するソリューションを開発していて
  • 顧客後のカスタマイズが発生した場合はフォークしたプロジェクトで開発
  • フォーク先は標準パッケージのバージョンアップや修正も適宜取り込む

ということをやりたい。

リポジトリの話だけではなく、VSTSその他の機能(WorkItem関連とかCI系の機能とかビルドサービスとか)もベースの開発プロジェクトとは分離さているほうが望ましいという事情もあって。で、今回はこういうのがうまくできないか試してみようとしているという次第です。

 

私が知る限り2016/12/06現在はVSTSにはこういった簡単にリポジトリをforkできるような機能がない(はず)です。しかし所詮リポジトリはgitですのでremoteでフォーク元を追跡すればどうにもでできるはず。少しググると、割と似たようなことをVSTS(当時はVSO)やってている記事を見つけたので、参考にさせていただきながらやってみました。

www.woodcp.com

 

注意:

これから紹介する内容は、実際に私が実務で「これから本格的に利用しよう」と思ってまずは実験的に作ってみた構成のメモです。 ほぼこのまま実務で利用しようとしてはいますが、まだ本格的に使っているわけではないので、気が付いていない不味いことや問題点などがあることは十分に考えられます。お気づきの点があればぜひ、教えていただけると本当にうれしいです。

 

Step by Step でやってみる

では、実際にstep by stepでやってみます。 操作やスクリーンショットは2016/12/06現在のものです。VSTSは比較的短いスプリントで割とドラスティックに画面変わったりするので、少し先には全然違うものになってる可能性はありますがご了承ください。

大まかに以下の手順をやってみます

  1. フォークの作成
    1. フォーク先のチームプロジェクトの作成
    2. フォーク元のプロジェクトを手元にクローン
    3. クローンしたリポジトリの内容をフォーク先にpush
    4. フォーク元のmaster取り込み用のブランチの作成
  2. フォーク元の更新の取り込み
    1. フォーク元のリポジトリをremoteに追加
    2. 取り込み用ブランチにマージ

 

0.フォーク元のプロジェクトとリポジトリについて

フォーク元として以下のプロジェクトがあることとします。パラメータはソースプロバイダをgitにする他は任意です。

  • Team Project Name : SomeSolutionStd
  • Process template:Scrum
  • Version control:Git

f:id:kiyokura:20161207010925p:plain

とりあえず、こんなコミット履歴があるとします。

f:id:kiyokura:20161207010943p:plain

 

1. フォークの作成

ここからが本番です。

 

1.フォーク先のプロジェクトを作成

とりあえずパラメータはこんな感じで。Version control だけGitになっていれば他は任意でよいでしょう。

  • Team Project Name : SomeSolutionCustomZ
  • Process template:Scrum
  • Version control:Git

f:id:kiyokura:20161207010309p:plain

 

2. フォーク元のプロジェクトを手元にクローン

まずフォーク元のリポジトリを手元の適当な場所にクローンします。このとき、originの設定などをいじるので、普段フォーク元の開発に利用しているものとは別のディレクトリに展開するする必要があります。 むしろフォーク先プロジェクトをローカルにチェックアウトするディレクトリが決まっているのであればそこにクローンしてしまってもよいです。

とりあえず今回は C:\Work\ 等にクローンしてみました。コマンドラインでやるなら以下のような感じでしょうか。

C:\Work> git clone https://<account>.visualstudio.com/DefaultCollection/_git/SomeSolutionStd

実行結果はこんな感じ。

f:id:kiyokura:20161207010325p:plain

 

3. クローンしたリポジトリの内容をフォーク先にpush

このクローンしたリポジトリを、fork先のリモートリポジトリにpushします

まずは、リモートオリジンとしてfork元のリポジトリが追加されてるので削除しておきましょう。 その後、としてfork先のリポジトリを追加し、プッシュします。 フォーク先のリポジトリのURLはクローン用のコピペ元とか適当に入手してください。

C:\Work> cd SomeSolutionStd
C:\Work\SomeSolutionStd> git remote remove origin
C:\Work\SomeSolutionStd> git remote add origin https://<account>.visualstudio.com/DefaultCollection/_git/SomeSolutionCustomZ
C:\Work\SomeSolutionStd> git push -u origin --all

これで、フォーク元のリポジトリが、フォーク先のリモートリポジトリに反映されました。

f:id:kiyokura:20161207010436p:plain

ブラウザで確認すると、ちゃんとコミット履歴もあります。

f:id:kiyokura:20161207010449p:plain

フォーク自体はこれで完了です。

 

4. フォーク元のmaster取り込み用のブランチの作成

フォーク自体は完了しているのですが、今後のメンテナンスを考えて、一つブランチを作成しておくことにしました。 このブランチのmasterには、先に述べだ通り「フォーク元とに決して反映することのない変更」が追加されていくことになります。

なので、フォーク元の変更を取り込む際に、いきなりmasterを更新するわけにはいきません*1

取り込むときに都度ブランチを作成してもよいのですが、今回はプロジェクト体制などの都合もあって「標準パッケージ(フォーク元)のmasterを定期的に取り込んでおくブランチ」を持っておくことにしました。

ブランチの名前は upstream-master にしておきます。

f:id:kiyokura:20161207010503p:plain

 

2. フォーク元の更新の取り込み

次は、実際に開発が進んだフォーク元の更新をフォーク先に取り込む手順です。

 

1. フォーク元のリポジトリをremoteに追加

フォーク元のリポジトリを、upstreamという名前でremoteリポジトリに追加しておきます。

git remote add upstream https://<account>.visualstudio.com/DefaultCollection/_git/SomeSolutionStd

 

2. 取り込み用ブランチにマージ

前工程の最後で作っておいたブランチupstream-masterにfork元の変更をmasterをそのままマージします。 (ローカルにupstream-masterをチェックアウトしてない場合は先にチェックアウトしておきます) このマージは基本的に競合することはないはずです(むしろupstream-masterはそのために一切独自の変更を加えないようにする)

git checkout upstream-master
git fetch upstream
git merge upstream-master upstream/master
git push origin upstream-master

f:id:kiyokura:20161207010516p:plain

あとはupstream-masterから(場合によってはcommitを取捨選択しながら)タイミングを見てmasterに取り込んだりすればいいかな、と今のところろ考えています。

 

まとめ

とりあえずこんな感じで、始めに書いた「実現したいこと」は実現できている感じです。 フォークするくらいはVSTSで標準で面倒見てくれてもいいかなという気がしないでもないですが、まあそんなに何度もやる処理でもないのでいいかなという気もしてきました。

 

余談ですが、チームプロジェクトをまたがっいても、pull requestに紐づいたWorkItemの情報はちゃんと参照できます。これは地味にうれしいですね。

f:id:kiyokura:20161207010526p:plain

*1:「いきません」というか、今回はそのような運用をしたい、というだけではあります