リモートでの作業の例

スポンサーリンク

ここではリモートリポジトリとしてLocalプロトコルを用います。
ローカルリポジトリはLocalReposディレクトリに、リモートリポジトリはRemoteReposディレクトリで管理するとします。

スポンサーリンク

リモートサーバーの確認 (git remote -v)

git remote -vで登録されているリモートサーバーを確認できます。
例えば、リポジトリをクローンするとリモートサーバーとしてクローンするリポジトリが登録されます。
クローンによってデフォルトで登録されるリモートリポジトリの名前はoriginになります。

リモートリポジトリの登録を追加 (git remote add)

git remote addでリモートリポジトリを登録することもできます。リモートリポジトリを登録する際に名前をつけます。この名前はリモートリポジトリを指定したいときに利用します。

リモートリポジトリの登録を解除 (git remote rm)

git remote rmでリモートリポジトリの登録を解除できます。

フェッチ。リモートリポジトリの内容をダウンロード (git fetch)

フェッチすることでリモートリポジトリの内容をダウンロードすることができます。
リモートリポジトリのブランチ名はタグのような感じでリモートリポジトリから情報を更新しない限り、ローカルリポジトリでは変化しません。

チェックアウト時にリモートリポジトリのリモート追跡ブランチ(例のorigin/masterのこと)のブランチ名を指定することで、ローカルリポジトリにそのブランチ名が追跡ブランチ(例ではmasterブランチのこと)として作成されリモートリポジトリの同期に利用されるブランチとして使用できます。

どのブランチを追跡しているかは

で確認できます。

プッシュ。リモートリポジトリへの記録 (git push)

プッシュはローカルリポジトリの情報をリモートリポジトリへと記録することができます。

ローカルリポジトリの情報をリモートリポジトリへ記録する際はリポジトリ間の整合性が重要になります。
リモートリポジトリにローカルリポジトリとは違う更新内容があったりするとプッシュは失敗します。その場合はフェッチを行い、リモートリポジトリの内容をマージやリベースで取り込んだ後に再度プッシュを行います。

以下は競合がなくプッシュを行われた例になります。

プッシュが成功するとリモート追跡ブランチ(origin/masterのこと)の位置が動いていることが分かります。

プル。フェッチとマージの連続操作 (git pull)

git pullはフェッチとマージの連続操作として利用できます。Gitの設定によってはフェッチとリベースとしても利用でき、プロジェクト環境によって様々な設定があります。
私の環境のデフォルト設定ではfast forward(ff)ができない場合はフェッチだけを行うようです。
fast forwardとは片方のブランチのコミット履歴が進んでいる場合、そのままそのコミット履歴を取り込むことです。
補足として、git mergeでfast forwardを行わないオプションとして--no-ffオプションやGitの設定の値としてno-ffがあります。
Gitの基本的なデフォルト値はffの利用ですが、プロジェクトのバージョン管理の方法としてno-ffを利用する場合もあります。

以下はローカルリポジトリに新しいコミットがなく、git pullを行った例です。

上の例で省略したgit pullの出力は以下のようになります。

競合を起こした場合

私の環境では競合を起こした場合はフェッチのみが行われました。以下は手作業でマージ操作を行った例になります。
git mergetoolはGitの設定でマージするときに利用するエディタをしっかり指定していた場合は-tオプションでエディタを指定する必要ありません。

コミットまで操作を行なったら、競合していた内容をリモートリポジトリへ記録するためにプッシュを行います。
この時、私は変なコミットメッセージ(例なので基本的に変なコミットメッセージですが(汗))をつけてコミットしていたことに気づいていませんでした。

プッシュは完了しましたが、変なコミットメッセージをつけたままプッシュしてしまいました。リモートリポジトリが誰かと共同で利用しているリポジトリの場合は修正を諦めるか管理者や関係者等と相談する必要があるでしょう。リモートリポジトリがプライベート利用の場合は勝手に強制プッシュを行って修正するという選択肢があります。

強制プッシュでの修正の例

ここでのリモートリポジトリは完全にプライベート利用のため、強制プッシュの修正を行ってみます。まず、リモートリポジトリの設定でdenyNonFastforwardsをfalseに変更します。

ローカルリポジトリのコミットメッセージを変更して、強制プッシュを行います。強制プッシュのオプションとして--force-with-leaseオプションという-fオプションより共同作業を破壊するリスクを減らすオプションもありますが、ここではプライベートなリモートリポジトリなので簡単に-fオプションを使って強制プッシュを行っています。

これで、リモートリポジトリのコミットメッセージを修正することができました。あとはリモートリポジトリの設定を元に戻しても良いでしょう。

プル。フェッチとリベースの連続操作 (git pull --rebase)

リモートリポジトリの変更内容をリベースでローカルリポジトリへ統合します。ローカルリポジトリと競合を起こしていない場合は通常のpullと同じようにリモートリポジトリの内容を取り込んだ後にローカルリポジトリの内容を再適用します。

以下はローカルリポジトリに新しいコミットがなく、git pull --rebaseを行った例です。

競合を起こした場合

競合を起こした場合はリモートリポジトリの内容を取り込まれてから、その後にローカルリポジトリの内容を再適用していって競合内容を解決することになります。
競合を解決した後はローカルリポジトリのコミット内容を、そのまま通常のコミット内容をリモートリポジトリにプッシュするように、リモートリポジトリへとプッシュできるような状態になります。

ローカルリポジトリのコミット内容が複数ある場合もリモートリポジトリの内容を取り込んだ後に、ローカルリポジトリのコミット内容をその複数個を順番に再適用してリポジトリの内容を統合していきます。
競合を解決してリポジトリをローカルリポジトリで統合した内容はそのままプッシュしてもいいです。ここでは行っていませんが、リモートリポジトリにプッシュする前ならば、必要があれば、さらにコミット内容をgit rebase -iを用いてsquashの機能を利用してローカルリポジトリだけにあるコミット内容を統合した後にリモートリポジトリにプッシュすることも選択肢として取れます。

リベースを用いるとリポジトリのコミット履歴が一直線になり、とてもシンプルなものとなります。また、リモートリポジトリの内容をシステム上であまり変化がないもの(安定したもの)や清書したものとして扱い、ローカルリポジトリのパッチ内容をリモートリポジトリにプッシュするまでは変化をさせやすいもの(不安定なもの)やまだ下書き段階みたいなものとして扱うとすると、マージよりもリベースで統合していく方がより自然な感じに見えるかもしれません。また、コミット履歴はインクリメンタルな開発がよりできていると感じられるかもしれません。

リモートリポジトリの名前を表示 (git remote show)

git remote showはリモートリポジトリの名前を表示できます。

また、git remote -vはリモートリポジトリのより詳しい情報を確認できます。

リモートリポジトリの登録の名前の変更 (git remote rename)

git remote renameでリモートリポジトリで登録した名前を変更できます。