7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

基本的なgitコマンド操作のみを知っている状態から、実際にgitがどのようにバージョン管理をしているかを理解するために学んだことをまとめた記事です。

.gitディレクトリの構成

git init.gitディレクトリを作成します

mkdir git-internals-demo
cd git-internals-demo
git init

tree .gitでディレクトリ構造を確認してみましょう

tree .git
.git
├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── fsmonitor-watchman.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-merge-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   ├── push-to-checkout.sample
│   ├── sendemail-validate.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags

HEAD

  • 現在チェックアウトされているブランチやコミットへの参照を保持するものです
    通常は.git/refs/heads/ 内の特定のブランチを指しており、ref: refs/heads/master のような形式で表示されます。

config

  • リポジトリ固有のGit設定が書かれています
    [core], [remote origin], [branch master], [user]などの情報が中で見られます。
  1. [remote origin] : リモートリポジトリ情報
    リモートURLやブランチの追跡設定(例: origin, heroku)
  2. [branch master] : ブランチ情報
    各ブランチがどのリモートブランチを追跡しているか
  3. [core] : Git設定
    プロジェクト固有の動作を制御する設定
  4. [user] : ローカルユーザー情報(必要に応じて追加)
    特定リポジトリ用のuser.nameやuser.email(グローバル設定を上書きする場合のみ記載)

 
例として以下のリンクで使われているリポジトリをリモートにして中身を見てみる。
https://git-scm.com/book/ja/v2/Gitの内側-配管(Plumbing)と磁器(Porcelain)

git remote add origin https://github.com/schacon/simplegit-progit
cat .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	precomposeunicode = true
[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*

description

  • GitHubなどで使用される、リポジトリの簡単な説明を保存する場所(赤線の場所)
    スクリーンショット 2024-12-01 14.21.53.png

hooks

  • コミットなどのGitのイベント時に自動実行されるスクリプトのことです
    • pre-commit: コミット前に実行(コードスタイルチェックなど)
    • post-commit: コミット後に実行
    • pre-push: プッシュ前に実行(テストの実行など)
    • prepare-commit-msg: コミットメッセージ準備時に実行

hooks/にはデフォルトで14個のサンプルが入っています。
その中のpre-push.sampleを見てみる。

cat .git/hooks/pre-push.sample
#!/bin/sh

# An example hook script to verify what is about to be pushed.  Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed.  If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
#   <local ref> <local oid> <remote ref> <remote oid>
#
# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).

remote="$1"
url="$2"

zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')

while read local_ref local_oid remote_ref remote_oid
do
	if test "$local_oid" = "$zero"
	then
		# Handle delete
		:
	else
		if test "$remote_oid" = "$zero"
		then
			# New branch, examine all commits
			range="$local_oid"
		else
			# Update to existing branch, examine new commits
			range="$remote_oid..$local_oid"
		fi

		# Check for WIP commit
		commit=$(git rev-list -n 1 --grep '^WIP' "$range")
		if test -n "$commit"
		then
			echo >&2 "Found WIP commit in $local_ref, not pushing"
			exit 1
		fi
	fi
done

exit 0

今回の例のpre-pushフックは、リモートにプッシュする前に実行されるサンプルコードです。
このフックを使用して、プッシュされる内容(コミットメッセージやコミット自体)を検査したり、特定の条件に基づいてプッシュを拒否することができます。
例えば、上記のコードで言うと特定のコミットメッセージ(WIP)が含まれている場合にプッシュを止めています。

info

  • exclude: プロジェクトでバージョン管理しないファイルを記載する場所
    gitignore似ているが、個人的な除外設定に使用される

# 念のため個人的なIDE設定を除外
/.idea/

objects

  • Gitリポジトリ内のすべての変更履歴を保存する「オブジェクトデータベース」

refs

  • ブランチタグなど、リポジトリ内の「名前付きポインタ」
    これらの参照は、各ブランチやタグが指し示す最新のコミットハッシュを格納しています。
    それぞれのブランチやタグは、コミットに対するポインタとして機能します。

以下は、refs のサブディレクトリの構成です。

└── refs
    ├── heads
    │   └── master
    ├── remotes
    │   └── origin
    │       └── master
    └── tags
  • refs/heads/: ローカルブランチへの参照
  • refs/remotes/: リモートブランチへの参照
  • refs/tags/: タグへの参照

また、実際にrefs/heads/masterの中身は以下のようになっています。

cat .git/refs/heads/master
ca82a6dff817ec66f44342007202690a93763949

これは、ローカルのmasterブランチに対する最新のコミットのハッシュがca82a6dff817ec66f44342007202690a93763949であることを示している。

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?