firisu the shooter

プログラミング、Web開発について

縛りプレイで覚える Git ~git init 編~

序論

まず基本中の基本、 git init から攻略する

実際の Git を使った開発では git clone から始めることが多いが、 git clone は複数の要素が絡む複雑なコマンドなので、 企画後半で扱うことにする。

まずは動作を調べる

とりあえず空のディレクトリで git init を実行してみよう。

$ git init
Initialized empty Git repository in ~/dom-git/.git/

$ tree .git
.git
├── HEAD
├── branches
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-commit.sample
│   ├── post-receive.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-rebase.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
        └── tags

        9 directories, 14 files

結構たくさんファイルが含まれているが、重要なファイルは少ない。

  • HEAD
    • 現在のブランチを示すテキストファイル。
    • 初期状態だと ref: refs/heads/master とだけ書かれている
    • 例えばこれを ref: refs/heads/develop と書き換えると、develop ブランチにいることになる
      • ワーキングツリーとインデックスは変化せず、HEAD だけが動く
      • つまり git reset --soft develop を実行したのと同じ結果である
  • branches/
    • 古いバージョンの Git で使われていたディレクトリで、今はもう使われていない
  • config
    • Git のコンフィグファイル
    • ローカルリポジトリ特有の設定を管理しており、 git config -e で編集できる
  • description
    • サーバ側のリポジトリでのみ使うファイル(だったと思う…)
  • hooks/
    • Git のフックを管理するディレクトリ
    • 初期状態ではサンプルファイルしか入っていない
  • info/exclude
    • Git の管理対象外とするファイル名を記述する
    • .gitignore と似ているが、こっちはリポジトリとして管理されない
  • objects/
    • Git の内部オブジェクトを管理するディレクトリ
    • 後に詳述する
  • refs/
    • ブランチの先頭を格納するディレクトリ
    • ローカルリポジトリは refs/heads/, リモートリポジトリは refs/remotes/ に格納される
    • 中身はブランチを示すハッシュを記しただけのテキストファイル

ざっとこんな物である。

大切なのは HEAD, objects/, refs/ くらいだ。

実現手順

動作が分かった所で、これを実現する手順を考えてみよう。

  1. 必要なディレクトリをまとめて作成
  2. HEAD に ref: refs/heads/master をセット
  3. config ファイルに最低限の設定をセット

これだけである。

他のファイルは全部空白で構わない。

実装

さっそくコードで実装してみよう。

今回は非常に簡単なので、シェルスクリプトで実装する。

dom-init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/sh

# .git/ を作成
mkdir .git
cd .git

# HEAD を作成
echo "ref: refs/heads/master" > HEAD

# ディレクトリをまとめて作成
mkdir -p branches hooks info objects/info objects/pack refs/heads refs/tags

# config を作成
echo << EOT > config
[core]
»---repositoryformatversion = 0 # 互換性のための記述
»---filemode = true             # パーミッション等も管理対象
»---bare = false                # ベアリポジトリではないので false
»---logallrefupdates = true     # git reflog を使用できるようにする
EOT

# description は空でOK
touch description

# info/exclude も空でOK
touch info/exclude

結果

$ rm -rf .git
$ ./dom-init
$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       dom-init
nothing added to commit but untracked files present (use "git add" to track)

ふむふむ、ちゃんと Git のリポジトリとして認識されているようだ。

次 > git add 編: インデックスを作る

Comments