Version Control with Git, 2nd Edition 簡單的一些筆記。
Task list: 😄
Version Control with Git, 2nd Edition
Powerful tools and techniques for collaborative software development
sudo apt install git
gitk
git-gui
建立程式庫
在想監控的目錄中
git init
即會產生一個隱形的 .git
目錄,用來存放修改記錄。
加入檔案
$git add somefile.txt
$git commit -m "Initial Message" --author="Jon Doe <jdl@example.com>"
$git status
提交後,改動會進到本地的儲存庫中。
預先設定好作者資料
$git config user.name "Joe Due"
$git config user.email "joe@example"
如果前面的 somefile.txt
改動過後,只要再 commit
就好,不必 add
git log
: 檢視目前的修改記錄。
commit e62f7fd572775ca2479e3ae4ce64bd73ded6a532 (HEAD -> master)
Author: Nero Miller <ming927@spp.url.com.tw>
Date: Sun Apr 1 05:22:46 2018 +0800
readingHackingvim Ch7,first draft
commit 後的是 SHA-1 hash,用來分辨各版本間的不同
See Also
git show
: 看詳細資料
git diff a-hash b-hash
$git mv somefile.txt somefileB.txt
$git rm somefileB.txt
$git commit -m "mv rm some file"
檔案修改都是要提交後,才會生效。
git clone url_to_the_depo
: copy depo to local
設定
--file
(.git/config): 整個程式庫--global
(~/.gitconfig): 使用者--system
(/etc/gitconfig): 整個系統別名
git config --global alias.show-graph 'log --graph --abbrev-commit --pretty=oneline'
之後打git show-graph
就好
Git 版本控制的一些概念。
程式庫 Repositories
程式庫:
Depository n. 貯藏所, Repository n. 容器;貯藏處, 基本上算是同義字。
程式庫 = 檔案 + 修改記錄(及作者、日期) ,以資料夾為操作單位
翻譯術語,參考 git-it/guide/locale-zhtw.json
GIT物件
Binary large object,各版本間的差異以二進位物件儲存,
應該是在 .git/object/
下的檔案
各版本的目錄資訊,各 blos 的辨識碼,以 UNIX 來說 blobs 若是檔案,Tree 算是目錄
提交物件有每次提交時的所有資訊,作者、時間、歷史資訊
SHA1-hashs 難記, Tags提供一個別名的方式,
像是: 8.0.1616-Alpha 這類方便記憶的名字
索引 Index
一個動態、暫時的二進位檔,用以描述目前的檔案結構
See Also
可尋址內容名稱 Content-Addressable Names
** Git 追蹤內容**
Table 4-1. Database comparison
系統 | 索引機制 | 資料儲存 |
---|---|---|
傳統資料庫 | ISAM | 資料記錄 |
UNIX 檔案系統 | 目錄 | 資料塊 |
GIT | .git/object/hash 樹狀物件內容 | 物件,Blob 樹狀物件 |
打包檔案
GIT 只儲存各版本間的差異,所以佔的磁碟空間很少
物件儲存的示意圖
.git/
目錄內部
$git init
建立一個檔案庫後,會有一個 .git
目錄,
內部儲存變動記錄,和一些資訊。
物件,雜湊、及Blobs
index
是目前檔案庫的樹狀結構git ls-files -s
顯示目前的 index、和 working tree, -s
會顯示 SHA1-hashgit write-tree
將目前的index寫入樹狀結構中Git與SHA1-hash
樹狀結構
提交
每次的提交會儲存這些訊息:
標籤
標籤(TAG),基本上就是別名(Alias)的功能 分兩種: 1. 輕量 lightweight tag: 不會建立永久物件 2. 標示 annotated tag: 會建立你提交的物件
基本上,本章討論檔案管理的一些方法,create
, remove
,move
,rename
索引
被git add
指令加入的指令,才會被加入 index中
Git中的檔案分類
已被 add 的檔案
.gitignore
內的檔案,暫存檔、草稿檔、個人註記、程式自動產生的檔案。
不屬於前兩類的檔案
使用git commit
git commit --all(-a)
: 加入所有未被追蹤檔案
使用git rm
rm
git rm --cached xxx
,但要小心使用git checkout HEAD -- xxx-file
使用git mv
移動、重新命名檔案。
git log --follow xxx-file
:列出該內容的所有歷史記錄。
追蹤重新命名檔案的兩三事
.gitignore檔案
在這個檔案記錄要忽略的檔案:
#
開頭的行是註解,文字後有 #
則不會被視為註解/
結尾,會去找同名的目錄,會忽略同名的檔案。Git允許你在檔案庫的任何目錄放 .gitignore
,各目錄下都可以有
自已的 .gitignore
為了解決多個 .gitignore
檔案,Git 有忽略的優先順序的規則。
以下優先權由高到低排為:
.gitignore
.gitignore
, 離越遠的目錄,其 .gitignore
的優先權越低.git/info/exclude
檔案中的規則core.excludefile
中的規則.gitignore
這個檔案也會被追蹤,如果不想讓 .gitignore
被追蹤,
可以把規則放在 .git/info/exclude
中,就不會被複製了。
git的物件模型及檔案
pass
提交:檔案庫間的變動。
提交會將目前的狀態,送到檔案庫,Git只會儲存變動的部分, 並產生新的 SHA1-hash。Git 很適合經常性的提交。
單元改變集合
Commit
有點像拍照,儲存了那個瞬間檔案庫的樣子。
辨識提交
HEAD
: 最新提交版本的別名。
Git 中有許多寫提交名稱的方式,可以來存取、比較變動。
絕對提交名稱
絕對提交名稱 SHA1-hash
ref 與 symref
ref
: 用另一個好記的名字,來代替較長的 SHA1-hash , 像是 HEAD,tags
symref
(symbolic reference): 用來代表 ref
的別名
基本上 ref
就是存在下面目錄的檔案:
.git/ref
.git/refs/ref
.git/refs/tags/ref # 標籤
.git/refs/heads/ref # 本地
.git/refs/remotes/ref # 遠端
.git/refs/remotes/ref/HEAD
Git 內部已有的 ref
HEAD
先記錄在這,以備使用git fetch
時,會把動作時,遠端的分支,存在這這些都可以用 git symbolic-ref
來管理。
See Also:
相對提交名稱
就像 unix 中的目錄操作有絕對路徑、相對路徑,git 的別名也是
^
: 同世代中選擇不同的父物件
~
: 向上層選擇父物件
縮寫: C^ = C^1, C^^ = C^2 = C^1^1
master
或 master^
指的是倒數第二個提交
master^2
或 master~2
指的就是倒數第三個,
常用指令
git rev-parse master~3^2^2
git show-branch --more=35|tail -10
送交歷史記錄
查閱過往提交記錄
HeAD
: 目前最新的提交
master
: 目前的主分支
主要的指令是 git log
,等同於 git log HEAD
$ git log --pretty=short --abbrev-commit -p master~12..master~10
--pretty=short
: 列印的格式, (online, short, full)
--abbrev-commit
: SHA1-hash 以縮寫列出
master~12..master~10
範圍
-p
: 列出有改動的檔案
git show
用來印出儲存的物件
git show HEAD
git show origin/master:Makefile
** 送交的圖示**
Git 使用 DAG(Directed acyclic graph 有向非循環圖)
送交範圍
git log ^X Y
= git log X..Y
start..end
: 兩個點代表 相減
start...end
: 三個點代表 兩者間的 相對差異
尋找提交
使用 git bisect
git bisect
可以將一些有特定問題的提交分離出來。可以把一些有問題、有 bug 的提交丟掉。
git bisect
在給定 good , bad 後,會以互動式的提問,來幫你找出有問題的地方。
使用 git blame
由指令可以,這可以幫你找出產生問題的兇手 ,會在每個改變後,註記這個變動是在哪個提交後產生的。
使用 git log -Sstring
git log -Sstring
可以找出 string 這個字串是在哪個版本加入的。
一個專案中,為了不同的目的,可能需要的不同的方向,像是 dev, build, stable, alpha, …
而分支就是使專案有不同的特化型態而出現的功能。
使用分支的理由
分支名稱
master
使用分支
分支就像目前行駛的路徑,決定你取出哪些檔案,預設是 master
建立分支
$git branch some-branch-name/new-commit
列出分支
$git branch
檢視分支
顯示更詳細的資訊
$git show-branch
-r
: remote
-a
: all
取出分支
使用 git checkout
能取出其他分支的內容。或是說切換到另一個分支。
而分支的有改動在未提交之前,Git 會發出錯誤訊息。
合併分支
如果你目前工作的分支、和你想切換的分支有衝突,這時就需要合併分支了。
$git checkout -m dev
建立、並取出新的分支
建立新分支後,馬上切換過去
$git checkout -b bug/pr3
# 若是遇到問題,可以下面的指令
$git checkout -b new-branch start-point
缷載的 HEAD 分支
HEAD 通常會指向某個分支,但是在某些操作下 HEAD 剛才沒有指向分支時,這個就是斷頭了
See Also * 【冷知識】斷頭(detached HEAD)是怎麼一回事?
刪除分支
想要刪除的分支,用 -d
選項
$git branch -d bug/pr-3
若想刪的分支上,有一些變動是主要分支沒有的,可能沒辦法刪除, 這時可以將變動合併到主支線後,這個分支就能刪了。
$git merge bug/pr-3
$git branch -d bug/pr-3
Diffs 比較兩個物件的差異。 Unix 有一個指令 diff
也是用來比較檔案間的差異。
$ diff -u initial rewrite
--- initial 1867-01-02 11:22:33.000000000 -0500
+++ rewrite 2000-01-02 11:23:45.000000000 -0500
@@ -1,4 +1,5 @@
-Now is the time
+Today is the time
For all good men
+And women
To come to the aid
Of their country.
-u
: 使用 -u
的的顯示格式,+ , -
號@@
: 這行代表差異的行數,-1,4
指 initial
的 1,4 行-
: 減號開頭的是 old 有, new 沒有的內容+
: 加號開頭的是 old沒有,new 有的內容git diff
指令形式
git diff
: 比較目前目錄狀態,與索引間的差異git diff commit:
比較 commit
與索引git diff commit1 commit2
: 比較兩個 commit 的差異git diff --staged commit
: 比較已進入 staged
,與 HEAD
git diff --cached
目前狀態,和前一次 commit 比較staged
: 已 git add
,還未 commit
,用這個會比較直覺
-M
: 偵測改名檔案
-w
: 忽略空白
--stat
: 多顯示一些統計數據
--color
: 輸出著色
git diff 範例
pass
git diff 指令、及送交範圍
使用路徑限制結合 git diff 指令
git diff master~5 master Documentation/git-add.txt
:可以看單一檔案版本間的差異
比較 diffs 在 svn 和 git 差別
多人合作時,要將各別的成果整合時,就需要合併(Merge)資料。 合併時,其本上是把兩個分支整合成一個新的 commit 來表示這個合併後的新狀態。 有衝突的部分,會在 Index 上標示 unmerged ,讓使用者決定。
合併兩個分支
git merge alternate
: 將 alternate 合併到目前分支有衝突的合併
如果在合併的過程中,有衝突的檔案,會將兩個版本的內容放在檔案中, 自行解決衝突的檔案。
處理合併衝突
找到衝突的檔案
git status
, git ls-files -u
可以用來顯示工作目錄中尚未被合併的檔案集合。檢查衝突
git log --merge --left-right -p
--merge
只顯示跟衝突檔案相關的提交--left-right
當次的提交是從左邊來的,(–ours 我們起始的版本,–theirs 別人合併進來的版本)-p
顯示訊息跟修正檔案之間跟每個提交的關係Git 如何追蹤衝突
.git/MERGE\_HEAD
: 放了要合併的提交的 SHA1git/MERGE\_MSG
: 放了解決衝突後提交的預設合併訊息git diff
時,一定是比較索引、和工作目錄檔案放棄或是重新合併
git reset --hard HEAD
: 可以回復到執行 git merge
之前合併的策略
之前的例子是簡單的兩方合併,若是三方以上的情形的話。
正常的合併
特別的合併
翻譯有點…先pass
Commit
記錄著歷史、和變更記錄。 但是已送交的記錄也是有些工具可以修改。
要注意的是,如果是會出現在別人容器的送交,記得不要修改,以免產生問題。
git reset --soft commit
git reset
的指令可以讓目前工作目錄的 HEAD, Index, 工作目錄 回到之前的某的狀態。選項 | HEAD | 索引 | 工作目錄 |
---|---|---|---|
--soft |
Yes | No | No |
--mixed |
Yes | Yes | No |
--hard |
Yes | Yes | Yes |
Github 是有 社交功能的 原始碼分享網站。
git remote add URL
,兩邊連結。Github 的 Watch`
Watch
就像 twitter 的 follow ,會在主頁出現追蹤專案的動態Fork
專案複製,想將專案往不同的方向發展。Pull Request
對原專案的修改,發出請求,合併至原專案。Star
Favorite 的標記Wiki
各專案的維基,用來寫文件。Github Page
可用來放靜態 HTMLGIST
用來貼短篇文章的功能, Pastebin其他類似 Github 的網站
自架 Git
Depository n. 貯藏所 Repository n. 容器;貯藏處
qxnCIg7j
GitBook 中文解說 - 2.4 https://wastemobile.gitbooks.io/gitbook-chinese/content/
作者:Jon Loeliger 追蹤 譯者:吳曜撰 出版社:歐萊禮 出版社追蹤 功能說明 出版日:2013/1/25 ISBN:9789862766699 金石碼:2014713380050 語言:中文繁體 適讀年齡:全齡適讀
編/譯者:吳曜撰 語言:中文繁體 規格:平裝 分級:普級 開數:18.5x23 頁數:452 出版地:台灣
版本控制使用Git 第二版-目錄導覽說明
第1 章 簡介 第2章 安裝Git 第3章 準備開始 第4章 基本的Git概念 第5章 檔案管理以及索引 第6章 送交 第7章 分枝 第8章 Diffs 第9章 合併 第10章 修改送交 第11章 遠端容器 第12章 管理容器 第13章 補綴檔案 第14章 掛鉤 第15章 結合專案 第16章 在Subversion容器上使用Git
===
add (加入) 把檔案內容加入索引 (index,又稱預存區 (stage) 或快取 (cac he)) bisect (二分法) 用二分法找出引入 bug 的變改更 branch (分支) 列出、建立或刪除分支 checkout (檢出) 把特定分支或路徑下的檔案檢出到工作樹 clone (克隆) 把版本庫克隆到新目錄 commit (提交) 把變更記錄到版本庫 diff (差異) 顯示兩提交版本之差異、提交版本與工作樹之差異等等 fetch (獲取) 從其他版本庫下載物件和參照 grep 從檔案中尋找文字並印出匹配特定型態的行 init (初始化) 建立空的 Git 版本庫或把已存在的版本庫重新初始化 log (日誌) 顯示提交日誌 merge (合併) 把兩段以上的開發歷史合在一起 mv (移動) 把檔案、目錄或符號連結移動或更名 pull (拉收) 從其他版本庫或本地分支獲取及整合資料 push (推送) 更新遠端版本庫的參照及相關物件 rebase (變基) 上游分支更新時,把本地提交向前接到新的頭端 reset (重設) 把目前的 HEAD 重設為指特定狀態 rm (移除) 把檔案從工作樹及索引移除 show (展示) 展示各種類型的物件 status (狀態) 展示工作樹的狀態 tag (標籤) 建立、列出、刪除、或驗證標籤物件及其 GPG 簽字