Git と Perforce で作業: 統合ワークフロー

あなたのチームは独立して Git リポジトリで作業しているが、組織の一部はいまだ Perforce を使用し、同じコード ベースの一部を管理している、というシナリオを次に示します。Perforce のチームは移行を予定していませんが、あなたのチームは既に Git に移行しています (これには多くの正当な理由があります)。コード ベース間で双方向のコード共有プロセスを継続的に維持できることが重要です。そうすれば、どちらかのバージョンで開発された改善点を、時間をかけすぎたり、チームの負担を増やしたりすることなく共有することができます。

ここでは、このガイドを活用します。TomTom では、この同期操作は新しいリリースごとに 1 回、つまり 1 か月半に 1 回行われます。

-- この記事は、Andrea CarlevatoAdolfo BulfoniKrzysztof KarczewskiTomTomの NavApps Unit で使用されている Git プロセスを共有していただくことで執筆することができました。--

開始前の仮定

ここでは、基本の Git 使用方法を理解しており、フィーチャ― ブランチ ワークフローの経験があると仮定します。そうでない場合は、実践チュートリアルまたは ウェビナーを視聴し、準備ができた時点で続行してください。

このプロセスでは注意すべき細かな点がいくつかあるため、これらの統合を実行する場合は十分注意することをお勧めします。準備ができたら先へ進みましょう。

git p4 をインストールする

最初のステップは、ブリッジをインストールすることです。コマンド ラインで次のように入力して、インストール済みかどうかを確認します。

git p4

システムに git p4 がインストールされていないと判明した場合は、git-p4.py をダウンロードし、~/bin などの PATH のフォルダーに保存します (これを機能させるには、Python もインストールしておく必要があります)。

次のコマンドで実行可能にします。

chmod +x git-p4.py

次を追加して、~/.gitconfig ファイルを編集します。

[alias]
    p4 = !~/bin/bit-p4.py

次に git p4 をもう一度実行すると、エラーが発生しなくなります。これでツールがインストールされました。

ワークフローの概要

最初のクローン

P4 のプロジェクトでは履歴が膨大になる可能性があるため、チームは同期の基準となる切り捨てポイントを選択し、スペースと時間を大幅に節約できます。git p4 では、追跡を開始する変更リストを選択できます。

git p4 clone //depot/path/project@<earlier-cutoff-point>,<latest-changelist>
  • これで同期を実行して、すべての変更セットをローカルで受信したことを確認できます。

git p4 sync

sync コマンドは P4 の新しい変更を検出し、Git コミットとしてインポートします。

  • Perforce p4-integ と直接やり取りするために使用するブランチの名前を指定します。この時点では、単に remotes/p4/main から分岐するだけです。

git checkout -b p4-integ origin/p4/main

フォローアップ高速同期 (別名「ベイト アンド スイッチ」)

最初のインポートが完了したら、次のコマンドを使用して後続の git-> p4 同期を実行できます。

git checkout p4-integ
git p4 sync

上記は動作しますが、速度が低下する可能性があります。同期をスピードアップさせるには、最新の統合で使用されている refs と同じものを再作成します。これは、新たな開発者が統合を担当する場合に、正しいコミット/変更リストから開始できるようにするための優れた方法でもあります。

ここではその手順を説明します。

  • p4 リモートの古い元の refs を削除します (オプション)。

git symbolic-ref -d refs/remotes/p4/HEAD
git update-ref -d refs/remotes/p4/main
  • origin の p4-integ の最後のコミットを示す人工的な (別名「フェイク」) リモート refs を作成します。

git update-ref refs/remotes/p4/main remotes/origin/p4-integ
git symbolic-ref refs/remotes/p4/HEAD refs/remotes/p4/main

この同期は非常に高速ですが、唯一の欠点は、git p4 でブランチを明示的に指定する必要があることです。この最後のコマンドは次のとおりです。

git p4 sync --branch=refs/remotes/p4/main

git p4 で git コミット ID と P4 間のマッピングを追跡するには、コミットにメタデータで注釈を付けます。

Merge pull request #340 in MOB/project from bugfix/PRJ-3185 to develop

    Squashed commit of the following:

    commit c2843b424fb3f5be1ba64be51363db63621162b4
    Author: Some Developer
    Date:   Wed Jan 14 09:26:45 2015 +0100

        [PRJ-3185] The app shows ...

    commit abc135fc1fccf74dac8882d70b1ddd8a4750f078
    Author: Some Developer
    Date:   Tue Jan 13 14:18:46 2015 +0100

        [PRJ-3185] The app shows the rating ...

    [git-p4: depot-paths = "//depot-mobile/project/": change = 1794239]

git p4 の最新バージョンでは、git commit と P4 変更リストを関連付けるメタデータは、コミット メッセージではなくコミット ノートに格納されることに注意してください。TomTom チームでは、必要に応じて変更リストの番号を確認する作業がわずかに増えたため、この変更は歓迎されませんでした。

Git から Perforce に変更を移行する

上記の高速同期操作が完了し、git から Perforce に変更をプッシュする準備が整いました。

最初のステップは、remotes/p4/main からの変更を含めて p4-integリベースすることです。

git checkout p4-integ
git p4 rebase

この後、Perforce からの新しい変更はすべて p4-integ に保存され、main をアップデートできるようになります。

  • その後、簡単に次のことができます。

git checkout main
git merge develop
  • ローカルに最新のタグがあることを確認します。

git fetch --tags
  • P4 に既にあるコミットを削除する必要がある場合は、一時的な cleanup を使用します (コミットの P4 タグを参照)。コミットをスキップしない場合は、履歴を線形化する自動リベースを実行します。

git checkout -b cleanup #branching off from main
git rebase -s recursive -X theirs tag/last-p4-integ
  • 対話型リベースを使用すると、代わりに以下のように実行できます。

git rebase -i tag/last-p4-integ
  • cherry-pick を使用して新しいコミットを選択し、p4-integ ブランチに配置します。これは、git ブランチの maindevelopp4-integ ブランチの適切な上位として保持されると仮定していないためです。事実、既にこれは TomTom に該当しません。

git checkout p4-integ
git cherry-pick tag/last-p4-integ..cleanup
  • P4 に送信して p4-integ を同期します。

git p4 submit
git p4 sync --branch=refs/remotes/p4/main
git reset --hard refs/remotes/p4/main
  • 一時リベース ブランチを削除します。

git branch -D cleanup
  • ローカルおよびリモートの最新の統合ポイント (タグ) へのポインターを削除します。

git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
  • P4 の新しい統合ポイントを指すように、タグ last-p4-integ をアップデートします。

git checkout develop
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
git push origin main
git push origin tag/last-p4-integ
git push origin p4-integ

P4 コード ベースでテストを実行して、統合によって問題が発生していないことを確認します。

Perforce から Git に変更を移行する

これは git-> P4 プッシュの後に行う必要があります。P4 でテストが正常に完了したら、次のように P4 から git に変更を移行できます。

git checkout p4-integ
git p4 sync --branch=refs/remotes/p4/main
git p4 rebase
  • 以下は、堅牢な「独自の」マージ戦略を実行するためのヒントです。新しい変更を単一のコミットにスカッシュします。次のとおりです。

git checkout -b p4mergebranch #branching off from p4-integ
git merge -s ours main ## ignoring all changes from main
git checkout main
git merge p4mergebranch --squash
git commit -m "Type your integration message"
git branch -D p4mergebranch
  • 上記の作業が完了したら、変更を develop にマージします。

<p>Bitbucket has the following space stations:</p>
 <p>
     <b>Earth's Moon</b><br>
     Headquarters
 </p>

develop から変更を選択した後に新たに変更が生じた可能性があるため、最初にマージする必要があります。ただし、last-p4-integ タグを develop へのマージ コミットではなく正しいコミットにアップデートすることが重要です。これを安全に行うには、main の最新の状態にタグを付けます。

  • ローカルおよびリモートの古いタグを削除します。

git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
  • 新しい位置にタグを作成します。

git checkout main
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
  • 次に main、develop、p4-integ および tag/last-p4-integorigin にプッシュします。

結論

これが、Git と Perforce を使用して 2 つのアクティブな開発チーム間で同期する方法です。TomTom では上記のプロセスが時間の経過とともに進化し、これまで長期間にわたって大きな問題もなく実行されています。実際に機能していますが、維持するにはかなりの負担がかかっています。選択できるのであれば、Git に完全に移行することをお勧めします。

いずれにしても、双方向の同期を維持するために別のアプローチを採る場合、以下にコメントしていただければ参考にいたします。あるいは @durdn または @atlassiandev 宛てにツイートしてください。

Andrea CarlevatoAdolfo Bulfoni、およびKrzysztof Karczewskiに改めて感謝いたします。

推奨

Bitbucket ブログ

DevOps ラーニング パス

Git の詳細

その他の Git ガイドとリソースについては、このハブをご確認ください。