Git を1からやり直す(リモート編)

Gitを1からやり直す(目次)

リモートリポジトリ

リモートリポジトリは、GitHubのようなソースコード管理サービスやネットワーク上の共有ドライブなど、多くは自分のマシン外にあって他の人とコードを共有できるリポジトリのこと。

コマンド 動作など
git remote add origin URL リモートリポジトリにoriginという名前をつけてURLを設定
git remote -v リモートリポジトリの設定確認
git push origin ブランチ名 プッシュする。リモートリポジトリにブランチを送ること
git clone URL クローンする。リモートリポジトリのコピーをローカルに作ること

リモート名はoriginとすることが多い。他の名前でも可。

リモート追跡ブランチ

リモートリポジトリにプッシュすると、そのときのブランチを記録した"追跡ブランチ"がローカルにできる。これはmasterなどのブランチ名がブランチ先端のコミットを表すポインタであるのと同様、最新のプッシュ時のコミットを指すポインタのようなもの。追跡ブランチにコミットすることはできないが、現在のコミットとの差を確認したりするときに役立つ。

コマンド 動作など
git branch -r 追跡ブランチ名確認
git branch -r -v 追跡ブランチのコミット確認
git diff origin/master master 追跡ブランチとローカルブランチの差を見る(masterブランチの例)
git log origin/master..master 最後のプッシュ以降の変更履歴を見る例(masterブランチの例)
$ git log --oneline
ed4ef63 (HEAD -> master, origin/master) English追加
a67591b READMEに"▲▲▲▲"追加
4d7d34c READMEに"〇〇〇〇"追加
22b74e1 README作成

上の例では、origin/masterが追跡ブランチ。この後コミットすると master ブランチは伸びるが、origin/master は変わらない。次にプッシュしたときに origin/master はそのコミットに移動する。

Git - リモートブランチ

フェッチ

fetch は「取ってくる、連れてくる」という意味で、リモートリポジトリの変更をローカルリポジトリに取り込むこと。

コマンド 動作など
git fetch origin リモート(origin)の変更をローカルに取り込む。HEADは移動しない

使い方の例(リモートの masterブランチがローカルより進んでいる前提)

  1. $ git fetch origin:リモート(origin)の変更をローカルに取り込む
  2. $ git checkout master:ローカルの masterブランチ先端に移動
  3. $ git merge origin/master:追跡ブランチ(origin/master)にマージさせる(HEADがブランチ先端に移動)

プル

上の例のフェッチとマージを一気にできるのが、プル。リモートの変更を取り込んでマージする。

コマンド 動作など
git pull origin ブランチ名 origin(リモート)の内容をローカルにコピーする

プルとリベース

共有リポジトリにプッシュしようとしたときに、自分が開発を始めたときよりリモートリポジトリの開発が進んでいる場合がある。そのままプッシュすると、コンフリクトが起こるかもしれない。そういうときは、プッシュする前にリモートリポジトリの変更を取り込んで、コンフリクトを解消してからプッシュした方がよい。

プルでリモートの変更を取り込んで、ローカルでマージ → プッシュしてもよいが、並行して開発している人が多いとコミットグラフが複雑になる。

そこで、リベースしてからプッシュする方法がある(リベースについてはこちらの記事)。

実際にやってみた。リポジトリが下のようになっているとする。

# リモートリポジトリ
master  A - B

# ローカルリポジトリ
master  A
         \
fix       C

コミットAから fixブランチを切ってコミットし、プッシュしようとしたら、master に他の人がコミットしてBができていたという状態。

まず、プルでリモートの変更を取り込む。

$ git checkout master  # master ブランチに移動
$ git pull origin master  # リモート(origin)を取り込んで master ブランチにマージ
# ローカルリポジトリはこうなる
master  A - B
         \
fix       C

次に、fixブランチを masterブランチにリベースする。

$ git checkout fix  # fix ブランチに移動
$ git rebase master  # master ブランチにリベース
# コンフリクトが起きたときは解消して → add → git rebase --continue
# ローカルリポジトリはこうなる
master  A - B
             \
fix           C'

これで、$ git push origin fixでプッシュしてプルリクエストを作れば、コンフリクトは起こらないので、コードが適切ならそのままマージできる。

プル・リベース

$ git pull --rebaseを使うと、上のプルとリベースを一発でできる。正確には、マージの代わりにリベースするので、フェッチとリベース。

# fix ブランチにいる状態

# リモート(origin)を取り込んで master ブランチにリベース
$ git pull --rebase origin master 

# コンフリクトが起きたときは解消して → add → git rebase --continue

ただ、リベースは履歴を書き換えることなので、気軽に使うべきでないという議論もある。いずれにしろ、使うときは注意したい。

git pullgit pull --rebaseの違いについては、こちらの記事がわかりやすい。

kray.jp


(参考資料)わかる Git