Git&GitHub

廖雪峰教程

  • 0.使用GitHub
    0.1 添加到遠(yuǎn)程庫(kù)
    0.2 從遠(yuǎn)程庫(kù)克隆
    0.3 GitHub使用

  • 1.創(chuàng)建版本庫(kù)

  • 2.時(shí)光穿梭機(jī)
    2.1 版本回退
    2.2 工作區(qū)和暫存區(qū)
    2.3 管理修改
    2.4 撤銷(xiāo)修改
    2.5 刪除文件

  • 3.分支管理
    3.1 創(chuàng)建與合并分支
    3.2 解決沖突
    3.3 分支管理策略
    3.4 Bug分支
    3.5 Feature分支
    3.6 多人協(xié)作

  • 4.標(biāo)簽管理
    4.1 創(chuàng)建標(biāo)簽
    4.2 操作標(biāo)簽

  • 5.自定義Git
    5.1 忽略特殊文件
    5.2 配置別名
    5.3 搭建Git服務(wù)器

  • 6.擴(kuò)展
    6.1 rebase的使用

0.使用GitHub
生成SSH key,如果沒(méi)有key的話(huà)埃碱,在用戶(hù)主目錄下面猖辫,執(zhí)行下面語(yǔ)句:

ssh-keygen -t rsa -C "youremail@example.com"

該語(yǔ)句在用戶(hù)主目錄下面生成.ssh文件夾,文件夾中有兩個(gè)文件砚殿,分別是id_rsa和id_rsa.pub,前者是私鎖啃憎,不能告訴別人,后者是公鎖瓮具,可以告訴別人荧飞,需要將后者即是id_rsa.pub中內(nèi)容添加到GitHub的賬戶(hù)中,因?yàn)镚it支持SSH協(xié)議名党,SSH key是GitHub用來(lái)識(shí)別代碼是該用戶(hù)提交過(guò)來(lái)的叹阔。

0.1 添加到遠(yuǎn)程庫(kù)

git remote add origin https://github.com/Jayzen/demo_for_test.git 
#遠(yuǎn)程庫(kù)的名字叫做origin,是默認(rèn)的遠(yuǎn)程庫(kù)的名稱(chēng),其中demo_for_test是用戶(hù)自定義的倉(cāng)庫(kù)名稱(chēng)
git push -u origin master
#第一次推送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)化命令
git push origin master #第二次之后遠(yuǎn)程庫(kù)的代碼提交(對(duì)比第一次提交少了-u 參數(shù))

0.2 從遠(yuǎn)程庫(kù)克隆

git clone https://github.com/Jayzen/gitskill.git #自己的電腦這個(gè)可行
git clone git@github.com:Jayzen/gitskill.git

0.3 GitHub使用
如果要修改一個(gè)開(kāi)源庫(kù),步驟如下:

fork   #fork一個(gè)項(xiàng)目睛藻,相當(dāng)于在自己的github上面復(fù)制了一個(gè)相同的項(xiàng)目
git clone XX #在用戶(hù)的本地復(fù)制該代碼
git push  #用戶(hù)本地修改代碼之后启上,推送到GiHub中用戶(hù)本身的目錄下面
pull request #發(fā)起這個(gè)pull request,看作者是否接受

具體示意圖見(jiàn)如:

Paste_Image.png

1.創(chuàng)建版本庫(kù)

git init #初始化一個(gè)倉(cāng)庫(kù)
git add <file> #添加到倉(cāng)庫(kù)
git commit -m "some descriptions"  #提交到倉(cāng)庫(kù),其中后面顯示的-m是對(duì)本次提交的一次說(shuō)明

2.時(shí)光穿梭機(jī)

git status #查看用戶(hù)的狀態(tài)
#如果只是對(duì)代碼進(jìn)行了修改店印,之后沒(méi)有做任何改動(dòng)冈在,則會(huì)顯Changes not staged for commit
#如果是在當(dāng)前文件夾內(nèi)添加了一個(gè)文件,之后沒(méi)有做任何動(dòng)作按摘,則會(huì)顯示untracked files
#如果對(duì)文件進(jìn)行了修改包券,執(zhí)行了add,沒(méi)有執(zhí)行commit,則會(huì)顯示Changes to be committed
#如果代碼全部提交到倉(cāng)庫(kù)中炫贤,則會(huì)顯示nothing to commit, working directory clean
git diff #查看代碼做了哪些修改溅固,這種狀態(tài)修改的說(shuō)明只能是該文件沒(méi)有執(zhí)行g(shù)it add之前才能看到

2.1 版本回退

git log #顯示從近到遠(yuǎn)的提交日志
git log --pretty=oneline #將這些日志按照行顯示
git reset --hard HEAD^ #將版本退回到上一次提交,其中HEAD^表示上一個(gè)版本兰珍,HEAD^^表示上上一個(gè)版本
git reset --hard commit_id #其中commit_id是commit過(guò)程中生成的id值
git reflog #記錄head指向的每一次命令

head指向append GPL


Paste_Image.png

改為head指向add distributed

Paste_Image.png

2.2 工作區(qū)和暫存區(qū)
工作區(qū)其實(shí)就是git當(dāng)前工作的文件夾侍郭。

把文件往Git版本庫(kù)里添加的時(shí)候,是分兩步執(zhí)行的:
第一步是用git add把文件添加進(jìn)去掠河,實(shí)際上就是把文件修改添加到暫存區(qū)亮元;
第二步是用git commit提交更改,實(shí)際上就是把暫存區(qū)的所有內(nèi)容提交到當(dāng)前分支口柳。

Paste_Image.png

與此同時(shí)苹粟,在工作區(qū)中修改readme.txt文件和添加LICENSE,并且兩次使用add命令跃闹,結(jié)果如下所示:

Paste_Image.png

以上的結(jié)果可以看出,兩次add方法是將文件添加到暫存區(qū)中毛好,執(zhí)行g(shù)it commit -m "fourth commit",得到以下的結(jié)果望艺,暫存區(qū)是干凈的。

Paste_Image.png

2.3 管理修改
Git跟蹤的是修改肌访,而不是文件找默。
git commit 提交給是是暫存區(qū)的內(nèi)容,如果修改了文件吼驶,沒(méi)有執(zhí)行commit add惩激,那么git commit對(duì)修改的文件內(nèi)容無(wú)效。

git diff HEAD -- readme.txt  #查看工作區(qū)和版本庫(kù)里面最新版本的區(qū)別

2.4 撤銷(xiāo)修改
第一種情況:在工作區(qū)中修改蟹演,當(dāng)時(shí)沒(méi)有提交到暫存區(qū)

git checkout --file

命令git checkout -- readme.txt意思就是风钻,把readme.txt文件在工作區(qū)的修改全部撤銷(xiāo),這里有兩種情況:
一種是readme.txt自修改后還沒(méi)有被放到暫存區(qū)酒请,現(xiàn)在骡技,撤銷(xiāo)修改就回到和版本庫(kù)一模一樣的狀態(tài);
一種是readme.txt已經(jīng)添加到暫存區(qū)后,又作了修改布朦,現(xiàn)在囤萤,撤銷(xiāo)修改就回到添加到暫存區(qū)后的狀態(tài)。
第二種情況:已經(jīng)提交到暫存區(qū)

git reset HEAD file  #可以把暫存區(qū)的修改撤銷(xiāo)掉是趴,重新放回工作區(qū)
git checkout --file #重復(fù)第一種情況

其中

git reset  #命令既可以回退版本涛舍,也可以把暫存區(qū)的修改回退到工作區(qū)。當(dāng)我們用HEAD時(shí)唆途,表示最新的版本做盅。

2.5 刪除文件
當(dāng)前工作區(qū)內(nèi)有兩個(gè)文件,分別是demo.rb和test.rb窘哈,其中在工作區(qū)中刪除文件test.rb吹榴,則下面有兩種情況:

#第一種:確實(shí)要?jiǎng)h除該文件
git rm test.rb
git commit -m "remove test.rb"

自己測(cè)試了下,下面的代碼也可以實(shí)現(xiàn)刪除功能滚婉,因?yàn)榘姹究刂聘櫟男薷耐汲铮皇俏募?git add .
git commit -m "remove test.rb"

#第二種:
刪除文件出現(xiàn)錯(cuò)誤,因此相當(dāng)于撤銷(xiāo)修改
git checkout --test.rb #git checkout其實(shí)是用版本庫(kù)里的版本替換工作區(qū)的版本让腹,無(wú)論工作區(qū)是修改還是刪除远剩,都可以“一鍵還原”。

3.1 創(chuàng)建和合并分支

git branch #查看分支
git branch <name> #創(chuàng)建分支
git checkout <name> #切換分支
git checkout -b <name> #創(chuàng)建+切換分支
git merge <name> #合并某分支到當(dāng)前分支
git branch -d <name> #刪除分支

一開(kāi)始的時(shí)候骇窍,master分支是一條線(xiàn)瓜晤,Git用master指向最新的提交,再用HEAD指向master腹纳,就能確定當(dāng)前分支痢掠,以及當(dāng)前分支的提交點(diǎn),每次提交嘲恍,master分支都會(huì)向前移動(dòng)一步足画,這樣,隨著你不斷提交佃牛,master分支的線(xiàn)也越來(lái)越長(zhǎng):

Paste_Image.png

當(dāng)我們創(chuàng)建新的分支淹辞,例如dev時(shí),Git新建了一個(gè)指針叫dev俘侠,指向master相同的提交象缀,再把HEAD指向dev,就表示當(dāng)前分支在dev上:

Paste_Image.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指針不變:

Paste_Image.png

假如我們?cè)赿ev上的工作完成了,就可以把dev合并到master上州泊。Git怎么合并呢丧蘸?最簡(jiǎn)單的方法,就是直接把master指向dev的當(dāng)前提交遥皂,就完成了合并:

Paste_Image.png

合并完分支后力喷,甚至可以刪除dev分支。刪除dev分支就是把dev指針給刪掉演训,刪掉后弟孟,我們就剩下了一條master分支:

Paste_Image.png

3.2 解決沖突
當(dāng)主分支和從分支在同一個(gè)地方進(jìn)行修改了,并且進(jìn)行合并之后样悟,出現(xiàn)了沖突拂募。

#生成另外一個(gè)分支,對(duì)這個(gè)分支進(jìn)行修改窟她,然后提交
git checkout -b feature
修改demo.rb中的內(nèi)容
git add demo.rb
git commit -m "commit feature"

#回到master分支陈症,對(duì)master分支進(jìn)行修改,然后提交
git checkout master
修改demo.rb中的內(nèi)容震糖,并且和上一個(gè)部分修改同一個(gè)地方
git add demo.rb
git commit -m "commit master"

#對(duì)兩個(gè)分支進(jìn)行合并
git merge feature #出現(xiàn)了conflict

#修改conflict的內(nèi)容录肯,重新進(jìn)行提交
git add demo.rb
git commit -m "final commit"

#上面的內(nèi)容對(duì)conflict內(nèi)容進(jìn)行了修改,并且在master分支上進(jìn)行了合并成功

#刪除分支
git branch -d feature

#用圖像形式顯示合并
git log --graph --pretty=oneline --abbrev-commit

3.3 分支管理策略
每個(gè)人不應(yīng)該在master分支上建立分支吊说,而應(yīng)該在dev分支上建立分支论咏,每次提交應(yīng)該針對(duì)dev分支,當(dāng)發(fā)布版本時(shí)應(yīng)該從dev分支上提交到master分支

如果按照上文的合并方式(fast forward)進(jìn)行的話(huà)疏叨,如果刪除了分支潘靖,就會(huì)丟失分支信息,因此這里可以采用禁用Fast forward模式蚤蔓,Git就會(huì)在merge時(shí)生成一個(gè)新的commit。

git checkout -b dev
修改demo.rb文件內(nèi)容
git add demo.rb
git commit -m "commit dev"

#切換到master分支糊余,禁止fast forward模式
git checkout master
git merge --no-ff -m "merge with no-ff" dev

#查看log秀又,可以看到分支信息
git log --graph --pretty=oneline --abbrev-commit

下面圖片顯示分支信息:


Paste_Image.png

3.4 Bug分支
Bug分支的策略是把當(dāng)前的分支存儲(chǔ)起來(lái),然后建立bug分支贬芥,修復(fù)好之后再對(duì)當(dāng)前分支進(jìn)行恢復(fù)吐辙。

git status #當(dāng)前分支下的內(nèi)容
git stash #對(duì)當(dāng)前分支進(jìn)行存儲(chǔ)
git status #當(dāng)對(duì)當(dāng)前分支進(jìn)行存儲(chǔ)之后,發(fā)現(xiàn)當(dāng)前分支的status是空的

#對(duì)bug分支進(jìn)行修復(fù)
git checkout master
git checkout -b bug-issue
對(duì)demo.rb文件內(nèi)容進(jìn)行修改
git add demo.rb
git commit -m "bug commit"
git checkout master 
git merge --no-ff -m "merge bug commit" bug-issue
git status  #查看工作目錄是空的

git slash list #查看slash
git slash apply #恢復(fù)后蘸劈,stash內(nèi)容并不刪除昏苏,你需要用git stash drop來(lái)刪除
git stash apply stash@{0} #恢復(fù)指定的slash
git slash pop #恢復(fù)的同時(shí)把stash內(nèi)容也刪了
git slash list #恢復(fù)后查看slash的內(nèi)容也沒(méi)有了

3.5 Feature分支
如果是開(kāi)發(fā)新功能,最好是新建一個(gè)分支,如果這個(gè)分支已經(jīng)被合并贤惯,那么刪除這個(gè)分支使用:

git branch -d feature

如果這個(gè)分支沒(méi)有被合并洼专,刪除這個(gè)分支,需要用到下面的語(yǔ)句:

git branch -D feature

3.6 多人協(xié)作
從遠(yuǎn)程克隆倉(cāng)庫(kù)也是分多種情況孵构,第一種情況是只有一個(gè)master分支的情況下:

git clone XX  #遠(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)名稱(chēng)是origin
git remote #origin  此代碼是查看遠(yuǎn)程庫(kù)的信息蜡镶,遠(yuǎn)程庫(kù)的默認(rèn)信息是origin
git remote -v  #使用-v查看遠(yuǎn)程庫(kù)更為詳細(xì)的信息
  origin git@github.com:michaelliao/learngit.git (fetch)
  origin git@github.com:michaelliao/learngit.git (push)
git push origin master #推送master分支
git push origin dev  #推送dev分支

第二種情況是當(dāng)遠(yuǎn)程庫(kù)存在多個(gè)分支時(shí)候,使用git clone語(yǔ)句克隆代碼恤筛,使用git branch語(yǔ)句只能查看master分支官还,為了顯示其他分支,需要?jiǎng)?chuàng)建遠(yuǎn)程的origin的dev分支到本地:

git clone XX
git branch #master
#實(shí)際上被克隆的代碼庫(kù)有很多分支毒坛,而這里只能顯示master分支
git checkout -b dev origin/dev
#使用上面的語(yǔ)句在本地建立dev分支望伦,和遠(yuǎn)程庫(kù)的dev分支對(duì)象起來(lái),同時(shí)獲得遠(yuǎn)程庫(kù)的分支信息代碼
#在dev分支上修改代碼
git commit -m "add the dev" 
git push origin dev #將代碼推送到遠(yuǎn)程庫(kù)dev分支中

第三情況是處理沖突:兩個(gè)人同時(shí)寫(xiě)作同一個(gè)代碼庫(kù)粘驰,比如在feature分支上面屡谐,一個(gè)人已經(jīng)作為修改,另外一個(gè)人在此人修改之前已經(jīng)git clone到本地蝌数,并且在feature同一個(gè)地方做了修改愕掏,因此會(huì)出現(xiàn)conflict。

#已經(jīng)有其他用戶(hù)在feature分支上面建立test.rb文件
#下面的代碼都是在本地的feature分支上進(jìn)行
git add test.rb
git commit -m "add the test.rb"
git push origin feature

上面的代碼出現(xiàn)錯(cuò)誤顶伞,根據(jù)提示可以知道饵撑,是因?yàn)槌霈F(xiàn)了代碼沖突,根據(jù)提示使用git pull唆貌。

git pull #如果存在no tracking information滑潘,說(shuō)明本地分支和遠(yuǎn)程分支之間的鏈接關(guān)系沒(méi)有建立
git branch --set-upstream-to=origin/feature feature #設(shè)置feature和origin/feature的鏈接
git pull #出現(xiàn)沖突及沖突提示
#沖突解決好之后重新提交
git commit -m "conflict commit"
git push origin feature

4.標(biāo)簽管理
標(biāo)簽是版本庫(kù)的一個(gè)快照,若給版本庫(kù)打了一個(gè)標(biāo)簽锨咙,就相當(dāng)于在某個(gè)時(shí)候獲取一個(gè)特定時(shí)間的版本庫(kù)语卤,標(biāo)簽和分支不同,分支可以移動(dòng)酪刀,標(biāo)簽不能移動(dòng)粹舵。
4.1 創(chuàng)建標(biāo)簽

git checkout master #切換到最新的master分支上
git tag v1.0 #給最新的分支貼上標(biāo)簽
git tag #查看所有標(biāo)簽
默認(rèn)情況下標(biāo)簽是打在最新的提交的commit上,如果需要打在之前提交的commit上骂倘,需要如下的語(yǔ)句
git log --pretty=oneline --abbrev-commit  #顯示commit id log
git tag v0.9 1234234  #其中1234234是commit id值卦停,即將標(biāo)簽打在這個(gè)commit id中纽匙。
git show  v1.0 #查看某個(gè)版本的標(biāo)簽
git tag -a v0.1 -m "version 0.1 released" 3628164
#創(chuàng)建帶有說(shuō)明的標(biāo)簽疼进,用-a指定標(biāo)簽名淀零,-m指定說(shuō)明文字

4.2 操作標(biāo)簽

git tag -d v0.9  #刪除標(biāo)簽
git push origin v0.9 #因?yàn)闃?biāo)簽都是在本地的漾唉,此代碼是推送標(biāo)簽到遠(yuǎn)程
git push origin --tags #一次性推送全部尚未推送到遠(yuǎn)程的本地標(biāo)簽

#如果標(biāo)簽已經(jīng)推送到遠(yuǎn)程,要?jiǎng)h除遠(yuǎn)程標(biāo)簽就麻煩一點(diǎn)堰塌,先從本地刪除:
#然后赵刑,從遠(yuǎn)程刪除。刪除命令也是push
git tag -d v0.9
git push origin :refs/tags/v0.9

5.自定義Git

git config --global color.ui true #設(shè)置顏色

5.1 忽略特殊文件
在工作區(qū)建立 .gitignore
ruby的示例文件可以在這里找到

5.2 配置別名
配置別名就是在將Git的命令用其他名字來(lái)表示蔫仙,示例代碼如下所示:

git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch
#--global參數(shù)是全局參數(shù)料睛,也就是這些命令在這臺(tái)電腦的所有Git倉(cāng)庫(kù)下都有用。

每個(gè)倉(cāng)庫(kù)的Git配置文件都放在.git/config文件中摇邦,其中別名就在[alias]后面恤煞,要?jiǎng)h除別名,直接把對(duì)應(yīng)的行刪掉即可施籍。

[core] 
  repositoryformatversion = 0 
  filemode = true bare = false 
  logallrefupdates = true 
  ignorecase = true 
  precomposeunicode = true
[remote "origin"]
  url = git@github.com:michaelliao/learngit.git 
  fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"] 
  remote = origin 
  merge = refs/heads/master
[alias] 
  last = log -1

而當(dāng)前用戶(hù)的Git配置文件放在用戶(hù)主目錄下的一個(gè)隱藏文件.gitconfig
中:

[alias] 
  co = checkout 
  ci = commit 
  br = branch 
  st = status
[user]
  name = Your Name 
  email = your@email.com

5.3 搭建Git服務(wù)器
見(jiàn)這里

6.擴(kuò)展
6.1 rebase的使用
相關(guān)文檔
在master分支上簡(jiǎn)歷mywork分支居扒,示意圖如下所示:

Paste_Image.png

在mywork分支上提交兩次代碼,同時(shí)其他用戶(hù)在master分支上提交了兩次代碼丑慎,示意圖如下所示:

Paste_Image.png

在這里喜喂,你可以用"pull"命令把"origin"分支上的修改拉下來(lái)并且和你的修改合并; 結(jié)果看起來(lái)就像一個(gè)新的"合并的提交"竿裂,示意圖如下所示:

Paste_Image.png

但是玉吁,如果你想讓"mywork"分支歷史看起來(lái)像沒(méi)有經(jīng)過(guò)任何合并一樣,可以用git rebase腻异,代碼如下所示:

git checkout mywork
git rebase origin

這些命令會(huì)把你的"mywork"分支里的每個(gè)提交(commit)取消掉进副,并且把它們臨時(shí) 保存為補(bǔ)丁(patch)(這些補(bǔ)丁放到".git/rebase"目錄中),然后把"mywork"分支更新 到最新的"origin"分支,最后把保存的這些補(bǔ)丁應(yīng)用到"mywork"分支上悔常。

Paste_Image.png

當(dāng)'mywork'分支更新之后影斑,它會(huì)指向這些新創(chuàng)建的提交(commit),而那些老的提交會(huì)被丟棄。 如果運(yùn)行垃圾收集命令(pruning garbage collection), 這些被丟棄的提交就會(huì)刪除机打。

Paste_Image.png

現(xiàn)在我們可以看一下用合并(merge)和用rebase所產(chǎn)生的歷史的區(qū)別:

Paste_Image.png

6.2 修改最近一次的提交 commit --amend
該功能會(huì)修改最近一次的提交矫户,使用commit --amend
比如最開(kāi)始是這樣的:

git log

需要對(duì)添加add的講解進(jìn)行修改,使用下面代碼:

git add .
git commit --amend

上面的代碼會(huì)跳出一個(gè)編輯頁(yè)面残邀,可以修改添加add的講解的值皆辽,修改為添加add和commit的講解,并且進(jìn)行保存芥挣,使用git log操作膳汪,可以得到如下的結(jié)果:

git log

6.3 取消最新一次的提交 git revert head
下面的代碼可以取消最近一次的提交

git revert HEAD

原本最初的提交branch如下所示:

Paste_Image.png

執(zhí)行g(shù)it revert HEAD之后,變?yōu)槿缦碌慕Y(jié)果

Paste_Image.png

就是說(shuō)針對(duì)“添加pull的講解”所變化的內(nèi)容消失了九秀。

6.4 使用reset來(lái)刪除前面的幾個(gè)提交
代碼如下所示:

git reset --hard HEAD~~ #這是刪除最前面的兩個(gè)提交
git reset --hard HEAD~ #這是刪除了最前面的一個(gè)提交
git reset --hard ORGI_HEAD #如果之前的reset出錯(cuò)了,該代碼會(huì)返回最開(kāi)始進(jìn)行reset的位置

圖片演示如下:

before reset
after reset

6.5 **使用cherry-pick將其他分支中的內(nèi)容添加到主分支中 **
如下圖所示:

Paste_Image.png

廖雪峰教程

  • 0.使用GitHub
    0.1 添加到遠(yuǎn)程庫(kù)
    0.2 從遠(yuǎn)程庫(kù)克隆
    0.3 GitHub使用

  • 1.創(chuàng)建版本庫(kù)

  • 2.時(shí)光穿梭機(jī)
    2.1 版本回退
    2.2 工作區(qū)和暫存區(qū)
    2.3 管理修改
    2.4 撤銷(xiāo)修改
    2.5 刪除文件

  • 3.分支管理
    3.1 創(chuàng)建與合并分支
    3.2 解決沖突
    3.3 分支管理策略
    3.4 Bug分支
    3.5 Feature分支
    3.6 多人協(xié)作

  • 4.標(biāo)簽管理
    4.1 創(chuàng)建標(biāo)簽
    4.2 操作標(biāo)簽

  • 5.自定義Git
    5.1 忽略特殊文件
    5.2 配置別名
    5.3 搭建Git服務(wù)器

  • 6.擴(kuò)展
    6.1 rebase的使用

0.使用GitHub
生成SSH key,如果沒(méi)有key的話(huà)粘我,在用戶(hù)主目錄下面鼓蜒,執(zhí)行下面語(yǔ)句:

ssh-keygen -t rsa -C "youremail@example.com"

該語(yǔ)句在用戶(hù)主目錄下面生成.ssh文件夾痹换,文件夾中有兩個(gè)文件,分別是id_rsa和id_rsa.pub,前者是私鎖都弹,不能告訴別人娇豫,后者是公鎖,可以告訴別人畅厢,需要將后者即是id_rsa.pub中內(nèi)容添加到GitHub的賬戶(hù)中冯痢,因?yàn)镚it支持SSH協(xié)議,SSH key是GitHub用來(lái)識(shí)別代碼是該用戶(hù)提交過(guò)來(lái)的框杜。

0.1 添加到遠(yuǎn)程庫(kù)

git remote add origin https://github.com/Jayzen/demo_for_test.git 
#遠(yuǎn)程庫(kù)的名字叫做origin,是默認(rèn)的遠(yuǎn)程庫(kù)的名稱(chēng),其中demo_for_test是用戶(hù)自定義的倉(cāng)庫(kù)名稱(chēng)
git push -u origin master
#第一次推送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)化命令
git push origin master #第二次之后遠(yuǎn)程庫(kù)的代碼提交(對(duì)比第一次提交少了-u 參數(shù))

0.2 從遠(yuǎn)程庫(kù)克隆

git clone https://github.com/Jayzen/gitskill.git #自己的電腦這個(gè)可行
git clone git@github.com:Jayzen/gitskill.git

0.3 GitHub使用
如果要修改一個(gè)開(kāi)源庫(kù),步驟如下:

fork   #fork一個(gè)項(xiàng)目油狂,相當(dāng)于在自己的github上面復(fù)制了一個(gè)相同的項(xiàng)目
git clone XX #在用戶(hù)的本地復(fù)制該代碼
git push  #用戶(hù)本地修改代碼之后历恐,推送到GiHub中用戶(hù)本身的目錄下面
pull request #發(fā)起這個(gè)pull request,看作者是否接受

具體示意圖見(jiàn)如:

Paste_Image.png

1.創(chuàng)建版本庫(kù)

git init #初始化一個(gè)倉(cāng)庫(kù)
git add <file> #添加到倉(cāng)庫(kù)
git commit -m "some descriptions"  #提交到倉(cāng)庫(kù),其中后面顯示的-m是對(duì)本次提交的一次說(shuō)明

2.時(shí)光穿梭機(jī)

git status #查看用戶(hù)的狀態(tài)
#如果只是對(duì)代碼進(jìn)行了修改专筷,之后沒(méi)有做任何改動(dòng)弱贼,則會(huì)顯Changes not staged for commit
#如果是在當(dāng)前文件夾內(nèi)添加了一個(gè)文件,之后沒(méi)有做任何動(dòng)作磷蛹,則會(huì)顯示untracked files
#如果對(duì)文件進(jìn)行了修改吮旅,執(zhí)行了add,沒(méi)有執(zhí)行commit,則會(huì)顯示Changes to be committed
#如果代碼全部提交到倉(cāng)庫(kù)中弦聂,則會(huì)顯示nothing to commit, working directory clean
git diff #查看代碼做了哪些修改鸟辅,這種狀態(tài)修改的說(shuō)明只能是該文件沒(méi)有執(zhí)行g(shù)it add之前才能看到

2.1 版本回退

git log #顯示從近到遠(yuǎn)的提交日志
git log --pretty=oneline #將這些日志按照行顯示
git reset --hard HEAD^ #將版本退回到上一次提交,其中HEAD^表示上一個(gè)版本莺葫,HEAD^^表示上上一個(gè)版本
git reset --hard commit_id #其中commit_id是commit過(guò)程中生成的id值
git reflog #記錄head指向的每一次命令

head指向append GPL


Paste_Image.png

改為head指向add distributed

Paste_Image.png

2.2 工作區(qū)和暫存區(qū)
工作區(qū)其實(shí)就是git當(dāng)前工作的文件夾匪凉。

把文件往Git版本庫(kù)里添加的時(shí)候,是分兩步執(zhí)行的:
第一步是用git add把文件添加進(jìn)去捺檬,實(shí)際上就是把文件修改添加到暫存區(qū)再层;
第二步是用git commit提交更改,實(shí)際上就是把暫存區(qū)的所有內(nèi)容提交到當(dāng)前分支堡纬。

Paste_Image.png

與此同時(shí)聂受,在工作區(qū)中修改readme.txt文件和添加LICENSE,并且兩次使用add命令烤镐,結(jié)果如下所示:

Paste_Image.png

以上的結(jié)果可以看出蛋济,兩次add方法是將文件添加到暫存區(qū)中,執(zhí)行g(shù)it commit -m "fourth commit",得到以下的結(jié)果炮叶,暫存區(qū)是干凈的碗旅。

Paste_Image.png

2.3 管理修改
Git跟蹤的是修改渡处,而不是文件。
git commit 提交給是是暫存區(qū)的內(nèi)容祟辟,如果修改了文件医瘫,沒(méi)有執(zhí)行commit add,那么git commit對(duì)修改的文件內(nèi)容無(wú)效旧困。

git diff HEAD -- readme.txt  #查看工作區(qū)和版本庫(kù)里面最新版本的區(qū)別

2.4 撤銷(xiāo)修改
第一種情況:在工作區(qū)中修改醇份,當(dāng)時(shí)沒(méi)有提交到暫存區(qū)

git checkout --file

命令git checkout -- readme.txt意思就是,把readme.txt文件在工作區(qū)的修改全部撤銷(xiāo)吼具,這里有兩種情況:
一種是readme.txt自修改后還沒(méi)有被放到暫存區(qū)僚纷,現(xiàn)在,撤銷(xiāo)修改就回到和版本庫(kù)一模一樣的狀態(tài)馍悟;
一種是readme.txt已經(jīng)添加到暫存區(qū)后畔濒,又作了修改,現(xiàn)在锣咒,撤銷(xiāo)修改就回到添加到暫存區(qū)后的狀態(tài)侵状。
第二種情況:已經(jīng)提交到暫存區(qū)

git reset HEAD file  #可以把暫存區(qū)的修改撤銷(xiāo)掉,重新放回工作區(qū)
git checkout --file #重復(fù)第一種情況

其中

git reset  #命令既可以回退版本毅整,也可以把暫存區(qū)的修改回退到工作區(qū)趣兄。當(dāng)我們用HEAD時(shí),表示最新的版本悼嫉。

2.5 刪除文件
當(dāng)前工作區(qū)內(nèi)有兩個(gè)文件艇潭,分別是demo.rb和test.rb,其中在工作區(qū)中刪除文件test.rb戏蔑,則下面有兩種情況:

#第一種:確實(shí)要?jiǎng)h除該文件
git rm test.rb
git commit -m "remove test.rb"

自己測(cè)試了下蹋凝,下面的代碼也可以實(shí)現(xiàn)刪除功能,因?yàn)榘姹究刂聘櫟男薷淖芸茫皇俏募?git add .
git commit -m "remove test.rb"

#第二種:
刪除文件出現(xiàn)錯(cuò)誤鳍寂,因此相當(dāng)于撤銷(xiāo)修改
git checkout --test.rb #git checkout其實(shí)是用版本庫(kù)里的版本替換工作區(qū)的版本,無(wú)論工作區(qū)是修改還是刪除情龄,都可以“一鍵還原”迄汛。

3.1 創(chuàng)建和合并分支

git branch #查看分支
git branch <name> #創(chuàng)建分支
git checkout <name> #切換分支
git checkout -b <name> #創(chuàng)建+切換分支
git merge <name> #合并某分支到當(dāng)前分支
git branch -d <name> #刪除分支

一開(kāi)始的時(shí)候,master分支是一條線(xiàn)骤视,Git用master指向最新的提交鞍爱,再用HEAD指向master,就能確定當(dāng)前分支专酗,以及當(dāng)前分支的提交點(diǎn),每次提交橄碾,master分支都會(huì)向前移動(dòng)一步,這樣,隨著你不斷提交冠桃,master分支的線(xiàn)也越來(lái)越長(zhǎng):

Paste_Image.png

當(dāng)我們創(chuàng)建新的分支葬项,例如dev時(shí),Git新建了一個(gè)指針叫dev汗贫,指向master相同的提交涯鲁,再把HEAD指向dev崇败,就表示當(dāng)前分支在dev上:

Paste_Image.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指針不變:

Paste_Image.png

假如我們?cè)赿ev上的工作完成了经柴,就可以把dev合并到master上。Git怎么合并呢牛哺?最簡(jiǎn)單的方法,就是直接把master指向dev的當(dāng)前提交淳附,就完成了合并:

Paste_Image.png

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

Paste_Image.png

3.2 解決沖突
當(dāng)主分支和從分支在同一個(gè)地方進(jìn)行修改了吠裆,并且進(jìn)行合并之后试疙,出現(xiàn)了沖突。

#生成另外一個(gè)分支怀跛,對(duì)這個(gè)分支進(jìn)行修改,然后提交
git checkout -b feature
修改demo.rb中的內(nèi)容
git add demo.rb
git commit -m "commit feature"

#回到master分支,對(duì)master分支進(jìn)行修改,然后提交
git checkout master
修改demo.rb中的內(nèi)容,并且和上一個(gè)部分修改同一個(gè)地方
git add demo.rb
git commit -m "commit master"

#對(duì)兩個(gè)分支進(jìn)行合并
git merge feature #出現(xiàn)了conflict

#修改conflict的內(nèi)容贩据,重新進(jìn)行提交
git add demo.rb
git commit -m "final commit"

#上面的內(nèi)容對(duì)conflict內(nèi)容進(jìn)行了修改,并且在master分支上進(jìn)行了合并成功

#刪除分支
git branch -d feature

#用圖像形式顯示合并
git log --graph --pretty=oneline --abbrev-commit

3.3 分支管理策略
每個(gè)人不應(yīng)該在master分支上建立分支,而應(yīng)該在dev分支上建立分支壹无,每次提交應(yīng)該針對(duì)dev分支,當(dāng)發(fā)布版本時(shí)應(yīng)該從dev分支上提交到master分支

如果按照上文的合并方式(fast forward)進(jìn)行的話(huà),如果刪除了分支豺撑,就會(huì)丟失分支信息胞得,因此這里可以采用禁用Fast forward模式危号,Git就會(huì)在merge時(shí)生成一個(gè)新的commit猪半。

git checkout -b dev
修改demo.rb文件內(nèi)容
git add demo.rb
git commit -m "commit dev"

#切換到master分支,禁止fast forward模式
git checkout master
git merge --no-ff -m "merge with no-ff" dev

#查看log,可以看到分支信息
git log --graph --pretty=oneline --abbrev-commit

下面圖片顯示分支信息:


Paste_Image.png

3.4 Bug分支
Bug分支的策略是把當(dāng)前的分支存儲(chǔ)起來(lái),然后建立bug分支,修復(fù)好之后再對(duì)當(dāng)前分支進(jìn)行恢復(fù)句葵。

git status #當(dāng)前分支下的內(nèi)容
git stash #對(duì)當(dāng)前分支進(jìn)行存儲(chǔ)
git status #當(dāng)對(duì)當(dāng)前分支進(jìn)行存儲(chǔ)之后旨别,發(fā)現(xiàn)當(dāng)前分支的status是空的

#對(duì)bug分支進(jìn)行修復(fù)
git checkout master
git checkout -b bug-issue
對(duì)demo.rb文件內(nèi)容進(jìn)行修改
git add demo.rb
git commit -m "bug commit"
git checkout master 
git merge --no-ff -m "merge bug commit" bug-issue
git status  #查看工作目錄是空的

git slash list #查看slash
git slash apply #恢復(fù)后洪碳,stash內(nèi)容并不刪除瞳腌,你需要用git stash drop來(lái)刪除
git stash apply stash@{0} #恢復(fù)指定的slash
git slash pop #恢復(fù)的同時(shí)把stash內(nèi)容也刪了
git slash list #恢復(fù)后查看slash的內(nèi)容也沒(méi)有了

3.5 Feature分支
如果是開(kāi)發(fā)新功能荚坞,最好是新建一個(gè)分支各淀,如果這個(gè)分支已經(jīng)被合并璃俗,那么刪除這個(gè)分支使用:

git branch -d feature

如果這個(gè)分支沒(méi)有被合并,刪除這個(gè)分支,需要用到下面的語(yǔ)句:

git branch -D feature

3.6 多人協(xié)作
從遠(yuǎn)程克隆倉(cāng)庫(kù)也是分多種情況,第一種情況是只有一個(gè)master分支的情況下:

git clone XX  #遠(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)名稱(chēng)是origin
git remote #origin  此代碼是查看遠(yuǎn)程庫(kù)的信息,遠(yuǎn)程庫(kù)的默認(rèn)信息是origin
git remote -v  #使用-v查看遠(yuǎn)程庫(kù)更為詳細(xì)的信息
  origin git@github.com:michaelliao/learngit.git (fetch)
  origin git@github.com:michaelliao/learngit.git (push)
git push origin master #推送master分支
git push origin dev  #推送dev分支

第二種情況是當(dāng)遠(yuǎn)程庫(kù)存在多個(gè)分支時(shí)候,使用git clone語(yǔ)句克隆代碼,使用git branch語(yǔ)句只能查看master分支,為了顯示其他分支塔淤,需要?jiǎng)?chuàng)建遠(yuǎn)程的origin的dev分支到本地:

git clone XX
git branch #master
#實(shí)際上被克隆的代碼庫(kù)有很多分支,而這里只能顯示master分支
git checkout -b dev origin/dev
#使用上面的語(yǔ)句在本地建立dev分支露泊,和遠(yuǎn)程庫(kù)的dev分支對(duì)象起來(lái),同時(shí)獲得遠(yuǎn)程庫(kù)的分支信息代碼
#在dev分支上修改代碼
git commit -m "add the dev" 
git push origin dev #將代碼推送到遠(yuǎn)程庫(kù)dev分支中

第三情況是處理沖突:兩個(gè)人同時(shí)寫(xiě)作同一個(gè)代碼庫(kù)川蒙,比如在feature分支上面,一個(gè)人已經(jīng)作為修改,另外一個(gè)人在此人修改之前已經(jīng)git clone到本地悬垃,并且在feature同一個(gè)地方做了修改,因此會(huì)出現(xiàn)conflict靖榕。

#已經(jīng)有其他用戶(hù)在feature分支上面建立test.rb文件
#下面的代碼都是在本地的feature分支上進(jìn)行
git add test.rb
git commit -m "add the test.rb"
git push origin feature

上面的代碼出現(xiàn)錯(cuò)誤星压,根據(jù)提示可以知道劲绪,是因?yàn)槌霈F(xiàn)了代碼沖突颤枪,根據(jù)提示使用git pull艘蹋。

git pull #如果存在no tracking information,說(shuō)明本地分支和遠(yuǎn)程分支之間的鏈接關(guān)系沒(méi)有建立
git branch --set-upstream-to=origin/feature feature #設(shè)置feature和origin/feature的鏈接
git pull #出現(xiàn)沖突及沖突提示
#沖突解決好之后重新提交
git commit -m "conflict commit"
git push origin feature

4.標(biāo)簽管理
標(biāo)簽是版本庫(kù)的一個(gè)快照手报,若給版本庫(kù)打了一個(gè)標(biāo)簽凶掰,就相當(dāng)于在某個(gè)時(shí)候獲取一個(gè)特定時(shí)間的版本庫(kù),標(biāo)簽和分支不同冒萄,分支可以移動(dòng)逻住,標(biāo)簽不能移動(dòng)银受。
4.1 創(chuàng)建標(biāo)簽

git checkout master #切換到最新的master分支上
git tag v1.0 #給最新的分支貼上標(biāo)簽
git tag #查看所有標(biāo)簽
默認(rèn)情況下標(biāo)簽是打在最新的提交的commit上锣吼,如果需要打在之前提交的commit上隧膘,需要如下的語(yǔ)句
git log --pretty=oneline --abbrev-commit  #顯示commit id log
git tag v0.9 1234234  #其中1234234是commit id值艇肴,即將標(biāo)簽打在這個(gè)commit id中娘侍。
git show  v1.0 #查看某個(gè)版本的標(biāo)簽
git tag -a v0.1 -m "version 0.1 released" 3628164
#創(chuàng)建帶有說(shuō)明的標(biāo)簽枫浙,用-a指定標(biāo)簽名是嗜,-m指定說(shuō)明文字

4.2 操作標(biāo)簽

git tag -d v0.9  #刪除標(biāo)簽
git push origin v0.9 #因?yàn)闃?biāo)簽都是在本地的掂僵,此代碼是推送標(biāo)簽到遠(yuǎn)程
git push origin --tags #一次性推送全部尚未推送到遠(yuǎn)程的本地標(biāo)簽

#如果標(biāo)簽已經(jīng)推送到遠(yuǎn)程舱卡,要?jiǎng)h除遠(yuǎn)程標(biāo)簽就麻煩一點(diǎn)赵辕,先從本地刪除:
#然后,從遠(yuǎn)程刪除概龄。刪除命令也是push
git tag -d v0.9
git push origin :refs/tags/v0.9

5.自定義Git

git config --global color.ui true #設(shè)置顏色

5.1 忽略特殊文件
在工作區(qū)建立 .gitignore
ruby的示例文件可以在這里找到

5.2 配置別名
配置別名就是在將Git的命令用其他名字來(lái)表示还惠,示例代碼如下所示:

git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch
#--global參數(shù)是全局參數(shù),也就是這些命令在這臺(tái)電腦的所有Git倉(cāng)庫(kù)下都有用私杜。

每個(gè)倉(cāng)庫(kù)的Git配置文件都放在.git/config文件中蚕键,其中別名就在[alias]后面,要?jiǎng)h除別名衰粹,直接把對(duì)應(yīng)的行刪掉即可锣光。

[core] 
  repositoryformatversion = 0 
  filemode = true bare = false 
  logallrefupdates = true 
  ignorecase = true 
  precomposeunicode = true
[remote "origin"]
  url = git@github.com:michaelliao/learngit.git 
  fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"] 
  remote = origin 
  merge = refs/heads/master
[alias] 
  last = log -1

而當(dāng)前用戶(hù)的Git配置文件放在用戶(hù)主目錄下的一個(gè)隱藏文件.gitconfig
中:

[alias] 
  co = checkout 
  ci = commit 
  br = branch 
  st = status
[user]
  name = Your Name 
  email = your@email.com

5.3 搭建Git服務(wù)器
見(jiàn)這里

6.擴(kuò)展
6.1 rebase的使用
相關(guān)文檔
在master分支上簡(jiǎn)歷mywork分支,示意圖如下所示:

Paste_Image.png

在mywork分支上提交兩次代碼寄猩,同時(shí)其他用戶(hù)在master分支上提交了兩次代碼嫉晶,示意圖如下所示:

Paste_Image.png

在這里,你可以用"pull"命令把"origin"分支上的修改拉下來(lái)并且和你的修改合并田篇; 結(jié)果看起來(lái)就像一個(gè)新的"合并的提交",示意圖如下所示:

Paste_Image.png

但是椎镣,如果你想讓"mywork"分支歷史看起來(lái)像沒(méi)有經(jīng)過(guò)任何合并一樣,可以用git rebase兽赁,代碼如下所示:

git checkout mywork
git rebase origin

這些命令會(huì)把你的"mywork"分支里的每個(gè)提交(commit)取消掉状答,并且把它們臨時(shí) 保存為補(bǔ)丁(patch)(這些補(bǔ)丁放到".git/rebase"目錄中),然后把"mywork"分支更新 到最新的"origin"分支,最后把保存的這些補(bǔ)丁應(yīng)用到"mywork"分支上刀崖。

Paste_Image.png

當(dāng)'mywork'分支更新之后惊科,它會(huì)指向這些新創(chuàng)建的提交(commit),而那些老的提交會(huì)被丟棄。 如果運(yùn)行垃圾收集命令(pruning garbage collection), 這些被丟棄的提交就會(huì)刪除亮钦。

Paste_Image.png

現(xiàn)在我們可以看一下用合并(merge)和用rebase所產(chǎn)生的歷史的區(qū)別:

Paste_Image.png

6.2 修改最近一次的提交 commit --amend
該功能會(huì)修改最近一次的提交馆截,使用commit --amend
比如最開(kāi)始是這樣的:

git log

需要對(duì)添加add的講解進(jìn)行修改,使用下面代碼:

git add .
git commit --amend

上面的代碼會(huì)跳出一個(gè)編輯頁(yè)面蜂莉,可以修改添加add的講解的值蜡娶,修改為添加add和commit的講解,并且進(jìn)行保存映穗,使用git log操作窖张,可以得到如下的結(jié)果:

git log

6.3 取消最新一次的提交 git revert head
下面的代碼可以取消最近一次的提交

git revert HEAD

原本最初的提交branch如下所示:

Paste_Image.png

執(zhí)行g(shù)it revert HEAD之后,變?yōu)槿缦碌慕Y(jié)果

Paste_Image.png

就是說(shuō)針對(duì)“添加pull的講解”所變化的內(nèi)容消失了蚁滋。

6.4 使用reset來(lái)刪除前面的幾個(gè)提交
代碼如下所示:

git reset --hard HEAD~~ #這是刪除最前面的兩個(gè)提交
git reset --hard HEAD~ #這是刪除了最前面的一個(gè)提交
git reset --hard ORGI_HEAD #如果之前的reset出錯(cuò)了宿接,該代碼會(huì)返回最開(kāi)始進(jìn)行reset的位置

圖片演示如下:

before reset
after reset

6.5 **使用cherry-pick將其他分支中的內(nèi)容添加到主分支中 **
如下圖所示:

Paste_Image.png

添加commit的講解添加到master分支中赘淮,代碼如下所示:

git checkout master 
git cherry-pick 99daed2

#下面的提示代碼是正常現(xiàn)象睦霎,說(shuō)明提交成功
error: could not apply 99daed2... commit
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

#但是如果出現(xiàn)沖突的話(huà)拥知,需要添加如下的進(jìn)行如下的操作
git add filename
git commit 

6.6 **使用rebase -i 匯合提交 **
這是做的事情是講master上面最近的兩次進(jìn)行合并,匯合為一次提交碎赢,使用的代碼如下:

git rebase -i HEAD~~

#上面的代碼執(zhí)行之后,會(huì)有下面的代碼界面出現(xiàn)速梗,將第二行的pick改為squash

pick 9a54fd4 添加commit的說(shuō)明
pick 0d4a808 添加pull的說(shuō)明

# Rebase 326fc9f..0d4a808 onto d286baa
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.


#編輯保存退出肮塞,然后出現(xiàn)了編輯界面,編輯里面的值姻锁,該值將成為合并commit的說(shuō)明

示意圖如下所示:

Paste_Image.png

就是將添加commit的講解添加pull的講解進(jìn)行合并枕赵,成為一個(gè)commit。示意圖如下所示:

Paste_Image.png

6.7 用rebase -i 修改提交
在這里修改添加commit的講解

Paste_Image.png

代碼修改如下所示:

git rebase -i HEAD~~

將第一行的pick改為eidt,保存之后退出
pick 9a54fd4 添加commit的說(shuō)明
pick 0d4a808 添加pull的說(shuō)明

# Rebase 326fc9f..0d4a808 onto d286baa
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

#打開(kāi)sample.txt位隶,適當(dāng)?shù)匦薷摹癱ommit的講解”部分
git add sample.txt
git commit --amend

#已經(jīng)commit拷窜,但是rebase操作還沒(méi)結(jié)束。若要通知這個(gè)提交的操作已經(jīng)結(jié)束涧黄,請(qǐng)指定 --continue選項(xiàng)執(zhí)行rebase篮昧。
git rebase --continue

6.8 把分支內(nèi)容合并成一個(gè)提交,并導(dǎo)入到master分支
示意圖如下所示:

Paste_Image.png

把下面的一個(gè)分支合并成一個(gè)提交笋妥,并導(dǎo)入的master分支中懊昨,具體的代碼如下所示:

git checkout master
git merge --squash issue1
#出現(xiàn)了下面的提示,說(shuō)明提交成功
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested
#出現(xiàn)下面的提示春宣,則說(shuō)明提交失敗酵颁,出現(xiàn)了沖突
Auto-merging sample.txt
CONFLICT (content): Merge conflict in sample.txt
Squash commit -- not updating HEAD
Automatic merge failed; 
fix conflicts and then commit the result.

#說(shuō)明發(fā)生了沖突,修改之后進(jìn)行提交
git add sample.txt
git commit

6.9使用二分法查找bug
二分法的原理
代碼演示如下:

git bisect start master commit_id #master是bad點(diǎn)月帝,commit_id是最開(kāi)始提交點(diǎn)
git bisect run make test  #進(jìn)行了自動(dòng)化測(cè)試躏惋,此代碼可以測(cè)試出錯(cuò)誤點(diǎn)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市嚷辅,隨后出現(xiàn)的幾起案子簿姨,更是在濱河造成了極大的恐慌,老刑警劉巖潦蝇,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件款熬,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡攘乒,警方通過(guò)查閱死者的電腦和手機(jī)贤牛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)则酝,“玉大人殉簸,你說(shuō)我怎么就攤上這事闰集。” “怎么了般卑?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵武鲁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蝠检,道長(zhǎng)沐鼠,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任叹谁,我火速辦了婚禮饲梭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘焰檩。我一直安慰自己憔涉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布析苫。 她就那樣靜靜地躺著兜叨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪衩侥。 梳的紋絲不亂的頭發(fā)上国旷,一...
    開(kāi)封第一講書(shū)人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音茫死,去河邊找鬼议街。 笑死,一個(gè)胖子當(dāng)著我的面吹牛璧榄,可吹牛的內(nèi)容都是我干的特漩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼骨杂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼涂身!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起搓蚪,我...
    開(kāi)封第一講書(shū)人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蛤售,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后妒潭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體悴能,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年雳灾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了漠酿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谎亩,死狀恐怖炒嘲,靈堂內(nèi)的尸體忽然破棺而出宇姚,到底是詐尸還是另有隱情,我是刑警寧澤夫凸,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布浑劳,位于F島的核電站,受9級(jí)特大地震影響夭拌,放射性物質(zhì)發(fā)生泄漏魔熏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一鸽扁、第九天 我趴在偏房一處隱蔽的房頂上張望道逗。 院中可真熱鬧,春花似錦献烦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至此蜈,卻和暖如春即横,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背裆赵。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工东囚, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人战授。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓页藻,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親植兰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子份帐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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