💬

Gitの仕組み,説明できる?基本とfetch, merge,rebase...

2023/11/05に公開3

改めて、Gitを振り返り学んでみよう

今回はGitについてです!
誰でも理解できるように、でも仕組みをしっかり理解してもらえるように、
改めてまとめてみました。

具体的に今回の内容は以下の項目です。本当の"基本のキ"から書くので、
興味のある分野をご覧ください!

<内容大枠>

  • [基本のキ]Gitって何?
  • [基本のキ]Gitの仕組み
  • fetchについて
  • pullとその関連:
    • merge,
    • rebase,

Gitって何?

以下タブでわかりやすいように、イラストも交えて書いています。
まだ分散型バージョン管理システムって何? 結局Gitは何がいいの?
の方は、見てください!

Gitは"データを圧縮してスナップショットで保存"している!
これに関しては以下次の章で解説を書きます。

Gitとは

Gitとは

  • 分散型バージョン管理システム.
  • Gitの本質: "データを圧縮してスナップショットで保存"
      => これによってバージョンを管理を行うことができている。

■ バージョン管理ツールとは
データを"誰が、どこを、いつ編集したのか"を履歴残しながら、データを保存するもの。
ファイルの作成日時、変更日時、変更点などの履歴を保管ファイルの作成者、
作成日付、更新日付、更新者、変更履歴、コメントを記録できる。
=> 過去の状態や変更内容を確認したり、変更前の状態を復元することが可能。


バージョン管理: 分散型と集中型ってなに?

上記項目で、Gitは "分散型バージョン管理システム" と記述した。
バージョンの管理の仕方には、大きく2通りある。

  1. 集中型(Centralized Version Control System)
  2. 分散型(Distributed Version Control System)

■ 集中型(Centralized Version Control System)

集中型の代表的なツールは、Subversion(SVN)だ。
このタイプのバージョン管理システムでは、ファイルの保管場所は一箇所のみ.
(= リモートリポジトリが唯一の存在。)
ユーザーがサーバにアクセスできない場合、ファイルの変更情報を記録することができない。
同時に複数の人が同じファイルを編集すると、変更が競合し、
一部の変更が上書きされる可能性がある。
これによって作業のコンフリクトが起こり、誰かは作業を保存できても、他の誰かはできない状態になる。

■ 分散型(Distributed Version Control System)

分散型の代表的なツールは、Git(SourceTreeを含む)。
利用者1人1人に専用の保管場所であるローカルリポジトリがる。
バージョンを個々のローカルに完全に複製(クローン)し、それぞれの作業を個別に行う。
ファイルの修正が一段落したら、変更内容をチーム全体で共有するためのリモートリポジトリに
反映(プッシュ)させる。
各ユーザーが自分のPC内にリポジトリ(保存場所)を保持しているため、
ネットワークに接続できなくても作業が可能。これにより、オフラインで作業することができる!
個々の開発者がローカルで作業でき、
リモートへの依存が低く、作業コピーの完全なバックアップが得られる点が利点だ。

特徴 集中型 (SVN) 分散型 (Git)
ファイルの保管場所 一箇所のみ (リモートリポジトリのみ) 利用者1人1人に専用の保管場所あり (ローカルリポジトリ)
ファイルの変更情報記録 サーバ上で一括管理 各個人のローカルで完全な複製を保持
作業時のネットワーク依存性 サーバにつながっていないとファイル情報記録不可 ネットワークに依存せずに作業可能
同時編集時の問題 同時編集時に競合が起こり、上書きの可能性あり 各自のローカルで作業し、後で統合可能
オフラインでの作業可能性 不可 可能
プロジェクトへの依存度 リモートへの依存が高い リモートへの依存が低く、各個人の完全なバックアップを持つ

Gitのデータ管理の仕組み

Gitのデータの持ち方は"スナップショット"
commitはスナップショットであり差分ではないよ、ということと、
"addとか、commitって内部で何してるん?"について書いていきます。

"Git がリポジトリデータをどのように保存しているか"がわかると、これ以降の部分が
理解しやすくなると思います!(だいじ!)

addとか、commitって内部で何してるん??を解決する

基本コマンド

ひとまず先に基本的なコマンドがどんな意味かを、Tableにする。

コマンド 説明
git init リポジトリを新規作成するコマンド .gitディレクトリを作成
git add 変更をステージに追加 blobオブジェクトの作成.
圧縮ファイルを作成。ハッシュ値を付与する
git commit -m "コメント" メッセージをつけて変更履歴を保存 treeオブジェクトの作成
git branch -M main デフォルトブランチをmasterからmainに変更する。デフォルトブランチmainの場合は不要
git remote add origin リポジトリURL originという名前でリモートリポジトリのURLを登録する。
git push origin ブランチ名 ローカルの変更をリモートリポジトリにアップロードする。「ブランチ名」にアップロードしたいブランチの名前を指定します。

■ blob(訳:カタマリ) :ファイルの中身を圧縮しただけのカタマリ
Gitの専門用語では、ファイルは『ブロッブ(blob)』と呼ばれる。
また、ここでの**圧縮ファイルは正確に名前を言うと、 "ハッシュID"**という。

▶️ ローカルでは三つのエリアになっている: stageについて

ローカル環境でのGit構成について

ローカルでは3つのエリアに分かれている。

■ stageって何?

簡単にいうと、"commitするための変更を準備するためのところ"だ。
別の言い方をすると、"変更をコミットする前に一時的な保存領域として機能するもの"だ。
コミットを変更する順にをする時や、一部の変更を記録する際など、
一度その"一部の変更"を記録するために存在しているのが"ステージ"。

addのところで、詳しく知ることができます!

▶️ git add の裏側で行われていること

addの裏側

圧縮ファイルが作られインデックスに追記、ステージングエリアに追加
上記でも書いたとおり、stageに追加されます。
これは、簡単にいうとcommitするための準備だ。

この裏側はどうなってるかというと...

git add .このコマンドが行われた裏側では、

  1. 変更のあったファイルの圧縮ファイルをまずはリポジトリに作成し、圧縮ファイルを作成
  2. ファイル名と圧縮ファイルをまとめた(マッピングした)"インデックス"がステージに作成される
    (ステージングされる)

▶️ git commit の裏側で行われていること

commitの裏側

メッセージをつけて変更履歴を保存

補足:HEADとかMainってなんだ?

これについては、ここのサイトに過去にまとめたのでわからない方は見てください!

■ リモートリポジトリから情報を取得する方法: fetchpull

リモートリポジトリから情報を取得する方法は、fetchpullの2つだ。
これらについてここから詳しく見ていこう。

  • fetch: リモートリポジトリから最新の情報を取得するコマンド
  • pull: git fetchgit mergeを組み合わせたコマンド

取り込み方法①: fetchについて

git fetch コマンドは、リモート・リポジトリからローカル・リポジトリにコミット、ファイル、参照をダウンロードします。フェッチとは、他の開発者の作業内容を確認する場合に行う操作です。このコマンドは、変更はリポジトリに統合されません。Git によってフェッチされたコンテンツは既存のローカル・コンテンツから分離されるため、ローカルな開発作業には全く影響を与えません。

このコマンドは、リモートからデータを取り込む、だけで、それ以外は何もしない。
その取り込んだデータの反映先がアップストリームブランチなので、
ローカルな開発作業には影響がない。

イラストで表すと...

さっきのaddやcommitの裏側のタブでも少し説明したが、
リポジトリには来るが、ワークツリーには来ないのがfetchだ。

アップストリームブランチは以下コマンドで確認可能だ。
$ git branch -vv

取り込み方法②: pullとその関連:  merge, rebase, fastfoward

pullにも種類がある。
defaultは、mergeだが、rebaseとfastfowardが存在する。

▶️ pullについて詳しくみていこう

リモート・リポジトリからコンテンツをフェッチしてダウンロードし、そのコンテンツと一致するようローカル・リポジトリを即時にアップデートするために使用

git pullの仕組み: fetch+merge

git pull コマンドでは、最初に git fetch が実行されて、指定されたリモート リポジトリからコンテンツがダウンロードされます。次に git merge が実行されて、リモート コンテンツ参照がマージされて新しいローカル マージ コミットに進みます。

git pull コマンドを実行すると、以下の手順が実行される。
(※mergeは後程詳しく解説します。)

1. git fetch の実行:
最初に、リモートリポジトリから新しいコンテンツが取得される。
git fetch は、リモートリポジトリの最新の変更をローカルにダウンロードし、
それを参照することが可能になるもの。

2. git merge の実行:
取得したリモートコンテンツが、現在の作業ブランチにマージされる。
これにより、リモートでの変更がローカルの作業コピーに取り込まれ、
新しいローカルマージコミットが作成される。

< 変更統合ユーティリティ: mergeとrebase >

▶️ merge

複数の連続するコミットを 1 つの履歴に統合する。git merge を使って 2 つのブランチを統合するのが最も一般的な使い方です。

独立した変更履歴を持つ2つのブランチを結合するもので、これにより、
両方の変更が保持され、新しいマージコミットが作成されるもの

統合される側のブランチのコミットは変化せず、
そのブランチの最新のコミットは新しいマージコミットを親として含むことになるが、
そのコミット自体は変更されず、そのまま保持
される形になる。
(マージコミットによって、どのようにブランチが統合されたのかが履歴として残る!)

▶️ rebase

リベースは、コミットのシーケンスを新しいベース コミットに移動または組み合わせるプロセスです。リベースは、フィーチャー ブランチ ワークフローにおいて最も役立ち、簡単に視覚化されています。

簡単に言うと、rebaseは変更を統合するとき、履歴をきれいに整えるために使用するもの。
指定したコミットを、ひとまとめにしたりして、ログを綺麗にすることができるコマンド

変更分を取り込んで、(分岐開始場所を変更して)最新ブランチとするもの。
ブランチの基点(切った場所)となるブランチを、別のブランチに移動するようなコマンドで、
そして、その間の他のブランチでの変更分も自分に取り込み最新ブランチにする
= コミットの履歴もきれいに一直線になる(複雑にならない)
= git logも確認しやすくなる。

最後に...

今回は基本部分いついて書いたので、
今度はcherry-pickなどの便利コマンドも取り上げて説明を書きたいと思います!

Git資料一覧

もしこれからエンジニア転職だったり、改めて理解するために学習する方がいましたら、
以下を参考にしてみてください!

使えたから終わりになるのではなく、
何をしているのか理解するのは時間かかってでも大事なことだと思うので、
私も時説振り返りながら、説明しながら、自分の理解度を上げていきたいなと思います。

Discussion

ソニソニ

Cherry-pick少し調べました!協業する時すごく良さそうです!
あいりさんの記事でまた見たいですー