安裝git
如果你正在使用Mac做開發(fā)厉碟,有兩種安裝git
的方法娘侍。
- 一是安裝homebrew侦讨,然后通過homebrew安裝Git窘面,具體方法請參考homebrew的文檔:http://brew.sh/。
- 第二種方法更簡單件相,登錄https://developer.apple.com/download/more/ 然后下載
dmg
安裝再扭,或者Terminal
運行xcode-select --install
然后點擊安裝。
安裝完成后夜矗,還需要最后一步設(shè)置泛范,在命令行輸入:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
創(chuàng)建git倉庫
git
倉庫,你可以簡單理解成一個目錄侯养,這個目錄里面的所有文件都可以被git
倉庫管理起來敦跌,每個文件的修改、刪除逛揩,git
都能跟蹤,以便任何時刻都可以追蹤歷史麸俘,或者在將來某個時刻可以“還原”辩稽。
首先創(chuàng)建一個空目錄:
? desktop git:(master) ? mkdir learngit
? desktop git:(master) ? cd learngit
? learngit git:(master) ? pwd
/Users/michael/desktop/learngit
? learngit git:(master) ?
注意:pwd
命令用于顯示當前目錄的相對路徑。
通過git init
命令初始化一個git
倉庫:
? learngit git:(master) ? git init
Initialized empty Git repository in /Users/michael/Desktop/learngit/.git/
? learngit git:(master)
通過ls -ah
命令可以看到當前目錄下多了一個.git
的目錄从媚,這個目錄就是git
來跟蹤管理git
庫的逞泄。
? learngit git:(master) ls -ah
. .. .git
? learngit git:(master)
創(chuàng)建測試文本文件
? learngit git:(master) touch readme.txt
? learngit git:(master) ? ls
readme.txt
? learngit git:(master) ?
通過vim
命令添加測試內(nèi)容。
? learngit git:(master) ? vim readme.txt
2 files to edit
? learngit git:(master) ?
一定要放到
learngit
目錄下(子目錄也行)拜效,因為這是一個git
倉庫喷众,放到其他地方git
再厲害也找不到這個文件。
把文件添加到git
倉庫
? learngit git:(master) ? git add readme.txt
? learngit git:(master) ?
把文件提交到git
倉庫
? learngit git:(master) ? git commit -m "wrote a readme file"
[master (root-commit) e030980] wrote a readme file
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 readme.txt
? learngit git:(master) ?
git status
修改剛才提交的readme.txt
文件紧憾,git status
:查看git
倉庫當前的狀態(tài)
? learngit git:(master) ? git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
? learngit git:(master) ?
git diff
git diff
可以查看文件的修改內(nèi)容
diff --git a/readme.txt b/readme.txt
index e69de29..4d53f0e 100644
--- a/readme.txt
+++ b/readme.txt
@@ -0,0 +1,2 @@
+git is a distributed version control system.
+git is free software.
版本回退
git log
查看git
倉庫里面提交的歷史記錄到千。
commit 3eb6880960b72a578eb2ee6308d6b3e26bb92e0e
Author: 孫金帥 <s_mike@163.com>
Date: Wed Jun 7 10:17:24 2017 +0800
add distributed
commit e03098052675e44512f8f2869e2d56636eb2e16b
Author: 孫金帥 <s_mike@163.com>
Date: Wed Jun 7 10:01:33 2017 +0800
wrote a readme file
注意:git log
命令顯示從最近到最遠的提交日志。
如果嫌輸出信息太多赴穗,看得眼花繚亂的憔四,可以試試加上--pretty=oneline
參數(shù):
3eb6880960b72a578eb2ee6308d6b3e26bb92e0e add distributed
e03098052675e44512f8f2869e2d56636eb2e16b wrote a readme file
注意:
看到的一大串類似3628164...882e1e0的是commit id
(版本號)膀息,和svn
不一樣,git
的commit id
不是1了赵,2潜支,3……遞增的數(shù)字,而是一個SHA1
計算出來的一個非常大的數(shù)字柿汛,用十六進制表示冗酿,而且你看到的commit id
和我的肯定不一樣,以你自己的為準络断。為什么commit id
需要用這么一大串數(shù)字表示呢已烤?因為git
是分布式的版本控制系統(tǒng),后面我們還要研究多人在同一個版本庫里工作妓羊,如果大家都用1胯究,2,3……作為版本號躁绸,那肯定就沖突了裕循。
版本回退,首先净刮,git
必須知道當前版本是哪個版本剥哑,在git
中,用HEAD
表示當前版本淹父,也就是最新的提交3628164...882e1e0(注意我的提交ID和你的肯定不一樣)株婴,上一個版本就是HEAD~1
,上上一個版本就是HEAD~2
暑认,往上100個版本寫成HEAD~100
困介。
把當前版本add distributed
回退到上一個版本wrote a readme file
,就可以使用git reset
命令:
? learngit git:(master) git reset --hard head~1
HEAD is now at e030980 wrote a readme file
? learngit git:(master)
用git log
再看看現(xiàn)在版本庫的狀態(tài):
commit e03098052675e44512f8f2869e2d56636eb2e16b
Author: 孫金帥 <s_mike@163.com>
Date: Wed Jun 7 10:01:33 2017 +0800
wrote a readme file
最新的那個版本add distributed
已經(jīng)看不到了蘸际。好比你從21世紀坐時光穿梭機來到了19世紀座哩,想再回去已經(jīng)回不去了,腫么辦粮彤?
辦法其實還是有的根穷,只要上面的命令行窗口還沒有被關(guān)掉,你就可以順著往上找啊找啊导坟,找到那個add distributed
的commit id是3eb6880960b72a578eb2ee6308d6b3e26bb92e0e屿良,于是就可以指定回到未來的某個版本:
? learngit git:(master) git reset --hard 3eb6880960b72a578eb2ee6308d6b3e26bb92e0e
HEAD is now at 3eb6880 add distributed
? learngit git:(master)
版本號沒必要寫全,前幾位就可以了惫周,git
會自動去找尘惧。當然也不能只寫前一兩位,因為git
可能會找到多個版本號闯两,就無法確定是哪一個了褥伴。
查看readme.txt
的內(nèi)容:
? learngit git:(master) cat readme.txt
git is a distributed version control system.
git is free software.
? learngit git:(master)
git
的版本回退速度非沉陆快,因為git
在內(nèi)部有個指向當前版本的HEAD
指針重慢,當你回退版本的時候饥臂,git
僅僅是把HEAD
從指向add distributed
:
改為指向wrote a readme file
:
然后順便把工作區(qū)的文件更新了。所以你讓HEAD
指向哪個版本號似踱,你就把當前版本定位在哪隅熙。
git reflog
假如,你想回退到新版本核芽,但是又找不到新版本的commit id
囚戚,在git
中,可以使用git reflog
找到新版本的commit id
轧简。然后在使用git reset 3eb6880960b72a578eb2ee6308d6b3e26bb92e0e
驰坊,就可以回退到新版本了。
git reflog
查看命令歷史哮独,用來記錄你的每一次命令:
3eb6880 HEAD@{0}: reset: moving to 3eb6880960b72a578eb2ee6308d6b3e26bb92e0e
e030980 HEAD@{1}: reset: moving to head~1
3eb6880 HEAD@{2}: reset: moving to head
3eb6880 HEAD@{3}: commit: add distributed
e030980 HEAD@{4}: commit (initial): wrote a readme file
工作區(qū)和暫存區(qū)
工作區(qū)可以理解為拳芙,新建或者workingcopy下來的文件夾,可以在文件夾里面皮璧,新增刪除文件等等舟扎。
暫存區(qū)可以理解為,當使用git init
命令初始化git
倉庫里面有一個隱藏的.git
文件悴务,里面就存放暫存區(qū)空間和分支master
空間睹限,以及指向的一個指針叫HEAD
。
使用git add
把文件添加git
倉庫讯檐,實際上就是把文件修改添加到暫存區(qū)羡疗;
使用git commit
提交文件,實際上就是把暫存區(qū)的所有內(nèi)容提交到當前分支裂垦。
例如:
修改readme.txt
顺囊,然后在工作區(qū)新增一個LICENSE
文本文件。
然后蕉拢,git status
查看狀態(tài);
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
LICENSE
no changes added to commit (use "git add" and/or "git commit -a")
git
非常清楚地告訴我們诚亚,readme.txt
被修改了晕换,而LICENSE
還從來沒有被添加過,所以它的狀態(tài)是Untracked
站宗。
現(xiàn)在闸准,使用命令git add .
,把readme.txt
和LICENSE
都添加后,用git status
再查看一下:
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: LICENSE
modified: readme.txt
? learngit git:(master) ?
現(xiàn)在勺远,暫存區(qū)的狀態(tài)就變成這樣了:
所以故响,git add
命令實際上就是把要提交的所有修改放到暫存區(qū)(Stage)纷责。然后捐下,執(zhí)行git commit
就可以一次性把暫存區(qū)的所有修改提交到分支产阱。
? learngit git:(master) ? git commit -m "understand how stage works"
[master 97bf1a5] understand how stage works
2 files changed, 3 insertions(+), 2 deletions(-)
create mode 100644 LICENSE
? learngit git:(master)
一旦提交后惕虑,如果你又沒有對工作區(qū)做任何修改庇忌,那么工作區(qū)就是“干凈”的:
? learngit git:(master) git status
On branch master
nothing to commit, working tree clean
? learngit git:(master)
現(xiàn)在版本庫變成了這樣义屏,暫存區(qū)就沒有任何內(nèi)容了:
撤銷修改
場景1:當你改亂了工作區(qū)某個文件的內(nèi)容靠汁。
例如,在readme.txt
改亂了一行代碼闽铐,但是沒有通過git add
命令把錯誤文件添加到git
倉庫里面的暫存區(qū)蝶怔。
? learngit git:(master) ? cat readme.txt
git is a distributed version control system.
git is free software.
Git has a mutable index called stage.
Git tracks changes of files.
My stupid boss still prefers SVN. // 錯誤代碼
? learngit git:(master) ?
既然錯誤發(fā)現(xiàn)得很及時,就可以很容易地糾正它兄墅。你可以刪掉最后一行踢星,手動把文件恢復到上一個版本的狀態(tài)。如果用git status查看一下:
? learngit git:(master) ? git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
? learngit git:(master) ?
git
會告訴你隙咸,git checkout -- file
可以丟棄工作區(qū)的修改:
git checkout -- readme.txt
命令git checkout -- readme.txt
意思就是沐悦,把readme.txt
文件在工作區(qū)的修改全部撤銷,這里有兩種情況:
一種是readme.txt
自修改后還沒有被放到暫存區(qū)扎瓶,現(xiàn)在所踊,撤銷修改就回到和版本庫一模一樣的狀態(tài);
一種是readme.txt
已經(jīng)添加到暫存區(qū)后概荷,又作了修改秕岛,現(xiàn)在,撤銷修改就回到添加到暫存區(qū)后的狀態(tài)误证。
總之继薛,就是讓這個文件回到最近一次git commit
或git add
時的狀態(tài)。
查看readme.txt
的文件內(nèi)容:
? learngit git:(master) cat readme.txt
git is a distributed version control system.
git is free software.
? learngit git:(master)
場景2:當你不但改亂了工作區(qū)某個文件的內(nèi)容愈捅,還添加到了暫存區(qū)時.
例如遏考,在readme.txt
改亂了一行代碼,并且使用通過git add
命令把錯誤文件添加到git
倉庫里面的暫存區(qū)蓝谨。但是在commit
之前灌具,你發(fā)現(xiàn)了這個問題。用git status
查看一下譬巫,修改只是添加到了暫存區(qū)咖楣,還沒有提交:
? learngit git:(master) ? git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: readme.txt
? learngit git:(master) ?
git
同樣告訴我們,用命令git reset HEAD file
可以把暫存區(qū)的修改撤銷掉(unstage)芦昔,重新放回工作區(qū):
? learngit git:(master) ? git reset HEAD readme.txt
Unstaged changes after reset:
M readme.txt
? learngit git:(master) ?
git reset
命令既可以回退版本诱贿,也可以把暫存區(qū)的修改回退到工作區(qū)。當我們用HEAD
時,表示最新的版本珠十。
再用git status
查看一下料扰,現(xiàn)在暫存區(qū)是干凈的,工作區(qū)有修改:
? learngit git:(master) ? git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
? learngit git:(master) ?
然后使用git checkout -- file
可以丟棄工作區(qū)的修改:
? learngit git:(master) ? git checkout -- readme.txt
? learngit git:(master) git status
On branch master
nothing to commit, working tree clean
? learngit git:(master)
刪除文件
在git
中焙蹭,刪除也是一個修改操作晒杈,我們實戰(zhàn)一下,先添加一個新文件test.txt
到git
并且提交:
? learngit git:(master) touch test.txt
? learngit git:(master) ? git add test.txt
? learngit git:(master) ? git commit -m "add test.txt"
[master 2c26a6d] add test.txt
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test.txt
? learngit git:(master)
一般情況下壳嚎,你通常直接在文件管理器中把沒用的文件刪了桐智,或者用rm命令刪了:
? learngit git:(master) rm test.txt
? learngit git:(master) ? git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
? learngit git:(master) ?
現(xiàn)在你有兩個選擇,一是確實要從版本庫中刪除該文件烟馅,那就用命令git rm
刪掉说庭,并且git commit
:
? learngit git:(master) ? git rm test.txt
rm 'test.txt'
? learngit git:(master) ? git commit -m "remove test.txt"
[master 584464a] remove test.txt
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 test.txt
? learngit git:(master)
現(xiàn)在,文件就從版本庫中被刪除了郑趁。
另一種情況是刪錯了刊驴,因為版本庫里還有呢,所以可以很輕松地把誤刪的文件恢復到最新版本:
git checkout -- test.txt
git checkout
其實是用版本庫里的版本替換工作區(qū)的版本寡润,無論工作區(qū)是修改還是刪除捆憎,都可以“一鍵還原”。
命令
git rm
用于刪除一個文件梭纹。如果一個文件已經(jīng)被提交到版本庫躲惰,那么你永遠不用擔心誤刪,但是要小心变抽,你只能恢復文件到最新版本础拨,你會丟失最近一次提交后你修改的內(nèi)容。
創(chuàng)建與合并分支
在初始化git
倉庫的時候绍载,會有一個master
分支诡宗,HEAD
是指向master
分支的指針。
開始的時候击儡,master
分支是一條線塔沃,git
用master
指向最新的提交,再用HEAD
指向master
阳谍,就能確定當前分支蛀柴,以及當前分支的提交點:
每次提交,master
分支都會向前移動一步矫夯,這樣名扛,隨著你不斷提交,master
分支的線也越來越長:
當我們創(chuàng)建新的分支茧痒,例如dev
時,git
新建了一個指針叫dev
融蹂,指向master
相同的提交旺订,再把HEAD
指向dev
弄企,就表示當前分支在dev
上:
在git
倉庫中,創(chuàng)建一個分支很快区拳,因為除了增加一個dev
指針拘领,改變head
的指向,工作區(qū)的文件沒有任何的變化樱调。
首先约素,我們創(chuàng)建dev
分支,然后切換到dev
分支:
? learngit git:(master) ? git checkout -b dev
A test.txt
Switched to a new branch 'dev'
? learngit git:(dev) ?
git checkout
命令加上-b
參數(shù)表示創(chuàng)建并切換笆凌,相當于以下兩條命令:
? learngit git:(master) ? git branch dev
? learngit git:(master) ? git checkout dev
A test.txt
Switched to branch 'dev'
? learngit git:(dev) ?
然后圣猎,用git branch
命令查看當前分支:
? learngit git:(dev) ? git branch
* dev
master
? learngit git:(dev) ?
git branch
命令會列出所有分支,當前分支前面會標一個*
號乞而。
? learngit git:(dev) ? git add readme.txt
? learngit git:(dev) ? git commit -m "branch test"
[dev 08a2a35] branch test
2 files changed, 1 insertion(+)
create mode 100644 test.txt
? learngit git:(dev)
現(xiàn)在送悔,dev
分支的工作完成,我們就可以切換回master
分支:
? learngit git:(dev) git checkout master
Switched to branch 'master'
? learngit git:(master)
切換回master
分支后爪模,再查看一個readme.txt
文件欠啤,剛才添加的內(nèi)容不見了!因為那個提交是在dev
分支上屋灌,而master
分支此刻的提交點并沒有變:
現(xiàn)在洁段,我們把dev
分支的工作成果合并到master
分支上:
? learngit git:(master) git merge dev
Updating 584464a..08a2a35
Fast-forward
readme.txt | 1 +
test.txt | 0
2 files changed, 1 insertion(+)
create mode 100644 test.txt
? learngit git:(master)
git merge
命令用于合并指定分支到當前分支。合并后共郭,再查看readme.txt
的內(nèi)容祠丝,就可以看到,和dev
分支的最新提交是完全一樣的落塑。
? learngit git:(master) cat readme.txt
git is a distributed version control system.
git is free software.
Creating a new branch is quick.
? learngit git:(master)
合并完成后纽疟,就可以放心地刪除dev
分支了:
? learngit git:(master) git branch -d dev
Deleted branch dev (was 08a2a35).
? learngit git:(master)
刪除后,查看branch
憾赁,就只剩下master
分支了:
? learngit git:(master) git branch
* master
? learngit git:(master)
綜上污朽,在dev
的分支上,對工作區(qū)的修改和提交后龙考,而master
指針不變:
如果在dev
上的工作完成了蟆肆,就可以把dev
合并到master
上,就是直接把master指向dev的當前提交晦款,就完成了合并:
合并完分支后炎功,甚至可以刪除dev
分支。刪除dev
分支就是把dev
指針給刪掉缓溅,刪掉后蛇损,我們就剩下了一條master
分支:
總結(jié):
查看分支:git branch
創(chuàng)建分支:git branch <name>
切換分支:git checkout <name>
創(chuàng)建+切換分支:git checkout -b <name>
合并某分支到當前分支:git merge <name>
刪除分支:git branch -d <name>
解決沖突
場景:把feature1
分支merge
到master
分支,造成代碼沖突
準備新的feature1分支,繼續(xù)我們的新分支開發(fā):
$ git checkout -b feature1
Switched to a new branch 'feature1'
修改readme.txt最后一行淤齐,改為:
Creating a new branch is quick AND simple.
在feature1
分支上提交:
$ git add readme.txt
$ git commit -m "AND simple"
[feature1 75a857c] AND simple
1 file changed, 1 insertion(+), 1 deletion(-)
然后切換到master
分支:
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
git
還會自動提示我們當前master
分支比遠程的master
分支要超前1個提交股囊。
在master
分支上把readme.txt
文件的最后一行改為:
Creating a new branch is quick & simple.
提交:
$ git add readme.txt
$ git commit -m "& simple"
[master 400b400] & simple
1 file changed, 1 insertion(+), 1 deletion(-)
現(xiàn)在,master
分支和feature1
分支各自都分別有新的提交更啄,變成了這樣:
這種情況下稚疹,git
無法執(zhí)行“快速合并”,只能試圖把各自的修改合并起來祭务,但這種合并就可能會有沖突内狗,我們試試看:
$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
果然沖突了!git
告訴我們义锥,readme.txt
文件存在沖突柳沙,必須手動解決沖突后再提交。git status
也可以告訴我們沖突的文件:
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
# Unmerged paths:
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: readme.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
我們可以直接查看readme.txt的內(nèi)容:
? learngit git:(master) ? cat readme.txt
git is a distributed version control system.
git is free software.
Creating a new branch is quick.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
git
用<<<<<<<缨该,=======偎行,>>>>>>>
標記出不同分支的內(nèi)容,我們修改如下后保存:
Creating a new branch is quick and simple.
再提交:
$ git add readme.txt
$ git commit -m "conflict fixed"
[master 59bc1cb] conflict fixed
現(xiàn)在贰拿,master分支和feature1分支變成了下圖所示:
用帶參數(shù)的git log也可以看到分支的合并情況:
* f110aa7 conflict fixed
|\
| * 62f8819 AND simple
* | 930642f & simple
|/
* 08a2a35 branch test
* 584464a remove test.txt
* 2c26a6d add test.txt
* 9d7eb44 commit
* 3eb6880 add distributed
* e030980 wrote a readme file
分支管理策略
通常蛤袒,合并分支時,如果可能膨更,git
會用Fast forward
模式妙真,但這種模式下,刪除分支后荚守,會丟掉分支信息珍德。
如果要強制禁用Fast forward
模式,git
就會在merge
時生成一個新的commit
矗漾,這樣锈候,從分支歷史上就可以看出分支信息。
下面我們實戰(zhàn)一下--no-ff
方式的git merge
:
首先敞贡,仍然創(chuàng)建并切換dev
分支:
$ git checkout -b dev
Switched to a new branch 'dev'
修改readme.txt文件泵琳,并提交一個新的commit:
$ git add readme.txt
$ git commit -m "add merge"
[dev 6224937] add merge
1 file changed, 1 insertion(+)
現(xiàn)在,我們切換回master:
$ git checkout master
Switched to branch 'master'
準備合并dev
分支誊役,請注意--no-ff
參數(shù)获列,表示禁用Fast forward
:
$ git merge --no-ff -m "merge with no-ff" dev
Merge made by the 'recursive' strategy.
readme.txt | 1 +
1 file changed, 1 insertion(+)
因為本次合并要創(chuàng)建一個新的commit
,所以加上-m
參數(shù)蛔垢,把commit
描述寫進去击孩。
合并后,我們用git log --graph --pretty=oneline --abbrev-commit
看看分支歷史:
* 25e02ae merge with no-ff
|\
| * 661745d add merge
|/
* f110aa7 conflict fixed
|\
| * 62f8819 AND simple
* | 930642f & simple
|/
* 08a2a35 branch test
* 584464a remove test.txt
* 2c26a6d add test.txt
* 9d7eb44 commit
* 3eb6880 add distributed
* e030980 wrote a readme file
可以看到鹏漆,不使用Fast forward
模式巩梢,merge
后就像這樣:
分支策略
在實際開發(fā)中创泄,我們應(yīng)該按照幾個基本原則進行分支管理:
首先,master
分支應(yīng)該是非常穩(wěn)定的且改,也就是僅用來發(fā)布新版本验烧,平時不能在上面干活;
那在哪干活呢又跛?干活都在dev
分支上,也就是說若治,dev
分支是不穩(wěn)定的慨蓝,到某個時候,比如1.0版本發(fā)布時端幼,再把dev
分支合并到master
上礼烈,在master
分支發(fā)布1.0版本;
你和你的小伙伴們每個人都在dev
分支上干活婆跑,每個人都有自己的分支此熬,時不時地往dev
分支上合并就可以了。
所以滑进,團隊合作的分支看起來就像這樣:
標簽管理
在Git中打標簽非常簡單犀忱,首先,切換到需要打標簽的分支上:
$ git branch
* dev
master
$ git checkout master
Switched to branch 'master'
然后扶关,敲命令git tag <name>
就可以打一個新標簽:
$ git tag v1.0
可以用命令git tag
查看所有標簽:
$ git tag
v1.0
默認標簽是打在最新提交的commit
上的阴汇。有時候,如果忘了打標簽节槐,比如搀庶,現(xiàn)在已經(jīng)是周五了,但應(yīng)該在周一打的標簽沒有打铜异,怎么辦哥倔?
方法是找到歷史提交的commit id
,然后打上就可以了:
$ git log --pretty=oneline --abbrev-commit
6a5819e merged bug fix 101
cc17032 fix bug 101
7825a50 merge with no-ff
6224937 add merge
59bc1cb conflict fixed
400b400 & simple
75a857c AND simple
fec145a branch test
d17efd8 remove test.txt
...
比方說要對add merge
這次提交打標簽揍庄,它對應(yīng)的commit id
是6224937
咆蒿,敲入命令:
$ git tag v0.9 6224937
再用命令git tag
查看標簽:
$ git tag
v0.9
v1.0
注意,標簽不是按時間順序列出币绩,而是按字母排序的蜡秽。可以用git show <tagname>
查看標簽信息:
$ git show v0.9
commit 622493706ab447b6bb37e4e2a2f276a20fed2ab4
Author: Michael Liao <askxuefeng@gmail.com>
Date: Thu Aug 22 11:22:08 2013 +0800
add merge
...
可以看到缆镣,v0.9確實打在add merge
這次提交上芽突。
還可以創(chuàng)建帶有說明的標簽,用-a
指定標簽名董瞻,-m
指定說明文字:
$ git tag -a v0.1 -m "version 0.1 released" 3628164
用命令git show <tagname>
可以看到說明文字:
$ git show v0.1
tag v0.1
Tagger: Michael Liao <askxuefeng@gmail.com>
Date: Mon Aug 26 07:28:11 2013 +0800
version 0.1 released
commit 3628164fb26d48395383f8f31179f24e0882e1e0
Author: Michael Liao <askxuefeng@gmail.com>
Date: Tue Aug 20 15:11:49 2013 +0800
append GPL
如果標簽打錯了寞蚌,也可以刪除:
$ git tag -d v0.1
Deleted tag 'v0.1' (was e078af9)
因為創(chuàng)建的標簽都只存儲在本地田巴,不會自動推送到遠程。所以挟秤,打錯的標簽可以在本地安全刪除壹哺。
如果要推送某個標簽到遠程,使用命令git push origin <tagname>
:
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:michaelliao/learngit.git
* [new tag] v1.0 -> v1.0
或者艘刚,一次性推送全部尚未推送到遠程的本地標簽:
$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 554 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:michaelliao/learngit.git
* [new tag] v0.2 -> v0.2
* [new tag] v0.9 -> v0.9
如果標簽已經(jīng)推送到遠程管宵,要刪除遠程標簽就麻煩一點,先從本地刪除:
$ git tag -d v0.9
Deleted tag 'v0.9' (was 6224937)
然后攀甚,從遠程刪除箩朴。刪除命令也是push,但是格式如下:
$ git push origin :refs/tags/v0.9
To git@github.com:michaelliao/learngit.git
- [deleted] v0.9
總結(jié):
命令git push origin <tagname>可以推送一個本地標簽秋度;
命令git push origin --tags可以推送全部未推送過的本地標簽炸庞;
命令git tag -d <tagname>可以刪除一個本地標簽;
命令git push origin :refs/tags/<tagname>可以刪除一個遠程標簽荚斯。