【 git pull 】コマンド――リモートリポジトリの変更内容を取り込む:Linux基本コマンドTips(382)
本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は「git」コマンドのうち、リモートリポジトリの変更を取り込む「git pull」コマンドです。
本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。Gitでリモートリポジトリの変更を取り込む「git pull」コマンドです。
git/git pullコマンドとは?
「git」は「Git」という分散型バージョン管理システム用のコマンドです。Gitは元々Linuxカーネルのソースコードを管理するために作られた「バージョン管理システム」で、現在は多くのソフトウェアのソースコードやWebサイトのコード、ドキュメント管理などに用いられています。
ソースコードを管理する際、最新版だけを保存するやり方はうまくいきません。開発中のさまざまなタイミングで状態を管理し、必要に応じて比較、参照したり、元に戻したりできるようにする仕組みが「バージョン管理システム」です。
Gitでは、テスト版など複数に枝分かれした状態も管理できます。複数のメンバーによる開発を前提としており、開発中の各時点におけるコメントや、コメントへの返信なども管理できるようになっています。
gitのサブコマンドとGitの仕組み
gitコマンドはほとんどの場合、「サブコマンド」と組み合わせて利用します。今回紹介する「git pull」は「リモートリポジトリ」の変更を取り込みます(本連載ではgitとサブコマンドの組み合わせをコマンドとして紹介します)。
リポジトリ(repository)とは、ソースコードや変更履歴、コメントなどを一括して保管する場所です。リポジトリには、自分のPC上に作る「ローカルリポジトリ」と、「GitHub」などのWebサービス上に作る「リモートリポジトリ」があり、両者を連携させることで複数の開発者による開発を1本にまとめることができます。
既存のリポジトリ(リモートリポジトリ)にあるソースコードなどを入手したい場合は、まず、「git clone」(連載第381回)でリポジトリを自分の環境に複製します(※1)。リモートリポジトリの内容がバージョンアップされたら「git pull」コマンドで最新版を取得します。開発に参加するのではなく、単に最新版を取得したいという場合は、「git clone」と「git pull」を利用すればよいでしょう。
※1 特定のファイルだけが欲しい場合、例えばGitHub(github.com)にあるリポジトリであれば「Raw」というボタンで表示されるURLを使い、「wget」コマンドなどを使ってダウンロードできる。この他、プロジェクト全体をダウンロードするためのリンクも用意されている([Clone or download]ボタン→「Download ZIP」)。
保管場所であるリポジトリに対し、ファイルの編集などを行う場所を「ワークツリー」あるいは「ワーキングエリア」などと呼びます。「git clone」や「git pull」で取得した最新版のファイルはワークツリーに配置されます。つまり「作業ディレクトリ」です。
ワークツリー(作業ディレクトリ)で編集した結果をリポジトリに反映する操作を「コミット」と呼びます。「git add」コマンドでコミットしたいファイルを「インデックス」あるいは「ステージングエリア」と呼ばれる領域に追加します。インデックスにはファイルの変更箇所などが記録されます。
インデックスの内容は「git commit」コマンドでローカルリポジトリにコミットされ、「git push」コマンドでローカルリポジトリの内容をリモートリポジトリに反映します。従って、「git add」や「git commit」などを行わなければ、自分の環境で編集した内容がリポジトリに影響を与えることはありません。自由に編集し、テストできます。なお、ワークツリーのファイルを過去の任意のコミット状態に戻すことも可能です。
Gitには、この他、開発中のプログラムやドキュメントを、「テスト版」「○○版」……のように枝分かれさせたり、それらを合流させたりする機能もあります。枝分かれしたそれぞれのバージョンを「ブランチ」(branch)と呼び、ブランチを合流させることを「マージ」(merge)と呼びます。
git pullコマンドの動作は2つの過程に分かれている
「git pull」コマンドがリポジトリの変更内容を取り込む際、内部では2つの過程を処理します。最初の過程は「git fetch」で、リポジトリの内容がどのように変更されているのかという情報を取得します(リモートリポジトリ→ローカルリポジトリ)。
次の過程は「git merge」で、「git fetch」で取得した情報を、現在のブランチに取り込みます(ローカルリポジトリ→作業ツリーに反映)。「fetch」や「merge」については今後の連載で取り上げる予定です。
なお、自分自身も開発を進めている場合は、単純に「git pull」するのではなく、「リベース」(rebase)と呼ばれる処理をした方がよい場合もあります(本文を参照)。
コマンドの書式
git [オプション] サブコマンド [サブコマンドごとのオプションや引数]
git pull [オプション] [リポジトリ] [ブランチ]
※ [ ]は省略可能な引数を示しています。
gitの主なオプション
短いオプション | 長いオプション | 意味 |
---|---|---|
-C パス | カレントディレクトリではなく指定したディレクトリで実行したものとする | |
--bare | リポジトリを「bareリポジトリ」(ワーキングディレクトリが存在しない、管理だけを目的としたリポジトリ)として扱う | |
-c 設定=値 | 設定値を指定する(設定は「git config」で確認可能) | |
-p | --paginate | 全ての出力を「less」コマンドまたは環境変数PAGERで指定されたコマンドで表示する |
-P | --no-pager | lessコマンドで表示しない(「-p」の指定を打ち消す) |
--exec-path=パス | gitの実行ファイルのパスを指定する(「--exec-path」のみの場合、実行ファイルのパスを表示する) | |
--html-path | gitのHTML形式のドキュメントがインストールされたパスを表示する | |
--man-path | gitのmanファイルのパスを表示する | |
--info-path | gitのinfoファイルのパスを表示する |
gitのサブコマンド
コマンド | 実行内容 |
---|---|
clone | リポジトリのクローンを作成する |
init | リポジトリを新規作成する、または既存のリポジトリを初期化する |
remote | リモートリポジトリを関連付けする |
fetch | リモートリポジトリの内容を取得する |
pull | リモートリポジトリの内容を取得し、現在のブランチに取り込む(「fetch」と「merge」を行う) |
push | ローカルリポジトリの変更内容をリモートリポジトリに送信する |
add | ファイルをインデックスに追加する(コミットの対象にする) |
rm | ファイルをインデックスから削除する |
mv | ファイルやディレクトリの名前を変更する |
reset | ファイルをインデックスから削除し、特定のコミットの状態まで戻す |
status | ワークツリーにあるファイルの状態を表示する |
show | ファイルの内容やコミットの差分などを表示する |
diff | コミット同士やコミットと作業ツリーの内容を比較する |
commit | インデックスに追加した変更をリポジトリに記録する |
tag | コミットにタグを付ける、削除する、一覧表示する |
log | コミット時のログを表示する |
grep | リポジトリで管理されているファイルをパターン検索する |
branch | ブランチを作成、削除、一覧表示する |
checkout | 作業ツリーを異なるブランチに切り替える |
merge | 他のブランチやコミットの内容を現在のブランチに取り込む |
rebase | コミットを再適用する(ブランチの分岐点を変更したり、コミットの順番を入れ替えたりできる) |
config | 現在の設定を取得、変更する |
git pullの主なオプション
短いオプション | 長いオプション | 意味 |
---|---|---|
--ff | マージ先に変更がない場合など、マージで競合がない場合は「fast-forwardマージ」を行う(マージ時のコミットを省略する) | |
--no-ff | fast-forwardマージを行わず、必ずコミットを行う(「--ff」の指定を打ち消す) | |
--ff-only | fast-forwardマージが可能な場合のみマージを行う | |
--commit | マージされた変更をすぐにコミットする | |
--no-commit | 自動コミットを行わない | |
-e | --edit | コミットメッセージ用のエディタを必要に応じて起動する |
--no-edit | コミットメッセージ用のエディタを起動しない | |
--squash | 複数のコミットを1つにまとめる | |
--no-squash | 複数のコミットをまとめない | |
-r | --rebase | コミットの順番を入れ替える(リモートリポジトリに対して反映させていないコミットがローカルにある場合などに使用する、本文を参照) |
--no-rebase | rebaseを行わない(「--rebase」の指定を打ち消す) | |
--autostash | 「--rebase」指定時に作業ツリーで変更があった場合、いったん退避させて、「--rebase」を実施後、元の状態に戻す | |
--no-autostash | 「--rebase」指定時の「--autostash」指定を打ち消す |
git pullの主なオプション(fetch関連)
短いオプション | 長いオプション | 意味 |
---|---|---|
--all | 全ての情報を取得する | |
--depth=個数 | それぞれのブランチで取得する履歴の個数を指定する | |
--shallow-since=日付 | 指定した日付後の情報を取得する | |
--shallow-exclude=リビジョン | 取得対象としないリビジョンを指定する | |
--unshallow | 最新の履歴だけではなく、全ての履歴を取得する | |
--update-shallow | 「.git/shallow」ファイル(git cloneで「--depth」を指定すると生成されるファイル)を更新する | |
-f | --force | 強制的に実行する |
--no-tags | タグを取得しない | |
-4 | --ipv4 | IPv4だけを使用する |
-6 | --ipv6 | IPv6だけを使用する |
git pullの主なオプション(その他)
短いオプション | 長いオプション | 意味 |
---|---|---|
-v | --verbose | 詳しいメッセージを表示する |
-q | --quiet | メッセージをなるべく表示しない |
リモートリポジトリの変更内容を取り込む
リモートリポジトリの変更内容を取り込むには、作業ディレクトリ(.gitの親ディレクトリ)で、「git pull」を実行します(画面1)。
「git pull」では、全てのブランチの変更内容を取得し、現在作業対象としているブランチ(通常はデフォルトブランチである「master」)の変更内容を作業ディレクトリに反映します。
特定のブランチの変更内容だけを取り込みたい場合は「git pull リモートの名前 ブランチの名前」のように指定します。
「git clone」を実行すると、複製元のリポジトリ(リモートリポジトリ)には「origin」という名前が付きます。デフォルトのブランチは、通常、「master」という名前になっているため、「git pull origin master」を実行すると、デフォルトブランチだけを更新します(画面2、※2)。
※2 masterと並行して他のブランチも取得したい場合は「git checkout --track ブランチ リモート名/ブランチ」を実行する(追跡ブランチ)。
コマンド実行例
git pull
(リモートリポジトリで変更された内容を全て取得し、現在の作業ツリーに反映する)
git pull リモートの名前 ブランチの名前
(指定したブランチの変更内容を取り込む)
git pull origin master
(デフォルトブランチの変更内容を取り込む)
(補足事項)自分自身でも開発を進めていた場合の操作は?
「git pull」は、リモートリポジトリの変更内容を取得し(git fetch相当)、現在の作業ツリーに反映します(git merge相当)。ただ単に、リモートリポジトリの最新情報を追っているのであれば「git pull」で問題ありません。しかし、自分自身でも作業ツリーでソースコードを変更していた場合は、何らかの調整が必要になることがあります。
例えば、「A」というプロジェクトに対して、自分用のオリジナルの設定「X」を加えて試していたような場合、次のようなことが起こるかもしれません。
- Aの一部である「A1」に対し「X」という変更を加えた
- リモートリポジトリが更新されて「A1」が「A2」に変わっていた
この場合、いったん「X」という変更を加えなかったことにして次のように処理するとよいでしょう。なぜなら、メインの変更である「A1」→「A2」と、プラスαである「X」という位置付けが明確になり、後々のメンテナンスが楽になるからです。具体的には、「--rebase」オプションを付けて「git pull」を実行します。
- 「A1」を「A2」に更新
- その後「A2」に対して「X」という変更を加える
なお、以上の説明は、GitHubなどで公開されているプロジェクトに対して、自分用にローカルで手を加えているものの、他人には公開していないというケースを想定しています。チーム開発に参加するのであれば、手を加える目的によって「A1」→「X」→「A2」の順番で進めた方がよいかもしれませんし、そもそも「X」という別のブランチを作る必要があるかもしれません。いずれにせよ、「git pull」ではなく、状況に応じて「git fetch」と「git merge」「git rebase」を個別に行う必要があるでしょう。
筆者紹介
西村 めぐみ(にしむら めぐみ)
元々はDOSユーザーで「DOS版UNIX-like tools」を愛用。ソフトハウスに勤務し生産管理のパッケージソフトウェアの開発およびサポート業務を担当、その後ライターになる。著書に『図解でわかるLinux』『らぶらぶLinuxシリーズ』『Accessではじめるデータベース超入門[改訂2版]』『macOSコマンド入門』など。地方自治体の在宅就業支援事業にてMicrosoft Officeの教材作成およびeラーニング指導を担当。会社などの"PCヘルパー"やピンポイント研修なども行っている。
Copyright © ITmedia, Inc. All Rights Reserved.