Git Fetch Pull Request: Proficiency Unlocked

Nicola Paolucci
Nicola Paolucci
リストに戻る

最近では、プロジェクトの修正は、フォークの作成 と同じくらい簡単になりました。プロジェクトを完全にリモートコピーして、一瞬で作業用のフォークを作成できるように、変更したいファイルを選択して、編集を押して、修正をコミットすれば、プロジェクトが修正できます。

それでは、プル リクエスト (以下では PR と略記) を受け取る側にいる場合はどうでしょうか。洗練された Web UI を使用することはすばらしいことであり、多くの場合、それがあれば十分です。ボタンをクリックして承認し、マージすれば、それで完了です。

プル リクエストの承認

しかし、常にそうであるとは限りません。プル リクエスト (PR) に含まれる変更をローカルにダウンロードし、いくつかのテストを実行し、実行された内容を理解するために IDE で変更がどのように表示されるかを確認しなければならないことがよくあります。

同僚または貢献者のプル リクエストをダウンロードする手順、つまり、もっとはっきり言えば、fetchcheckout の手順は、概念的には単純ですが、いくつかの重要な詳細とヒントを知っていれば、さらに簡単になります。

というわけで、コマンド ラインからプル リクエストを簡単に操作できる git のコマンド ライン機能をわかりやすく説明して行きましょう。

始める前に:ブランチ名とステータスでシェルプロンプトの機能を高めましょう

私がいつも驚かされるのは、自分が作業中の git ブランチ名が表示されず、作業ディレクトリに変更済みファイルまたは未コミット ファイルがあるかどうかも表示されない、素っ気ないコマンド プロンプトを使っている人の多さです。あっ、それは私だ、と思う人には、便利かつ驚くべき方法をお教えします!

git 作業ディレクトリのステータスに関する優れた注釈を提供してくれる、すばらしい liquid prompt 風のプロンプトをインストールしてください (他のどの VCS にも対応しています)。

Liquid prompt

(上のスクリーンショットでは、私が newbranch という名前のブランチで作業中であり、作業ディレクトリ内で追跡しているファイルに 5 行追加し、0 行削除したことがプロンプトで通知されているのがわかります。)

全員が同じリポジトリで作業をしている場合

チームと同じリポジトリで作業をしている場合は、プル リクエストをチェックアウトするプロセスは非常に簡単です。プル リクエストが作成されたブランチを fetch して checkout するだけです。

  • 共有リポジトリに公開されたブランチをすべて取得する:
git fetch origin
  • 関心のあるリモート ブランチを追跡するローカル ブランチを作成します。
git checkout -b PRJ-1234 origin/PRJ-1234
  • これで、diffmerge、テストを思う存分実行できます。
 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
  • これで、diffmerge、テストを思う存分実行できます。
 git diff main ./run-tests.sh

プルリクエスト ref を使用して作業を削減する

上記は効果的ですが、いくつかの場合において、うまく行かないことがあります。

  • 貢献者が多く、それぞれが独自のフォークを持っているとしたらどうでしょうか。すべてのフォークを個別に追加して処理することは実用的ではありません。
  • 一部のフォークにはアクセスさえできず、ソース ブランチをチェックアウトできないとしたら、どうでしょうか。

これらの問題を解決するには、一部の git サーバーが提供するプル リクエスト ref を使用します。ここで説明する手順は、一部の git サーバーでサポートされており、使用するサーバーによって若干異なります。以下では、Stash (現在は Bitbucket Server と呼ばれている) と 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 Server) 開発者がまさに指摘しているように、以下に使用例を挙げたリファレンスは、undocumentedprivate であると考えられていて、任意の時点で変更される可能性があります。

すべてのプルリクエストをダウンロードする: 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/configfetch エントリを設定したくない場合や 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 spr 100

結論

これがお役に立てば幸いです。結局のところ、単純なエイリアスをいくつか作成するか、.git/config に適切な refspec を追加すれば、同僚や貢献者の作業を継続的に把握するのは簡単です。何か質問があれば、Twitter の @durdn@AtlDevtools にお寄せください。喜んで回答させていただきます。

Git を学習する準備はできていますか?

この対話式チュートリアルを利用しましょう。

今すぐ始める