🙌

【Git入門】git config と git push の仕組みをわかりやすく解説

に公開

はじめに

Gitを使用して、普段何気なく、git pushgit pull を使用しますが、どうやってネットワーク環境を介してリモートリポジトリとローカルリポジトリを同期しているのか、そのメカニズムがわからなかったので、調べてわかったことをここにメモとして記録していきます。

この記事でわかること

  • .git/config ファイルの役割と構成

  • git remote add で設定される内容と、その意味

  • git push がどのようにリモートのURLを判断しているか

.git/config による管理

Git は、git remote add コマンドでリモートリポジトリを紐づけた際に、その情報をローカルの git/config ファイルに保存します。このファイルには、リモートリポジトリの名前(通常は origin)と、それに対応する URL が記録されています。

git pushgit pull のようなコマンドを実行すると、Git はこの設定ファイルを参照し、指定されたリモートの名前(例:origin)に関連付けられた URL を読み取って接続します。
つまり、一度設定すれば、Git はその情報を恒久的に使用するため、毎回 URL を確認するようなネットワーク通信は発生しません。

この仕組みにより、Git は高速にリモート操作を実行でき、ユーザーは煩雑な URL の入力を省略できます。もし URL が変更された場合は、git remote set-url コマンドを使って git/config ファイル の情報を手動で更新する必要があります。

実際に、過去に作成した frontend-portfolio ディレクトリで git/config ファイルを以下のコマンドで確認してみました。

ターミナルで実行したコマンド
$ cat .git/config
出力結果
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	precomposeunicode = true
[remote "origin"]
	url = https://github.com/Mavo39/frontend-portfolio.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
	vscode-merge-base = origin/main
[branch "feat/01_travel_spot"]
	vscode-merge-base = origin/feat/01_travel_spot
	remote = origin
	merge = refs/heads/feat/01_travel_spot
[branch "feat/01_travel_spot_data"]
	vscode-merge-base = origin/feat/01_travel_spot
...

Git の push がどのように機能するか

設定ファイルの役割

Git は、リモートリポジトリの情報を .git/config というローカルファイルに保存しています
これは、まるでコンピューターにあるアドレス帳のようなものです。このアドレス帳には、"origin" のようなニックネーム(リモート名)と、対応する GitHub の URL がペアで記録されています。

$ git remote add origin https://github.com/user/repo.git

このコマンドは、「https://... というURLに、origin という名前をつけてアドレス帳に登録する」ことを意味します。

push コマンドの実行

基本構文
git push <リモートリポジトリのニックネーム> <アップロードするローカルブランチ名>
$ git push origin main

コマンド全体の意味
origin と名付けられたリモートリポジトリに、ローカルの main ブランチの変更内容をプッシュ

各コマンドの意味

  • git push : ローカルリポジトリの変更をリモートリポジトリにアップロード
  • origin : リモートリポジトリに付けられたニックネーム
  • main : プッシュする対象となるローカルブランチの名前

コマンド実行後の動作

処理の流れの全体像
git push → .git/config → URL判定 → HTTPS or SSH → GitHub

1. アドレス帳(.git/config)を開く
2. "origin" というニックネームを探し、その横に書かれているURLを読み取る

一部抜粋
...
[remote "origin"]
	url = https://github.com/Mavo39/frontend-portfolio.git
...

3. 読み取ったURL(https://...git@...)を見て、どの方法で接続すればよいかを判断

  • https://... であれば、HTTPS接続を選択 ←上記のケースはこっち
  • git@... であれば、SSH接続を選択

4. 正しい方法でGitHubに接続し、main ブランチの変更内容を送信

.git/config ファイルの構成

.git/config ファイルは、いくつかのセクションに分かれており、それぞれが特定の役割を持っています。

[core]

このセクションは、Gitの基本的な動作設定を定義します。
例えば、logallrefupdates = true は、ブランチやタグの変更履歴をすべて記録することを意味します。

[remote "origin"]

これはリモートリポジトリのURLを定義する重要なセクションです。
ここで設定された url = https://github.com/Mavo39/frontend-portfolio.git が、git pushgit pull の際にアクセスする GitHub の場所になります。
この「origin」というリモート名は、ローカルリポジトリが紐づいているリモートの「ニックネーム」です。

[branch "main"] や [branch "feat/..."]

これらのセクションは、特定のブランチに関する設定を定義します。
ここには、そのブランチがどのリモートブランチを追跡するかなどの情報が記述されます。

例えば、

上記の例から一部抜粋
[branch "feat/01_travel_spot"]
	vscode-merge-base = origin/feat/01_travel_spot
	remote = origin
	merge = refs/heads/feat/01_travel_spot

[branch "feat/01_travel_spot"] セクションの
「remote = origin」 と 「merge = refs/heads/feat/01_travel_spot」 は、
「このローカルブランチは、"origin" というリモートの "feat/01_travel_spot" ブランチを追跡します」ということを意味します。

これにより、git pushgit pull を実行する際に、Gitは自動的に正しいリモートブランチと同期します。

ポイント

  • リモートリポジトリのURLは一つ(または複数)の[remote]セクションで定義され、各ブランチはそのURLを間接的に参照していること

  • 各ブランチセクション([branch "feat/..."])では、「remote = origin」 のように、リモート名を参照することで、どのリモートリポジトリと関連しているかを指定していること

これは、同じリモートリポジトリ(origin)に複数のブランチをプッシュする際に、URLをブランチごとに重複して記述する必要がないため、効率的です。

補足

上記の例から一部抜粋
[branch "feat/01_travel_spot"]
...
	merge = refs/heads/feat/01_travel_spot
...

これは、ローカルブランチ(feat/01_travel_spot)は、リモートブランチ(feat/01_travel_spot)を追跡(track)することを意味します。

この設定があることで、git pull や git push を実行する際に、Gitは自動的にローカルの feat/01_travel_spot ブランチとリモートの feat/01_travel_spot ブランチを同期します。Gitは remote = origin とこの merge の設定を組み合わせて、同期すべきリモートのURLとブランチを決定します。
※ この部分はGeminiの説明を参考にしました

まとめ

今回わかったこと

  • .git/config はリモートのURLやブランチ追跡情報を保存している
  • git push は、この情報を元にリモートと通信する
  • HTTPS か SSH かは、URLの形式で決まる

この記事では、git pushgit pull コマンドによってネットワークを介してどうやって同期しているのか、という疑問から始まり、その仕組みを簡単にまとめさせていただきました。
普段何気なく使っているからこそ、どういう処理を行なっているかを知ることで、より理解できたように感じますが、皆様はどうでしょうか。

最後までお読みいただき、ありがとうございました。

参考URL・解説

https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes

https://git-scm.com/docs/git-push

https://stackoverflow.com/questions/43317872/understanding-git-configs-remote-and-branch-sections

Geminiによる解説

Discussion