iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 3
1
DevOps

Git 其然,Git 其所以然系列 第 3

Git Initialize

  • 分享至 

  • xImage
  •  
# Outline
一、前言
二、Git CLI
三、Git GUI Tools
A、待敘項目

# TL;DR
通常我們透過 `git init` 去初始化一個 Git 倉庫,它會在專案目錄下產生一個 `.git` 目錄。儘管該目錄有不少子目錄和檔案,但一個被認可的 Git 倉庫,在 `.git` 目錄下只要有擁有 `objects` 和 `refs` 空目錄、以及一個記錄著 `ref: refs/heads/master` 的文字檔 `HEAD` 即可。

# Updated
2019-10-06: 更新標題與文章結構

在雙十連假前,此系列文每天的發文時都會以最簡陳述為主,以求在繁忙的日常中,至少能先維持挑戰鐵人賽的進度,並且逐漸拓展思路與系列結構。預期會在國慶連假將本篇文章論述完整。

前言

平時我們都知道可以透過 git init 去將一個專案 git 化,變成一個被 Git 追蹤、版本控制的專案。那到底 git init 後會發生什麼事呢?這就是今天要來談的內容。

Git Init

# Command Synopsis: git-init 
git init [--options] [directory]

在下面的範例裡,我們新增一個目錄,並透過 ls -al 查看該目錄在執行 git init 前後是有什麼差異。

# Location: ~
$ mkdir how-git-works-lab
$ cd how-git-works-lab

# Location: ~/how-git-works-lab
$ ls -Al

$ git init
Initialized empty Git repository in /Users/ironman/how-git-works-lab/.git/

$ ls -Al
drwxr-xr-x   9 ironman  staff  288  9 19 23:07 .git

在這裡,我們發現多了一個 .git 目錄。這就是 Git 用來儲存所以版本歷史、變動、分支、標籤、等等資訊的地方。

在下面的範例中,我們透過用來查詢當前檔案變動狀態的指令 git status 去驗證現在是否是一個被 Git 所追蹤的專案。並且嘗試在刪除 .git 後再執行驗證,去看會有什麼變化。

# Location: ~/how-git-works-lab
$ git status
On branch master

No commits yet

# Delete `.git` directory
$ rm -rf .git
$ git status
fatal: not a git repository (or any of the parent directories): .git

實驗過後,我們發現在刪除 .git 目錄後,再次下 git status 指令後,就會顯示 fatal: not a git repository 的錯誤,表示所在目錄與其父目錄都不是 Git 倉庫(repository)。

.git Directory

透過下面的範例中,我們可以得知 .git 裡面的目錄結構:

$ ls -Al .git
-rw-r--r--   1 ironman  staff    23B  9 19 23:33 HEAD
-rw-r--r--   1 ironman  staff   137B  9 19 23:33 config
-rw-r--r--   1 ironman  staff    73B  9 19 23:33 description
drwxr-xr-x  13 ironman  staff   416B  9 19 23:33 hooks
drwxr-xr-x   3 ironman  staff    96B  9 19 23:33 info
drwxr-xr-x   4 ironman  staff   128B  9 19 23:33 objects
drwxr-xr-x   4 ironman  staff   128B  9 19 23:33 refs

用一個文字圖來繪製其樹狀結構大致如此:

# [Repo] dot-git: 2fecdda
# Location: ~/how-git-works-lab
$ 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-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── info/
│   └── exclude
├── objects/
│   ├── info/
│   └── pack/
└── refs/
    ├── heads/
    └── tags/

這時候我有一個好奇,乍看之下 .git 目錄下也是有不少檔案和子目錄,那這些都是必要的嗎?有什麼是作為一個 Git 倉庫必備的存在呢?所以做了些實驗。

透過下面範例,我們暸解到並不是專案根目錄下面有一個 .git 目錄,Git 就會照單全收、認為這是一個 Git 倉庫。

# Location: ~
$ mkdir fake-git-repository
$ cd fake-git-repository

# Location: ~/fake-git-repository
$ mkdir .git
$ git status
fatal: not a git repository (or any of the parent directories): .git

接下來我又嘗試一個個把 .git 裡面原本存在的檔案和子目錄刪除,並在刪除某個檔案或目錄時,在專案根目錄下執行 git status 確認這個專案是否是一個 Git 倉庫。

最後得到以下目錄結構:

# [Repo] 61d0acc @ dot-git
# Location: ~/how-git-works-lab
$ tree .git
.git/
├── HEAD
├── objects/
└── refs/

objectsrefs 是空目錄,而 HEAD 是一個文字檔,內容如下:

ref: refs/heads/master

所以只要符合上面目錄結構,且 HEAD 有這樣的文字目錄,就會被認可是一個 Git 倉庫。或許接下來我們就可以先專注在這些目錄與檔案,來暸解 Git 的操作到底是如何透過對 .git 目錄的修改,讓其變成一個版控資料庫的。

附錄 A、待敘項目

  • 補上 git init 的詳細介紹

上一篇
Git Client
下一篇
Git Commit
系列文
Git 其然,Git 其所以然31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言