git的使用

本文主要講解以下內(nèi)容:

一郊愧、安裝 Git 、創(chuàng)建版本庫(kù)
二井佑、時(shí)光機(jī)穿梭
三属铁、遠(yuǎn)程倉(cāng)庫(kù)
四、分支管理
五毅糟、標(biāo)簽管理
六红选、使用GitHub澜公、碼云

第一章

最早Git是在Linux上開(kāi)發(fā)的姆另,很長(zhǎng)一段時(shí)間內(nèi),Git也只能在Linux和Unix系統(tǒng)上跑坟乾。不過(guò)迹辐,慢慢地有人把它移植到了Windows上。現(xiàn)在甚侣,Git可以在Linux明吩、Unix、Mac和Windows這幾大平臺(tái)上正常運(yùn)行了殷费。

要使用Git印荔,第一步當(dāng)然是安裝Git了。本文只講在 Mac OS X 平臺(tái)上的安裝详羡,其他平臺(tái)的安裝都很簡(jiǎn)單仍律,網(wǎng)上教程也很多,再次不再詳述实柠。

如果你正在使用Mac做開(kāi)發(fā)水泉,有兩種安裝Git的方法。

1.1窒盐、安裝 Git

一是安裝homebrew草则,然后通過(guò)homebrew安裝Git,具體方法請(qǐng)參考homebrew的文檔:http://brew.sh/蟹漓。

第二種方法更簡(jiǎn)單炕横,也是推薦的方法,就是直接從AppStore安裝Xcode葡粒,Xcode集成了Git份殿,不過(guò)默認(rèn)沒(méi)有安裝姿锭,你需要運(yùn)行Xcode,選擇菜單“Xcode”->“Preferences”伯铣,在彈出窗口中找到“Downloads”往声,選擇“Command Line Tools”宅荤,點(diǎn)“Install”就可以完成安裝了。

1.2、創(chuàng)建版本庫(kù)

什么是版本庫(kù)呢喂分?版本庫(kù)又名倉(cāng)庫(kù),英文名repository男翰,你可以簡(jiǎn)單理解成一個(gè)目錄痊焊,這個(gè)目錄里面的所有文件都可以被Git管理起來(lái),每個(gè)文件的修改凭语、刪除葱她,Git都能跟蹤,以便任何時(shí)刻都可以追蹤歷史似扔,或者在將來(lái)某個(gè)時(shí)刻可以“還原”吨些。

所以,創(chuàng)建一個(gè)版本庫(kù)非常簡(jiǎn)單炒辉,首先豪墅,選擇一個(gè)合適的地方,創(chuàng)建一個(gè)空目錄:

$ mkdir learngit
$ cd learngit
$ pwd
/Users/Michael/learngit

pwd 命令用于顯示當(dāng)前目錄黔寇。在我的Mac上偶器,這個(gè)倉(cāng)庫(kù)位于/Users/Michael/learngit。

第二步缝裤,通過(guò)git init命令把這個(gè)目錄變成Git可以管理的倉(cāng)庫(kù):

$ git init
Initialized empty Git repository in /Users/michael/learngit/.git/

瞬間Git就把倉(cāng)庫(kù)建好了屏轰,而且告訴你是一個(gè)空的倉(cāng)庫(kù)(empty Git repository),細(xì)心的讀者可以發(fā)現(xiàn)當(dāng)前目錄下多了一個(gè).git的目錄憋飞,這個(gè)目錄是Git來(lái)跟蹤管理版本庫(kù)的霎苗,沒(méi)事千萬(wàn)不要手動(dòng)修改這個(gè)目錄里面的文件,不然改亂了搀崭,就把Git倉(cāng)庫(kù)給破壞了叨粘。

如果你沒(méi)有看到.git目錄,那是因?yàn)檫@個(gè)目錄默認(rèn)是隱藏的瘤睹,用ls -ah命令就可以看見(jiàn)升敲。

也不一定必須在空目錄下創(chuàng)建Git倉(cāng)庫(kù),選擇一個(gè)已經(jīng)有東西的目錄也是可以的轰传。不過(guò)驴党,不建議你使用自己正在開(kāi)發(fā)的公司項(xiàng)目來(lái)學(xué)習(xí)Git,否則造成的一切后果概不負(fù)責(zé)获茬。

1.3 把文件添加到版本庫(kù)

在當(dāng)前目錄下(或者子目錄)下創(chuàng)建一個(gè)文件港庄,然后:

  • git add xxx
  • git commit -m "xxx"

說(shuō)明
添加文件到Git倉(cāng)庫(kù)倔既,分兩步:
使用命令git add <file>,注意鹏氧,可反復(fù)多次使用渤涌,添加多個(gè)文件;
使用命令git commit -m <message>把还,完成实蓬。

第二章

Git和其他版本控制系統(tǒng)如SVN的一個(gè)不同之處就是有暫存區(qū)的概念。
先來(lái)看名詞解釋吊履。

2.1安皱、 工作區(qū)(Working Directory)

就是你在電腦里能看到的目錄,比如我的learngit文件夾就是一個(gè)工作區(qū):

Working Directory.png

2.2艇炎、版本庫(kù)(Repository)

工作區(qū)有一個(gè)隱藏目錄.git酌伊,這個(gè)不算工作區(qū),而是 Git 的版本庫(kù)缀踪。
Git的版本庫(kù)里存了很多東西居砖,其中最重要的就是稱為stage(或者叫index)的暫存區(qū),還有Git為我們自動(dòng)創(chuàng)建的第一個(gè)分支master辜贵,以及指向master的一個(gè)指針叫HEAD悯蝉。

Repository.png

分支和HEAD的概念我們以后再講归形。

前面講了我們把文件往Git版本庫(kù)里添加的時(shí)候托慨,是分兩步執(zhí)行的:

第一步是用git add把文件添加進(jìn)去,實(shí)際上就是把文件修改添加到暫存區(qū)暇榴;

第二步是用git commit提交更改厚棵,實(shí)際上就是把暫存區(qū)的所有內(nèi)容提交到當(dāng)前分支。

因?yàn)槲覀儎?chuàng)建Git版本庫(kù)時(shí)蔼紧,Git自動(dòng)為我們創(chuàng)建了唯一一個(gè)master分支婆硬,所以,現(xiàn)在奸例,git commit就是往master分支上提交更改彬犯。

你可以簡(jiǎn)單理解為,需要提交的文件修改通通放到暫存區(qū)查吊,然后谐区,一次性提交暫存區(qū)的所有修改。

當(dāng)我們使用多次 Git add 命令之后逻卖,版本庫(kù)就會(huì)變成下面的樣子:


Repository_change1.png

我們發(fā)現(xiàn)暫存區(qū)的內(nèi)容改變了K瘟小!评也!所以炼杖,git add命令實(shí)際上就是把要提交的所有修改放到暫存區(qū)(Stage)灭返。

然后接著執(zhí)行 git commit -m "XXX",執(zhí)行以后結(jié)果如下圖:


Repository_change2.png

發(fā)現(xiàn)暫存區(qū)變得很“干凈”@ば啊熙含!執(zhí)行git commit就可以一次性把暫存區(qū)的所有修改提交到分支。如果我們修改的文件很多

2.3艇纺、撤銷文件

工作中我們經(jīng)常用遇到要撤銷修改的情況婆芦,大致分為兩種撤銷:

  • 僅僅在工作區(qū)進(jìn)行了修改,并沒(méi)有添加到暫存區(qū)
  • 修改的內(nèi)容添加到了暫存區(qū)
  • 修改的內(nèi)容已經(jīng)提交到了 版本庫(kù)

第一種情況:
命令 git checkout -- xxx意思就是喂饥,把xxx文件在工作區(qū)的修改全部撤銷消约。git checkout -- file命令中的--很重要,沒(méi)有--员帮,就變成了“切換到另一個(gè)分支”的命令或粮,我們?cè)诤竺娴姆种Ч芾碇袝?huì)再次遇到git checkout命令。

第二種情況:
Git同樣告訴我們捞高,用命令 git reset HEAD <file>可以把暫存區(qū)的修改撤銷掉(unstage)氯材,重新放回工作區(qū)。git reset命令既可以回退版本硝岗,也可以把暫存區(qū)的修改回退到工作區(qū)氢哮。當(dāng)我們用HEAD時(shí),表示最新的版本

Tips: 如果不知道指令怎么寫型檀,可以使用 git status 查看冗尤。

如果只是發(fā)生上述兩種情況,那么還是很好解決的胀溺。如果要是當(dāng)初一個(gè)不當(dāng)心裂七,把修改提交到 版本庫(kù) 了!2治搿背零!怎么辦?无埃?徙瓶?這就用到了 版本回退...

第三種情況:
回退之前,用git log可以查看提交歷史嫉称,以便確定要回退到哪個(gè)版本侦镇。
HEAD指向的版本就是當(dāng)前版本,因此澎埠,Git允許我們?cè)诎姹镜臍v史之間穿梭虽缕,使用命令 git reset --hard commit_id
要重返未來(lái),用git reflog查看命令歷史,以便確定要回到未來(lái)的哪個(gè)版本

2.4氮趋、刪除文件

刪除文件分為兩種情況:
情況一:
直接在文件管理器中把沒(méi)用的文件刪了伍派,或者用rm命令刪了:rm xxx
情況二:
從版本庫(kù)中刪除該文件,那就用命令 git rm 刪掉剩胁,并且 git commit

第三章

3.1诉植、添加遠(yuǎn)程庫(kù)

現(xiàn)在的情景是,你已經(jīng)在本地創(chuàng)建了一個(gè)Git倉(cāng)庫(kù)后昵观,又想在GitHub創(chuàng)建一個(gè)Git倉(cāng)庫(kù)晾腔,并且讓這兩個(gè)倉(cāng)庫(kù)進(jìn)行遠(yuǎn)程同步,這樣啊犬,GitHub上的倉(cāng)庫(kù)既可以作為備份灼擂,又可以讓其他人通過(guò)該倉(cāng)庫(kù)來(lái)協(xié)作,真是一舉多得觉至。

首先剔应,登陸GitHub,然后语御,在右上角找到“Create a new repo”按鈕峻贮,創(chuàng)建一個(gè)新的倉(cāng)庫(kù):


0.png

在Repository name填入learngit,其他保持默認(rèn)設(shè)置应闯,點(diǎn)擊“Create repository”按鈕纤控,就成功地創(chuàng)建了一個(gè)新的Git倉(cāng)庫(kù):


0-1.png

目前,在GitHub上的這個(gè)learngit倉(cāng)庫(kù)還是空的碉纺,GitHub告訴我們船万,可以從這個(gè)倉(cāng)庫(kù)克隆出新的倉(cāng)庫(kù),也可以把一個(gè)已有的本地倉(cāng)庫(kù)與之關(guān)聯(lián)惜辑,然后唬涧,把本地倉(cāng)庫(kù)的內(nèi)容推送到GitHub倉(cāng)庫(kù)。

現(xiàn)在盛撑,我們根據(jù)GitHub的提示,在本地的learngit倉(cāng)庫(kù)下運(yùn)行命令:

git remote add origin git@github.com:michaelliao/learngit.git

這樣的話本地倉(cāng)庫(kù)和遠(yuǎn)程倉(cāng)庫(kù)就可以產(chǎn)生關(guān)聯(lián)捧搞!
請(qǐng)千萬(wàn)注意抵卫,把上面的michaelliao替換成你自己的GitHub賬戶名,否則胎撇,你在本地關(guān)聯(lián)的就是我的遠(yuǎn)程庫(kù)介粘,關(guān)聯(lián)沒(méi)有問(wèn)題,但是你以后推送是推不上去的晚树,因?yàn)槟愕腟SH Key公鑰不在我的賬戶列表中姻采。

添加后,遠(yuǎn)程庫(kù)的名字就是origin爵憎,這是Git默認(rèn)的叫法慨亲,也可以改成別的婚瓜,但是origin這個(gè)名字一看就知道是遠(yuǎn)程庫(kù)。
下一步刑棵,就可以把本地庫(kù)的所有內(nèi)容推送到遠(yuǎn)程庫(kù)上:

$ git push -u origin master
Counting objects: 20, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (20/20), 1.64 KiB | 560.00 KiB/s, done.
Total 20 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), done.
To github.com:michaelliao/learngit.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

把本地庫(kù)的內(nèi)容推送到遠(yuǎn)程巴刻,用git push命令,實(shí)際上是把當(dāng)前分支master推送到遠(yuǎn)程蛉签。

由于遠(yuǎn)程庫(kù)是空的胡陪,我們第一次推送master分支時(shí),加上了-u參數(shù)碍舍,Git不但會(huì)把本地的master分支內(nèi)容推送的遠(yuǎn)程新的master分支柠座,還會(huì)把本地的master分支和遠(yuǎn)程的master分支關(guān)聯(lián)起來(lái),在以后的推送或者拉取時(shí)就可以簡(jiǎn)化命令片橡。

推送成功后愚隧,可以立刻在GitHub頁(yè)面中看到遠(yuǎn)程庫(kù)的內(nèi)容已經(jīng)和本地一模一樣:


0-2.png

從現(xiàn)在起,只要本地作了提交锻全,就可以通過(guò)命令:

git push origin master

把本地master分支的最新修改推送至GitHub狂塘,現(xiàn)在,你就擁有了真正的分布式版本庫(kù)鳄厌!

添加遠(yuǎn)程庫(kù)分為三步:

  • 要關(guān)聯(lián)一個(gè)遠(yuǎn)程庫(kù)荞胡,使用命令git remote add origin git@server-name:path/repo-name.git
  • 關(guān)聯(lián)后,使用命令git push -u origin master第一次推送master分支的所有內(nèi)容
  • 此后了嚎,每次本地提交后泪漂,只要有必要,就可以使用命令git push origin master推送最新修改歪泳。
3.2萝勤、 從遠(yuǎn)程庫(kù)克隆

上次我們講了先有本地庫(kù),后有遠(yuǎn)程庫(kù)的時(shí)候呐伞,如何關(guān)聯(lián)遠(yuǎn)程庫(kù)敌卓。

現(xiàn)在,假設(shè)我們從零開(kāi)發(fā)伶氢,那么最好的方式是先創(chuàng)建遠(yuǎn)程庫(kù)趟径,然后,從遠(yuǎn)程庫(kù)克隆癣防。

首先蜗巧,登陸GitHub,創(chuàng)建一個(gè)新的倉(cāng)庫(kù)蕾盯,名字叫g(shù)itskills:


0.png

我們勾選Initialize this repository with a README幕屹,這樣GitHub會(huì)自動(dòng)為我們創(chuàng)建一個(gè)README.md文件。創(chuàng)建完畢后,可以看到README.md文件:


0-1.png

現(xiàn)在望拖,遠(yuǎn)程庫(kù)已經(jīng)準(zhǔn)備好了渺尘,下一步是用命令git clone克隆一個(gè)本地庫(kù):
$ git clone git@github.com:michaelliao/gitskills.git
Cloning into 'gitskills'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 3
Receiving objects: 100% (3/3), done.

第四章

4.1、創(chuàng)建與合并分支

在上文靠娱,已經(jīng)知道沧烈,每次提交,Git都把它們串成一條時(shí)間線像云,這條時(shí)間線就是一個(gè)分支锌雀。截止到目前,只有一條時(shí)間線迅诬,在Git里腋逆,這個(gè)分支叫主分支,即master分支侈贷。HEAD嚴(yán)格來(lái)說(shuō)不是指向提交惩歉,而是指向mastermaster才是指向提交的俏蛮,所以撑蚌,HEAD指向的就是當(dāng)前分支。

一開(kāi)始的時(shí)候搏屑,master分支是一條線争涌,Git用master指向最新的提交,再用HEAD指向master辣恋,就能確定當(dāng)前分支亮垫,以及當(dāng)前分支的提交點(diǎn):

0.png

每次提交,master分支都會(huì)向前移動(dòng)一步伟骨,這樣饮潦,隨著你不斷提交,master分支的線也越來(lái)越長(zhǎng)携狭。
當(dāng)我們用git checkout -b xxx(創(chuàng)建并切換)創(chuàng)建分支继蜡,Git新建了一個(gè)指針叫dev,指向master相同的提交暑中,再把HEAD指向dev壹瘟,就表示當(dāng)前分支在dev上:

0-1.png

你看,Git創(chuàng)建一個(gè)分支很快鳄逾,因?yàn)槌嗽黾右粋€(gè)dev指針,改改HEAD的指向灵莲,工作區(qū)的文件都沒(méi)有任何變化雕凹!

不過(guò),從現(xiàn)在開(kāi)始,對(duì)工作區(qū)的修改和提交就是針對(duì)dev分支了枚抵,比如新提交一次后线欲,dev指針往前移動(dòng)一步,而master指針不變:


0-2.png

假如我們?cè)赿ev上的工作完成了汽摹,就可以把dev合并到master上李丰。Git怎么合并呢?最簡(jiǎn)單的方法逼泣,就是直接把master指向dev的當(dāng)前提交趴泌,就完成了合并:


0-3.png

所以Git合并分支也很快!就改改指針拉庶,工作區(qū)內(nèi)容也不變嗜憔!

合并完分支后,甚至可以刪除dev分支氏仗。刪除dev分支就是把dev指針給刪掉吉捶,刪掉后,我們就剩下了一條master分支:


0-4.png

下面用代碼說(shuō)明:
首先皆尔,我們創(chuàng)建dev分支呐舔,然后切換到dev分支:

$ git checkout -b dev
Switched to a new branch 'dev'

git checkout命令加上-b參數(shù)表示創(chuàng)建并切換,相當(dāng)于以下兩條命令

$ git branch dev
$ git checkout dev
Switched to branch 'dev'

然后慷蠕,用git branch命令查看當(dāng)前分支:

$ git branch
* dev
  master

可以在Dev分支上進(jìn)行操作珊拼,操作完成以后,我們就可以切換回master分支:

$ git checkout master
Switched to branch 'master'

切換回master分支后砌们,master分支上的東西并沒(méi)有同步之前提交的:


0-5.png

如果想讓master分支上也有同樣的內(nèi)容:

$ git merge dev
Updating d46f35e..b17d20e
Fast-forward
 readme.txt | 1 +
 1 file changed, 1 insertion(+)

git merge命令用于合并指定分支到當(dāng)前分支
合并完成后杆麸,就可以放心地刪除dev分支了:

$ git branch -d dev
Deleted branch dev (was b17d20e).

總結(jié):
Git鼓勵(lì)大量使用分支:

  • 查看分支:git branch

  • 創(chuàng)建分支:git branch <name>

  • 切換分支:git checkout <name>

  • 創(chuàng)建+切換分支:git checkout -b <name>

  • 合并某分支到當(dāng)前分支:git merge <name>

  • 刪除分支:git branch -d <name>

4.2、解決沖突

我們先創(chuàng)建一個(gè)分支并切換到當(dāng)前分支feature1

$ git checkout -b feature1
Switched to a new branch 'feature1'

假設(shè)工作區(qū)有個(gè)文件為 readme.txt,我們修改這個(gè)文件里面的內(nèi)容:

Creating a new branch is quick AND simple.

然后提交:

$ git add readme.txt

$ git commit -m "AND simple"
[feature1 14096d0] 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.
  (use "git push" to publish your local commits)

Git還會(huì)自動(dòng)提示我們當(dāng)前master分支比遠(yuǎn)程的master分支要超前1個(gè)提交浪感。

正常情況下昔头,現(xiàn)在我們就可以合并了!S笆蕖=腋!但是如果沒(méi)有合并會(huì)出現(xiàn)什么情況呢峻堰?讹开?
比如,在工作區(qū)做一次修改 再次提交到當(dāng)前分支:
在master分支上把readme.txt文件的最后一行改為:

Creating a new branch is quick & simple.

提交:

$ git add readme.txt 
$ git commit -m "& simple"
[master 5dc6824] & simple
 1 file changed, 1 insertion(+), 1 deletion(-)

現(xiàn)在捐名,master分支和feature1分支各自都分別有新的提交旦万,變成了這樣:

0-6.png

這種情況下,Git無(wú)法執(zhí)行“快速合并”镶蹋,只能試圖把各自的修改合并起來(lái)成艘,但這種合并就可能會(huì)有沖突赏半,我們?cè)囋嚳矗?/p>

$ 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文件存在沖突断箫,必須手動(dòng)解決沖突后再提交。git status也可以告訴我們沖突的文件:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:   readme.txt

no changes added to commit (use "git add" and/or "git commit -a")

我們可以直接查看readme.txt的內(nèi)容:

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1

Git用<<<<<<<秋冰,=======仲义,>>>>>>>標(biāo)記出不同分支的內(nèi)容,我們修改如下后保存:

Creating a new branch is quick and simple.

再提交:

$ git add readme.txt 
$ git commit -m "conflict fixed"
[master cf810e4] conflict fixed

現(xiàn)在剑勾,master分支和feature1分支變成了下圖所示:


0-7.png

用帶參數(shù)的git log也可以看到分支的合并情況:

$ git log --graph --pretty=oneline --abbrev-commit
*   cf810e4 (HEAD -> master) conflict fixed
|\  
| * 14096d0 (feature1) AND simple
* | 5dc6824 & simple
|/  
* b17d20e branch test
* d46f35e (origin/master) remove test.txt
* b84166e add test.txt
* 519219b git tracks changes
* e43a48b understand how stage works
* 1094adb append GPL
* e475afc add distributed
* eaadf4e wrote a readme file

最后埃撵,刪除feature1分支:

$ git branch -d feature1
Deleted branch feature1 (was 14096d0).

小結(jié)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  • 當(dāng)Git無(wú)法自動(dòng)合并分支時(shí),就必須首先解決沖突甥材。解決沖突后盯另,再提交,合并完成洲赵。

  • 解決沖突就是把Git合并失敗的文件手動(dòng)編輯為我們希望的內(nèi)容鸳惯,再提交。

  • 用git log --graph命令可以看到分支合并圖叠萍。

4.3芝发、分支策略

在實(shí)際開(kāi)發(fā)中,我們應(yīng)該按照幾個(gè)基本原則進(jìn)行分支管理:

首先苛谷,master分支應(yīng)該是非常穩(wěn)定的辅鲸,也就是僅用來(lái)發(fā)布新版本,平時(shí)不能在上面干活腹殿;

那在哪干活呢独悴?干活都在dev分支上,也就是說(shuō)锣尉,dev分支是不穩(wěn)定的刻炒,到某個(gè)時(shí)候,比如1.0版本發(fā)布時(shí)自沧,再把dev分支合并到master上坟奥,在master分支發(fā)布1.0版本;

你和你的小伙伴們每個(gè)人都在dev分支上干活拇厢,每個(gè)人都有自己的分支爱谁,時(shí)不時(shí)地往dev分支上合并就可以了。

所以孝偎,團(tuán)隊(duì)合作的分支看起來(lái)就像這樣:


0-8.png
4.4访敌、bug分支

假如我們現(xiàn)在在Dev分支上進(jìn)行開(kāi)發(fā),突然要去 master 分支上解決一個(gè)bug衣盾。怎么辦捐顷?

  • 先把當(dāng)前的工作區(qū)給保存 使用 git stash
  • 切換到master分支上荡陷,創(chuàng)建并切換一個(gè)新的分支雨效,在新分支上手動(dòng)修改
  • 修改完成以后迅涮,切換到master分支,合并新的修改徽龟,刪除新建的bug分支
  • 重新切換到Dev分支叮姑,使用 git stash pop 恢復(fù)剛才的工作區(qū)內(nèi)容

注意:
如果多次使用 git stash 之后,再pop之前可以先進(jìn)行查看保存的列表 git stash list据悔,如果想回到指定的地方可以使用 $ git stash apply stash@{n}

4.5传透、Feature分支

軟件開(kāi)發(fā)中,總有無(wú)窮無(wú)盡的新的功能要不斷添加進(jìn)來(lái)极颓。
添加一個(gè)新功能時(shí)朱盐,你肯定不希望因?yàn)橐恍?shí)驗(yàn)性質(zhì)的代碼,把主分支搞亂了菠隆,所以兵琳,每添加一個(gè)新功能,最好新建一個(gè)feature分支骇径,在上面開(kāi)發(fā)躯肌,完成后,合并破衔,最后清女,刪除該feature分支。
如果在合并之前想放棄修改晰筛,可以使用 git branch -D xxx

4.6嫡丙、多人協(xié)作

當(dāng)你從遠(yuǎn)程倉(cāng)庫(kù)克隆時(shí),實(shí)際上Git自動(dòng)把本地的master分支和遠(yuǎn)程的master分支對(duì)應(yīng)起來(lái)了读第,并且曙博,遠(yuǎn)程倉(cāng)庫(kù)的默認(rèn)名稱是origin

要查看遠(yuǎn)程庫(kù)的信息卦方,用git remote

$ git remote
origin
推送分支

推送分支羊瘩,就是把該分支上的所有本地提交推送到遠(yuǎn)程庫(kù)。推送時(shí)盼砍,要指定本地分支尘吗,這樣,Git就會(huì)把該分支推送到遠(yuǎn)程庫(kù)對(duì)應(yīng)的遠(yuǎn)程分支上:

$ git push origin master

如果要推送其他分支浇坐,比如dev睬捶,就改成:

$ git push origin dev

但是,并不是一定要把本地分支往遠(yuǎn)程推送近刘,那么擒贸,哪些分支需要推送臀晃,哪些不需要呢?

  • master分支是主分支介劫,因此要時(shí)刻與遠(yuǎn)程同步徽惋;

  • dev分支是開(kāi)發(fā)分支,團(tuán)隊(duì)所有成員都需要在上面工作座韵,所以也需要與遠(yuǎn)程同步险绘;

  • bug分支只用于在本地修復(fù)bug,就沒(méi)必要推到遠(yuǎn)程了誉碴,除非老板要看看你每周到底修復(fù)了幾個(gè)bug宦棺;

  • feature分支是否推到遠(yuǎn)程,取決于你是否和你的小伙伴合作在上面開(kāi)發(fā)黔帕。

抓取分支

多人協(xié)作時(shí)代咸,大家都會(huì)往master和dev分支上推送各自的修改。
現(xiàn)在成黄,模擬一個(gè)你的小伙伴呐芥,可以在另一臺(tái)電腦(注意要把SSH Key添加到GitHub)或者同一臺(tái)電腦的另一個(gè)目錄下克隆:

$ git clone git@github.com:michaelliao/learngit.git
Cloning into 'learngit'...
remote: Counting objects: 40, done.
remote: Compressing objects: 100% (21/21), done.
remote: Total 40 (delta 14), reused 40 (delta 14), pack-reused 0
Receiving objects: 100% (40/40), done.
Resolving deltas: 100% (14/14), done.

當(dāng)你的小伙伴從遠(yuǎn)程庫(kù)clone時(shí)慨默,默認(rèn)情況下贩耐,你的小伙伴只能看到本地的master分支。不信可以用git branch命令看看:

$ git branch
* master

現(xiàn)在厦取,你的小伙伴要在dev分支上開(kāi)發(fā)潮太,就必須創(chuàng)建遠(yuǎn)程origindev分支到本地,于是他用這個(gè)命令創(chuàng)建本地dev分支:

git checkout -b dev origin/dev

現(xiàn)在虾攻,他就可以在dev上繼續(xù)修改铡买,然后,時(shí)不時(shí)地把dev分支push到遠(yuǎn)程:

$ git add env.txt

$ git commit -m "add env"
[dev 7a5e5dd] add env
 1 file changed, 1 insertion(+)
 create mode 100644 env.txt

$ 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), 308 bytes | 308.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
   f52c633..7a5e5dd  dev -> dev

你的小伙伴已經(jīng)向origin/dev分支推送了他的提交霎箍,而碰巧你也對(duì)同樣的文件作了修改奇钞,這樣就會(huì)報(bào)錯(cuò)!可以先用git pull把最新的提交從origin/dev抓下來(lái)漂坏,然后景埃,在本地合并,解決沖突
如果git pull失敗顶别,那是因?yàn)闆](méi)有指定本地dev和遠(yuǎn)程origin/dev之間的關(guān)聯(lián):git branch --set-upstream-to=origin/<branch> dev

小結(jié)

  • 查看遠(yuǎn)程庫(kù)信息谷徙,使用git remote -v;

  • 本地新建的分支如果不推送到遠(yuǎn)程驯绎,對(duì)其他人就是不可見(jiàn)的完慧;

  • 從本地推送分支,使用git push origin branch-name剩失,如果推送失敗屈尼,先用git pull抓取遠(yuǎn)程的新提交册着;

  • 在本地創(chuàng)建和遠(yuǎn)程分支對(duì)應(yīng)的分支,使用git checkout -b branch-name origin/branch-name脾歧,本地和遠(yuǎn)程分支的名稱最好一致甲捏;

  • 建立本地分支和遠(yuǎn)程分支的關(guān)聯(lián),使用git branch --set-upstream branch-name origin/branch-name涨椒;

  • 從遠(yuǎn)程抓取分支摊鸡,使用git pull,如果有沖突蚕冬,要先處理沖突。

第五章

5.1是辕、創(chuàng)建標(biāo)簽

在Git中打標(biāo)簽非常簡(jiǎn)單囤热,首先,切換到需要打標(biāo)簽的分支上:

$ git branch
* dev
  master
$ git checkout master
Switched to branch 'master'

然后获三,敲命令git tag <name>就可以打一個(gè)新標(biāo)簽:

$ git tag v1.0

可以用命令git tag查看所有標(biāo)簽:

$ git tag
v1.0

默認(rèn)標(biāo)簽是打在最新提交的commit上的旁蔼。有時(shí)候,如果忘了打標(biāo)簽疙教,比如棺聊,現(xiàn)在已經(jīng)是周五了,但應(yīng)該在周一打的標(biāo)簽沒(méi)有打贞谓,怎么辦限佩?

方法是找到歷史提交的commit id,然后打上就可以了:

$ git log --pretty=oneline --abbrev-commit
12a631b (HEAD -> master, tag: v1.0, origin/master) merged bug fix 101
4c805e2 fix bug 101
e1e9c68 merge with no-ff
f52c633 add merge
cf810e4 conflict fixed
5dc6824 & simple
14096d0 AND simple
b17d20e branch test
d46f35e remove test.txt
b84166e add test.txt
519219b git tracks changes
e43a48b understand how stage works
1094adb append GPL
e475afc add distributed
eaadf4e wrote a readme file

比方說(shuō)要對(duì)add merge這次提交打標(biāo)簽裸弦,它對(duì)應(yīng)的commit id是f52c633祟同,敲入命令:

$ git tag v0.9 f52c633

再用命令git tag查看標(biāo)簽:

$ git tag
v0.9
v1.0

注意,標(biāo)簽不是按時(shí)間順序列出理疙,而是按字母排序的晕城。可以用git show <tagname>查看標(biāo)簽信息:

$ git show v0.9
commit f52c63349bc3c1593499807e5c8e972b82c8f286 (tag: v0.9)
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 21:56:54 2018 +0800

    add merge

diff --git a/readme.txt b/readme.txt
...

小結(jié)

  • 命令git tag <tagname>用于新建一個(gè)標(biāo)簽窖贤,默認(rèn)為HEAD砖顷,也可以指定一個(gè)commit id;

  • 命令git tag -a <tagname> -m "blablabla..."可以指定標(biāo)簽信息赃梧;

  • 命令git tag可以查看所有標(biāo)簽滤蝠。

5.2、操作標(biāo)簽

如果標(biāo)簽打錯(cuò)了槽奕,也可以刪除:

$ git tag -d v0.1
Deleted tag 'v0.1' (was f15b0dd)

因?yàn)閯?chuàng)建的標(biāo)簽都只存儲(chǔ)在本地几睛,不會(huì)自動(dòng)推送到遠(yuǎn)程。所以粤攒,打錯(cuò)的標(biāo)簽可以在本地安全刪除所森。

如果要推送某個(gè)標(biāo)簽到遠(yuǎn)程囱持,使用命令git push origin <tagname>:

$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
 * [new tag]         v1.0 -> v1.0

或者,一次性推送全部尚未推送到遠(yuǎn)程的本地標(biāo)簽:

$ git push origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
 * [new tag]         v0.9 -> v0.9

如果標(biāo)簽已經(jīng)推送到遠(yuǎn)程焕济,要?jiǎng)h除遠(yuǎn)程標(biāo)簽就麻煩一點(diǎn)纷妆,先從本地刪除:

$ git tag -d v0.9
Deleted tag 'v0.9' (was f52c633)

然后,從遠(yuǎn)程刪除晴弃。刪除命令也是push掩幢,但是格式如下:

$ git push origin :refs/tags/v0.9
To github.com:michaelliao/learngit.git
 - [deleted]         v0.9

小結(jié)

  • 命令git push origin <tagname>可以推送一個(gè)本地標(biāo)簽;

  • 命令git push origin --tags可以推送全部未推送過(guò)的本地標(biāo)簽上鞠;

  • 命令git tag -d <tagname>可以刪除一個(gè)本地標(biāo)簽际邻;

  • 命令git push origin :refs/tags/<tagname>可以刪除一個(gè)遠(yuǎn)程標(biāo)簽。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末芍阎,一起剝皮案震驚了整個(gè)濱河市世曾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谴咸,老刑警劉巖轮听,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異岭佳,居然都是意外死亡血巍,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門珊随,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)述寡,“玉大人,你說(shuō)我怎么就攤上這事玫恳”娲停” “怎么了坎匿?”我有些...
    開(kāi)封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵失仁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我救氯,道長(zhǎng)惭婿,這世上最難降的妖魔是什么不恭? 我笑而不...
    開(kāi)封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮财饥,結(jié)果婚禮上换吧,老公的妹妹穿的比我還像新娘。我一直安慰自己钥星,他們只是感情好沾瓦,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般贯莺。 火紅的嫁衣襯著肌膚如雪风喇。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天缕探,我揣著相機(jī)與錄音魂莫,去河邊找鬼。 笑死爹耗,一個(gè)胖子當(dāng)著我的面吹牛耙考,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播潭兽,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼倦始,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了讼溺?” 一聲冷哼從身側(cè)響起楣号,我...
    開(kāi)封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎怒坯,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體藻懒,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡剔猿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嬉荆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片归敬。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鄙早,靈堂內(nèi)的尸體忽然破棺而出汪茧,到底是詐尸還是另有隱情,我是刑警寧澤限番,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布舱污,位于F島的核電站,受9級(jí)特大地震影響弥虐,放射性物質(zhì)發(fā)生泄漏扩灯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一霜瘪、第九天 我趴在偏房一處隱蔽的房頂上張望珠插。 院中可真熱鬧,春花似錦颖对、人聲如沸捻撑。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)顾患。三九已至番捂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間描验,已是汗流浹背白嘁。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留膘流,地道東北人絮缅。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像呼股,于是被迫代替她去往敵國(guó)和親耕魄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

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

  • 1.設(shè)置 初次使用需要設(shè)置姓名和郵箱git config --global user.name "git用戶名"g...
    jrg陳咪咪sunny閱讀 753評(píng)論 0 1
  • 1.git的安裝 1.1 在Windows上安裝Git msysgit是Windows版的Git彭谁,從https:/...
    落魂灬閱讀 12,650評(píng)論 4 54
  • 一吸奴、Git是什么呢? Git是目前世界上最先進(jìn)的分布式版本控制系統(tǒng)缠局。那什么是版本控制系統(tǒng)则奥?簡(jiǎn)單的點(diǎn)就是控制每次修改...
    奔跑的時(shí)間閱讀 607評(píng)論 0 2
  • Git和Github學(xué)習(xí) 1.創(chuàng)建版本庫(kù) 安裝git,至于這個(gè)話題就不細(xì)說(shuō)了狭园,按照你電腦的操作系統(tǒng)下載一個(gè)合適的g...
    郭子web閱讀 366評(píng)論 0 0
  • “你是我最好的朋友读处,別人永遠(yuǎn)也取代不了你在我心里的位置……”曾經(jīng)讓我感動(dòng)的話現(xiàn)在反倒變成了一把尖銳的匕首直直的插進(jìn)...
    琳啊哩閱讀 209評(píng)論 0 0