Git のリモートリポジトリに新しいコミットがあるかどうかを確認する方法

GitGitBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、Git のリモートリポジトリに、まだローカルリポジトリに存在しない新しいコミットがあるかどうかを確認する方法を学びます。これは共同開発において重要なスキルであり、他の人が行った変更を最新の状態に保つことができます。

まず、リモートリポジトリをシミュレートし、ローカルプロジェクトに追加します。次に、git fetch コマンドを使用して、リモートのブランチとコミットに関する情報を取得しますが、マージは行いません。最後に、ローカルブランチとその上流のブランチを比較して、リモート上の新しいコミットを特定する方法を探ります。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL git(("Git")) -.-> git/BranchManagementGroup(["Branch Management"]) git(("Git")) -.-> git/CollaborationandSharingGroup(["Collaboration and Sharing"]) git(("Git")) -.-> git/DataManagementGroup(["Data Management"]) git/DataManagementGroup -.-> git/reset("Undo Changes") git/BranchManagementGroup -.-> git/log("Show Commits") git/CollaborationandSharingGroup -.-> git/fetch("Download Updates") git/CollaborationandSharingGroup -.-> git/pull("Update & Merge") git/CollaborationandSharingGroup -.-> git/remote("Manage Remotes") subgraph Lab Skills git/reset -.-> lab-560074{{"Git のリモートリポジトリに新しいコミットがあるかどうかを確認する方法"}} git/log -.-> lab-560074{{"Git のリモートリポジトリに新しいコミットがあるかどうかを確認する方法"}} git/fetch -.-> lab-560074{{"Git のリモートリポジトリに新しいコミットがあるかどうかを確認する方法"}} git/pull -.-> lab-560074{{"Git のリモートリポジトリに新しいコミットがあるかどうかを確認する方法"}} git/remote -.-> lab-560074{{"Git のリモートリポジトリに新しいコミットがあるかどうかを確認する方法"}} end

git fetch でリモートの変更を取得する

このステップでは、リモートリポジトリから変更を取得する方法を学びます。他の人と一緒にプロジェクトを進めていて、彼らが何らかの更新を行ったと想像してみてください。あなたはそれらの更新を自分のローカルマシンに取得する必要があります。そのために使用するのが git fetch コマンドです。このコマンドはリモートリポジトリから最新の変更をダウンロードしますが、現在のブランチにマージすることはありません。

まず、リモートリポジトリをシミュレートしましょう。空のリポジトリ (bare repository) を作成し、既存の my-time-machine リポジトリにリモートとして追加します。

cd ~/project
mkdir remote-repo.git
cd remote-repo.git
git init --bare

これにより、空の Git リポジトリが作成されます。このようなリポジトリは、開発者がプッシュとプルを行う中央リポジトリとして一般的に使用されます。

次に、my-time-machine リポジトリに戻り、この空のリポジトリをリモートとして追加しましょう。

cd ~/project/my-time-machine
git remote add origin ~/project/remote-repo.git

リモートの名前を origin としました。これは一般的な命名規則です。次に、リモートが正しく追加されたことを確認しましょう。

git remote -v

以下のような出力が表示され、origin リモートのフェッチとプッシュの URL が示されるはずです。

origin	/home/labex/project/remote-repo.git (fetch)
origin	/home/labex/project/remote-repo.git (push)

次に、リモートリポジトリでの変更をシミュレートしましょう。これは空のリポジトリなので、直接コミットを行うことはできません。代わりに、空のリポジトリのディレクトリに新しいファイルを作成することで変更をシミュレートします。

cd ~/project/remote-repo.git
echo "This is a remote change" > remote_file.txt

次に、my-time-machine リポジトリに戻りましょう。

cd ~/project/my-time-machine

この時点で、ローカルリポジトリはシミュレートされたリモートに追加された remote_file.txt のことを知りません。ここで git fetch が役に立ちます。

git fetch コマンドを実行しましょう。

git fetch origin

出力がほとんど表示されない場合もあれば、新しいオブジェクトが受信されたことを示すメッセージが表示される場合もあります。

git fetch origin が行ったことは、origin リモートに接続し、ローカルリポジトリに存在しない新しいコミットとオブジェクトをダウンロードすることです。ただし、これらの変更を現在のブランチ (master) にマージすることはありません。変更は現在、ローカルリポジトリに利用可能ですが、リモートを追跡する特別なブランチ (通常は origin/master と呼ばれます) に保存されています。

これが git fetchgit pull の重要な違いです。git pull は基本的に git fetch の後にマージを行うものです。まず git fetch を使用することで、リモート上で利用可能な変更を確認してから、自分の作業に統合するかどうかを決めることができます。これにより、より多くのコントロールが可能になり、予期しない競合を防ぐのに役立ちます。

次のステップでは、ローカルブランチと取得したリモートブランチを比較して、ダウンロードされた変更を理解する方法を見ていきます。

git log HEAD..@{u} を実行する

前のステップでは、git fetch を使用してリモートリポジトリから変更をダウンロードしました。次に、リモートに存在するがまだローカルブランチに反映されていないコミットを表示する方法を見ていきましょう。この際に非常に便利なのが git log HEAD..@{u} コマンドです。

まだ ~/project/my-time-machine ディレクトリにいることを確認してください。

cd ~/project/my-time-machine

次に、以下のコマンドを実行します。

git log HEAD..@{u}

以下のような出力が表示されるかもしれません。

commit abcdef1234567890abcdef1234567890abcdef (origin/master)
Author: Simulated User <[email protected]>
Date:   Mon Aug 7 10:05:00 2023 +0000

    Simulated remote commit

このコマンドを分解してみましょう。

  • git log:これはコミット履歴を表示するためのコマンドです。
  • HEAD:これは現在のブランチが指しているコミットを指します。
  • @{u}:これは上流ブランチ (upstream branch) の省略形です。今回の場合、origin からフェッチし、ローカルの master ブランチが origin/master を追跡しているため、@{u}origin/master を指します。
  • HEAD..@{u}:これは Git の範囲指定表記です。「@{u} から到達可能で、HEAD からは到達不可能なコミットを表示する」という意味です。簡単に言えば、リモート追跡ブランチ (origin/master) に存在するが、現在のローカルブランチ (master) には存在しないコミットを表示します。

このコマンドは、ローカルブランチをリモート追跡ブランチとマージまたはリベースした場合に得られる変更を確認するのに非常に役立ちます。変更を統合する前に、受け入れる変更をレビューすることができ、これは安全でコントロールされたワークフローの重要な部分です。

「Git はどうやってシミュレートされたリモートコミットを知ったのか」と疑問に思うかもしれません。前のステップで git fetch origin を実行したとき、Git は origin リポジトリのコミット情報をダウンロードしました。その中には remote_file.txt を導入したコミットの情報も含まれています。この情報は、ローカルリポジトリの origin/master 追跡ブランチに保存されます。そして、git log HEAD..@{u} コマンドは、ローカルの master ブランチ (HEAD) とこの origin/master 追跡ブランチ (@{u}) を比較して、差分を表示します。

ログビューが全画面モードの場合は、q を押して終了します。

ローカルブランチとリモート追跡ブランチの差分を理解することは、リモートリポジトリを効果的に操作するための基本です。このコマンドは、それらの差分を明確に可視化する方法を提供します。

同期されたリモートのテスト

前のステップでは、シミュレートされたリモートリポジトリから変更を取得し、git log HEAD..@{u} を使用してリモートに存在するがローカルブランチには存在しないコミットを表示する方法を学びました。次に、ローカルブランチがリモート追跡ブランチと最新状態で同期されている場合に何が起こるかを見ていきましょう。

まず、リモートの変更をローカルブランチにマージする状況をシミュレートしましょう。git fetch は変更をダウンロードするだけですが、git pull はダウンロードしてからマージします。このテストの目的で、手動でローカルブランチをリモート追跡ブランチと一致するように更新することで、プル後の状態をシミュレートします。

~/project/my-time-machine ディレクトリにいることを確認してください。

cd ~/project/my-time-machine

次に、ローカルの master ブランチを origin/master と同じコミットにリセットすることで、マージをシミュレートしましょう。注意: 実際のシナリオでは、通常 git merge origin/master または git pull origin master を使用して変更を統合します。ここで git reset --hard を使用するのは、テストのためにローカルブランチをリモート追跡ブランチとすぐに同期させるためのデモンストレーション目的だけです。

git reset --hard origin/master

ブランチが更新され、作業ツリーがクリーンであることを示す出力が表示されるはずです。

HEAD is now at abcdef1 Simulated remote commit

ローカルの master ブランチが origin/master と同期されたので、再度 git log HEAD..@{u} コマンドを実行しましょう。

git log HEAD..@{u}

今回は、何も出力されないはずです。

なぜ出力がないのでしょうか?HEAD (ローカルの master ブランチ) と @{u} ( origin/master 追跡ブランチ) が同じコミットを指しているからです。HEAD..@{u} の範囲は空で、@{u} から到達可能で HEAD から到達不可能なコミットはありません。

これは、ローカルブランチが上流のリモート追跡ブランチと完全に同期されているときの期待される動作です。git log HEAD..@{u} コマンドは、まだ統合していないリモートからの変更があるかどうかをすばやく確認する方法です。このコマンドが何も出力しない場合、ローカルブランチがリモート追跡ブランチと最新状態であることを意味します。

受け入れる変更を確認する方法と git log HEAD..@{u} の出力を解釈する方法を理解することは、他の人とのコラボレーションやローカルリポジトリをリモートと同期させるために不可欠です。

まとめ

この実験 (Lab) では、Git のリモートリポジトリに新しいコミットがあるかどうかを確認する方法を学びました。まず、git fetch の目的を理解しました。このコマンドは、リモートリポジトリから変更をダウンロードしますが、マージは行いません。裸の Git リポジトリ (bare Git repository) を作成し、それを origin という名前のリモートとしてローカルの my-time-machine リポジトリに追加することで、リモートリポジトリをシミュレートしました。git remote -v を使用して、リモートの設定を確認しました。

次に、裸のリポジトリのディレクトリに直接ファイルを作成することで、リモートリポジトリの変更をシミュレートしました。その後、git fetch origin コマンドを使用して、これらの変更をローカルリポジトリに取得し、新しいコミットを確認する準備をしました。