標簽: git
[TOC]
1.Git結(jié)構(gòu)
- 工作區(qū)/工作樹/工作目錄:當前Git正在管理的這個文件夾
- 暫存區(qū)/索引區(qū)/緩存區(qū):stage/index/cache,即工作區(qū)根目錄下的'.git/index'文件
- 版本庫/本地倉庫/文檔庫:Repository,即工作區(qū)根目錄下的'.git'目錄
- 遠程倉庫

2.工作區(qū)目錄追蹤
當處于工作區(qū)目錄或子目錄下時,可用下面命令查詢各目錄:
- 顯示版本庫(.git)位置
$ git rev-parse --git-dir
- 顯示工作區(qū)根目錄
$ git rev-parse --show-toplevel
- 顯示當前位置相對于工作區(qū)根目錄的相對目錄
$ git rev-parse --show-prefix
- 顯示從當前目錄(cd)后退(up)到工作區(qū)的根的深度
$ git rev-parse --show-cdup
- 瀏覽暫存區(qū)目錄樹
$ git ls-files
- 瀏覽HEAD目錄樹
$ git ls-tree HEAD
3.Git配置
Git的配置文件 "INI"格式的。
(1)配置文件及其優(yōu)先級
Git共有3個配置文件,優(yōu)先級高的配置會覆蓋優(yōu)先級低的配置。在git config命令中加上配置文件的位置命令標識,可以配置指定級別的配置文件。默認不加則為 “--global”。
| 名稱 | 優(yōu)先級 | 命令標識 | 配置文件位置 | 別稱 |
|---|---|---|---|---|
| 倉庫級 | 最高 | --local | 工作區(qū)的".git/config"文件 | 本地配置文件 |
| 全局級 | 中等 | --global | 用戶主目錄下的".gitconfig"文件 | 全局配置文件 |
| 系統(tǒng)級 | 最低 | --system | "/etc/gitconfig"文件 | 系統(tǒng)配置文件 |
(2)常用配置命令
Git的 "config" 命令可根據(jù)指定的配置文件位置標識來配置特定的文件,不指定則默認全局配置。
$ git config [--local|--global|--system] action其中"action"可有以下取值(其中的鍵值格式為 "<section>.<key> [value]" ):
- --get : 獲取鍵的值
- --add : 添加鍵值
- --unset : 刪除鍵的值
- --list, -l : 查看已配置的選項
- --edit, -e : 直接編輯配置文件
另外,也可用下面的命令獲取和設(shè)置鍵值(命令中省略了文件位置標識):
- 獲取鍵值
$ git config <section>.<key>
- 設(shè)置舊鍵的新值或添加新鍵值
$ git config <section>.<key> value
(3)配置用戶名和密碼
Git中必須配置用戶名和密碼,它們的鍵分別為 "user.name" 和 "user.email" 。
(3)使用"git config"命令操作其他INI文件
- 設(shè)置鍵值
$ GIT_CONFIG=INI文件名.ini git config <section>.<key> value
- 讀取鍵值
$ GIT_CONFIG=INI文件名.ini git config <section>.<key>
4.狀態(tài)查看
使用下列命令可以查看文件狀態(tài):
$ git status
加上"-s"選項表示使用精簡模式:
$ git status -s
精簡模式下顯示的文件狀態(tài)中,格式如下:
狀態(tài)標識1狀態(tài)標識2 文件名
其中狀態(tài)標識1和狀態(tài)標識2分別位于第1列和第2列,其含義為:
- 第一列:"暫存區(qū)"相對于"版本庫"中的文件有改動,藍色標記
- 第二列:"工作區(qū)"相對于"暫存區(qū)"中的文件有改動,紅色標記
每列的標識可取以下值:
- A: 新增了文件
- C: 文件的一個新拷貝
- D: 刪除了文件
- M: 文件的內(nèi)容或者mode被修改了
- R: 文件名被修改了
- T: 文件的類型被修改了
- U: 文件沒有被合并(你需要完成合并才能進行提交)
- X: 未知狀態(tài)(很可能是遇到Git的bug了,你可以向git提交bug report)
5.Git工作區(qū)、版本庫、暫存區(qū)原理圖

簡要說明:
- 圖中左側(cè)為工作區(qū),右側(cè)為版本庫。在版本庫中標記為index的區(qū)域是暫存區(qū),標記為master的是master分支所代表的的目錄樹。
- 圖中的HEAD實際上是指向master分支的一個"游標",所以圖示的命令中出現(xiàn)HEAD的地方可以用master替換。
- 圖中的objects標識的區(qū)域為Git的對象庫,實際位于".git/objects"目錄下。
- 對工作區(qū)修改或新增的文件執(zhí)行
git add命令時,暫存區(qū)的目錄樹將被更新,同時工作區(qū)修改或新增的文件內(nèi)容會被寫入到對象庫中的一個新的對象中,而該對象的ID被記錄在暫存區(qū)的文件索引中。 - 當執(zhí)行提交操作(
git commit)時,暫存區(qū)的目錄樹會寫到版本庫(對象庫)中,master分支會做相應(yīng)的更新,即master最新指向的目錄樹就是提交時原暫存區(qū)的目錄樹。 - 當執(zhí)行
"git reset HEAD"命令時,暫存區(qū)的目錄樹會被重寫,會被master分支指向的目錄樹所替換,但是工作區(qū)不收影響。 - 當執(zhí)行
"git rm --cached <file>"命令時,會直接從暫存區(qū)刪除文件,工作區(qū)則不會做出改變。 - 當執(zhí)行
"git checkout ."或"git checkout -- <file>"命令時,會用暫存區(qū)全部的文件或指定的文件替換工作區(qū)的文件。這個命令會清除工作區(qū)中未添加到暫存區(qū)的改動。 - 當執(zhí)行
"git checkout HEAD ."或"git checkout HEAD <file>"命令時,會用HEAD指向的master分支中的全部或部分文件替換暫存和工作區(qū)中的文件。這個命令不但會清除工作區(qū)中未提交的改動,也會清除暫存區(qū)中未提交的改動。
6.工作區(qū)、暫存區(qū)和版本庫之間的差異比較

(1)工作區(qū)與暫存區(qū)比較
$ git diff
(2)工作區(qū)與HEAD比較
$ git diff HEAD
(3)暫存區(qū)與HEAD比較
$ git diff --cached|--staged
7.HEAD與master
- master:在版本庫的引用目錄(.git/refs)中體現(xiàn)為一個引用文件".git/refs/head/master",其內(nèi)容就是分支中最新提交的提交ID
- HEAD:位于版本庫的".git/HEAD"文件,其內(nèi)容指向了"master",因此和master是一樣的
8.分支與ID查看
- 查看當前分支
$ git branch
- 根據(jù)對象SHA1 ID顯示對象信息
$ git cat-file -t|-p|-s "對象ID"
- 顯示分支對應(yīng)的SHA1 ID
$ git rev-parse "分支名稱(HEAD/master)"
9.重置命令
(1)用法1
不會重置引用,更不會改變工作區(qū),而是用指定提交狀態(tài)下的文件替換掉暫存區(qū)中的文件
$ git reset [-q] [<commit>] [--] <paths>...
<commit>為可選項,可以首映引用或提交ID;如果省略則相當于使用了HEAD的指向作為提交ID。
(2)用法2
會重置引用,根據(jù)不同選項,可以對暫存區(qū)或工作區(qū)進行重置。
$ git reset [--soft|--mixed|--hard|--merge|--keep] [-q] [<commit>]

- --soft:執(zhí)行圖中的動作1,只更改引用的指向,不改變工作區(qū)和暫存區(qū)
- --mixed:默認參數(shù),執(zhí)行圖中的動作1、2。即更改引用的指向并重置暫存區(qū),但不改變工作區(qū)
- --hard:會執(zhí)行上圖中的全部動作1、2、3,即:
a.替換引用的指向。引用指向新的提交ID
b.替換暫存區(qū)。替換后,暫存區(qū)的內(nèi)容和引用指向的目錄樹一致
c.替換工作區(qū)。替換后,工作區(qū)的內(nèi)容和暫存區(qū)一致,當然同時也和引用指向的目錄樹一致
(3)例子
-
git reset或git reset HEAD:僅用HEAD指向的目錄樹重置暫存區(qū),工作區(qū)不會受到影響,相當于將之前用"git add"命令跟新到暫存區(qū)的內(nèi)容撤出暫存區(qū)。引用也未改變,因為引用重置到HEAD相當于沒有重置 -
git reset -- filename或git reset HEAD filename:僅將文件filename的改動撤出暫存區(qū),暫存區(qū)中其他文件不改變。相當于對命令"git add filename"的反向操作 -
git reset --soft HEAD^:工作區(qū)和暫存區(qū)不改變,但是引用向前回退一次。當對最新提交的提交說明或提交的更改不滿意時,撤銷最新的提交以便重新提交 -
git reset --mixed HEAD^:工作區(qū)不改變,但是暫存區(qū)會回退到上一次提交之前,引用也會回退一次 -
git reset --hard HEAD^:徹底撤銷最近的提交。引用回退到前一次,而且工作區(qū)和暫存區(qū)都會回退到上一次提交的狀態(tài)。自上一次一來的提交全部丟失。
10.檢出命令
檢出命令會重寫工作區(qū)。
(1)用法1
$ git checkout [-q] [<commit>] [--] <paths>...
<commit>是可選項,如果省略則相當于從暫存區(qū)進行檢出。
此種用法不會改變HEAD頭指針,主要用于用指定版本的文件覆蓋工作區(qū)中對應(yīng)的文件。如果省略<commit>,則會用暫存區(qū)的文件覆蓋工作區(qū)的文件,否則用指定提交中的文件覆蓋暫存區(qū)和工作區(qū)中對應(yīng)的文件。
注意:此用法和重置命令大不相同,重置命令默認值是HEAD,而檢出命令默認值是暫存區(qū)。因此重置一般用于重置暫存區(qū)(除非使用--hard參數(shù),否則不重置工作區(qū));檢出主要是覆蓋工作區(qū)(如果<commit>不省略,也會提換暫存區(qū)中相應(yīng)的文件)。
(2)用法2
$ git checkout [<branch>]
此種用法會改變HEAD頭指針。主要是用來切換到分支。如果省略了<branch>則相當于對工作區(qū)進行狀態(tài)檢查。
(3)用法3
$ git checkout [-m] [[-b]--orphan] <new_branch>] [<start_point>]
此種用法主要是創(chuàng)建和切換到新的分支,新的分支從<start_point>指定的提交開始創(chuàng)建。
(4)例子

-
git checkout branch:檢出branch分支。會執(zhí)行上圖中的1、2、3步驟,并更新HEAD以指向branch分支 -
git checkout或git checkout HEAD:匯總顯示工作區(qū)、暫存區(qū)與HEAD的差異 -
git checkout -- filename:用暫存區(qū)中的filename文件來覆蓋工作區(qū)中的filename文件。相當于取消自上次執(zhí)行"git add filename"以來(如果執(zhí)行過)的本地修改 -
git checkout -- .或git checkout .:會取消本地所有的相對于暫存區(qū)的更改,相當于用暫存區(qū)的所有文件直接覆蓋工作區(qū)文件。 -
git checkout branch -- filename:維持HEAD的指向不變。用branch所指向的提交中的filename替換暫存區(qū)和工作區(qū)中的filename文件。