git tutorial

79
Git Tutorial Jian-Long Huang @c4Lab 14/7/17

Upload: jian-long-huang

Post on 09-Dec-2014

176 views

Category:

Software


4 download

DESCRIPTION

c4Lab 2014 暑期訓練課程

TRANSCRIPT

Page 1: Git Tutorial

Git Tutorial

Jian-Long Huang

@c4Lab 14/7/17

Page 2: Git Tutorial

2

什麼是版本控制 (version control) ?

在軟體開發的過程中,程式碼每天不斷的產生,過程中會

發生以下狀況:

1. 檔案被別人或自己覆蓋,甚至遺失

2. 想恢復昨天寫的版本

3. 想知道跟昨天寫的差在哪裡

4. 是誰改了這段程式碼,為什麼

5. 軟體發行需要分成維護版和開發版

Page 3: Git Tutorial

3

常見檔案管理方式

直接修改法

複製貼上法

FTP 共同管理法

Page 4: Git Tutorial

4

直接修改法

修改 修改

直接在原資料夾修改檔案內容

Page 5: Git Tutorial

5

面臨問題

我這次到底修改了什麼

改錯檔案怎麼辦

檔案被我改壞掉,明天要 demo 給老闆怎麼辦

Page 6: Git Tutorial

6

複製貼上法

每修改到一定次數就 copy 一次資料夾

複製 & 修改 複製 & 修改

Page 7: Git Tutorial

7

面臨問題

這份複製是從那一份複製 copy 來的

這份複製改了什麼

每一份複製都有重複內容,很佔硬碟空間

Page 8: Git Tutorial

8

多人協作?

Page 9: Git Tutorial

9

FTP 共同管理法

用 FTP 來存放共同開發的檔案

Page 10: Git Tutorial

10

面臨問題

誰修改了我的檔案

我改的東西,別人會不會也正在改

別人改了什麼

Page 11: Git Tutorial

11

Page 12: Git Tutorial

12

因此

我們希望有一種機制,可以幫助我們:

1. 可以隨時復原修改,回到之前版本

2. 多人協作時,不會把別人的東西蓋掉

3. 保留修改紀錄,以供查詢

4. 軟體發行時,可以方便管理不同版本

Page 13: Git Tutorial

13

什麼是 Git ?

開源的分散式版本控制系統

Distribution Version Control System (DVCS)

Page 14: Git Tutorial

14

Git 簡史

Linus Torvalds 發明

基於 BitKeeper 經驗設計

目的是管理 Linux Kernel 原始碼

2005/4/3 誕生

2005/4/6 第一版發布

2005/6/16 開始管理 Linux Kernel 原始碼

Page 15: Git Tutorial

15

誰在用 Git ?

Git

X.org

PostgreSQL

Wine

Fedora

Samba

Eclipse

Qt

Ruby on Rails

Gnome

Debian

Perl

Page 16: Git Tutorial

16

Git 特性

分散式版本控制

非線性開發模式

內容定址 (content-addressable) 檔案系統

Page 17: Git Tutorial

17

集中式

Page 18: Git Tutorial

18

分散式

Page 19: Git Tutorial

19

集中式版本控制系統的缺點

沒有網路就不能開發

做什麼事情都要排隊

單點故障風險 (Single point of failure)

Page 20: Git Tutorial

20

分散式版本控制系統的優點

參與 Git 開發的每個人,都擁有完整的開發歷史紀錄

當開發人員第一次將 Git 儲存庫複製 (clone) 下來後,完

全等同於這份 Git 儲存庫的完整備份

不需要網路連線就可以獨立運作

當主機損毀時,皆可透過任何一個客戶端先前複製的資

料還原到伺服器

Page 21: Git Tutorial

21

非線性開發模式

每個人可以按照自己的步調開發

開分支和合併都相當容易

Page 22: Git Tutorial

22

用 Git 表示台北捷運

http://gugod.org/2009/12/git-graphing/

Page 23: Git Tutorial

23

內容定址檔案系統

將檔案內容經過 SHA1 運算所得到一個雜湊值當作檔案

路徑名稱

內容一樣的檔案可以 reuse

Page 24: Git Tutorial

24

其他 SCM 的版本儲存方式

只儲存差異的部份

Page 25: Git Tutorial

25

Git 的版本儲存方式

利用有向無環圖 (DAG)建立快照(snapshot) ,相同內容只會有一份紀錄

Page 26: Git Tutorial

26

儲存庫 (repository)

用來儲存所有版本的一個空間(在 Git 是一個資料夾與

一堆檔案)

建立儲存庫: git init

產生 .git 資料夾,就是一個完整的 Git 儲存庫

Page 27: Git Tutorial

27

工作目錄 (working directory)

別名working tree

我們正在準備開發的專案檔案,無論是新增檔案、修改

檔案、刪除檔案、檔案更名,都是在這個目錄下完成

使用 Git 相關指令的時候,也是在工作目錄下完成

Page 28: Git Tutorial

28

Git 資料結構

Git 有兩種資料結構,分別是物件 (object) 和索引

(index)

Page 29: Git Tutorial

29

Git物件

透過內容產生一組 SHA1雜湊值,然後依照這個雜湊值

所命名的一個檔案

所有物件經過 Zlib演算法進行壓縮,並儲存

在 .git/objects/ 目錄裡面,稱為物件資料庫

物件資料庫只會增加資料、不會減少

裡面的資料都是不可變 (immutable)

四種物件類型: blob、 tree、 commit及 tag

Page 30: Git Tutorial

30

範例

一個 Ruby library專案

Page 31: Git Tutorial

31

blob物件

記錄檔案內容

Page 32: Git Tutorial

32

tree物件

記錄特定目錄下的資訊,包含檔名、對應

的 blob物件名稱以及其他 tree物件

Page 33: Git Tutorial

33

commit物件

記錄提交訊息及所包含的 tree物件

(及上一層 commit物件名稱)

每一個 commit物件都是一個版本

Page 34: Git Tutorial

34

commit物件內容第一次 commit

第二次以後的 commit ,包含上一層 commit物件名稱

Page 35: Git Tutorial

35

tag物件

記錄一個 commit物件(或 blob、 tree

物件)及 tag名稱

Page 36: Git Tutorial

36

http://youtu.be/PZbSRy_ow0U

物件關係圖 (= DAG!)

Page 37: Git Tutorial

37

物件名稱

由 SHA1 運算出來的值,稱為物件的絕對名稱

前面 4 碼 ~40 碼都可以代替絕對名稱

以下的指令都可以達到相同目的

git cat-f ile -p 07c1321be49815d53eb2413f0ad5286010ebb6cc

git cat-f ile -p 07c1

git cat-f ile -p 07c132

Page 38: Git Tutorial

38

參照

物件絕對名稱的別名 (alias) 或指標

目的是方便記憶

每一個參照都對應到一個 Git物件絕對名稱

Page 39: Git Tutorial

39

Git 參照

.git/refs/heads/(本地分支參照)

.git/refs/remotes/(遠端分支參照)

.git/refs/tags/(標籤)

分支參照指向該分支的最新 commit物件名稱

Page 40: Git Tutorial

40

Git 內建參照

儲存在 .git/ 下

HEAD:指向目前分支或目前 commit物件名稱

ORIG_HEAD: 指向HEAD 的前一版

FETCH_HEAD:指向遠端儲存庫各分支的 HEAD

MERGE_HEAD: 執行合併工作時,指向合併來源的

commit物件名稱

Page 41: Git Tutorial

41

開分支不用錢

建立分支 (branch) 和標籤 (tag) 事實上等於建立參照,

參考到已經建好的 commit物件名稱

不會有額外負擔(佔空間、耗資源等等)

Page 42: Git Tutorial

42

Git索引

索引檔: .git/index

包含檔案路徑、對應的 blob物件和權限

記錄「有哪些檔案即將要被提交到下一個 commit 版本

中」

在提交的時候,索引檔內容用來產生 tree物件

Page 43: Git Tutorial

43

操作索引檔

檢視: git ls-f iles

新增檔案: git add

移動檔案: git mv

移除檔案: git rm

檢視工作目錄狀態: git status

記錄變更: git commit

Page 44: Git Tutorial

44

索引別名

index(索引)

cache(快取)

directory cache(目錄快取)

current directory cache(當前目錄快取)

staging area(等待被 commit 的地方)

staged f iles(等待被 commit 的檔案)

Page 45: Git Tutorial

45

檔案的四種狀態

Untracked f iles

Changes not staged for

commit

Changes to be committed

Committed

索引 目前版本

Page 46: Git Tutorial

46

git status

檢視檔案在索引和目前版本之間的差異

Untracked f iles索引和目前版本都沒有

Changes not staged for commit索引沒有

– new f ile: 目前版本沒有

– modif ied: 目前版本有

Changes to be committed索引有

– new f iles: 目前版本沒有

– modif ied: 目前版本有

Page 47: Git Tutorial

47

git add

將工作目錄變更寫到索引檔中

git add -u: 僅將「更新」或「刪除」的檔案寫到索引檔

Page 48: Git Tutorial

48

git rm

rm: 從檔案系統裡面刪除檔案,但未更新到索引檔中

git rm:刪除檔案同時也更新到索引檔

– 相當於 rm + git add -u

git rm --cached: 更新「刪除檔案」到索引檔,但保留工

作目錄下的實體檔案

Page 49: Git Tutorial

49

git mv

將檔案重新命名並更新到索引檔

– 相當於 mv + git add -u

Page 50: Git Tutorial

50

git commit

將檔案狀態為 Changes to be committed及Committed

的檔案提交變更成一個 commit物件

Page 51: Git Tutorial

51

git ls-f iles

列出所有目前已經儲存在「索引檔」中的那些檔案路

徑,預設包含目前版本的所有檔案

Page 52: Git Tutorial

52

安裝Git

yum install git-core

apt-get install git

Mac: http://sourceforge.net/projects/git-osx-installer/

Windows: http://msysgit.github.io/

Page 53: Git Tutorial

53

Git GUI

GitX (Mac)

GitHub Windows (Win), SourceTree (Mac, Win)

TortoiseGit (Win)

SmartGit/Hg (Mac, Win and Linux)

Page 54: Git Tutorial

54

基本設定

編輯~/.gitconf ig 或輸入以下指令

git conf ig --global user.name 'Your name'

git conf ig --global user.email '[email protected]'

git conf ig --global color.ui true

git conf ig --global core.editor 'vi'

Page 55: Git Tutorial

55

建立儲存庫

mkdir git-demo

cd git-demo

git init

Page 56: Git Tutorial

56

第一次 commit

touch README

git add README

git status

git commit -m 'First commit'

Page 57: Git Tutorial

57

修改檔案

編輯 README 做些變更

git status

git diff

git add . (加入所有變更,但不包括刪除檔案)

git status

git diff --cached

git commit -m 'Update README'

Page 58: Git Tutorial

58

建立新檔,刪除舊檔

git touch hello.sh

git rm README(或 rm README; git add -u .)

git status

git add hello.sh

git commit -m 'Remove README; add hello.sh'

git log

Page 59: Git Tutorial

59

只 commit部份檔案

touch a.pl

touch b.pl

git add a.pl

git commit -m 'Add a.pl'

git add b.pl

git commit -m 'Add b.pl'

Page 60: Git Tutorial

60

add 之後又修改內容

修改 hello.sh 做些變更

git add hello.sh

再次修改 hello.sh 做些變更

git commit -m 'Add contents to hello.sh'

– 這時 commit 內容只包含第一次修改的內容

Page 61: Git Tutorial

61

重置索引

想把原本加入到索引檔的檔案恢復成尚未加入

(unstaged) 的狀態

git touch Temp

git add Temp

git status

git reset

git status

Page 62: Git Tutorial

62

重置索引(二)

恢復被刪除或更新的檔案,需加 --hard

git rm hello.sh

git reset --hard

Page 63: Git Tutorial

63

還原被改壞的檔案

想把改壞的檔案恢復到上一次 commit 的狀態

編輯 hello.sh 做些變更

git status

git checkout -- hello.sh

git status

cat hello.sh

git log

Page 64: Git Tutorial

64

查詢歷史紀錄

git log

git log -10(限定輸出 10筆記錄)

Page 65: Git Tutorial

65

比較版本差異

git diff(working tree比較當前版本)

git diff <SHA1>(working tree比較<SHA1>)

git diff <SHA1> <SHA1>(比較兩個版本)

git diff --stat <SHA1>

git diff --cached( staging area比較當前版本)

Page 66: Git Tutorial

66

刪除 untracked 檔案

git clean -n(列出打算要清除的檔案)

git clean -f(刪除 untracked 檔案)

git clean -x (連 .gitignore列的檔案都刪除)

Page 67: Git Tutorial

67

設定忽略清單

需手動建立 .gitignore 檔案來定義忽略清單

.gitignore所定義的檔名或路徑將不會被加入索引

https://github.com/github/gitignore

Page 68: Git Tutorial

68

Git 分支—什麼時候用?

New features

Bug f ixes

重構

任何實驗

Page 69: Git Tutorial

69

查看分支

預設是 master

git branch

master HEAD

Page 70: Git Tutorial

70

建立分支

git branch develop

git branch

develop

master HEAD

Page 71: Git Tutorial

71

在分支上建立不同版本

echo master >master.txt

git add master.txt

git commit -m 'Add master to master.txt'

develop

master HEAD

Page 72: Git Tutorial

72

在分支上建立不同版本

git checkout develop(切換到 develop 分支)

develop

master

HEAD

Page 73: Git Tutorial

73

在分支上建立不同版本

echo develop >develop.txt

git commit -m 'Add develop to develop.txt'

develop

master

HEAD

Page 74: Git Tutorial

74

將 develop 合併到 master

git checkout master

git merge develop

develop

master HEAD

Page 75: Git Tutorial

75

合併衝突 (merge CONFLICT)

兩個分支都在修改同一個檔案,內容不同時

衝突檔案內容會出現 <<<<< =====

>>>>>>

手動解決或 git reset --hard 放棄合併

Page 76: Git Tutorial

76

Git遠端操作

事實上就是本地分支和遠端分支之間的合併

產生 ssh key: ssh-keygen -t rsa -b 4096 -C

'yourname@hostname'

將 ~/.ssh/id_rsa.pub 上傳到遠端伺服器

(GitHub、Gitolite)

Page 77: Git Tutorial

77

上傳儲存庫到遠端伺服器

在 GitHub新增一個專案 git-demo

git remote add origin [email protected]:your_account/git-

demo.git

git push -u origin master(加 -u預設追蹤 origin 的

master 分支)

之後只需要打 git push進行分支合併

如果出現 ![rejected] 表示衝突,需先 git pull 合併

Page 78: Git Tutorial

78

下載已經存在的儲存庫

SSH 協定

– 可以設定讀寫權限

– git clone [email protected]:your_account/git-demo.git

HTTPS 協定

– 只有讀取權限

– git clone https://github.com/your_account/git-demo.git

Page 79: Git Tutorial

79

參考資料

Git Internals PDFhttps://github.com/pluralsight/git-internals-pdf

ihower Git教學http://ihower.tw/git/

30 天精通Git 版本控管https://github.com/doggy8088/Learn-Git-in-30-days

那些台灣軟體產業所缺少的–版本控制系統http://blog.ez2learn.com/2011/10/20/taiwan-software-lacking-of-vcs/

Pro Git http://git-scm.com/book/zh-tw/