Git命令行使用匯總

前言

最近實習中上手了一個簡單的TMC項目,實際開發中使用SVN,可是忽然有了想對比下Git和SVN的想法,因而就上網看了下教程。GitHub一直在用,可是基本都是clone別人的項目,因此對Git的使用一直沒有跟進,因此如今算是亡羊補牢。
就實際工做而言,只須要掌握常見的Git提交文件以及管理分支的幾個指令,學會怎樣進行版本回退等(Git的命令清單)就能夠知足平常團隊寫做需求。爲了進一步瞭解經常使用指令,本文對Git作一個詳盡的介紹,主要內容是對廖雪峯的官方網站內容的總結,尊重版權,從我作起。linux

1 版本控制系統:集中式or分佈式

集中式版本控制系統(SVN):版本庫存放在服務器中,工做的時候須要先從服務器拷貝最新版本到本地,修改完成後推送給服務器。注意:單個非服務器的電腦之間是沒法相互通訊的。集中式版本控制的最大問題在於須要時刻聯網,對局域網來講,帶寬大,速度快,可是對於互聯網,速度就會很慢。
分佈式版本控制系統(Git):每一個用戶的電腦上都有一個完整的版本庫,工做的時候不須要聯網,多用戶之間交換修改只須要將修改互相推送給對方。雖然也有一個形式上的中央服務器,可是該服務器做用是用來方便交換用戶之間的修改。優勢是安全性較好,一方的電腦故障,在另外一個電腦上依舊保存有完整的版本庫。並且,減小了對服務器的依賴。git

1.1 在windows上安裝Git

Windows上安裝linux/Unix須要Cygwin工具,配置較爲複雜。msysgit是Windows上的Git,從https://git-for-windows.githu...下載,而後按默認選項安裝便可。安裝完成後,在開始菜單裏找到「Git」->「Git Bash」,蹦出一個相似命令行窗口的東西,就說明Git安裝成功!
安裝完成後,還須要最後一步設置,在命令行輸入:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
由於Git是分佈式版本控制系統,因此,每一個機器都必須自報家門:你的名字和Email地址。
注意git config命令的--global參數,用了這個參數,表示你這臺機器上全部的Git倉庫都會使用這個配置,固然也能夠對某個倉庫指定不一樣的用戶名和Email地址。github

1.2 工做區和暫存區

工做區(working directory)就是在電腦裏可以看到的目錄,工做區中有一個隱藏目錄.git,這是Git的版本庫,裏面存儲了名叫stage的暫存區,還有Git爲用戶自動建立的一個分支master,以及指向master的一個指針叫HEAD。
圖片描述windows

在將修改過的文件提交到Git版本庫的時候,須要git add將文件添加進去,實際上就是添加到暫存區,而後經過git commit提交文件,實質上就是將暫存區的全部文件一次性提交。一旦提交後,再使用git status命令,顯示工做區是乾淨的。安全

1.3 建立版本庫

版本庫即一個倉庫(repository),這個目錄裏的全部文件均可以被Git管理起來,每一個文件的修改、刪除,Git都能跟蹤,以便於任什麼時候刻均可以追蹤歷史。建立版本庫的代碼以下:
圖片描述服務器

pwd用於顯示當前目錄,若是你使用Windows系統,爲了不遇到各類莫名其妙的問題,請確保目錄名(包括父目錄)不包含中文。
而後經過git init將版本庫變成Git能夠管理的倉庫:
圖片描述網絡

在learngit目錄下建立文件index.js,而後將其添加到Git倉庫,須要兩步,用git add <fileName>添加文件,用git commit提交到倉庫:
圖片描述app

-m後的字符串是提交說明,提交後輸出版本庫的改動信息。add和commit的區別在於,add能夠屢次添加不一樣的文件,commit能夠一次提交多個文件。ssh

1.4 查詢文件狀態

對index.js文件作修改,而後經過git status 查詢狀態:
圖片描述分佈式

Git指出那些文件被修改了,並給出建議提交更改的命令。「no changes added to commit」代表改變的部分並未被提交。甚至能夠經過git diff <filename>查詢更改發生的具體內容。
圖片描述

更改完以後就是提交文件,這和在版本庫中增長文件操做相同,先add再commit。
圖片描述

提交完成後再觀察版本庫的目前狀態,能夠發現,沒有須要提交的更改,工做樹是乾淨的。
圖片描述

總之:git status 查看是否有須要提交的文件;git diff <fileName>輸出更改的具體部分。

1.5 版本回退:git reset –hard <fileVersion>

事實上我對index.js作了不止一次修改和提交,所以能夠經過 git log 查看最近屢次修改的內容,這時能夠看出爲何在git commit命令後加-m 「修改說明」了,這些修改說明會在log時顯示出來,依次顯式:版本號、修改日期、提交的修改說明。
圖片描述

回退到先前版本:Git用HEAD表示當前版本,HEAD^表示上一版本,HEAD^^表示再上一個版本。若是回溯的版本比價多,能夠用HEAD~100表示回溯到100版本。回溯命令是git reset --hard <回溯版本>,例如想回溯到modified index.js,使用命令:
git reset --hard HEAD^
圖片描述

Git顯示已經恢復到上一版本,經過cat <fileName>命令查看文件內容,能夠看到,文件已經恢復。
圖片描述

Git的版本回退速度很是快,由於Git在內部有個指向當前版本的HEAD指針,當你回退版本的時候,Git僅僅是把HEAD從當前版本指向舊版本,而後順便把工做區的文件更新了。
一種更直接的版本回退方式是經過 git reset --hard <version-id>,並且能夠經過 git reflog顯式全部先前輸入的命令來幫助得到版本號。
總結:
HEAD指向的版本就是當前版本,所以,Git容許咱們在版本的歷史之間穿梭,使用命令git reset --hard commit_id。
穿梭前,用git log能夠查看提交歷史,以便肯定要回退到哪一個版本。
要重返將來,用git reflog查看命令歷史,以便肯定要回到將來的哪一個版本。

2 管理修改

爲何Git比其餘版本控制系統設計得優秀,由於Git跟蹤並管理的是修改,而非文件。假設有這樣一個操做過程:第一次修改 -> git add -> 第二次修改 -> git commit,此時經過git status顯示第二次修改並無被提交,這是由於只有經過git add才能將文件的修改提交到暫存區,而後git commit提交的是這部分修改,不在暫存區的修改是沒辦法提交的。總之,若是不add到暫存區,就不能commit到版本庫中。

2.1 撤銷修改

假設工做區有一份index.js文件,將它add到暫存區中,
圖片描述

而後,在文件中加入 and tall,此時cat index.js顯示以下,更改已經生效,可是沒有add。
圖片描述

此時經過git checkout撤銷更改,此處的撤銷是返回到上一次add以後的文件
圖片描述

命令git checkout -- file意思就是,把index.js文件在工做區的修改所有撤銷,這裏有兩種狀況:
一種是index.js自修改後尚未被放到暫存區,如今,撤銷修改就回到和版本庫如出一轍的狀態;
一種是index.js已經添加到暫存區後,又做了修改,如今,撤銷修改就回到添加到暫存區後的狀態。
總之,就是讓這個文件回到最近一次git commit或git add時的狀態。git checkout -- file命令中的--很重要,沒有--,就變成了「切換到另外一個分支」的命令。
若是已經將修改add到暫存區,怎麼撤回呢?
圖片描述

此時經過git reset HEAD <fileName>將暫存區的修改撤銷,從新回到工做區:
圖片描述

此時內容修改依舊存在,可是git status代表changes not staged for commit,即修改沒有add到暫存區,這時就可使用上述git checkout撤銷工做區的更改:
圖片描述

cat輸出原來內容,上傳到暫存區的更改被撤銷。
場景1:當你改亂了工做區某個文件的內容,想直接丟棄工做區的修改時,用命令git checkout -- file。可是這僅僅返回到上一次add或commit時的版本。
場景2:當你不但改亂了工做區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步,第一步用命令git reset HEAD fileName,就回到了場景1,第二步按場景1操做。
場景3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節,不過前提是沒有推送到遠程庫。

2.2 文件刪除

若是須要刪除文件,使用rm <fileName>便可,刪除以後,工做區和版本庫中的文件不一致,若是是確認刪除,再commit一下便可,文件就會從版本庫刪除;若是是誤刪,版本庫裏依舊有文件,所以可使用git checkout用版本庫中的文件恢復到工做區,git checkout 其實就是用版本庫中版本替換工做區的版本。
圖片描述

2.3 遠程倉庫

上述關於Git管理倉庫文件的功能和集中式版本管理系統SVN沒有區別,如下介紹Git的分佈式特性:遠程倉庫。GitHub網站提供了遠程倉庫的簡易實現,可是因爲由於本地Git倉庫和GitHub之間是經過SSH加密的,因此須要進行設置SSH。
建立ssh密匙
命令: ssh-keygen -t rsa -C 「emailAdress」
圖片描述

登陸GitHub,打開SSH Keys頁面,點擊 add SSH Key,粘貼id-rsa.pub的內容。而後在GitHub網站建立本身的倉庫learngit,創建本地庫和遠程庫的鏈接:
圖片描述

而後將本地版本庫push到遠程github,本地庫的內容推送到遠程,用git push命令,其實是把當前分支master推送到遠程。因爲遠程庫是空的,咱們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關聯起來,在之後的推送或者拉取時就能夠簡化命令。
圖片描述

因爲遠程庫是空的,咱們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關聯起來,在之後的推送或者拉取時就能夠簡化命令。
推送成功後,能夠馬上在GitHub頁面中看到遠程庫的內容已經和本地如出一轍。從如今起,只要本地做了提交,就能夠經過命令:
$ git push origin master
把本地master分支的最新修改推送至GitHub,如今,你就擁有了真正的分佈式版本庫!
總之,要記住如下幾點:
要關聯一個遠程庫,使用命令git remote add origin git@server-name:path/repo-name.git;
關聯後,使用命令git push -u origin master第一次推送master分支的全部內容;
此後,每次本地提交後,只要有必要,就可使用命令git push origin master推送最新修改;
分佈式版本系統的最大好處之一是在本地工做徹底不須要考慮遠程庫的存在,也就是有沒有聯網均可以正常工做,而SVN在沒有聯網的時候是拒絕幹活的!當有網絡的時候,再把本地提交推送一下就完成了同步,真是太方便了!
2.4 克隆倉庫
要克隆一個倉庫,首先必須知道倉庫的地址,而後使用git clone命令克隆。Git支持多種協議,包括https,但經過ssh支持的原生git協議速度最快。
圖片描述

3 分支管理

若是在Git中僅有一條時間線,也就意味着僅有一條分支:master分支,HEAD指針指向master分支,master指向最新的提交,因此HEAD指向的就是當前分支。
圖片描述

每次提交,master就會向前移動一步,這樣隨着不斷提交,master分支的線也愈來愈長。當咱們建立新的分支dev時,Git新建了一個指針叫作dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上。
圖片描述

Git建立一個分支很快,由於除了增長一個dev指針,改變HEAD的指向,工做區的文件沒有變化。指向dev後,全部的修改和提交就是針對dev了。
當分支上的工做完成以後,就能夠把dev合併到master之上,合併的方式就是把master指向dev的當前提交。
圖片描述

合併分支後,就能夠把dev分支刪除,刪除分支就是刪除dev指針。

3.1 分支轉換

建立dev分支,而後切換到dev分支,git checkout 加上-b至關於建立而且換分支,其中git branch <branchName>是建立分支、git checkout <branchName>是轉換分支;git branch命令列出全部分支,當前分支前會有*號。
圖片描述

隨後對index.js進行修改並add和commit到分支,在dev分支上正常提交,隨後切換到master分支:git checkout master,此時查看index.js發現,內容沒有修改,這很正常,由於主分支沒有修改。
圖片描述

如今將dev分支合併到master分支上,git merge命令用於合併指定分支到當前分支,合併後查看index.js的內容,發現修改已經反應到master分支上。
圖片描述

合併後就能夠刪除dev分支,刪除以後分支就只有master了。
圖片描述

由於建立、合併和刪除分支很是快,因此Git鼓勵你使用分支完成某個任務,合併後再刪掉分支,這和直接在master分支上工做效果是同樣的,但過程更安全。
注意,以上合併基於fast-forward模式,這種模式下,刪除分以後,會丟掉分支信息,對此可使用—no-ff方式進行合併:
git merge --no-ff -m "merge with no-ff" dev

Git鼓勵大量使用分支:
查看分支:git branch
建立分支:git branch <name>
切換分支:git checkout <name>
建立+切換分支:git checkout -b <name>
合併某分支到當前分支:git merge <name>
刪除分支:git branch -d <name>

3.2 分支策略

首先,master分支應該是很是穩定的,也就是僅用來發布新版本,平時不能在上面幹活;那在哪幹活呢?幹活都在dev分支上,也就是說,dev分支是不穩定的,到某個時候,好比1.0版本發佈時,再把dev分支合併到master上,在master分支發佈1.0版本;你和你的小夥伴們每一個人都在dev分支上幹活,每一個人都有本身的分支,時不時地往dev分支上合併就能夠了。
圖片描述

3.3 Bug分支

若是工做過程當中須要解決一個bug,此時最好可以將當前工做現場保存起來,而後建立bug分支,並轉換到須要修復bug的分支進行修復。在bug分支修復bug以後,將其合併到目標分支上,而後刪除bug分支。
Git提供了一個stash功能,能夠將當前的工做現場保存起來,等之後恢復現場後繼續工做:

git stash

bug修復以後,切換回到原來分支,經過 git stash list查看工做現場列表,而後進行恢復:採用git stash apply恢復,恢復以後,stash內容並不刪除,用git stash drop刪除便可;採用git stash pop恢復,同時stash的內容也被刪除,這是針對只有一個stash的狀況。固然,若是進行了屢次stash,恢復的時候須要先用git stash list查看須要回覆的stash的名稱,經過git stash apply <stashName>恢復:

git stash apply stash@{0}

3.4 Feature分支

軟件開發過程當中,會有新功能不斷加進來,添加新功能時,爲了保證主分支不被弄亂,最好是新建一個feature分支,在上面開發,完成後再進行合併,並刪除feature分支。也可能最後設計好的新功能不須要了,也就是須要刪除未合併的分支,這時候刪除分支就須要強制刪除,也就是 git branch -D feature命令。

3.5 多人協做的分支操做

當你從遠程倉庫克隆時,實際上Git自動把本地的master分支和遠程的master分支對應起來了,而且,遠程倉庫的默認名稱是origin。要查看遠程庫的信息,用git remote:

$ git remote

或者,用git remote -v顯示更詳細的信息:

$ git remote -v
origin  git@github.com:michaelliao/learngit.git (fetch)
origin  git@github.com:michaelliao/learngit.git (push)

上面顯示了能夠抓取和推送的origin的地址。若是沒有推送權限,就看不到push的地址。

3.6 推送分支

推送分支,就是把該分支上的全部本地提交推送到遠程庫。推送時,要指定本地分支,這樣,Git就會把該分支推送到遠程庫對應的遠程分支上:

$ git push origin master

並非必定要把本地分支往遠程推送,那麼,哪些分支須要推送,哪些不須要呢?
master分支是主分支,所以要時刻與遠程同步;
dev分支是開發分支,團隊全部成員都須要在上面工做,因此也須要與遠程同步;
bug分支只用於在本地修復bug,就不必推到遠程了,除非老闆要看看你每週到底修復了幾個bug;
feature分支是否推到遠程,取決於你是否和你的小夥伴合做在上面開發。

3.7.gitignore:

該文件指出哪些文件不該該加到版本庫中,已經添加過的文件不受影響,因此最好在項目一開始就配置.gitignore文件,不然就沒啥做用了。.gitignore文件自己要放到版本庫裏,而且能夠對.gitignore作版本管理!文件中的規則包含兩類:過濾規則和添加規則,區別在於添加規則多了開頭的感嘆號。過濾規則:/表示.gitignore所在的目錄,通常是主目錄。  以星號「*」通配多個字符;  以問號「?」通配單個字符  以方括號「[]」包含單個字符的匹配列表;  以歎號「!」表示不忽略(跟蹤)匹配到的文件或目錄;git 對於 .ignore 配置文件是按行從上到下進行規則匹配的,意味着若是前面的規則匹配的範圍更大,則後面的規則將不會生效。(1)規則:fd1/*     說明:忽略目錄 fd1 下的所有內容;注意,無論是根目錄下的 /fd1/ 目錄,仍是某個子目錄 /child/fd1/ 目錄,都會被忽略;(2)規則:/fd1/*     說明:忽略根目錄下的 /fd1/ 目錄的所有內容;(3)規則:/*!.gitignore!/fw/bin/!/fw/sf/說明:忽略所有內容,可是不忽略 .gitignore 文件、根目錄下的 /fw/bin/ 和 /fw/sf/ 目錄;

相關文章
相關標籤/搜索