git fetch のプル リクエストに習熟しましょう
Nicola Paolucci
開発者アドボケート
最近では、プロジェクトの修正は、フォークの作成 と同じくらい簡単になりました。プロジェクトを完全にリモート・コピーして、一瞬で作業用のフォークを作成できるように、変更したいファイルを選択して、編集を押して、修正をコミットすれば、プロジェクトを修正できます。
それでは、プル リクエスト (以下では PR と略記) を受け取る側にいる場合はどうでしょうか。洗練された Web UI を使用することはすばらしいことであり、多くの場合、それがあれば十分です。ボタンをクリックして承認し、マージすれば、それで完了です。
しかし、常にそうであるとは限りません。プル リクエスト (PR) に含まれる変更をローカルにダウンロードし、いくつかのテストを実行し、実行された内容を理解するために IDE で変更がどのように表示されるかを確認しなければならないことがよくあります。
同僚または貢献者のプル リクエストをダウンロードする手順、つまり、もっとはっきり言えば、fetch
と checkout
の手順は、概念的には単純ですが、いくつかの重要な詳細とヒントを知っていれば、さらに簡単になります。
というわけで、コマンド ラインからプル リクエストを簡単に操作できる git
のコマンド ライン機能をわかりやすく説明して行きましょう。
始める前に:ブランチ名とステータスでシェルプロンプトの機能を高めましょう
私がいつも驚かされるのは、自分が作業中の git
ブランチ名が表示されず、作業ディレクトリに変更済みファイルまたは未コミット ファイルがあるかどうかも表示されない、素っ気ないコマンド プロンプトを使っている人の多さです。あっ、それは私だ、と思う人には、便利かつ驚くべき方法をお教えします!
git 作業ディレクトリのステータスに関する優れた注釈を提供してくれる、すばらしい liquid prompt
風のプロンプトをインストールしてください (他のどの VCS にも対応しています)。
(上のスクリーンショットでは、私が newbranch
という名前のブランチで作業中であり、作業ディレクトリ内で追跡しているファイルに 5
行追加し、0
行削除したことがプロンプトで通知されているのがわかります。)
関連資料
Git チュートリアル - Gitをインストールする
ソリューションを見る
Bitbucket Cloud での Git の使用方法についてのチュートリアルです。
全員が同じリポジトリで作業をしている場合
チームと同じリポジトリで作業をしている場合は、プル リクエストをチェックアウトするプロセスは非常に簡単です。プル リクエストが作成されたブランチを fetch
して checkout
するだけです。
- 共有リポジトリに公開されたブランチをすべて取得する:
git fetch origin
- 関心のあるリモート ブランチを追跡するローカル ブランチを作成します。
git checkout -b PRJ-1234 origin/PRJ-1234
- これで、
diff
、merge
、テストを思う存分実行できます。
git diff main ./run-tests.sh
- 問題がなければ、Web UI に戻ってフィードバックを提供するか、即座に変更を承認します。
コントリビューターが自分のフォークで作業している場合
一部の貢献者が別々のフォークで作業する場合、プロセスは少し変わります。この場合、貢献またはフィーチャーがコミットされたリモート ブランチを fetch
できます。
- 貢献者のリモートを先に追加するには:
git remote add jsmith http://bitbucket.org/jsmith/coolproject.git
- 始めに、自分のメイン リポジトリである
origin
から最新の更新をすべて収集します。
git checkout main git fetch origin git merge main
- 貢献者のフォークで公開されたすべてのブランチを取得します。
git fetch jsmith
- 関心のあるリモート ブランチを追跡するローカル ブランチを作成します。
git checkout -b jsmith-PRJ-1234 jsmith/PRJ-1234
- これで、
diff
、merge
、テストを思う存分実行できます。
git diff main ./run-tests.sh
プルリクエスト ref を使用して作業を削減する
上記は効果的ですが、いくつかの場合において、うまく行かないことがあります。
- 貢献者が多く、それぞれが独自のフォークを持っているとしたらどうでしょうか。すべてのフォークを個別に追加して処理することは実用的ではありません。
- 一部のフォークにはアクセスさえできず、ソース ブランチをチェックアウトできないとしたら、どうでしょうか。
これらの問題を解決するには、一部の git サーバーが提供するプル リクエスト ref を使用します。ここで説明する手順は、一部の git
サーバーでサポートされており、使用するサーバーによって若干異なります。以下では、Stash (現在は Bitbucket Data Center と呼ばれている) と Github ですべてのプル リクエストを fetch
する方法について説明します。
Refspecs は怖くない
まず必要なのは、Refspecs に慣れることです。Refspecs は大変便利なので、恐れる必要はありません。これらは、リモート ブランチからローカル参照への単純なマッピングです。つまり、"このリモート ブランチ (またはこのリモート ブランチのセット) はこの名前空間でローカルにマッピングする必要がある” ことを git
に伝える簡単な方法です。
たとえば、次のようなコマンドの場合:
git fetch +refs/heads/main:refs/remotes/origin/main
origin
リモート上のリモート ブランチ main
がローカルの origin/main
にマップされるので、次のように入力できるようになります。
git checkout origin/main
このように入力しても、まだそのリモート ブランチを参照しています。定義内にプラス記号 (+
) が存在する理由は、ファストフォワードでなくても git
が参照を更新することを示すためです。
これを使用して、すべてのプルリクエストをダウンロードする方法は、リモートリポジトリ内の PR HEAD の格納状態をマッピングし、それをローカル名前空間にマッピングして、参照を簡単にするというものです。
したがって、origin
(または upstream
) リモート リポジトリを定義してあれば、次に行うのは以下のことです。
注: 一部の Stash (現在の名称は Bitbucket Data Center) 開発者がまさに指摘しているように、以下に使用例を挙げたリファレンスは、undocumented
で private
であると考えられていて、任意の時点で変更される可能性があります。
すべてのプルリクエストをダウンロードする: Stash
- リポジトリをフォークする。
- フォークをローカルにクローンする:
git clone git@stash.atlassian.com:durdn/tis.git
- upstream オリジナル リポジトリを
upstream
として追加します。
git remote add upstream git@stash.atlassian.com:tpettersen/tis.git
- メンテナーの「upstream」から最新の HEAD を取得します
git fetch upstream
- リモートのプル リクエスト ヘッドをローカルの
pr
名前空間にマッピングするrefspec
を追加します。これはconfig
コマンドで実行できます。
git config --add remote.origin.fetch '+refs/pull-requests/*/from:refs/remotes/origin/pr/*'
.git/config
を見ると、fetch
エントリは次のようになります。
[remote "upstream"]
url = git@stash.atlassian.com:docker/libswarm.git
fetch = +refs/heads/*:refs/remotes/upstream/*
fetch = +refs/pull-requests/*/from:refs/remotes/upstream/pr/*
- これで、すべてのプル リクエスト ブランチを簡単に
fetch
できます。
$ git fetch upstream
remote: Counting objects: 417, done.
remote: Compressing objects: 100% (274/274), done.
remote: Total 417 (delta 226), reused 277 (delta 128)
Receiving objects: 100% (417/417), 105.28 KiB | 0 bytes/s, done.
Resolving deltas: 100% (226/226), done.
From stash.atlassian.com:docker/libswarm
* [new ref] refs/pull-requests/10/from-> upstream/pr/10
[...]
* [new ref] refs/pull-requests/100/from -> upstream/pr/100
* [new ref] refs/pull-requests/101/from -> upstream/pr/101
[...]
* [new ref] refs/pull-requests/109/from -> upstream/pr/109
* [new ref] refs/pull-requests/110/from -> upstream/pr/110
[...]
- ここで特定のプルリクエストに切り替えるには、次のように入力するだけです:
git checkout pr/102
すべてのプル リクエストをダウンロードする: Github
フォークまたはアップストリームが Github 上にある場合でも、上記とまったく同じように動作しますが、config
コマンドが以下のように変わります。
git config --add remote.origin.fetch '+refs/pull//head:refs/remotes/origin/pr/'
そして .git/config
のリモートリポジトリが、PR ヘッドを pr
と呼ばれるローカル名前空間にマッピングするための追加の fetch
設定を含むように変更されます。
[remote "upstream"] url = git@github.com:docker/libswarm.git fetch = +refs/heads/*:refs/remotes/upstream/* fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*
ref を使用して 1 つのプル リクエストをフェッチする
.git/config
に fetch
エントリを設定したくない場合や 1 つのコマンドでプル リクエストにすばやくアクセスしたい場合は、次のように行います。
- Stash で単一の PR をチェックアウトします。
git fetch refs/pull-requests/your-pr-number/from:local-branch-name
- Github で単一の PR をチェックアウトする場合:
git fetch refs/pull/your-pr-number/head:local-branch-name
なお、上記のコマンドを頻繁に使用する場合は、git
エイリアスを作成するとプロセスを効率化できます。
# For Stash
git config alias.spr '!sh -c "git fetch origin pull-requests/${1}/from:pr/${1}" -'
# For Github
git config alias.gpr '!sh -c "git fetch origin pull/${1}/head:pr/${1}" -'
そのエイリアスを設定すれば、次のように簡単にプル リクエストをフェッチできます (inuit に感謝)。
結論
単純なエイリアスをいくつか作成するか、.git/config
に適切な refspec を追加すれば、同僚や貢献者の作業を継続的に把握するのは簡単です。
この記事を共有する
次のトピック
おすすめコンテンツ
次のリソースをブックマークして、DevOps チームのタイプに関する詳細や、アトラシアンの DevOps についての継続的な更新をご覧ください。