Git經常使用功能教程

聲明:本文參考廖雪峯老師的Git教程,刪除部分我的不經常使用功能作爲我的的參考筆記,若是有錯漏,歡迎批評我,原文地址是https://www.liaoxuefeng.com/w...git

<!-- TOC -->github

<!-- /TOC -->this

Git簡介

Git是分佈式版本控制系統,能記錄每次對文件的改動加密

clipboard.png

集中式VS分佈式

svn是集中式的版本控制系統,必須聯網才能工做,版本庫集中存放在中央服務器,首先本身從中央服務器取得最新版本,在本地服務器修改後,再把更改推送給中央服務器。記住每次提交前要先進行更新操做,是否有有版本衝突。

clipboard.png

分佈式版本控制系統在每一個人本地服務器裏都有完整的版本庫,能夠直接把各自的修改推送給對方,可是分佈式版本控制系統一般也有一臺充當「中央服務器」的電腦,能夠方便交換你們的修改。特別是Git有強大的分支管理。

clipboard.png

安裝Git

在Windows上安裝Git,直接在Git官網直接下載安裝程序而後按默認選項安裝便可。
在開始菜單裏找到「Git」->「Git Bash」,會彈出一個相似命令行窗口,說明Git安裝成功。

clipboard.png

安裝完成後,須要設置本地服務器的用戶名和Email,在命令行輸入:

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

注意git config命令的--global參數,表示本地服務器上全部的Git倉庫都會使用這個配置,固然能夠給某個倉庫指定不一樣的用戶名和Email

Git命令

建立版本庫(倉庫repository)

首先建立一個空目錄
$ mkdir learngit //新建目錄
$ cd learngit //進入這個目錄
$ pwd // 顯示當前目錄
/Users/michael/learngit

初始化這個目錄變成Git能夠管理的倉庫
$ git init
Initialized empty Git repository in /Users/michael/learngit/.git/ //倉庫成功而且告知是一個空的倉庫

當前目錄會多一個.git的目錄,這個目錄是Git用來跟蹤管理版本庫的,不要手動修改,以避免破壞倉庫

注意:圖片、視頻這些二進制文件,雖然也能由版本控制系統管理,但無法跟蹤文件的變化,只能看整體大小的變化,沒法知道具體更改部分,Microsoft的Word格式是二進制格式,版本控制系統是無法跟蹤Word文件的改動的,若是要真正使用版本控制系統,就要以純文本方式編寫文件

把文件提交到倉庫

第一步,把文件添加到倉庫
$ git add 文件名

$ git add . //把全部的文件都添加倉庫

第二步,把文件提交到倉庫
$ git commit -m "本次提交的說明"

爲何Git添加文件須要add,commit一共兩步呢?下面再解釋

工做區和暫存區

工做區(Working Directory)

新建的文件夾learngit就是一個工做區

版本庫(Repository)

工做區有一個隱藏目錄.git,這個不算工做區,而是Git的版本庫。
Git的版本庫裏存了不少東西,其中最重要的就是稱爲stage(或者叫index)的暫存區,還有Git爲咱們自動建立的第一個分支master,以及指向master的一個指針叫HEAD。

clipboard.png

第一步是用git add把文件添加進去,實際上就是把文件修改添加到暫存區;

第二步是用git commit提交更改,實際上就是把暫存區的全部內容提交到當前分支。

由於咱們建立Git版本庫時,Git自動爲咱們建立了惟一一個master分支,因此,如今,git commit就是往master分支上提交更改。

版本回退

查看倉庫當前的狀態,能夠確認有沒有須要提交的修改
$ git status

查看修改的內容
$ git diff 文件名

查看提交的日誌,輸出版本號,做者,日期和提交信息
$ git log

git log加上--pretty=oneline參數就只輸出版本號和提交的書面
$ git log --pretty=oneline

把當前版本回退到上一個版本,用HEAD表示當前版本,上一個版本就是HEAD^,上上一個版本就是HEAD^^,能夠寫成HEAD~100
$ git reset --hard HEAD^

查看文件內容
$ cat 文件名

查看回退前的版本,查看回退前的日誌找回版本號
$ git reset --hard 版本號

Git版本回退速度很快,由於Git在內部有個指向當前版本的HEAD指針,當你回退版本的時候,Git僅僅是把HEAD指向更改了。

查看命令的日誌,能夠找尋到回退前的版本號,從而能夠回到回退前的版本
$ git reflog

撤銷修改

git checkout -- file能夠丟棄工做區的修改:
$ git checkout -- 文件名

命令git checkout -- readme.txt意思就是,把readme.txt文件在工做區的修改所有撤銷,這裏有兩種狀況:

一種是readme.txt自修改後尚未被放到暫存區,如今,撤銷修改就回到和版本庫如出一轍的狀態;

一種是readme.txt已經添加到暫存區後,又做了修改,如今,撤銷修改就回到添加到暫存區後的狀態。

總之,就是讓這個文件回到最近一次git commit或git add時的狀態。
假設你不但改錯了東西,還從暫存區提交到了版本庫,能夠進行版本回退,不過前提是沒有推送到遠程庫。

刪除文件

能夠直接在文件管理器中把沒用的文件刪了,或者用rm命令刪
$ rm 文件名

要從版本庫中刪除該文件,那就用命令git rm刪掉,而且git commit:
$ git rm 文件名
rm 文件名
$ git commit -m "刪除說明"

遠程倉庫GitHub

關聯Git和github

GitHub能夠提供Git倉庫託管服務,註冊一個GitHub帳號,就能夠免費得到Git遠程倉庫。因爲你的本地Git倉庫和GitHub倉庫之間的傳輸是經過SSH加密的,因此須要設置:

第1步:建立SSH Key。在用戶主目錄下,看看有沒有.ssh目錄,若是有,再看看這個目錄下有沒有id_rsa和id_rsa.pub這兩個文件,若是已經有了,可直接跳到下一步。若是沒有,打開Shell(Windows下打開Git Bash),建立SSH Key:
$ ssh-keygen -t rsa -C "你的郵箱地址"

一路回車,若是一切順利的話,能夠在用戶主目錄裏找到.ssh目錄,裏面有id_rsa和id_rsa.pub兩個文件,這兩個就是SSH Key的祕鑰對,id_rsa是私鑰,不能泄露出去,id_rsa.pub是公鑰,能夠放心地告訴任何人。

第2步:登錄GitHub,打開「Account settings」,「SSH Keys」頁面:

而後,點「Add SSH Key」,填上任意Title,在Key文本框裏粘貼id_rsa.pub文件的內容:

clipboard.png

點「Add Key」,你就應該看到已經添加的Key:

clipboard.png

爲何GitHub須要SSH Key呢?由於GitHub須要識別出你推送的提交確實是你推送的,而不是別人冒充的,而Git支持SSH協議,因此,GitHub只要知道了你的公鑰,就能夠確認只有你本身才能推送。

GitHub容許你添加多個Key。假定你有若干電腦,你一下子在公司提交,一下子在家裏提交,只要把每臺電腦的Key都添加到GitHub,就能夠在每臺電腦上往GitHub推送了。

添加遠程庫

登錄GitHub,而後,在右上角找到「Create a new repo」按鈕,建立一個新的倉庫:

clipboard.png

在Repository name填入learngit,其餘保持默認設置,點擊「Create repository」按鈕,就成功地建立了一個新的Git倉庫:

clipboard.png

目前,在GitHub上的這個learngit倉庫仍是空的,GitHub告訴咱們,能夠從這個倉庫克隆出新的倉庫,也能夠把一個已有的本地倉庫與之關聯,而後,把本地倉庫的內容推送到GitHub倉庫。

如今,咱們根據GitHub的提示,在本地的learngit倉庫下運行命令:
$ git remote add origin git@github.com:Github帳戶名/learngit.git

添加後,遠程庫的名字就是origin,這是Git默認的叫法。

下一步,就能夠把本地庫的全部內容推送到遠程庫上:
$ git push -u origin master

其實是把當前分支master推送到遠程。

因爲遠程庫是空的,咱們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關聯起來,在之後的推送或者拉取時就能夠簡化命令。

推送成功後,能夠馬上在GitHub頁面中看到遠程庫的內容已經和本地如出一轍,從如今起,只要本地做了提交,就能夠經過命令:
$ git push origin master

把本地master分支的最新修改推送至GitHub,如今,你就擁有了真正的分佈式版本庫!

從遠程庫克隆

假設咱們從零開發,那麼最好的方式是先建立遠程庫,而後,從遠程庫克隆。

首先,登錄GitHub,建立一個新的倉庫,名字叫gitskills:

clipboard.png

咱們勾選Initialize this repository with a README,這樣GitHub會自動爲咱們建立一個README.md文件。建立完畢後,能夠看到README.md文件:

clipboard.png

如今,遠程庫已經準備好了,下一步是用命令git clone克隆一個本地庫
git clone git@github.com:你的GitHub帳號/gitskills.git

GitHub給出的地址不止一個,還能夠用https://github.com/michaellia...。實際上,Git支持多種協議,默認的git://使用ssh,但也可使用https等其餘協議。

使用https除了速度慢之外,還有個最大的麻煩是每次推送都必須輸入口令,可是在某些只開放http端口的公司內部就沒法使用ssh協議而只能用https。

使用Git上傳文件到GitHub

在須要上傳文件的文件夾右鍵->Git Bash Here打開命令行窗口
在提交代碼以前,首先應該檢查目前所作的修改
$ git status

檢查沒有無誤後
$ git add . //.表明當前目錄下的全部文件都加入暫存區
$ git commit -m "本次提交的說明" //每次提交都應該寫清楚說明
$ git pull origin master //將服務器代碼同步到本地
$ git push -u origin master
//接着根據提示輸入GitHub的用戶名和密碼

推送成功後,能夠馬上在GitHub頁面中看到遠程庫的內容已經和本地如出一轍。

若是執行失敗,通常是沒有將服務器代碼同步到本地致使的,先執行上面的git pull命令

分支管理

爲何須要分支?

建立一個屬於你本身的分支,別人看不到,還繼續在原來的分支上正常工做,而你在本身的分支上幹活,想提交就提交,直到開發完畢後,再一次性合併到原來的分支上,這樣,既安全,又不影響別人工做。

建立和合並分支

首先,咱們建立dev分支,而後切換到dev分支:
$ git checkout -b dev
Switched to a new branch 'dev'

git checkout命令加上-b參數表示建立並切換,至關於如下兩條命令:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'

而後,用git branch命令查看當前分支:
$ git branch

  • dev
    master


git branch命令會列出全部分支,當前分支前面會標一個*號。
而後,咱們就能夠在dev分支上正常提交
$ git add readme.txt
$ git commit -m "branch test"
[dev fec145a] branch test
1 file changed, 1 insertion(+)

如今,dev分支的工做完成,咱們就能夠切換回master分支:
$ git checkout master
Switched to branch 'master'

切換回master分支後,剛纔提交的內容不見了!由於那個提交是在dev分支上,而master分支此刻的提交點並無變:

clipboard.png

如今,咱們把dev分支的工做成果合併到master分支上:
$ git merge dev
Updating d17efd8..fec145a
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)

合併完成後,就能夠放心地刪除dev分支了:
$ git branch -d dev
Deleted branch dev (was fec145a).

刪除後,查看branch,就只剩下master分支了:
$ git branch

  • master


由於建立、合併和刪除分支很是快,因此Git鼓勵你使用分支完成某個任務,合併後再刪掉分支,這和直接在master分支上工做效果是同樣的,但過程更安全。

解決衝突

若是master分支和dev分支各自都分別有新的提交,就會出現衝突:

clipboard.png

這種狀況下,Git沒法執行「快速合併」,只能試圖把各自的修改合併起來,但這種合併就可能會有衝突:

$ git merge feature1

git status告訴咱們衝突的文件:

$ git status

能夠直接查看衝突的內容,Git用<<<<<<<,=======,>>>>>>>標記出不一樣分支的內容,咱們修改後保存
再提交:
$ git add readme.txt
$ git commit -m "conflict fixed"

如今,master分支和feature1分支變成了下圖所示:

clipboard.png

用帶參數的git log也能夠看到分支的合併狀況:
$ git log --graph --pretty=oneline --abbrev-commit

最後,刪除feature1分支:
$ git branch -d feature1

當Git沒法自動合併分支時,就必須首先解決衝突。解決衝突後,再提交,合併完成。

注意:合併分支時,加上--no-ff參數就能夠用普通模式合併,合併後的歷史有分支,能看出來曾經作過合併,而fast forward合併就看不出來曾經作過合併。

Bug分支

當手頭工做沒有完成時,先把工做現場git stash一下,而後去新建分支去修復bug,修復後,切換到master分支在完成合並,最後刪除Bug分支,在切換回到dev分支,一是用git stash apply恢復,可是恢復後,stash內容並不刪除,你須要用git stash drop來刪除;
另外一種方式是用git stash pop,恢復的同時把stash內容也刪了,回到工做現場。

feature分支

開發一個新feature,最好新建一個分支;
若是要丟棄一個沒有被合併過的分支,能夠經過git branch -D <name>強行刪除。

標籤管理

發佈一個版本時,咱們一般先在版本庫中打一個標籤(tag),這樣,就惟一肯定了打標籤時刻的版本。未來不管何時,取某個標籤的版本,就是把那個打標籤的時刻的歷史版本取出來。因此,標籤也是版本庫的一個快照。
Git的標籤雖然是版本庫的快照,但其實它就是指向某個commit的指針(跟分支很像對不對?可是分支能夠移動,標籤不能移動),因此,建立和刪除標籤都是瞬間完成的。

Git有commit,爲何還要引入tag?

由於版本號很差記~

建立分支

在Git中打標籤很是簡單,首先,切換到須要打標籤的分支上:

$ git branch

  • dev
    master

$ git checkout master
Switched to branch 'master'

而後,敲命令git tag <name>就能夠打一個新標籤:
$ git tag v1.0

能夠用命令git tag查看全部標籤:
$ git tag
v1.0

默認標籤是打在最新提交的commit上的。有時候,若是忘了打標籤,好比,如今已是週五了,但應該在週一打的標籤沒有打,怎麼辦?

方法是找到歷史提交的commit id,而後打上就能夠了:
$ git log --pretty=oneline --abbrev-commit
6a5819e merged bug fix 101
cc17032 fix bug 101
7825a50 merge with no-ff
6224937 add merge
59bc1cb conflict fixed
400b400 & simple
75a857c AND simple
fec145a branch test
d17efd8 remove test.txt

比方說要對add merge此次提交打標籤,它對應的commit id是6224937,敲入命令:
$ git tag v0.9 6224937

再用命令git tag查看標籤:
$ git tag
v0.9
v1.0

注意,標籤不是按時間順序列出,而是按字母排序的。能夠用git show <tagname>查看標籤信息

還能夠建立帶有說明的標籤,用-a指定標籤名,-m指定說明文字:
$ git tag -a v0.1 -m "version 0.1 released" 3628164

操做標籤

若是標籤打錯了,也能夠刪除:
$ git tag -d v0.1

由於建立的標籤都只存儲在本地,不會自動推送到遠程。因此,打錯的標籤能夠在本地安全刪除。

若是要推送某個標籤到遠程,使用命令git push origin <tagname>:
$ git push origin v1.0

或者,一次性推送所有還沒有推送到遠程的本地標籤:
$ git push origin --tags

能夠刪除一個遠程標籤
$ git push origin :refs/tags/tagname

相關文章
相關標籤/搜索