git的學(xué)習(xí)匯總--原創(chuàng)

tools/git/git-banner

這篇博文是自己在學(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,如下圖所示--

tools/git/git_install

根據(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 helpgit --helpgit命令來查看。在控制臺上會展示相關(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粗略的畫了下流程圖惠险,如下--

tools/git/git_brief_process

本地倉庫(repo)包含工作區(qū)和版本庫,那么什么是工作區(qū)和版本庫呢?基本的流程又是什么呢抒线?

工作區(qū)和版本庫

我們新建一個倉庫班巩,就像我們新建的learngit倉庫,現(xiàn)在在里面添加一個文件README.md嘶炭,用sublime打開learngit目錄抱慌。此時會出現(xiàn)如下圖的情況(當(dāng)然你設(shè)置了其他東西例外)--

tools/git/working_version_area

如上圖,出現(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é)如下--

  1. 在工作區(qū)目錄中修改文件
  2. 暫存區(qū)中暫存文件,將文件的快照放入暫存區(qū)域
  3. 提交更新汞窗,找到暫存區(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)洲尊。

tools/git/related_github_step1

tools/git/related_github_step2

tools/git/related_github_step3

現(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克隆到本地眨补。

tools/git/git_clone_repository
$ 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)容)×潘椋看者如果看得不明白猴娩,自己上手嘗試一下唄!

tools/git/merge_branch

完成后勺阐,你會看到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主分支)∠渎溃克隆下來后芥驳,如果還存在本地分支,也將它刪除茬高,之后我將在masterdev分支中重新填充里面的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)容解決剪廉,重新commitGIT倉庫娃循,最后你就可以提交到遠(yuǎn)程庫了(這步我沒有演示,也就是git push origin master一行命令行的事情)斗蒋。最后我還使用git log ----graph打印出整個分支合并圖(從下往上看)淮野,方便查看捧书。?? 此時退出git log --graph是書寫英文狀態(tài)按鍵盤的q鍵。

說這么多骤星,目的只有一個 --> 產(chǎn)生沖突后经瓷,需要手動調(diào)整??

分支管理策略

先放上一張分支管理策略圖,然后再慢慢講解相關(guān)的內(nèi)容...

tools/git/manager_branch_tactics

在分支管理中洞难,我們不斷的新建分支舆吮,開發(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é)束之后仅胞,必須合并到devmaster分支上面每辟。這里我就不演示了,跟功能分支差不多干旧,就是合并的時候要合并到devmaster上渠欺,這時候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版本整合到masterdev中夜郁,這時候火眼精金發(fā)現(xiàn)了遺留的一個bug,然后新建一個bug分支處理粘勒,再合并到masterdev中竞端,之后將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)容

廖雪峰官方網(wǎng)站--Git教程

易百教程--Git教程

git官網(wǎng)

分支管理模型圖

Git分支管理策略 - 阮一峰的網(wǎng)絡(luò)日志

原文鏈接

git的學(xué)習(xí)匯總--原創(chuàng)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膘魄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子竭讳,更是在濱河造成了極大的恐慌创葡,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绢慢,死亡現(xiàn)場離奇詭異灿渴,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門骚露,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹬挤,“玉大人,你說我怎么就攤上這事荸百。” “怎么了滨攻?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵够话,是天一觀的道長。 經(jīng)常有香客問我光绕,道長女嘲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任诞帐,我火速辦了婚禮欣尼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘停蕉。我一直安慰自己愕鼓,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布慧起。 她就那樣靜靜地躺著菇晃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚓挤。 梳的紋絲不亂的頭發(fā)上磺送,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機(jī)與錄音灿意,去河邊找鬼估灿。 笑死,一個胖子當(dāng)著我的面吹牛缤剧,可吹牛的內(nèi)容都是我干的馅袁。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼荒辕,長吁一口氣:“原來是場噩夢啊……” “哼司顿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起兄纺,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤大溜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后估脆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钦奋,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了付材。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片朦拖。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖厌衔,靈堂內(nèi)的尸體忽然破棺而出璧帝,到底是詐尸還是另有隱情,我是刑警寧澤富寿,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布睬隶,位于F島的核電站,受9級特大地震影響页徐,放射性物質(zhì)發(fā)生泄漏苏潜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一变勇、第九天 我趴在偏房一處隱蔽的房頂上張望恤左。 院中可真熱鬧,春花似錦搀绣、人聲如沸飞袋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锣险,卻和暖如春蹄皱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芯肤。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工巷折, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人崖咨。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓锻拘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親击蹲。 傳聞我的和親對象是個殘疾皇子署拟,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1. 安裝 Github 查看是否安裝git: $ git config --global user.name "...
    Albert_Sun閱讀 13,631評論 9 163
  • 1.git的安裝 1.1 在Windows上安裝Git msysgit是Windows版的Git,從https:/...
    落魂灬閱讀 12,649評論 4 54
  • Git是目前最流行的版本管理系統(tǒng)歌豺,也是最先進(jìn)的分布式版本控制系統(tǒng)(distributed version cont...
    pro648閱讀 5,676評論 1 17
  • 選擇遺忘推穷,我只是為了更好的活下去。 那種疼类咧,你不懂馒铃,你也不在乎蟹腾。 就像我們是兩個世界的人,僅僅只是過客区宇。 你的不在...
    千層云林閱讀 532評論 4 17
  • 前言 永澄老師在StepAs模型學(xué)習(xí)課上布置了第一個作業(yè) 選定一個任務(wù)娃殖,然后產(chǎn)生成果,并書寫下成果產(chǎn)生方式议谷。 擔(dān)心...
    想飛的小粉豬閱讀 245評論 0 0