today::エンジニアに憧れる非エンジニア

今のところは、エンジニアとは言えないところの職種です。しかしエンジニア的なものの考え方に興味津津。

Gitにおけるデータ管理の仕組み備忘録

Gitはデータをスナップショットとして保存する

  • 変更されたファイルの内容全体を保存する
  • 前のデータとの差分を保存しているわけではない

スナップショットを保存することのメリット

  • 頻繁に行われる基本的な操作が劇的に高速化する
    • 変更同士で差分を取る操作
    • 変更をマージする操作
    • ブランチに関する操作
      • 新規にブランチを切る操作
      • ブランチを切り替える操作
  • 堅牢なデータ管理が実現できる
    • コミット同士が疎結合になる
    • 「前のコミットの内容がないと、あるコミットの内容を復元できない」という事態が発生しない

スナップショットを保存することのデメリット

  • 巨大なファイルを扱う場合、リポジトリが肥大化しやすい
    • 特に圧縮済みバイナリファイルの管理には全く向かない

Gitリポジトリを構成する要素

blob

  • 管理対象ファイルの内容そのものを指す実体
  • git addコマンドの実行により、リポジトリ上に生成される
  • 生の内容そのものではなく、圧縮された上で保管される
    • 既に圧縮済みのバイナリファイルを管理対象とした場合、みるみるうちにリポジトリが肥大化していく
  • blobにはファイル名の情報は含まれない

tree

  • ディレクトリ構造全体のうち、変更が加えられた部分のスナップショットを表す実体
    • 一つのtreeの構成要素
      • ファイル名と対応するblobの組
      • サブディレクトリ名と対応するtreeの組
    • 変更が加えられていない部分を取得するためには、前のスナップショットを順次参照していく
  • git commitコマンドの実行により、リポジトリ上に生成される
    • その内容は、git addコマンドによりステージングエリアに生成されたindexの内容に基づいて定義される
  • 有効なtreeの条件
    • 有効なtreeは、blobまたは別のtreeを1つ以上参照していなければならない
    • treeチェーンがループすることはありえない
    • treeチェーンの末端にはblobが必要となる
  • 「空ディレクトリ」はGitでは管理できない
    • 上記の条件から導かれる

commit

  • コミットそのものの情報を表す実体
    • 誰がコミットしたか
    • いつコミットしたか
    • 1つ前のコミット
      • イニシャルコミットに1つ前のコミットは存在しない
      • 通常のコミットの場合、1つ前のコミットは1つのみ存在する
      • マージコミットの場合、1つ前のコミットは2つ以上存在する
    • コミットメッセージ
  • git commitコマンドの実行により、treeと同時にリポジトリ上に生成される
  • branchやtagは、それぞれ1つのcommitに紐づけされる
    • branchであっても、枝全体を指すわけではない
    • branchが指すcommitはあとから変更することができる
    • tagが指すcommitをあとから変更することはできない

ローカルマシンにおける、Gitに関する実体

ローカルリポジトリ

  • 管理対象文書群のスナップショットそのものを記録していく領域
  • 上記blob、tree、commitを主な内容とする
  • branchやHEADもローカルリポジトリを構成する主体である

ステージングエリア

  • ひとまとめとしてコミット処理を行いたい一連の変更をひとまとめにするための領域
index
  • ステージングエリアに存在する実体
  • 「ファイルパスと対応するblobの組」をひとまとめにしたもの
  • git commitを行うと、indexの内容から新たなtree群がローカルリポジトリに記録される

ワークスペース

  • 実際にファイルの編集作業が行われる領域
  • git add時の処理