初心者データサイエンティストの備忘録

調べたことは全部ここに書いて自分の辞書を作る

【Gitをはじめからていねいに】を読んで苦しんだ箇所一覧

社内異動に伴い、Gitを使うことになりました。
これを機にGitを勉強してみようと思い立ち、Gitをはじめからていねいにを読んでみました。 その際、一発で理解できなかったことを本記事ではまとめようと思います。

※git version = 2.28.0.windows.1

ファイル操作を行うコマンド

ファイル操作(ファイルの追加や中身の変更など)を行ったり、操作後のファイルを前の状態に戻したり、stageに上げたりするコマンドを整理しました。 文章を読んでもなかなか頭の中にイメージが湧かなかったのですが、図にすると見通しが良くなりました。

図1:ファイル操作を行うコマンド

隣接行変更だとマージの際にコンフリクトを起こす

変更した行に被りがない2つのブランチでもmergeする際にコンフリクトが発生してしまう場合があることがわかりました。 それは、変更した行が隣接している場合です(図2)。

図2:隣接行の変更によるコンフリクト

Gitに詳しい友人に確認したところ「仕様だと思う」とのことでした。

rebaseの感覚的理解

図3はrebaseしたときの挙動です。rebaseすると分岐の開始点が変わるというのがポイントです。

図3:rebaseのイメージ図

リモートリポジトリとローカルリポジトリの準備

リモートリポジトリとローカルリポジトリを初期設定する際に、やらなければいけないことが多くあるなと感じました。ここでは、その初期設定をまとめます。

説明の前提として、ローカルリポジトリ1、ローカルリポジトリ2、リモートリポジトリの3つのリポジトリを考えます。 まず最初に、ローカルリポジトリ1をコピーしてリモートリポジトリを設定。その後、リモートリポジトリをコピーすることでローカルリポジトリ2を設定することを想定しています。

リモートリポジトリの設定

リモートリポジトリ作成のためにやることは、ローカルリポジトリ1をコピーしてくることだけです。 ただし、単なるファイルやフォルダのコピーではありません。ちゃんとリモートリポジトリであることをGitに認識させるようなコピーが必要です。 このようなコピーをcloneと呼びます。コマンドは下記の通りです。

git clone --bare <ローカルリポジトリ1のパス> <リモートリポジトリのパス>

これでリモートリポジトリが完成しました。

ローカルリポジトリの設定

ローカルリポジトリがリモートリポジトリとやり取りできるようにするためには、以下の条件を満たしている必要があります。

  1. ローカルリポジトリにリモートリポジトリが登録されている。
  2. ローカルリポジトリにリモートリポジトリのブランチが入ってきている。
  3. ローカルリポジトリの各ブランチがリモートリポジトリの各ブランチを追跡している。

この条件を満たすための作業をローカルリポジトリ1と2それぞれに行っていきます。

ローカルリポジトリ1の設定

1の条件を確認します。ローカルリポジトリ1で下記コマンドを打ちます。

git remote

このコマンドを打つことで、ローカルリポジトリ1のリモートリポジトリが何かを確認することができます。 今はまだ、ローカルリポジトリ1に何も登録していないので、何も返されません。そこで下記のコマンドを打って、ローカルリポジトリ1にリモートリポジトリを登録します。

git remote add origin <リモートリポジトリのパス>

これによってローカルリポジトリ1にoriginという名前でリモートリポジトリを登録することができました。

次に2の条件を確認します。次のコマンドを打ちます。

git graph

このとき、出てくるのはローカルリポジトリ1にもともとあるブランチのみです。つまり、ローカルリポジトリ1にリモートリポジトリのブランチがまだ入ってきていません。 そこで、fetchという作業を行います。

fetchとはリモートリポジトリのブランチをローカルリポジトリに反映させるコマンドです*1。 これで、再度git graphをすると、「origin/ブランチ名」となっているブランチが出てくると思います。これがローカルリポジトリの中に入ってきたリモートリポジトリです。

最後に3の条件を満たすように設定します。これは下記のコマンドを打ちます。

git branch --set-upstream-to=<追跡したいリモートブランチ> <手元のブランチ>

以上の作業を経ることで1,2,3を満たすことができました。これをまとめたものが図4です。

図4:ローカルリポジトリ1の設定

ローカルリポジトリ2の設定

ローカルリポジトリ2を作成します。今回はリモートリポジトリからcloneして作成します。

git clone <リモートリポジトリのパス> <ローカルリポジトリ2のパス>

これでひとまずはローカルリポジトリ2が作成されました。次に各条件を満たしているか確認していきます。

「1. ローカルリポジトリにリモートリポジトリが登録されている」を調べるためには、git remoteです。リモートリポジトリからcloneしてくるとGitが自動的にリモートリポジトリを登録してくれるので、originが返ってきました。

さらに「2. ローカルリポジトリにリモートリポジトリのブランチが入ってきている」についても調べてみます。これはgit graphで確認します。これについてもcloneしているので、origin/masterなどがローカルリポジトリ2に入ってきているはずです。

最後に「3. ローカルリポジトリの各ブランチがリモートリポジトリの各ブランチを追跡している」です。これについては、ローカルリポジトリ2にそもそもブランチを作成していないので、作成と追跡をまとめて行います

git branch <手元のブランチの名前> <追跡したいリモートブランチの名前>

図5:ローカルリポジトリ2の設定

なお、追跡させるためのコマンドについては、図6のような場合分けがあるので注意です。

図6:ブランチを追跡させるコマンドの使い分け

git pushの感覚的理解

git pushはローカルリポジトリのコミット履歴をリモートリポジトリに反映させるコマンドです。感覚的な理解を図7に記載しました。

図7:git_pushのイメージ図

git pullの感覚的理解

git pullはfetch+mergeです。図8に感覚的理解を記載しました。

図8:git_pullのイメージ図

まとめ

  • ファイル操作は「ディレクトリでの作業」「前の状態に戻す」「staging」「commit」という観点で整理するとわかりやすい。
  • マージは2個のブランチの変更の合計。
    • 隣接行だと変更した行に被りがなくてもコンフリクト起きる場合がある。
  • rebaseすると分岐点が変わる
  • ローカルリポジトリからリモートリポジトリを操作できるよう状態にするための条件は3つ。
  • pushはローカルリポジトリのコミット履歴をリモートリポジトリに反映させる。
  • pullはfetch+merge。

*1:cloneはリポジトリ全体を持ってくるのに対して、fetchはブランチだけ持ってきます。