這篇博文是自己在學(xué)習(xí)git過程中的思考總結(jié)。本文僅僅代表個人的看法少办,如有不妥地方還請本文文末留言扼鞋。 ??
原文鏈接git的學(xué)習(xí)匯總--原創(chuàng)
GIT是什么
GIT
是一個免費并且開源的分布式版本控制系統(tǒng),能夠高速有效的處理或小或大的項目阴颖。(以上的話是自己翻譯github官網(wǎng))
至今活喊,自己用過了window系統(tǒng)的TortoiseSVN
, mac系統(tǒng)的CornerStone
,最近的大半年也在用GIT
(主要管理自己的github項目)。比較下來量愧,還是GIT優(yōu)勢比較明顯钾菊。
GIT跨平臺
GIT
可以在不同的操作系統(tǒng)中使用。也許你注意到了偎肃,我在window上和mac系統(tǒng)上工作的時候是使用兩個不同的svn煞烫。如果我在linux上工作會不會又是一個呢。
GIT是分布式版本控制系統(tǒng),而svn是集中式版本控制系統(tǒng)
集中式版本控制系統(tǒng)
是集中放在中央服務(wù)器上面的累颂,而團(tuán)隊的人需要從中央服務(wù)器上面拉取最新的代碼滞详,然后進(jìn)行開發(fā),最后推送到中央服務(wù)器上面,就像串聯(lián)的電路料饥。而分布式版本控制系統(tǒng)
沒有中央服務(wù)器蒲犬,團(tuán)隊的每個人的電腦就是一個完整的版本庫,就好像并聯(lián)的電路(自我理解)稀火。
集中式版本控制系統(tǒng)
必須聯(lián)網(wǎng)才能工作暖哨,如果是在局域網(wǎng)內(nèi)還好,帶寬足夠大凰狞,速度足夠快篇裁,但是遇到網(wǎng)速慢的話,那心里就一萬個羊駝??在蹦騰了赡若。
集中式版本控制系統(tǒng)
安全性比較低达布,如果中央系統(tǒng)崩潰了,那就有點悲催了逾冬。當(dāng)然你不嫌麻煩黍聂,可以定期備份的啦。而分布式中央系統(tǒng)
就比較安全身腻,團(tuán)隊的每個成員的電腦就是一個完整的版本庫产还。如果其中一個壞掉了,你可以從團(tuán)隊另外一個的人員電腦那里拷貝一份就行了嘀趟。對了脐区,GIT
也會有一臺中央的機(jī)子,主要是為了方便團(tuán)隊的交流她按,它是可以不存在的牛隅。
GIT安裝
GIT
支持不同的系統(tǒng),看者可以在鏈接https://git-scm.com/downloads中酌泰,找到和自己電腦系統(tǒng)匹配的GIT
版本媒佣,下載安裝包后根據(jù)提示進(jìn)行安裝。當(dāng)然陵刹,GIT
還提供圖形界面管理工具默伍,看者也可以在鏈接中下載GUI Clients
,如下圖所示--
根據(jù)提示安裝完成后衰琐,要驗證是否安裝成功巡验。看者可打開命令行工具碘耳,輸入
git --version
命令,如果安裝成功,控制臺輸出安裝的版本號(當(dāng)然框弛,安裝前就應(yīng)該輸入git --version查看是否安裝了git)辛辨,我這里安裝的GIT
版本是2.10.0
。
GIT配置
GIT
在使用前,需要進(jìn)行相關(guān)的配置斗搞。每臺計算機(jī)上面只需要配置一次指攒,程序升級的時候會保留配置信息。當(dāng)然僻焚,看者可以在任何時候再次通過運行命令行來修改它們允悦。
用戶信息
設(shè)置GIT
的用戶名稱和郵件地址,這個很重要虑啤,因為每個GIT
的提交都會使用這些信息隙弛,并且它會寫入到每一次的提交中。你可以在自己的倉庫中使用git log
狞山,控制臺上面顯示的每次的提交都有Author
字段全闷,它的值就是用戶名稱 <郵件地址>
。方便查看某次的提交的負(fù)責(zé)人是誰萍启。
$ git config --global user.name "你的用戶名"
$ git config --global user.email 你的郵箱地址
?? GIT
一般和github
配合使用总珠,看者應(yīng)該設(shè)置用戶名稱為你的github
用戶名。當(dāng)然勘纯,還有和gitlab
等配合使用...
?? 如果配置中使用了--global
選項局服,那么該命令只需要運行一次,因為之后無論你在該系統(tǒng)上做任何事情驳遵,GIT
都會使用這些信息淫奔。但是,當(dāng)你想針對特定項目使用不同的用戶名稱與郵件地址的時候超埋,可以在那個倉庫目錄下運行不使用global
選項的命令來配置搏讶。
檢查配置信息
通過git config --list
命令可以列出所有GIT
能找到的配置。如下:(我的git版本為2.10.0)
...
user.name=reng99
user.email=1837895991@qq.com
color.ui=true
core.repositoryformatversion=0
core.filemode=true
core.bare=false
...
當(dāng)然霍殴,你可以通過git config <key>
來檢查GIT
的某一項配置媒惕。比如$ git config user.name
。
幫助中心
在使用GIT
的時候来庭,遇到問題尋求幫助的時候妒蔚,可以運行git help
或git --help
或git
命令來查看。在控制臺上會展示相關(guān)的幫助啦月弛。
usage:
...
start a working area (see also: git help tutorial)
...
work on the current change (see also: git help everyday)
...
examine the history and state (see alse: git help revisions)
...
grow,mark and tweak your common history
...
collaborate (see also: git help workflows)
...
更加詳細(xì)的內(nèi)容肴盏,請點擊傳送門
創(chuàng)建版本庫
版本庫又名倉庫(repository),可以理解成一個目錄帽衙,這個目錄里面所有文件都可以被GIT
管理起來菜皂,每個文件的修改、刪除厉萝,GIT
都能跟蹤恍飘,以便任何時刻都能可以追蹤歷史榨崩,或者在將來某個時刻可以還原。
創(chuàng)建一個版本庫章母,首先得選擇一個存放目錄的地方母蛛,我這里選擇了桌面,并且創(chuàng)建一個空的目錄乳怎。
$ cd desktop
$ mkdir -p learngit
$ cd learngit
$ pwd
/Users/reng/desktop/learngit
mkdir -p dirnanme
是創(chuàng)建一個子目錄彩郊,這里的-p
確保目錄的名稱存在,如果目錄不存在的就新建一個蚪缀,如果你確定目錄不存在秫逝,直接使用mkdir dirname
就可以了。pwd(Print Working Directory)
是顯示當(dāng)前目錄的整個路徑名椿胯。
然后筷登,通過命令行git init
,將創(chuàng)建的目錄變成GIT
可以管理的倉庫:
$ git init
Initialized empty Git repository in /Users/reng/Desktop/learngit/.git/
初始化好倉庫后就可以愉快的玩耍了哩盲,但是前方,得先來了解下GIT
整個工作流程先。
GIT工作流程
為了更好的學(xué)習(xí)廉油,自己用Axure RP 8
粗略的畫了下流程圖惠险,如下--
本地倉庫(repo)包含工作區(qū)和版本庫,那么什么是工作區(qū)和版本庫呢?基本的流程又是什么呢抒线?
工作區(qū)和版本庫
我們新建一個倉庫班巩,就像我們新建的learngit
倉庫,現(xiàn)在在里面添加一個文件README.md
嘶炭,用sublime打開learngit
目錄抱慌。此時會出現(xiàn)如下圖的情況(當(dāng)然你設(shè)置了其他東西例外)--
如上圖,出現(xiàn)的內(nèi)容就是工作區(qū)( 電腦上能看到的此目錄下的內(nèi)容)眨猎,這里工作區(qū)只有
README.md
一個文件抑进。工作區(qū)有一個隱藏的目錄.git
,這個不算工作區(qū)睡陪,而是GIT
的版本庫寺渗。版本庫又包括暫存區(qū)和GIT倉庫。暫存區(qū)是一個文件兰迫,保存了下次將提交的文件列表信息信殊,而GIT倉庫目錄是GIT
用來保存項目的元數(shù)據(jù)和對象數(shù)據(jù)庫的地方。這是GIT
中最重要的部分汁果,從其他計算機(jī)克隆倉庫的時候涡拘,拷貝的就是這里的數(shù)據(jù)。當(dāng)執(zhí)行git add .
或者git add path/to/filename
的時候据德,文件從工作區(qū)轉(zhuǎn)到暫存區(qū)鳄乏;執(zhí)行git commit -m"here is the message described the file you add"
的時候,文件從緩存區(qū)添加到GIT倉庫府蔗。
基本的工作流
基本的GIT
工作流可以簡單總結(jié)如下--
- 在工作區(qū)目錄中修改文件
- 暫存區(qū)中暫存文件,將文件的快照放入暫存區(qū)域
- 提交更新汞窗,找到暫存區(qū)域的文件,將快照永久性存儲到GIT倉庫目錄
時光機(jī)穿梭
到目前為止赡译,在自己創(chuàng)建的本地倉庫--learngit
中已經(jīng)初具形態(tài)了仲吏。進(jìn)入learngit
,執(zhí)行ls
蝌焚,可看到目前倉庫中已有的文件README.md裹唆。
$ cd desktop/learngit
$ ls
README.md
$ cat README.md
## content
上面展示了本地learngit
內(nèi)的相關(guān)的內(nèi)容。運行下git status
查看現(xiàn)在的狀態(tài)只洒。
$ git status
On branch master
nothing to commit, working tree clean
這時候會提示沒有內(nèi)容可以提交许帐,工作區(qū)是干凈的。因為我之前已經(jīng)提交(git commit)過了毕谴。上面還提示了目前是位于主分支上面成畦,GIT
在初始化(git init)的時候會自動創(chuàng)建一個HEAD
指針指向默認(rèn)master
分支,也只有一個分支涝开,看者可以通過git branch
查看循帐。
現(xiàn)在,在README.md
上添加一些內(nèi)容舀武。
## content
### first change
此刻再通過git status
查看當(dāng)前狀態(tài)拄养。
$ 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.md
no changes added to commit (use "git add" and/or "git commit -a")
這時候顯示出一堆的東西,告訴我們現(xiàn)在是位于主分支上面银舱,然后告訴我們修改的文件啊瘪匿,可以使用的命令進(jìn)行下一步的操縱氯夷。那么我們來進(jìn)行下一步的操作了苟耻,git add . 或者 git add README.md
將修改的文件添加到暫存區(qū)域。
$ git add .
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
對了渺贤,有時候需要在添加的之前(執(zhí)行g(shù)it add . 或者 git add path/to/filename)的時候操软,需要看下修改了哪些內(nèi)容可以執(zhí)行下git diff
嘁锯。那么,現(xiàn)在先回退到修改的前一個版本聂薪。
$ git reset HEAD README.md
Unstaged changes after reset:
M README.md
$ git checkout -- README.md
$ ls
README.md
$ cat README.md
## content
回退正確家乘,現(xiàn)在像上次那樣添加內(nèi)容### first change
,然后執(zhí)行命令git diff
來查看更改的內(nèi)容藏澳。
$ git diff
diff --git a/README.md b/README.md
index 75759ec..0bc52b9 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,3 @@
-## content
\ No newline at end of file
+## content
+
+### first change
\ No newline at end of file
現(xiàn)在就顯示了修改前的內(nèi)容---
前為修改前的內(nèi)容仁锯,和修改后的內(nèi)容--+
前修改后的內(nèi)容。查看完之后翔悠,覺得沒有問題了业崖,就可以進(jìn)行添加(git add)野芒,提交(git commit)。當(dāng)然双炕,一般不常用git diff的狞悲,因為自己修改的東西自己心里總有點數(shù)吧,可能合作中團(tuán)隊的其他人需要查看文件前后的不同點就需要用到git diff
啦妇斤。
版本回退
為了方便講解下版本回退摇锋,我先將上面添加的### first change
提交以下--git add . && git commit -m "add first change"
。下面通過git log
就可以查看自己提交的記錄了站超。
$ git log
commit 5c2639ee54bd7c8ef2cbf186f5dc4798e72a4a67
Author: reng99 <1837895991@qq.com>
Date: Sun Dec 17 17:11:53 2017 +0800
init README.md
$ git add . && git commit -m "add first change"
[master 0ac49ba] add first change
1 file changed, 3 insertions(+), 1 deletion(-)
$ git log
commit 0ac49bae6ab55df9c05d0770de347665a2568f31
Author: reng99 <1837895991@qq.com>
Date: Mon Dec 18 15:26:06 2017 +0800
add first change
commit 5c2639ee54bd7c8ef2cbf186f5dc4798e72a4a67
Author: reng99 <1837895991@qq.com>
Date: Sun Dec 17 17:11:53 2017 +0800
init README.md
在上面中荸恕,自己先執(zhí)行了git log
來顯示提交的日志,顯示只有一條死相,然后執(zhí)行了add和commit的命令融求,打印的內(nèi)容是現(xiàn)實主分支、commit的id算撮、commit的信息生宛、多少個文件的更改、多少個插入以及多少個刪除钮惠。之后再次執(zhí)行git log
打印日志茅糜,顯示了兩次提交。?? 注意:當(dāng)提交(commit)的次數(shù)較多之后素挽,控制臺會顯示不下(最多現(xiàn)實4條)那么多的條數(shù)蔑赘,可以通過按鍵盤的向上或向下
鍵查看日志的內(nèi)容,需要退出查看日志命令的話预明,在英文輸入法的狀態(tài)按下q
缩赛,意思就是quit(退出)。
版本的回退就是改變HEAD
指針的指向撰糠。通過git reset --hard HEAD^
返回上一個版本酥馍,通過git reset --hard HEAD^^
返回上上個版本...由此推論,往上100個版本的話就是100個^
阅酪,當(dāng)然旨袒,這樣你數(shù)到明天也未必數(shù)得正確,所以寫成git reset --hard HEAD~100
术辐。另外一種是砚尽,你知道提交的id,例如commit 5c2639ee54bd7c8ef2cbf186f5dc4798e72a4a67
的前7位就是commit的id(5c2639e)辉词,執(zhí)行git reset --hard 5c2639e
就回到此版本啦必孤。
$ reng$ git reset --hard HEAD^
HEAD is now at 5c2639e init README.md
$ git log
commit 5c2639ee54bd7c8ef2cbf186f5dc4798e72a4a67
Author: reng99 <1837895991@qq.com>
Date: Sun Dec 17 17:11:53 2017 +0800
init README.md
$ ls
README.md
$ cat README.md
## content
現(xiàn)在你已經(jīng)回到了最初的版本,這里演示的是通過HEAD
瑞躺,你也可以通過commit id
來實現(xiàn)的敷搪。執(zhí)行上面的代碼后兴想,README.md
文件里面只有一### content
文字內(nèi)容,但是過了段時間后,你想恢復(fù)到原先的版本赡勘,通過git log
命令行嫂便,控制臺顯示的以前的信息,通過它找不到回退前的commit id
闸与,怎么辦顽悼?GIT
提供一個git reflog
顯示提交的歷史記錄,在那里可以查看提交的id几迄、HEAD
的指針歷史和操作的信息記錄。下面演示回退到最新的版本(也就是commit -m "add first change")--
$ git log
commit 5c2639ee54bd7c8ef2cbf186f5dc4798e72a4a67
Author: reng99 <1837895991@qq.com>
Date: Sun Dec 17 17:11:53 2017 +0800
init README.md
$ git reflog
5c2639e HEAD@{0}: reset: moving to HEAD^
0ac49ba HEAD@{1}: commit: add first change
5c2639e HEAD@{2}: commit (initial): init README.md
$ git reset --hard 0ac49ba
HEAD is now at 0ac49ba add first change
$ ls
README.md
$ cat README.md
## content
### first
現(xiàn)在又回到了最新的版本冰评,又能夠愉快的玩耍了映胁。??
管理修改
GIT
比其他版本控制系統(tǒng)設(shè)計優(yōu)秀,其中一點是--GIT
跟蹤并管理的是修改甲雅,而非文件解孙。
下面在README.md
內(nèi)添加信息### second change
。之后看下變化后的文件的狀態(tài)和差異等抛人。
$ ls
README.md
$ cat README.md
## content
### first change
#### second change
$ 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.md
no changes added to commit (use "git add" and/or "git commit -a")
$ git add README.md
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
此時弛姜,對README.md
進(jìn)行第三次的修改,添加內(nèi)容### third change
妖枚。
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
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.md
$ cat README.md
## content
### first change
#### second change
### third change
$ git commit -m "test file modify"
[master 18f86ba] test file modify
1 file changed, 3 insertions(+), 1 deletion(-)
$ 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.md
no changes added to commit (use "git add" and/or "git commit -a")
上面的演示流程是這樣的第一次修改(#### second change) -> git add -> 第二次修改(### third change) -> git commit
廷臼。但是最后查看狀態(tài)的時候(git status),第二次的修改并沒有被提交上去绝页。因為GIT
管理的是修改荠商,當(dāng)使用git add
命令的時候,在工作區(qū)的第一次修改被放入暫存區(qū)续誉,準(zhǔn)備提交莱没,但是在工作區(qū)的第二次修改并沒有放入到暫存區(qū),而git commit
是將暫存區(qū)的修改提交到GIT倉庫
酷鸦,所以第二次修改的內(nèi)容是不會被提交的饰躲。這也是說明為什么可以多次添加(git add),一次提交(git commit)的原因了臼隔。
撤銷修改
文件的撤銷修改分成三種情況嘹裂,一種是修改在工作區(qū)的內(nèi)容,一種是修改在暫存區(qū)的內(nèi)容躬翁,另一種是修改在GIT
倉庫的內(nèi)容焦蘑。也許會有看者說,不能修改在遠(yuǎn)程庫中的內(nèi)容嗎盒发?有啊例嘱,就是git add
->git commit
->git push
將遠(yuǎn)程倉庫的內(nèi)容覆蓋被狡逢,不過團(tuán)隊人在克隆遠(yuǎn)程庫下來的時候,還是可以查看到你提交的錯誤內(nèi)容的拼卵。我們現(xiàn)在只針對本地倉庫的三種情況談下自己的看法--
情況一:撤銷工作區(qū)的內(nèi)容
在管理修改中奢浑,自己的工作區(qū)還是沒有提交,此時想放棄當(dāng)前工作區(qū)的編輯內(nèi)容執(zhí)行git checkout -- file
腋腮。接著上面的內(nèi)容雀彼,我這里的工作區(qū)內(nèi)有的內(nèi)容是### third change
,現(xiàn)在我要放棄第三次修改即寡,只要執(zhí)行git checkout -- README.md
就可以了徊哑。
$ 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.md
no changes added to commit (use "git add" and/or "git commit -a")
$ ls
README.md
$ cat README.md
## content
### first change
#### second change
### third change
$ git checkout -- README.md
$ cat README.md
## content
### first change
#### second change
$ git status
On branch master
nothing to commit, working tree clean
情況二:撤銷暫存區(qū)的內(nèi)容
當(dāng)你不但改亂了工作區(qū)的某個文件的內(nèi)容,還添加(git add)到了暫存區(qū)時聪富,想丟棄修改莺丑,那么得分兩步來撤銷文件。先是通過git reset HEAD file
墩蔓,將暫存區(qū)的文件退回到工作區(qū)梢莽,然后通過git checkout -- file
放棄修改改文件的內(nèi)容。為了方便演示奸披,我這里的暫存區(qū)沒什么內(nèi)容昏名,所以添加內(nèi)容### tentative content
并將它添加到緩存區(qū)。之后阵面,演示將緩存區(qū)的內(nèi)容撤回--
$ cat README.md
## content
### first change
#### second change
### tentative content
$ git add .
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
$ git reset HEAD README.md
Unstaged changes after reset:
M README.md
$ git checkout -- README.md
$ cat README.md
## content
### first change
#### second change
$ git status
On branch master
nothing to commit, working tree clean
情況三:撤銷GIT倉庫的內(nèi)容
如果你不僅添加(git add)了內(nèi)容到暫存區(qū)并且提交(git commit)了內(nèi)容到GIT倉庫
中了轻局。你需要撤銷上一次的內(nèi)容,也就是要回退到上一個版本样刷,執(zhí)行git reset --hard HEAD^
就可以啦嗽交,詳細(xì)的內(nèi)容查看版本回退
。如下--
$ git status
On branch master
nothing to commit, working tree clean
$ cat README.md
## content
### first change
#### second change
$ git reset --hard HEAD^
HEAD is now at 0ac49ba add first change
$ cat READMEmd
## content
### first change
遠(yuǎn)程倉庫
遠(yuǎn)程倉庫的使用能夠提高你和團(tuán)隊的工作效率颂斜,無論何時何地夫壁,團(tuán)隊的人員都可以在聯(lián)網(wǎng)的情況下將代碼進(jìn)行拉取,修改和更新沃疮。因為我是使用github
來管理項目的盒让,所以我的遠(yuǎn)程倉庫是放在github里面。這里默認(rèn)看者已經(jīng)安裝了github
司蔬,當(dāng)然也可以用碼云邑茄、gitlab等。
本地庫添加到遠(yuǎn)程庫
這點很容易俊啼,登錄自己注冊的github肺缕,如果打不開,請開下VPN。進(jìn)入自己的首頁(https://github.com/username)同木,點擊+
號創(chuàng)建(new repository)一個名為learngit
的倉庫(注意哦?? 名稱是本地倉庫已經(jīng)初始化過的浮梢,我這里本地有個同名初始化的learngit倉庫),其他的字段自選來填寫彤路。點擊Create repository
創(chuàng)建此遠(yuǎn)程倉庫秕硝。緊接著就是進(jìn)行本地倉庫和遠(yuǎn)程倉庫的關(guān)聯(lián)啦,github
很友好的提示了你怎么進(jìn)行一個遠(yuǎn)程倉庫的關(guān)聯(lián)洲尊。
現(xiàn)在按照上圖來關(guān)聯(lián)下遠(yuǎn)程倉庫远豺。
$ git remote add origin https://github.com/reng99/learngit.git
$ git push -u origin master
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 456 bytes | 0 bytes/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To https://github.com/reng99/learngit.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
注意?? 第一次向遠(yuǎn)程倉庫(關(guān)聯(lián))push的時候是$ git push -u origin master
,不能忽略-u
坞嘀,以后的push不用帶-u
躯护。至此,打開你的github的相關(guān)的倉庫就可以看到添加了README.md
文件丽涩,我這里地址是https://github.com/reng99/learngit
榛做,因為我是使用markdown語法寫的,控制臺顯示的內(nèi)容和倉庫的顯示內(nèi)容有所區(qū)別啦内狸。<del>(?? 后期我將learngit倉庫刪除啦,所以你訪問鏈接是找不到這個倉庫的厘擂,畢竟不想放一個沒什么內(nèi)容的倉庫在我的github上)</del>昆淡。
遠(yuǎn)程庫克隆到本地
從遠(yuǎn)程倉庫克隆東西到本地同樣很簡單,只需要進(jìn)入你想克隆的倉庫刽严,將倉庫的url
復(fù)制下來(當(dāng)然你也可以復(fù)制window.location.href的內(nèi)容)昂灵,運行git clone address
。現(xiàn)在我將本地桌面的learngit
的倉庫刪除舞萄,然后從遠(yuǎn)程將learngit
克隆到本地眨补。
$ cd desktop
$ rm -rf learngit
$ find learngit
find: learngit: No such file or directory
$ git clone https://github.com/reng99/learngit
Cloning into 'learngit'...
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 6 (delta 0), reused 6 (delta 0), pack-reused 0
Unpacking objects: 100% (6/6), done.
成功將gitlearn
從遠(yuǎn)程克隆下來,接下來又可以愉快的玩耍啦倒脓。
分支管理
分支管理允許創(chuàng)建另一條線/方向上開發(fā)撑螺,能夠讓你在不影響他人工作的情況下,正常的工作崎弃。當(dāng)在自己創(chuàng)建的分支中完成自己的功過后甘晤,合并到主分支就行了(git init初始化的時候已經(jīng)默認(rèn)創(chuàng)建了master主分支)。一般團(tuán)隊的合作是不在主分支上進(jìn)行的饲做,個人項目除外(個人理解)线婚。
創(chuàng)建分支
當(dāng)前learngit
倉庫上只有一個分支,那就是master
分支盆均,看者可以通過git branch
命令來查看當(dāng)前的分支塞弊,git branch branchName
命令來創(chuàng)建一個新的分支,我這里創(chuàng)建的是dev
分支。
$ cd desktop/learngit
$ git branch
* master
$ git branch dev
$ git branch
dev
* master
現(xiàn)在已經(jīng)創(chuàng)建了dev
分支游沿,有兩個分支了饰抒,分支前面帶有一個星號的分支說明是當(dāng)前的正在工作的分區(qū)。執(zhí)行上面的分支后奏候,可以簡單的畫下現(xiàn)在的情況了循集,有個HEAD
指針指向主分支的最新點,剛才新創(chuàng)建的dev
分支我這里默認(rèn)是一個dev
的指針指向了dev
分支的最新點蔗草。
.
. HEAD指針
. │
├────────*master
└────────dev
│
dev指針
切換分支
我們一般是很少在主分支進(jìn)行工作的咒彤,所以在創(chuàng)建出新的分支之后,我們就切換到新的分支進(jìn)行相關(guān)的工作咒精∠庵可以通過git checkout branchName
切換到已經(jīng)存在的分支工作,通過分支前面的*
可查看目前位于哪個分支內(nèi)∧P穑現(xiàn)在我切換到創(chuàng)建的dev
分支歇拆。
$ git branch
dev
* master
$ git checkout dev
Switched to branch 'dev'
$ git branch
* dev
master
合并分支
在創(chuàng)建好分支后,我們在新的分支上工作完成后范咨,就需要往主分支上進(jìn)行合并啦故觅。我修改了分支dev
上的README.md
的內(nèi)容,就是添加文字### new branch content
渠啊。合并分支可以分成兩個合并的方式输吏,一種是本地合并到materz主分支之后,推送(push)到遠(yuǎn)程庫替蛉,一種是直接將分支推送到遠(yuǎn)程庫贯溅,在遠(yuǎn)程庫進(jìn)行合并。
本地合并推送
在合并分支前躲查,需要切換到要合并到哪個分支(一般是master主分支)它浅,通過git merge branchName
將需要的合并的分支合并到當(dāng)前分支,我是將dev
分支合并到master
分支镣煮。
$ git branch
* dev
master
$ git checkout master
M README.md
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git merge dev
$ Already up-to-date.
$ git add .
$ git commit -m "merge dev branch"
[master d705e73] merge dev branch
1 file changed, 3 insertions(+), 1 deletion(-)
$ git push origin master
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 282 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/reng99/learngit
0ac49ba..d705e73 master -> master
合并之后,此時姐霍,HEAD
指針就指向了dev
指針,也就是兩者同時指向了master
主分支的最新處典唇。具體的內(nèi)容參考傳送門
.
.
.
├────────*master
└────────dev
│
dev指針 ── HEAD指針
遠(yuǎn)程庫推送合并
遠(yuǎn)程庫內(nèi)合并的話邮弹,要先將dev
的分支推送到遠(yuǎn)程庫,然后在遠(yuǎn)程庫進(jìn)行合并蚓聘。我這里在dev
分支上添加了### add new branch content into again
然后demo演示推送(git push origin dev)以及合并腌乡。
$ git branch
dev
* master
$ git checkout dev
Switched to branch 'dev'
$ git add .
$ git commit -m "add dev branch commit again"
[dev dc817c4] add dev branch commit again
1 file changed, 3 insertions(+), 1 deletion(-)
$ git push origin dev
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 300 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/reng99/learngit
* [new branch] dev -> dev
接下來就是進(jìn)入我的遠(yuǎn)程learngit倉庫進(jìn)行合并,你會看到下面圖示的提示夜牡。點擊Compare && pull request
与纽,然后寫點相關(guān)的comment
(選填)侣签,點擊Create pull request
。之后在綠色勾的提示下Merge pull request
急迂,緊接著點擊Confirm merge
按鈕確定合并此分支影所,這時候返回主分支就可以看到dev
內(nèi)合并的內(nèi)容了(后期我改動了dev的內(nèi)容)×潘椋看者如果看得不明白猴娩,自己上手嘗試一下唄!
完成后勺阐,你會看到learngit
倉庫的Pull requests
量為1卷中,branches
量為2。你可以點擊進(jìn)入分支渊抽,在ALL branches
里面查看分支的具體內(nèi)容蟆豫。
刪除分支
在創(chuàng)建了分支,然后將分支的內(nèi)容合并到主分支后懒闷,分支的使命就完成了十减,你就可以將分支刪除了,這里的刪除個人認(rèn)為可以是兩種愤估,一種是本地倉庫的分支刪除帮辟,一種是遠(yuǎn)程倉庫的分支的刪除。當(dāng)然啦玩焰,留著分支也沒啥由驹,可以留著唄<del>,自己認(rèn)為有點礙眼</del>震捣。
本地分支的刪除
在本地的learngit
的目錄下,執(zhí)行命令行git branch -D branchName
就可以刪除了闹炉。我這里刪除的是dev
分支蒿赢。注意?? ,刪除的分支不應(yīng)該是當(dāng)前工作的分支渣触,需要切換到其他分支羡棵,我這里切換的是master
分支,畢竟我只有兩個分支呢嗅钻。
$ git branch
* dev
master
$ git branch -D dev
error: Cannot delete branch 'dev' checked out at '/Users/reng/desktop/learngit'
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git branch
dev
* master
$ git branch -D dev
Deleted branch dev (was dc817c4).
$ git branch
* master
遠(yuǎn)程庫分支的刪除
刪除遠(yuǎn)程庫的分支皂冰,只要執(zhí)行git push origin :branchName
命令就行了。現(xiàn)在我要刪除我遠(yuǎn)程庫中的dev
分支养篓,執(zhí)行git push origin :dev
秃流。
$ git push origin :dev
To https://github.com/reng99/learngit
- [deleted] dev
此時,打開我的遠(yuǎn)程庫learngit柳弄,發(fā)現(xiàn)之前的Pull requests
量為0舶胀,branch
量為1。
重命名分支
通過git branch -m oldBranchName newBranchName
來重命名分支。我這里沒有分支了嚣伐,現(xiàn)在創(chuàng)建一個reng
分支糖赔,然后將它重命名為dev
分支。
$ git branch
* master
$ git branch reng
$ git branch
* master
reng
$ git branch -m reng dev
$ git branch
dev
* master
解決沖突
在我們開發(fā)的時候轩端,不知道分支和分支之間的進(jìn)度情況是什么放典,難免會產(chǎn)生沖突。當(dāng)產(chǎn)生沖突的時候基茵,就得將沖突的內(nèi)容更正奋构,然后提交。為了方便演示耿导,我將本地的learngit
刪除声怔,重新拉取遠(yuǎn)程的gitlearn
倉庫(因為我不知道我之前在本地倉庫做的修改是啥,對了舱呻,我將遠(yuǎn)程的分支刪除了醋火,只剩下master主分支)∠渎溃克隆下來后芥驳,如果還存在本地分支,也將它刪除茬高,之后我將在master
和dev
分支中重新填充里面的README.md
的內(nèi)容兆旬。
$ cd desktop
$ git clone https://github.com/reng99/learngit.git
Cloning into 'learngit'...
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 43 (delta 4), reused 38 (delta 1), pack-reused 0
Unpacking objects: 100% (43/43), done.
$ cd learngit
$ git branch
* master
$ ls
README.md
$ cat README.md
## master branch content
$ git add .
$ git commit -m "add master branch content"
[master 1cfa0aa] add master branch content
1 file changed, 1 insertion(+), 1 deletion(-)
$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 271 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/reng99/learngit.git
d2f936f..1cfa0aa master -> master
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
$ cat README.md
## master branch content
### dev branch content
$ git add .
$ git commit -m "add dev branch content"
[dev 80faf6d] add dev branch content
1 file changed, 2 insertions(+)
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ cat README.md
## master content
### new master branch content
$ git add .
$ git commit -m "change master content"
[master ec18715] change master content
1 file changed, 3 insertions(+), 1 deletion(-)
$ git merge dev
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
README.md
文件中沖突內(nèi)容--
<<<<<<< HEAD (當(dāng)前更改)
## master content
### new master branch content
=======
## master branch content
### dev branch content
>>>>>>> dev (傳入更改)
手動修改了README.md
文件中沖突的內(nèi)容--
## master branch content
### new master branch content
### dev branch content
然后命令行執(zhí)行--
$ git add .
$ git commit -m "fix confict content"
[master dd848b4] fix confict content
$ git log --graph
* commit 980788b7690d8bcf14610072fc072460bee7e9f1
|\ Merge: c49d09e 2929dca
| | Author: reng99 <1837895991@qq.com>
| | Date: Thu Dec 21 11:14:10 2017 +0800
| |
| | fix confict content
| |
| * commit 2929dca91ef8f493adba7744cdad19656538334f
| | Author: reng99 <1837895991@qq.com>
| | Date: Thu Dec 21 11:11:49 2017 +0800
| |
| | add dev branch content
| |
* | commit c49d09e33e7098d67b59c845d18e9c6f8a8f4fea
|/ Author: reng99 <1837895991@qq.com>
| Date: Thu Dec 21 11:12:50 2017 +0800
|
| change master content
|
* commit b07f0be8280e4e437cccf2a3f8fac6beef03ff41
| Author: reng99 <1837895991@qq.com>
| Date: Thu Dec 21 11:10:51 2017 +0800
|
:
上面操作過程是,我先從遠(yuǎn)程庫中克隆learngit
倉庫到本地怎栽,目前的本地learngit
的分支只有master
分支丽猬,然后我在master
分支的README.md
中添加相關(guān)的文字(見代碼),接著把它推送到遠(yuǎn)程庫熏瞄。然后創(chuàng)建并切換dev
分支脚祟,在README.md
文件中添加新內(nèi)容(見代碼),接著將它提交到GIT倉庫
强饮。又切換到master
分支由桌,修改README.md
到內(nèi)容(見代碼),提交到GIT倉庫后
開始執(zhí)行merge
命令合并dev
分支的內(nèi)容邮丰。此時行您,產(chǎn)生了沖突,這就需要手動將沖突的內(nèi)容解決剪廉,重新commit
到GIT倉庫
娃循,最后你就可以提交到遠(yuǎn)程庫了(這步我沒有演示,也就是git push origin master一行命令行的事情)斗蒋。最后我還使用git log ----graph
打印出整個分支合并圖(從下往上看)淮野,方便查看捧书。?? 此時退出git log --graph
是書寫英文狀態(tài)按鍵盤的q
鍵。
說這么多骤星,目的只有一個 --> 產(chǎn)生沖突后经瓷,需要手動調(diào)整??
分支管理策略
先放上一張分支管理策略圖,然后再慢慢講解相關(guān)的內(nèi)容...
在分支管理中洞难,我們不斷的新建分支舆吮,開發(fā),合并分支队贱,刪除分支的操作色冀。這里需要注意合并分子的操作,之前我們進(jìn)行分支的時候是直接將dev
開發(fā)的分支使用git merge dev
進(jìn)行合并柱嫌,這樣有個缺點:我們看不出分支信息锋恬。因為在默認(rèn)情況下,合并分支的時候编丘,GIT
是使用了Fast Foward
的模式与学,在這種模式下,刪除分支后嘉抓,會丟掉分支的信息索守。下面我重新克隆下我遠(yuǎn)程learngit
倉庫,然后創(chuàng)建并更改dev
分支的信息抑片,使用默認(rèn)的模式進(jìn)行合并卵佛。
$ git branch
* master
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
$ cat README.md
## master branch content
### new master branch content
### dev branch content
### new dev branch content
$ git add .
$ git commit -m "add new dev contentt"
[dev 750e1f1] add new dev content
1 file changed, 1 insertion(+)
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git merge dev
Updating 980788b..750e1f1
Fast-forward
README.md | 1 +
1 file changed, 1 insertion(+)
$ git log --graph
* commit 750e1f17854872eed4d6cff8315e404079ecb18f
| Author: reng99 <1837895991@qq.com>
| Date: Fri Dec 22 10:05:36 2017 +0800
|
| add new dev content
|
* commit 980788b7690d8bcf14610072fc072460bee7e9f1
...
上面的合并就是將master分支上面的HEAD
指向dev
指針,如下:
# 記錄是從上往下
- before merge
master
* (begin)
|
|
*
\
\
*
|
|
* (end)
dev
- after merge
master
* (begin)
|
|
*
|
|
*
|
|
* (end)
為了保留分支的情況敞斋,保證版本演進(jìn)的清晰截汪,我們就得使用普通模式合并,也就是在Fast Foward
的模式基礎(chǔ)上加上--no-ff
參數(shù)植捎,即git merge --no-ff branchName
衙解,不過我們一般加上你合并的相關(guān)信息,即git merge --no-ff -m "your msg here" banchName
∨父現(xiàn)在更改dev
分支的內(nèi)容丢郊,再進(jìn)行合并盔沫。
$ git checkout dev
Switched to branch 'dev'
$ cat README.md
## master branch content
### new master branch content
### dev branch content
### new dev branch content
### merge with no-ff
$ git add .
$ git commit -m "add no-ff mode content"
[dev 80b628c] add no-ff mode content
1 file changed, 2 insertions(+), 1 deletion(-)
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
$ git merge dev --no-ff -m "merge with no-ff" dev
Merge made by the 'recursive' strategy.
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
$ git log --graph
* commit 98746d93a9b64ea02b8ff1c7f0fa5e915405c0e6
|\ Merge: 750e1f1 80b628c
| | Author: reng99 <1837895991@qq.com>
| | Date: Fri Dec 22 14:39:32 2017 +0800
| |
| | merge with no-ff
| |
| * commit 80b628c334618711b77da81fa805ffc246a2cf7d
|/ Author: reng99 <1837895991@qq.com>
| Date: Fri Dec 22 14:38:17 2017 +0800
|
| add no-ff mode content
|
* commit 750e1f17854872eed4d6cff8315e404079ecb18f
...
使用--no-ff
參數(shù)的普通模式合并医咨,會執(zhí)行正常合并,在master
主分支上面會生成一個新的節(jié)點架诞,如下(我上面的分支管理策略圖里面的合并就是使用了普通的模式):
# 記錄是從上往下
- --no-ff合并
master
* (before)
|
|
*
|\
| \
| *dev
| |
| |
| *
| /
|/
* (after)
我們在開發(fā)中拟淮,分支管理可以分成master主分支、dev開發(fā)分支谴忧、feature功能分支很泊、release預(yù)發(fā)布分支角虫、hotfixes修補(bǔ)bug分支。其中功能分支委造、預(yù)發(fā)布分支和修補(bǔ)bug分支可以歸為臨時分支
戳鹅。臨時分支
在進(jìn)行分支的合并之后就可以被刪除了。下面就一一講解自己眼中的各種分支昏兆。
主分支master
主分支是在你初始化倉庫的時候(git init)枫虏,自動生成的一個master分支,刪除不了的哦(演示待會給)爬虱。主分支是有且僅有一個隶债,也是發(fā)布上線的分支,團(tuán)隊合作的最終代碼都會在master主分支上面體現(xiàn)出來跑筝。也許你也注意到了分支管理策略圖里面的主分支會被打上TAG
的標(biāo)簽死讹,這是為了方便到某個時間段對版本的查找,標(biāo)簽tag的學(xué)習(xí)總結(jié)后面給出曲梗。
# 記錄是從上往下
master
|
|
*(tag 1.0)
|
|
*(tag 1.1)
|
|
*(tag 1.2)
下面代碼演示下不能放刪除master的情況:
$ cd learngit
$ git branch
dev
* master
$ git branch -D master
error: Cannot delete branch 'master' checked out at '/Users/reng/desktop/learngit'
開發(fā)分支develop
在開發(fā)的過程中赞警,項目合作者應(yīng)該保持自己本地有一個開發(fā)環(huán)境的分支,在進(jìn)行分支開發(fā)之前稀并,需要進(jìn)行git pull
拉取master
主分支的最新內(nèi)容仅颇,或者通過其他的方法。在獲取到最新的內(nèi)容之后才可以進(jìn)行本地的新功能的開發(fā)碘举。在開發(fā)完成后將內(nèi)容merge
到主分支之后忘瓦,不用將dev
分支刪除,因為你開發(fā)的就是在這里進(jìn)行引颈,何必刪除后再新建一個開發(fā)環(huán)境的分支呢耕皮。
接著上面的情況,我目前已經(jīng)擁有了dev
開發(fā)分支:
$ cd learngit
$ git branch
dev
* master
功能(特性)分支feature
一個軟件就是一個個功能疊加起來的蝙场,在軟件的開發(fā)中凌停,我們總不能在主分支開發(fā),將主分支搞亂吧售滤。當(dāng)然罚拟,你可以在dev分支中開發(fā),一般新建功能分支來開發(fā)完箩,然后功能開發(fā)完再合并到dev分支赐俗,之后刪除功能分支。需要的時候就可以將dev
開發(fā)分支合并到master
主分支弊知,這樣就隨時保證dev
分支功能的完整性阻逮。
下面演示功能分支user
開發(fā)(隨便寫點內(nèi)容)的合并(這里也演示了合并到master主分支,跳過了release分支的測試)秩彤,刪除叔扼。
$ git checkout dev
Switched to branch 'dev'
$ git branch user
$ git branch
* dev
master
user
$ git checkout user
Switched to branch 'user'
$ cat README.md
## master branch content
### new master branch content
### dev branch content
### new dev branch content
### merge with no-ff
### function user
$ git add .
$ git commit -m "function user was acheive"
[user 26beda3] function user was acheive
1 file changed, 2 insertions(+), 1 deletion(-)
$ git checkout dev
Switched to branch 'dev'
$ git merge --no-ff -m "merge user feature" user
Merge made by the 'recursive' strategy.
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)
$ git merge --no-ff -m "merge dev branch" dev
Merge made by the 'recursive' strategy.
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
$ git log --graph
* commit f15a1e9012635fc21e944ab76c4cd4bbd539f82f
|\ Merge: 98746d9 0ca83c6
| | Author: reng99 <1837895991@qq.com>
| | Date: Fri Dec 22 16:35:43 2017 +0800
| |
| | merge dev branch
| |
| * commit 0ca83c654df64724743a966f5f0989477e504cbc
| |\ Merge: 80b628c 26beda3
| | | Author: reng99 <1837895991@qq.com>
| | | Date: Fri Dec 22 16:33:27 2017 +0800
| | |
| | | merge user feature
| | |
| | * commit 26beda3b8246e047f10ac0461ca11d1a6f132819
| |/ Author: reng99 <1837895991@qq.com>
| | Date: Fri Dec 22 16:31:41 2017 +0800
| |
| | function user was acheive
| |
* | commit 98746d93a9b64ea02b8ff1c7f0fa5e915405c0e6
|\ \ Merge: 750e1f1 80b628c
| |/ Author: reng99 <1837895991@qq.com>
:
$ git branch -D user
Deleted branch user (was 26beda3).
$ git branch
dev
* master
預(yù)發(fā)布分支release
在進(jìn)行一系列的功能的開發(fā)和合并后事哭,在滿足迭代目標(biāo)的時候,就可以打包送測了瓜富。這里就需要一個預(yù)發(fā)布分支release鳍咱。預(yù)發(fā)布分支是指在發(fā)布正式版本之前( 即合并到master分支之前,可查看上面分支管理策略圖)与柑,需要一個有預(yù)發(fā)布的版本(可以理解為灰度環(huán)境)進(jìn)行測試流炕。
預(yù)發(fā)布環(huán)境是從dev
分支上面分出來的,預(yù)發(fā)布結(jié)束之后仅胞,必須合并到dev
和master
分支上面每辟。這里我就不演示了,跟功能分支差不多干旧,就是合并的時候要合并到dev
和master
上渠欺,這時候dev
分支和master
的同步的代碼,就不需要將dev
分支合并到master
了椎眯。最后將預(yù)發(fā)布分支刪除掉挠将。
修復(fù)bug分支 bug/hotfixes
在寫代碼的過程中希柿,由于種種原因 -> 比如功能考慮不周全妇垢,版本上線時間有限蔚润,產(chǎn)品突然改需求等硬爆,我們寫的代碼就出現(xiàn)一些或大或小的bug或者需要緊急修復(fù)。那么我們就可以使用bug分支(其實就是新建一個分支處理bug而已啦欣簇,命名隨意起的)宣赔,然后在這個分支上處理編碼出現(xiàn)的問題讨永。我在分支管理策略圖
上面已經(jīng)展示了一種出現(xiàn)bug的情況 -> 就是在測試發(fā)布版本看似沒問題的情況下汞斧,將release
版本整合到master
和dev
中夜郁,這時候火眼精金發(fā)現(xiàn)了遺留的一個bug,然后新建一個bug分支
處理粘勒,再合并到master
和dev
中竞端,之后將bug分支
移除啦。
在開發(fā)的過程中庙睡,無論咋樣都是這樣 : 新建bug分支 -> 把分支合并 -> 刪除分支事富,這里的demo就不演示了,可以參考上面的功能(特性)分支feature
乘陪。
這里需要注意??的一點统台,當(dāng)在開發(fā)的過程中,開發(fā)到一定的程度暂刘,需要停下來需改緊急的bug饺谬,那么需要停下手頭的工作需改bug啦捂刺。這時候需要將工作現(xiàn)場儲藏(stash功能)起來谣拣,等以后回復(fù)現(xiàn)場了后接著工作∧颊現(xiàn)在我在原先的gitlearn
倉庫中README.md
文件文末添加### modify content
內(nèi)容來進(jìn)行演示。
$ cd desktop
$ cd learngit
$ cat README.md
## master branch content
### new master branch content
### dev branch content
### new dev branch content
### merge with no-ff
$ git status
On branch dev
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.md
no changes added to commit (use "git add" and/or "git commit -a")
$ git stash
Saved working directory and index state WIP on dev: 80b628c add no-ff mode content
HEAD is now at 80b628c add no-ff mode content
$ git status
On branch dev
nothing to commit, working tree clean
然后過段時間(這里省略修改的演示)森缠,代碼已經(jīng)修改好合并后拔鹰,需要回到最新的內(nèi)容區(qū)域進(jìn)行工作,這就需要還原最新的內(nèi)容了贵涵,demo如下:
$ cd learngit
$ git stash list
stash@{0}: WIP on dev: 80b628c add no-ff mode content
$ git stash pop
On branch dev
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.md
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (9e85bcc8435ae38c17db59ddc3cd8401af404827)
$ git stash list
?? git stash
不僅可以隱藏工作區(qū)的內(nèi)容列肢,也可以隱藏暫存區(qū)的內(nèi)容。git stash list
是查看隱藏的列表宾茂。git stash pop
是將隱藏的內(nèi)容恢復(fù)并刪除瓷马,git stash pop
相當(dāng)于git stash apply && git stash drop
,這里的git stash apply
是恢復(fù)隱藏內(nèi)容跨晴,git stash drop
是刪除隱藏內(nèi)容欧聘。
多人協(xié)作
簡單談下自己git協(xié)作的過程吧。在負(fù)責(zé)人將搭建好的倉庫上傳到遠(yuǎn)程的倉庫后(一般是包含了master默認(rèn)的分支和dev分支)端盆,自己將遠(yuǎn)程倉庫克隆到本地怀骤,然后在本地的倉庫上新建一個dev分支
,將遠(yuǎn)程的dev分支重新拉取下git pull origin dev
焕妙,開發(fā)完成后就可以提交自己的代碼到遠(yuǎn)程的dev分支了
蒋伦,如果提交之前或者之后需要修改bug或者添加新的需求的話,需要新建一個相關(guān)的分支并完成開發(fā)焚鹊,將他們合并到本地dev
分支后上傳到遠(yuǎn)程dev
分支痕届。如果新建的遠(yuǎn)程倉庫中只有master分支
,我是這樣處理的:依然要在本地新建一個dev
分支末患,然后在完成特定版本的開發(fā)后爷抓,將分支合并到本地master分支
然后再推送到遠(yuǎn)程master
分支,本地的dev分支
保留哦阻塑。我自己比較偏向于第一種情況蓝撇。
標(biāo)簽管理
發(fā)布一個版本前,為了唯一確定時刻的版本陈莽,我們通常在版本庫中打一個標(biāo)簽(tag)渤昌,方便在發(fā)布版本以后,可以在某個時刻將某個歷史的版本提取出來(因為標(biāo)簽tag也是版本庫的一個快照)走搁。
創(chuàng)建標(biāo)簽
創(chuàng)建標(biāo)簽是默認(rèn)在你切換的分支最新提交處創(chuàng)建的独柑。我這里在本地桌面的learngit倉庫
的master分支
上打一個v1.0標(biāo)簽
。
$ cd desktop/learngit
$ git branch
* dev
master
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git tag
$ git tag v1.0
$ git tag
v1.0
當(dāng)然私植,你可以在非新commit的地方進(jìn)行標(biāo)簽忌栅。這就需要你查找到需要打標(biāo)簽處的commit的id,然后執(zhí)行git tag tagName commitId
曲稼。這里我隨意找master分支中的commit id進(jìn)行標(biāo)簽v0.9
的標(biāo)簽創(chuàng)建索绪。
$ git log --pretty=oneline --abbrev-commit
f15a1e9 merge dev branch
0ca83c6 merge user feature
26beda3 function user was acheive
98746d9 merge with no-ff
...
現(xiàn)在在commit id為 98746d9
處打標(biāo)簽湖员。
$ git tag v0.9 98746d9
$ git tag
v0.9
v1.0
操作標(biāo)簽
在上面創(chuàng)建標(biāo)簽,我們已經(jīng)有了標(biāo)簽v0.9 v1.0
瑞驱。有時候我們標(biāo)簽打錯了娘摔,需要進(jìn)行刪除,那么就得更改啦唤反,運用git tag -d tagName
$ git tag -d v0.9
Deleted tag 'v0.9' (was 98746d9)
$ git tag
v1.0
$ git tag v0.8 80b628c -m "version 0.8"
$ git tag
v0.8
v1.0
$ git show v0.8
$ git show v0.8
tag v0.8
Tagger: reng99 <1837895991@qq.com>
tag v0.8
Tagger: reng99 <1837895991@qq.com>
Date: Wed Dec 27 16:07:46 2017 +0800
version 0.8
在上面的演示中凳寺,我刪除了v0.9,然后在創(chuàng)建v0.8的時候追加了打標(biāo)簽的信息彤侍,之后使用git show tagName
查看簽名信息肠缨。
我們還可以進(jìn)行分支切換標(biāo)簽,類似于分支的切換盏阶,我這里打的兩個標(biāo)簽的內(nèi)容是不同的怜瞒,我可以通過觀察內(nèi)容的改表來得知時候成功切換標(biāo)簽了。
$ git tag
v0.8
v1.0
$ git checkout v1.0
HEAD is now at f15a1e9... merge dev branch
$ cat README.md
## master branch content
### new master branch content
### dev branch content
### new dev branch content
### merge with no-ff
### function user
$ git checkout v0.8
Previous HEAD position was f15a1e9... merge dev branch
HEAD is now at 80b628c... add no-ff mode content
$ cat README.md
## master branch content
### new master branch content
### dev branch content
### new dev branch content
### merge with no-ff
在確認(rèn)好標(biāo)簽后般哼,就可以像遠(yuǎn)程推送標(biāo)簽了吴汪,我這里推送v1.0
。
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/reng99/learngit.git
* [new tag] v1.0 -> v1.0
上面是使用git push origin tagName
推送特定的tag
到遠(yuǎn)程庫蒸眠,但是我們能不能推送全部的tag呢漾橙?答案是肯定的,看者可以通過git push origin --tags
進(jìn)行推送楞卡。有時候霜运,我們推送了tag標(biāo)簽到遠(yuǎn)程庫中了
,現(xiàn)在想刪除掉怎么辦蒋腮?這個就略微麻煩點淘捡,我們不能像上面提到的刪除本地庫的標(biāo)簽?zāi)菢樱ㄟ^git tag -d tagName
那樣池摧,而是通過git push origin :refs/tags/tagName
焦除,這里不演示,如果看者感興趣可以自己來把弄一下哦作彤。
參考內(nèi)容
Git分支管理策略 - 阮一峰的網(wǎng)絡(luò)日志