Git常用命令編輯版

$ mkdir learngit                               //創(chuàng)建目錄
$ cd learngit                                   //進(jìn)入當(dāng)前目錄
$ pwd                                              //顯示當(dāng)前目錄
$ git   init                                         //將本地這個(gè)倉(cāng)庫(kù)變成git可以管理的倉(cāng)庫(kù)
$ ls  -ah                                          //查看隱藏的git目錄
$ git  add  file                                 //將當(dāng)前文件(有后綴)加到git緩存區(qū)    
$ git commit -m "wrote a readme file"           //提交到本地倉(cāng)庫(kù)   -m——"本次提交的說明"
$ git  status                                    //查看當(dāng)前倉(cāng)庫(kù)的狀態(tài) 
$ git  diff    fileName(加后綴的)    //查看上一次的修改     * 修改之后和提交新文件是一樣的兩步
$ git diff HEAD -- fileName              //可以查看工作區(qū)和版本庫(kù)里面最新版本的區(qū)別
$ git  log                                          //查看當(dāng)前之前的歷史提交記錄(可查commit_id(版本號(hào)))
$ git reflog                                      //記錄你的每一次命令  從這里可以找到之前的commit_id(版本號(hào))
$ git log --pretty=oneline                 //簡(jiǎn)單版的歷史提交記錄
$ git reset --hard HEAD^                //回退到當(dāng)前版本的上一個(gè)版本
$ git reset  --hard 1094a(版本號(hào)) //回退到指定的版本
$ cat  fileName                               //直接輸出文件中的內(nèi)容
$ git reflog                                      //記錄你的每一次命令  從這里可以找到之前的commit_id(版本號(hào))
$ git checkout   --   fileName        //可以丟棄工作區(qū)的修改
$ git reset HEAD fileName(eg:readme.txt)      //將暫存區(qū)的file撤銷掉(unstage),重新放回工作區(qū)
$ rm     test.txt                            //從工作區(qū)刪除指定文件
$ git rm test.txt              //從版本庫(kù)中刪除該文件婆芦,提交之后完成
$ git checkout  --  test.txt            //用版本庫(kù)里的版本替換工作區(qū)的版本
$ ssh-keygen -t rsa -C "youremail@example.com"                          //創(chuàng)建SSH Key
$ git remote add origin git@github.com:michaelliao/learngit.git        //關(guān)聯(lián)本地庫(kù)與遠(yuǎn)程庫(kù)  learngit是遠(yuǎn)程庫(kù)的name
$ git push -u origin master           //本地庫(kù)的所有內(nèi)容推送到遠(yuǎn)程庫(kù)上
$ git push origin master               //本地當(dāng)前分支的最新修改推送至GitHub
$ git clone git@github.com:michaelliao/gitskills.git            //從遠(yuǎn)程庫(kù)clone一個(gè)分支
$ git checkout -b dev              //創(chuàng)建`dev`分支仇参,然后切換到`dev`分支
$ git switch -c dev                   //創(chuàng)建`dev`分支啡专,然后切換到`dev`分支
$ git branch dev                     //創(chuàng)建`dev`分支
git branch <name>                //創(chuàng)建分支
$ git checkout dev                  //切換到`dev`分支
$ git switch master                   //切換到`master`分支
$ git branch                            //查看當(dāng)前分支
$ git checkout master            //切換回`master`分支
$ git merge dev                     //把`dev`分支的工作成果合并到`master`分支//當(dāng)前分支是master
$ git   branch   -d    dev                                             //刪除`dev`分支
git log --graph                                                                     //可以看到分支合并圖寂祥。
$ git log --graph --pretty=oneline --abbrev-commit            //可以看到分支合并圖做修。
$ git merge --no-ff -m "merge with no-ff" dev                     //準(zhǔn)備合并dev分支   請(qǐng)注意--no-ff參數(shù),表示禁用Fast forward
$ git log --graph --pretty=oneline --abbrev-commit            //查看分支歷史:
$ git stash                                           //保存當(dāng)前工作現(xiàn)場(chǎng)
$ git stash list                                     //查看工作現(xiàn)場(chǎng)
$ git cherry-pick 4c805e2                  //復(fù)制一個(gè)特定的提交到當(dāng)前分支4c805e2是提交的版本號(hào)
$ git branch -D feature-vulcan          //強(qiáng)行刪除分支 feature-vulcan 
git checkout -b branch-name origin/branch-name                          //在本地創(chuàng)建和遠(yuǎn)程分支對(duì)應(yīng)的分支
branch --set-upstream-to <branch-name> origin/<branch-name>  //本地分支和遠(yuǎn)程分支的鏈接關(guān)系創(chuàng)建
 git remote -v                                   //查看遠(yuǎn)程庫(kù)信息


詳細(xì)use:
1:常見命令
$ mkdir learngit                            //創(chuàng)建目錄
$ cd learngit                                 //進(jìn)入當(dāng)前目錄
$ pwd                                           //顯示當(dāng)前目錄
/Users/michael/learngit


2:初始化本地庫(kù)及提交命令
$ git   init                                       //將本地這個(gè)倉(cāng)庫(kù)變成git可以管理的倉(cāng)庫(kù)
Initialized empty Git repository in /Users/michael/learngit/.git/
git    ls  -ah                                  //查看隱藏的git目錄

**所有的版本控制系統(tǒng)赠制,其實(shí)只能跟蹤文本文件的改動(dòng)赶袄,比如TXT文件,網(wǎng)頁(yè)猴娩,所有的程序代碼等等冗尤,Git也不例外。而圖片胀溺、視頻這些二進(jìn)制文件裂七,雖然也能由版本控制系統(tǒng)管理,但沒法跟蹤文件的變化仓坞,只能把二進(jìn)制文件每次改動(dòng)串起來(lái)背零,也就是只知道圖片從100KB改成了120KB,但到底改了啥无埃,版本控制系統(tǒng)不知道徙瓶,也沒法知道。**

把一個(gè)文件放到Git本地倉(cāng)庫(kù)只需要兩步嫉称。
1:git  add  fileName                                       //將當(dāng)前文件加到git緩存區(qū)    
&&注意侦镇,可反復(fù)多次使用,添加多個(gè)文件织阅;
2:git commit -m "wrote a readme file"           //提交到本地倉(cāng)庫(kù)   -m——"本次提交的說明"
[master (root-commit) eaadf4e] wrote a readme file
 1 file changed, 2 insertions(+)
 create mode 100644 readme.txt

git  status                             //查看當(dāng)前倉(cāng)庫(kù)的狀態(tài) 
git  diff    fileName               //查看上一次的修改            修改之后和提交新文件是一樣的兩步
git diff HEAD -- fileName    //可以查看工作區(qū)和版本庫(kù)里面最新版本的區(qū)別
git  log                                 //查看當(dāng)前之前的歷史提交記錄
$ git log --pretty=oneline     //簡(jiǎn)單版的歷史提交記錄
1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master) append GPL
e475afc93c209a690c39c13a46716e8fa000c366 (16進(jìn)制的commit id(版本號(hào)))   add distributed
eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0   (16進(jìn)制的commit id(版本號(hào)))   wrote a readme 

  
3:版本回退命令
HEAD^                                           //當(dāng)前版本的上一個(gè)版本
HEAD^^                                         //當(dāng)前版本的上上一個(gè)版本  以次類推
HEAD~n                                        //當(dāng)前版本往上n個(gè)版本
$ git reset --hard HEAD^               //回退到當(dāng)前版本的上一個(gè)版本
HEAD is now at e475afc add distributed
$ git reset  --hard 1094a(版本號(hào)) //回退到指定的版本
$ cat  fileName                              //直接輸出文件中的內(nèi)容
git reflog                                        //記錄你的每一次命令  從這里可以找到之前的commit_id(版本號(hào))


4:git原理
工作區(qū)(Working Directory)
       就是你在電腦里能看到的目錄壳繁,比如我的learngit文件夾就是一個(gè)工作區(qū)。
 版本庫(kù)(Repository)
       工作區(qū)有一個(gè)隱藏目錄`.git`,這個(gè)不算工作區(qū)闹炉,而是Git的版本庫(kù)蒿赢。
Git的版本庫(kù)里存了很多東西,其中最重要的就是稱為stage(或者叫index)的暫存區(qū)渣触,還有Git為我們自動(dòng)創(chuàng)建的第一個(gè)分支`master`羡棵,以及指向`master`的一個(gè)指針叫`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分支上提交更改语御。
為什么Git比其他版本控制系統(tǒng)設(shè)計(jì)得優(yōu)秀峻贮,因?yàn)镚it跟蹤并管理的是修改,而非文件应闯。


5:丟棄修改
$ git checkout -- fileName        //可以丟棄工作區(qū)的修改
命令git checkout -- readme.txt意思就是,把readme.txt文件在工作區(qū)的修改全部撤銷碉纺,這里有兩種情況:
       一種是readme.txt自修改后還沒有被放到暫存區(qū)船万,現(xiàn)在,撤銷修改就回到和之前版本庫(kù)一模一樣的狀態(tài)骨田;
       一種是readme.txt已經(jīng)添加到暫存區(qū)后耿导,又作了修改,現(xiàn)在态贤,撤銷修改就回到添加到暫存區(qū)后的狀態(tài)舱呻。
        總之,就是讓這個(gè)文件回到最近一次(上一次)git commit或git add時(shí)的狀態(tài)悠汽。
        Git同樣告訴我們箱吕,用命令git reset HEAD <file>可以把暫存區(qū)的修改撤銷掉(unstage),重新放回工作區(qū):
$ git reset HEAD fileName(eg:readme.txt)      //暫存區(qū)的修改撤銷掉(unstage),重新放回工作區(qū)
Unstaged changes after reset:
M   readme.txt
git reset命令既可以回退版本柿冲,也可以把暫存區(qū)的修改回退到工作區(qū)茬高。當(dāng)我們用HEAD時(shí),表示最新的版本假抄。


6:刪除命令
         在Git中怎栽,刪除也是一個(gè)修改操作丽猬,一般情況下,你通常直接在文件管理器中把沒用的文件刪了婚瓜,或者用rm命令刪了:
$ rm     test.txt                            //從工作區(qū)刪除指定文件
這個(gè)時(shí)候宝鼓,Git知道你刪除了文件刑棵,因此巴刻,工作區(qū)和版本庫(kù)就不一致了,git status命令會(huì)立刻告訴你哪些文件被刪除了蛉签。
現(xiàn)在你有兩個(gè)選擇胡陪,一是確實(shí)要從版本庫(kù)中刪除該文件,那就用命令git rm刪掉碍舍,并且git commit:
$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master d46f35e] remove test.txt
 1 file changed, 1 deletion(-)
 delete mode 100644 test.txt
 小提示:先手動(dòng)刪除文件柠座,然后使用git rm <file>和git add<file>效果是一樣的。

另一種情況是刪錯(cuò)了片橡,因?yàn)榘姹編?kù)里還有呢妈经,所以可以很輕松地把誤刪的文件恢復(fù)到最新版本:
$ git checkout -- test.txt            //用版本庫(kù)里的版本替換工作區(qū)的版本
git checkout其實(shí)是用版本庫(kù)里的版本替換工作區(qū)的版本,無(wú)論工作區(qū)是修改還是刪除捧书,都可以“一鍵還原”吹泡。
 注意:從來(lái)沒有被添加到版本庫(kù)就被刪除的文件,是無(wú)法恢復(fù)的经瓷!


7:本地庫(kù)與遠(yuǎn)程倉(cāng)庫(kù)關(guān)聯(lián)的命令
由于你的本地Git倉(cāng)庫(kù)和GitHub倉(cāng)庫(kù)之間的傳輸是通過SSH加密的爆哑,所以,需要一點(diǎn)設(shè)置:
       第1步:創(chuàng)建SSH Key舆吮。在用戶主目錄下揭朝,看看有沒有.ssh目錄,如果有色冀,再看看這個(gè)目錄下有沒有id_rsa和id_rsa.pub這兩個(gè)文件潭袱,如果已經(jīng)有了,可直接跳到下一步锋恬。如果沒有敌卓,打開Shell(Windows下打開Git Bash),創(chuàng)建SSH Key:
$ ssh-keygen -t rsa -C "youremail@example.com"                     //創(chuàng)建SSH Key
你需要把 郵件地址 換成你自己的郵件地址伶氢,然后一路回車趟径,使用默認(rèn)值即可,由于這個(gè)Key也不是用于軍事目的癣防,所以也無(wú)需設(shè)置密碼蜗巧。
如果一切順利的話,可以在用戶主目錄里找到.ssh目錄蕾盯,里面有id_rsa和id_rsa.pub兩個(gè)文件幕屹,這兩個(gè)就是SSH Key的秘鑰對(duì),id_rsa是私鑰,不能泄露出去望拖,id_rsa.pub是公鑰渺尘,可以放心地告訴任何人。
        第2步:登陸GitHub说敏,打開“Account settings”鸥跟,“SSH Keys”頁(yè)面:
然后,點(diǎn)“Add SSH Key”盔沫,填上任意Title医咨,在Key文本框里粘貼id_rsa.pub文件的內(nèi)容:
點(diǎn)“Add Key”,你就應(yīng)該看到已經(jīng)添加的Key:
為什么GitHub需要SSH Key呢架诞?因?yàn)镚itHub需要識(shí)別出你推送的提交確實(shí)是你推送的拟淮,而不是別人冒充的,而Git支持SSH協(xié)議谴忧,所以很泊,GitHub只要知道了你的公鑰,就可以確認(rèn)只有你自己才能推送沾谓。
當(dāng)然委造,GitHub允許你添加多個(gè)Key。假定你有若干電腦争涌,你一會(huì)兒在公司提交,一會(huì)兒在家里提交辣恋,只要把每臺(tái)電腦的Key都添加到GitHub亮垫,就可以在每臺(tái)電腦上往GitHub推送了。
最后友情提示伟骨,在GitHub上免費(fèi)托管的Git倉(cāng)庫(kù)饮潦,任何人都可以看到喔(但只有你自己才能改)。所以携狭,不要把敏感信息放進(jìn)去继蜡。

如果你不想讓別人看到Git庫(kù),有兩個(gè)辦法逛腿,一個(gè)是交點(diǎn)保護(hù)費(fèi)稀并,讓GitHub把公開的倉(cāng)庫(kù)變成私有的,這樣別人就看不見了(不可讀更不可寫)单默。另一個(gè)辦法是自己動(dòng)手碘举,搭一個(gè)Git服務(wù)器,因?yàn)槭悄阕约旱腉it服務(wù)器搁廓,所以別人也是看不見的引颈。
現(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ù)既可以作為備份售滤,又可以讓其他人通過該倉(cāng)庫(kù)來(lái)協(xié)作罚拟,真是一舉多得。

首先趴泌,登陸GitHub舟舒,然后拉庶,在右上角找到“Create a new repo”按鈕嗜憔,創(chuàng)建一個(gè)新的倉(cāng)庫(kù):
現(xiàn)在,我們根據(jù)GitHub的提示氏仗,在本地的learngit倉(cāng)庫(kù)下運(yùn)行命令:

$ git remote add origin git@github.com:michaelliao/learngit.git        //關(guān)聯(lián)本地庫(kù)與遠(yuǎn)程庫(kù)
                                                                                                          //learngit是遠(yuǎn)程庫(kù)的name
請(qǐng)千萬(wàn)注意吉捶,把上面的michaelliao替換成你自己的GitHub賬戶名,否則皆尔,你在本地關(guān)聯(lián)的就是我的遠(yuǎn)程庫(kù)呐舔,關(guān)聯(liá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           //本地庫(kù)的所有內(nèi)容推送到遠(yuǎn)程庫(kù)上
把本地庫(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)化命令乳丰。
從現(xiàn)在起,只要本地作了提交镶蹋,就可以通過命令:
$ git push origin master               //本地master分支的最新修改推送至GitHub


SSH警告
當(dāng)你第一次使用Git的`clone`或者`push`命令連接GitHub時(shí)成艘,會(huì)得到一個(gè)警告:
The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)`
這是因?yàn)镚it使用SSH連接赏半,而SSH連接在第一次驗(yàn)證GitHub服務(wù)器的Key時(shí),需要你確認(rèn)GitHub的Key的指紋信息是否真的來(lái)自GitHub的服務(wù)器淆两,輸入`yes`回車即可断箫。
Git會(huì)輸出一個(gè)警告,告訴你已經(jīng)把GitHub的Key添加到本機(jī)的一個(gè)信任列表里了:
Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
這個(gè)警告只會(huì)出現(xiàn)一次秋冰,后面的操作就不會(huì)有任何警告了仲义。
如果你實(shí)在擔(dān)心有人冒充GitHub服務(wù)器,輸入`yes`前可以對(duì)照[GitHub的RSA Key的指紋信息](https://help.github.com/articles/what-are-github-s-ssh-key-fingerprints/)是否與SSH連接給出的一致剑勾。
現(xiàn)在埃撵,遠(yuǎn)程庫(kù)已經(jīng)準(zhǔn)備好了,下一步是用命令git clone克隆一個(gè)本地庫(kù):

$ git clone git@github.com:michaelliao/gitskills.git            //從遠(yuǎn)程庫(kù)clone一個(gè)分支
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.
注意把Git庫(kù)的地址換成你自己的虽另,然后進(jìn)入gitskills目錄看看暂刘,已經(jīng)有README.md文件了。
$ cd gitskills
$ ls
README.md
你也許還注意到捂刺,GitHub給出的地址不止一個(gè)谣拣,還可以用https://github.com/michaelliao/gitskills.git這樣的地址。實(shí)際上族展,Git支持多種協(xié)議森缠,默認(rèn)的git://使用ssh,但也可以使用https等其他協(xié)議仪缸。
使用https除了速度慢以外贵涵,還有個(gè)最大的麻煩是每次推送都必須輸入口令,但是在某些只開放http端口的公司內(nèi)部就無(wú)法使用ssh協(xié)議而只能用https恰画。
在版本回退里宾茂,你已經(jīng)知道,每次提交锣尉,Git都把它們串成一條時(shí)間線刻炒,這條時(shí)間線就是一個(gè)分支。截止到目前自沧,只有一條時(shí)間線坟奥,在Git里,這個(gè)分支叫主分支拇厢,即`master`分支爱谁。`HEAD`嚴(yán)格來(lái)說不是指向提交,而是指向`master`孝偎,`master`才是指向提交的访敌,所以,`HEAD`指向的就是當(dāng)前分支衣盾。
一開始的時(shí)候寺旺,`master`分支是一條線爷抓,Git用`master`指向最新的提交,再用`HEAD`指向`master`阻塑,就能確定當(dāng)前分支蓝撇,以及當(dāng)前分支的提交點(diǎn):
每次提交,`master`分支都會(huì)向前移動(dòng)一步陈莽,這樣渤昌,隨著你不斷提交,`master`分支的線也越來(lái)越長(zhǎng)走搁。
當(dāng)我們創(chuàng)建新的分支独柑,例如`dev`時(shí),Git新建了一個(gè)指針叫`dev`私植,指向`master`相同的提交忌栅,再把`HEAD`指向`dev`,就表示當(dāng)前分支在`dev`上:
你看兵琳,Git創(chuàng)建一個(gè)分支很快狂秘,因?yàn)槌嗽黾右粋€(gè)`dev`指針骇径,改改`HEAD`的指向躯肌,工作區(qū)的文件都沒有任何變化!
不過破衔,從現(xiàn)在開始清女,對(duì)工作區(qū)的修改和提交就是針對(duì)`dev`分支了,比如新提交一次后晰筛,`dev`指針往前移動(dòng)一步嫡丙,而`master`指針不變:

假如我們?cè)赻dev`上的工作完成了,就可以把`dev`合并到`master`上读第。Git怎么合并呢曙博?最簡(jiǎn)單的方法,就是直接把`master`指向`dev`的當(dāng)前提交怜瞒,就完成了合并:
所以Git合并分支也很快父泳!就改改指針,工作區(qū)內(nèi)容也不變吴汪!
合并完分支后惠窄,甚至可以刪除`dev`分支。刪除`dev`分支就是把`dev`指針給刪掉漾橙,刪掉后杆融,我們就剩下了一條`master`分支:
首先,我們創(chuàng)建`dev`分支霜运,然后切換到`dev`分支:
$ git checkout -b dev              //創(chuàng)建`dev`分支脾歇,然后切換到`dev`分支:
Switched to a new branch 'dev'
`git checkout`命令加上`-b`參數(shù)表示創(chuàng)建并切換蒋腮,相當(dāng)于以下兩條命令:
$ git branch dev                     //創(chuàng)建`dev`分支
$ git checkout dev                  //切換到`dev`分支
Switched to branch 'dev'
$ git branch                            //查看當(dāng)前分支
* dev
  master
`git branch`命令會(huì)列出所有分支,當(dāng)前分支前面會(huì)標(biāo)一個(gè)`*`號(hào)藕各。
然后徽惋,我們就可以在`dev`分支上正常提交,比如對(duì)`readme.txt`做個(gè)修改座韵,加上一行:
Creating a new branch is quick.
然后提交:
$ git add readme.txt    
$ git commit -m "branch test"
[dev b17d20e] branch test
 1 file changed, 1 insertion(+)
現(xiàn)在险绘,`dev`分支的工作完成,我們就可以切換回`master`分支:
$ git checkout master                     //切換回`master`分支
Switched to branch 'master'
切換回`master`分支后誉碴,再查看一個(gè)`readme.txt`文件宦棺,剛才添加的內(nèi)容不見了!因?yàn)槟莻€(gè)提交是在`dev`分支上黔帕,而`master`分支此刻的提交點(diǎn)并沒有變:
現(xiàn)在代咸,我們把`dev`分支的工作成果合并到`master`分支上:
$ git merge dev                           //把`dev`分支的工作成果合并到`master`分支//當(dāng)前分支是master
Updating d46f35e..b17d20e
Fast-forward
 readme.txt | 1 +
 1 file changed, 1 insertion(+)
`git merge`命令用于合并指定分支到當(dāng)前分支。合并后成黄,再查看`readme.txt`的內(nèi)容呐芥,就可以看到,和`dev`分支的最新提交是完全一樣的奋岁。
注意到上面的`Fast-forward`信息思瘟,Git告訴我們,這次合并是“快進(jìn)模式”闻伶,也就是直接把`master`指向`dev`的當(dāng)前提交忆首,所以合并速度非潮郏快肄程。
當(dāng)然贯钩,也不是每次合并都能`Fast-forward`,我們后面會(huì)講其他方式的合并畜份。
合并完成后诞帐,就可以放心地刪除`dev`分支了:
$ git   branch   -d    dev                                             //刪除`dev`分支
Deleted branch dev (was b17d20e).
刪除后,查看`branch`爆雹,就只剩下`master`分支了:
$ git branch
* master
因?yàn)閯?chuàng)建停蕉、合并和刪除分支非常快顶别,所以Git鼓勵(lì)你使用分支完成某個(gè)任務(wù)谷徙,合并后再刪掉分支,這和直接在`master`分支上工作效果是一樣的驯绎,但過程更安全完慧。


### switch
我們注意到切換分支使用`git checkout <branch>`,而前面講過的撤銷修改則是`git checkout -- <file>`剩失,同一個(gè)命令屈尼,有兩種作用册着,確實(shí)有點(diǎn)令人迷惑。
實(shí)際上脾歧,切換分支這個(gè)動(dòng)作甲捏,用`switch`更科學(xué)。因此鞭执,最新版本的Git提供了新的`git switch`命令來(lái)切換分支:
創(chuàng)建并切換到新的`dev`分支司顿,可以使用: 
$ git switch -c dev
直接切換到已有的`master`分支,可以使用:
$ git switch master
使用新的`git switch`命令兄纺,比`git checkout`要更容易理解大溜。
小結(jié)
Git鼓勵(lì)大量使用分支:
查看分支:git branch
創(chuàng)建分支:git branch <name>
切換分支:git checkout <name>或者git switch <name>
創(chuàng)建+切換分支:git checkout -b <name>或者git switch -c <name>
合并某分支到當(dāng)前分支:git merge <name>
刪除分支:git branch -d <name>
git log --graph                                                                          //可以看到分支合并圖。
$ git log --graph --pretty=oneline --abbrev-commit                  //可以看到分支合并圖估脆。
通常钦奋,合并分支時(shí),如果可能疙赠,Git會(huì)用Fast forward模式付材,但這種模式下,刪除分支后圃阳,會(huì)丟掉分支信息厌衔。
如果要強(qiáng)制禁用Fast forward模式,Git就會(huì)在merge時(shí)生成一個(gè)新的commit限佩,這樣葵诈,從分支歷史上就可以看出分支信息。
$ git merge --no-ff -m "merge with no-ff" dev                     //準(zhǔn)備合并dev分支
                                                                                           //請(qǐng)注意--no-ff參數(shù)祟同,表示禁用Fast forward
合并后,我們用git log看看分支歷史:
$ git log --graph --pretty=oneline --abbrev-commit            //查看分支歷史:
因?yàn)楸敬魏喜⒁獎(jiǎng)?chuàng)建一個(gè)新的commit理疙,所以加上-m參數(shù)晕城,把commit描述寫進(jìn)去。

修復(fù)bug時(shí)窖贤,我們會(huì)通過創(chuàng)建新的bug分支進(jìn)行修復(fù)砖顷,然后合并,最后刪除赃梧;
并不是你不想提交滤蝠,而是工作只進(jìn)行到一半,還沒法提交授嘀,預(yù)計(jì)完成還需1天時(shí)間物咳。但是,必須在兩個(gè)小時(shí)內(nèi)修復(fù)該bug蹄皱,怎么辦览闰?
幸好芯肤,Git還提供了一個(gè)stash功能,可以把當(dāng)前工作現(xiàn)場(chǎng)“儲(chǔ)藏”起來(lái)压鉴,等以后恢復(fù)現(xiàn)場(chǎng)后繼續(xù)工作:
$ git stash                                           //保存當(dāng)前工作現(xiàn)場(chǎng)
Saved working directory and index state WIP on dev: f52c633 add merge
回到現(xiàn)場(chǎng):工作區(qū)是干凈的崖咨,剛才的工作現(xiàn)場(chǎng)存到哪去了?用git stash list命令看看:
$ git stash list                                     //查看工作現(xiàn)場(chǎng)
stash@{0}: WIP on dev: f52c633 add merge
工作現(xiàn)場(chǎng)還在油吭,Git把stash內(nèi)容存在某個(gè)地方了击蹲,但是需要恢復(fù)一下,有兩個(gè)辦法:
        一是用git stash apply恢復(fù)婉宰,但是恢復(fù)后际邻,stash內(nèi)容并不刪除,你需要用git stash drop來(lái)刪除芍阎;
        另一種方式是用git stash pop世曾,恢復(fù)的同時(shí)把stash內(nèi)容也刪了:
$ git stash pop                                   //恢復(fù)的同時(shí)把stash內(nèi)容也刪了
你也可以多次stash,恢復(fù)的時(shí)候谴咸,先用git stash list查看轮听,然后恢復(fù)指定的stash,用命令:
$ git stash apply stash@{0}                //恢復(fù)指定的stash
在master分支上修復(fù)的bug岭佳,想要合并到當(dāng)前dev分支血巍,可以用git cherry-pick <commit>命令,把bug提交的修改“復(fù)制”到當(dāng)前分支珊随,避免重復(fù)勞動(dòng)述寡。
為了方便操作,Git專門提供了一個(gè)cherry-pick命令叶洞,讓我們能復(fù)制一個(gè)特定的提交到當(dāng)前分支:
$ git branch
* dev
  master
$ git cherry-pick 4c805e2               //復(fù)制一個(gè)特定的提交到當(dāng)前分支
[master 1d4b803] fix bug 101
 1 file changed, 1 insertion(+), 1 deletion(-)
4c805e2是上次提交的版本號(hào):如下
$ git add readme.txt 
$ git commit -m "fix bug 101"
[issue-101 4c805e2] fix bug 101
 1 file changed, 1 insertion(+), 1 deletion(-)

刪除未被合并的分支
$ git branch -d feature-vulcan
error: The branch 'feature-vulcan' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature-vulcan'.
銷毀失敗鲫凶。Git友情提醒,feature-vulcan分支還沒有被合并衩辟,如果刪除螟炫,將丟失掉修改,如果要強(qiáng)行刪除艺晴,需要使用大寫的-D參數(shù)昼钻。。
現(xiàn)在我們強(qiáng)行刪除:
$ git branch -D feature-vulcan             //強(qiáng)行刪除分支 feature-vulcan 
Deleted branch feature-vulcan (was 287773e).
終于刪除成功封寞!

因此然评,多人協(xié)作的工作模式通常是這樣:
首先,可以試圖用git push origin <branch-name>推送自己的修改狈究;
如果推送失敗碗淌,則因?yàn)檫h(yuǎn)程分支比你的本地更新,需要先用git pull試圖合并;
如果合并有沖突贯莺,則解決沖突风喇,并在本地提交;
沒有沖突或者解決掉沖突后缕探,再用git push origin <branch-name>推送就能成功魂莫!
如果git pull提示no tracking information,則說明本地分支和遠(yuǎn)程分支的鏈接關(guān)系沒有創(chuàng)建爹耗,用命令git 

branch --set-upstream-to <branch-name> origin/<branch-name>耙考。  
 //本地分支和遠(yuǎn)程分支的鏈接關(guān)系創(chuàng)建

查看遠(yuǎn)程庫(kù)信息,使用git remote -v潭兽;
本地新建的分支如果不推送到遠(yuǎn)程倦始,對(duì)其他人就是不可見的;
從本地推送分支山卦,使用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怨规,如果有沖突,要先處理沖突锡足。 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末波丰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子舱污,更是在濱河造成了極大的恐慌呀舔,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扩灯,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡霜瘪,警方通過查閱死者的電腦和手機(jī)珠插,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)颖对,“玉大人捻撑,你說我怎么就攤上這事。” “怎么了顾患?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵番捂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我江解,道長(zhǎng)设预,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任犁河,我火速辦了婚禮鳖枕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘桨螺。我一直安慰自己宾符,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布灭翔。 她就那樣靜靜地躺著魏烫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肝箱。 梳的紋絲不亂的頭發(fā)上哄褒,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天狭园,我揣著相機(jī)與錄音,去河邊找鬼唱矛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛绎谦,可吹牛的內(nèi)容都是我干的管闷。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼窃肠,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼包个!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起冤留,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤碧囊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后纤怒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糯而,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年泊窘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了熄驼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片像寒。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖瓜贾,靈堂內(nèi)的尸體忽然破棺而出诺祸,到底是詐尸還是另有隱情,我是刑警寧澤祭芦,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布筷笨,位于F島的核電站,受9級(jí)特大地震影響实束,放射性物質(zhì)發(fā)生泄漏奥秆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一咸灿、第九天 我趴在偏房一處隱蔽的房頂上張望构订。 院中可真熱鬧,春花似錦避矢、人聲如沸悼瘾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)亥宿。三九已至,卻和暖如春砂沛,著一層夾襖步出監(jiān)牢的瞬間烫扼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工碍庵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留映企,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓堰氓,卻偏偏與公主長(zhǎng)得像双絮,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子得问,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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