git的基本操做

git是作什麼的?html

git是一個用於幫助用戶實現版本控制的軟件git

1、版本控制概述

1.一、什麼是版本控制github

版本控制(Revision control)是一種在開發的過程當中用於管理咱們對文件、目錄或工程等內容的修改歷史,方便查看更改歷史記錄,備份以便恢復之前的版本的軟件工程技術。正則表達式

  • 實現跨區域多人協同開發
  • 追蹤和記載一個或者多個文件的歷史記錄
  • 組織和保護你的源代碼和文檔
  • 統計工做量
  • 並行開發、提升開發效率
  • 跟蹤記錄整個軟件的開發過程
  • 減輕開發人員的負擔,節省時間,同時下降人爲錯誤

簡單說就是用於管理多人協同開發項目的技術。算法

沒有進行版本控制或者版本控制自己缺少正確的流程管理,在軟件開發過程當中將會引入不少問題,如軟件代碼的一致性、軟件內容的冗餘、軟件過程的事物性、軟件開發過程當中的併發性、軟件源代碼的安全性,以及軟件的整合等問題。數據庫

1.二、經常使用術語

1)、倉庫(Repository)
受版本控制的全部文件修訂歷史的共享數據庫windows

2)、工做空間(Workspace) 
本地硬盤或Unix 用戶賬戶上編輯的文件副本安全

3)、工做樹/區(Working tree)
工做區中包含了倉庫的工做文件。您能夠修改的內容和提交更改做爲新的提交到倉庫。bash

4)、暫存區(Staging area)
暫存區是工做區用來提交更改(commit)前能夠暫存工做區的變化。服務器

5)、索引(Index)
索引是暫存區的另外一種術語。

6)、簽入(Checkin)
將新版本複製回倉庫

7)、簽出(Checkout)
從倉庫中將文件的最新修訂版本複製到工做空間

8)、提交(Commit)
對各自文件的工做副本作了更改,並將這些更改提交到倉庫

9)、衝突(Conflict)
多人對同一文件的工做副本進行更改,並將這些更改提交到倉庫

10)、合併(Merge)
將某分支上的更改聯接到此主幹或同爲主幹的另外一個分支

11)、分支(Branch)
從主線上分離開的副本,默認分支叫master

12)、鎖(Lock)
得到修改文件的專有權限。

13)、頭(HEAD)
頭是一個象徵性的參考,最經常使用以指向當前選擇的分支。

14)、修訂(Revision)
表示代碼的一個版本狀態。Git經過用SHA1 hash算法表示的ID來標識不一樣的版本。

15)、標記(Tags)
標記指的是某個分支某個特定時間點的狀態。經過標記,能夠很方便的切換到標記時的狀態。

1.三、常見的版本控制器

主流的版本控制器有以下這些:

  • Git
  • SVN(Subversion)
  • CVS(Concurrent Versions System)
  • VSS(Micorosoft Visual SourceSafe)
  • TFS(Team Foundation Server)
  • Visual Studio Online

版本控制產品很是的多(Perforce、Rational ClearCase、RCS(GNU Revision Control System)、Serena Dimention、SVK、BitKeeper、Monotone、Bazaar、Mercurial、SourceGear Vault),如今影響力最大且使用最普遍的是Git與SV

1.四、版本控制分類

1.4.一、本地版本控制

記錄文件每次的更新,能夠對每一個版本作一個快照,或是記錄補丁文件,適合我的用,如RCS。

1.4.二、集中版本控制

全部的版本數據都保存在服務器上,協同開發者從服務器上同步更新或上傳本身的修改

全部的版本數據都存在服務器上,用戶的本地只有本身之前所同步的版本,若是不連網的話,用戶就看不到歷史版本,也沒法切換版本驗證問題,或在不一樣分支工做。並且,全部數據都保存在單一的服務器上,有很大的風險這個服務器會損壞,這樣就會丟失全部的數據,固然能夠按期備份。表明產品:SVN、CVS、VSS

1.4.三、分佈式版本控制

全部版本信息倉庫所有同步到本地的每一個用戶,這樣就能夠在本地查看全部版本歷史,能夠離線在本地提交,只需在連網時push到相應的服務器或其餘用戶那裏。因爲每一個用戶那裏保存的都是全部的版本數據,只要有一個用戶的設備沒有問題就能夠恢復全部的數據,但這增長了本地存儲空間的佔用。

1.五、Git與SVN最主要區別

SVN是集中式版本控制系統,版本庫是集中放在中央服務器的,而工做的時候,用的都是本身的電腦,因此首先要從中央服務器獲得最新的版本,而後工做,完成工做後,須要把本身作完的活推送到中央服務器。集中式版本控制系統是必須聯網才能工做,對網絡帶寬要求較高。

 

Git是分佈式版本控制系統,沒有中央服務器,每一個人的電腦就是一個完整的版本庫,工做的時候不須要聯網了,由於版本都在本身電腦上。協同的方法是這樣的:好比說本身在電腦上改了文件A,其餘人也在電腦上改了文件A,這時,大家兩之間只需把各自的修改推送給對方,就能夠互相看到對方的修改了。

2、Git安裝與配置

2.一、什麼是Git

Git是目前世界上最早進的分佈式版本控制系統。

Git是免費、開源的

最初Git是爲輔助 Linux 內核開發的,來替代 BitKeeper

做者:Linux和Git之父李納斯·託沃茲(Linus Benedic Torvalds)196九、芬蘭

優勢:

  • 適合分佈式開發,強調個體。
  • 公共服務器壓力和數據量都不會太大。
  • 速度快、靈活。
  • 任意兩個開發者之間能夠很容易的解決衝突。
  • 離線工做。

缺點:

  • 模式上比SVN更加複雜。
  • 不符合常規思惟。
  • 代碼保密性差,一旦開發者把整個庫克隆下來就能夠徹底公開全部代碼和版本信息。

官網: https://git-scm.com/

源碼: https://github.com/git/git/

2.二、搭建Git工做環境

2.2.一、下載Git

打開 git官網,下載git對應操做系統的版本。

選擇版本:

這裏我選擇下載64-bit Git for Windows Setup

2.2.二、安裝Git

選擇安裝配置信息

一直Next默認就行了,若是須要設置就要仔細讀一下安裝界面上的選項。

2.2.三、啓動Git

安裝成功後在開始菜單中會有Git項,菜單下有3個程序:

Git Bash:Unix與Linux風格的命令行,使用最多,推薦最多

與DOS風格的命令有些區別,不習慣能夠選擇Git CMD

Git CMD:Windows風格的命令行

Git GUI:圖形界面的Git,不建議初學者使用,儘可能先熟悉經常使用命令

 

點擊Create New Repository能夠直接建立一個新的倉庫。

2.2.四、Linux與Mac OS安裝Git

Linux安裝Git:sudo apt-get install git 命令行就能夠安裝了。

Mac OS安裝Git: https://git-scm.com/download/mac,下載雙擊.pkg安裝

2.2.五、Bash基本操做命令

1)、cd : 改變目錄。
2)、cd . . 回退到上一個目錄,直接cd進入默認目錄
3)、pwd : 顯示當前所在的目錄路徑。
4)、ls(ll): 都是列出當前目錄中的全部文件,只不過ll(兩個ll)列出的內容更爲詳細。
5)、touch : 新建一個文件 如 touch index.js 就會在當前目錄下新建一個index.js文件。
6)、rm: 刪除一個文件, rm index.js 就會把index.js文件刪除。
7)、mkdir: 新建一個目錄,就是新建一個文件夾。
8)、rm -r : 刪除一個文件夾, rm -r src 刪除src目錄, 好像不能用通配符。
9)、mv 移動文件, mv index.html src index.html 是咱們要移動的文件, src 是目標文件夾,固然, 這樣寫,必須保證文件和目標文件夾在同一目錄下。
10)、reset 從新初始化終端/清屏。
11)、clear 清屏。
12)、history 查看命令歷史。
13)、help 幫助。
14)、exit 退出。
15)、#表示註釋

2.三、Git配置 - git config

2.3.一、查看配置 - git config -l

使用git config -l 能夠查看如今的git環境詳細配置,你的帳號信息都在裏面

查看不一樣級別的配置文件:

#查看系統config
git config --system --list
  
#查看當前用戶(global)配置
git config --global  --list
 
#查看當前倉庫配置信息
git config --local  --list

2.3.二、Git配置文件分類

Windows系統中,Git在$HOME目錄中查找.gitconfig文件(通常位於C:\Documents and Settings$USER下)

Git相關的配置文件有三個:

1)、 /etc/gitconfig:包含了適用於系統全部用戶和全部項目的值。(Win:C:\Program Files\Git\mingw64\etc\gitconfig) --system 系統級

2)、~/.gitconfig:只適用於當前登陸用戶的配置。(Win:C:\Users\Administrator\.gitconfig)  --global 全局

3)、位於git項目目錄中的.git/config:適用於特定git項目的配置。(Win:C:\gitProject) --local當前項目

注意:對於同一配置項,三個配置文件的優先級是1<2<3

這裏能夠直接編輯配置文件,經過命令設置後會響應到這裏。

2.3.三、設置用戶名與郵箱(用戶標識,必要)

當你安裝Git後首先要作的事情是設置你的用戶名稱和e-mail地址。這是很是重要的,由於每次Git提交都會使用該信息。它被永遠的嵌入到了你的提交中:

   $ git config --global user.name "manyqian"  #名稱
   $ git config --global user.email 850928058@qq.com   #郵箱

只須要作一次這個設置,若是你傳遞了--global 選項,由於Git將老是會使用該信息來處理你在系統中所作的一切操做。若是你但願在一個特定的項目中使用不一樣的名稱或e-mail地址,你能夠在該項目中運行該命令而不要--global選項。 總之--global爲全局配置,不加爲某個項目的特定配置。

2.3.四、添加或刪除配置項

1)、添加配置項 
git config [--local|--global|--system]  section.key value
[--local|--global|--system]  #可選的,對應本地,全局,系統不一樣級別的設置,請看2.3.2
section.key #區域下的鍵
value #對應的值

--local 項目級

--global 當前用戶級

--system 系統級 

例如咱們要在student區域下添加一個名稱爲height值爲198的配置項:

2)、刪除配置項 

git config [--local|--global|--system] --unset section.key

 將系統級的height配置項移除

2.3.五、更多配置項

git config --global color.ui true   #打開全部的默認終端着色
git config --global alias.ci commit   #別名 ci 是commit的別名
[alias]  
co = checkout  
ci = commit  
st = status  
pl = pull  
ps = push  
dt = difftool  
l = log --stat  
cp = cherry-pick  
ca = commit -a  
b = branch 

user.name  #用戶名
user.email  #郵箱
core.editor  #文本編輯器  
merge.tool  #差別分析工具  
core.paper "less -N"  #配置顯示方式  
color.diff true  #diff顏色配置  
alias.co checkout  #設置別名
git config user.name  #得到用戶名
git config core.filemode false  #忽略修改權限的文件  

全部config命令參數

語法: git config [<options>]        
        
文件位置        
    --global                  #use global config file 使用全局配置文件
    --system                  #use system config file 使用系統配置文件
    --local                   #use repository config file    使用存儲庫配置文件
    -f, --file <file>         #use given config file    使用給定的配置文件
    --blob <blob-id>          #read config from given blob object    從給定的對象中讀取配置
        
動做        
    --get                     #get value: name [value-regex]    得到值:[值]名[正則表達式]
    --get-all                 #get all values: key [value-regex]    得到全部值:[值]名[正則表達式]
    --get-regexp          #get values for regexp: name-regex [value-regex]    獲得的值根據正則
    --get-urlmatch            #get value specific for the URL: section[.var] URL    爲URL獲取特定的值
    --replace-all             #replace all matching variables: name value [value_regex]    替換全部匹配的變量:名稱值[ value_regex ]
    --add                     #add a new variable: name value    添加一個新變量:name值
    --unset                   #remove a variable: name [value-regex]    刪除一個變量名[值]:正則表達式
    --unset-all               #remove all matches: name [value-regex]    刪除全部匹配的正則表達式:名稱[值]
    --rename-section          #rename section: old-name new-name    重命名部分:舊名稱 新名稱
    --remove-section          #remove a section: name    刪除部分:名稱
    -l, --list                #list all    列出全部
    -e, --edit            #open an editor    打開一個編輯器
    --get-color               #find the color configured: slot [default]    找到配置的顏色:插槽[默認]
    --get-colorbool           #find the color setting: slot [stdout-is-tty]    發現顏色設置:槽[ stdout是TTY ]
        
類型        
    --bool                    #value is "true" or "false"    值是「真」或「假」。
    --int                     #value is decimal number    值是十進制數。
    --bool-or-int             #value is --bool or --int    值--布爾或int
    --path                    #value is a path (file or directory name)    值是路徑(文件或目錄名)
        
其它        
    -z, --null                #terminate values with NUL byte    終止值與null字節
    --name-only               #show variable names only    只顯示變量名
    --includes                #respect include directives on lookup    尊重包括查找指令
    --show-origin             #show origin of config (file, standard input, blob, command line)    顯示配置(文件、標準輸入、數據塊、命令行)的來源

3、Git理論基礎

3.一、工做區域

Git本地有三個工做區域:工做目錄(Working Directory)、暫存區(Stage/Index)、資源庫(Repository或Git Directory)。若是在加上遠程的git倉庫(Remote Directory)就能夠分爲四個工做區域。文件在這四個區域之間的轉換關係以下:

  • Workspace:工做區,就是你平時存放項目代碼的地方
  • Index / Stage:暫存區,用於臨時存放你的改動,事實上它只是一個文件,保存即將提交到文件列表信息
  • Repository:倉庫區(或本地倉庫),就是安全存放數據的位置,這裏面有你提交到全部版本的數據。其中HEAD指向最新放入倉庫的版本
  • Remote:遠程倉庫,託管代碼的服務器,能夠簡單的認爲是你項目組中的一臺電腦用於遠程數據交換

本地的三個區域確切的說應該是git倉庫中HEAD指向的版本

  • Directory:使用Git管理的一個目錄,也就是一個倉庫,包含咱們的工做空間和Git的管理空間。
  • WorkSpace:須要經過Git進行版本控制的目錄和文件,這些目錄和文件組成了工做空間。
  • .git:存放Git管理信息的目錄,初始化倉庫的時候自動建立。
  • Index/Stage:暫存區,或者叫待提交更新區,在提交進入repo以前,咱們能夠把全部的更新放在暫存區。
  • Local Repo:本地倉庫,一個存放在本地的版本庫;HEAD會只是當前的開發分支(branch)。
  • Stash:隱藏,是一個工做狀態保存棧,用於保存/恢復WorkSpace中的臨時狀態。

3.二、工做流程

git的工做流程通常是這樣的:

1、在工做目錄中添加、修改文件;

2、將須要進行版本管理的文件放入暫存區域;

3、將暫存區域的文件提交到git倉庫。

所以,git管理的文件有三種狀態:已修改(modified),已暫存(staged),已提交(committed)

3.三、圖解教程

我的認爲Git的原理相比別的版本控制器仍是複雜一些的,有一份圖解教程比較直觀:

圖解教程英文原版

圖解教程中文版

4、Git操做

4.一、建立工做目錄與經常使用指令

工做目錄(WorkSpace)通常就是你但願Git幫助你管理的文件夾,能夠是你項目的目錄,也能夠是一個空目錄,建議不要有中文。

平常使用只要記住下圖6個命令:

4.二、得到GIT倉庫

建立本地倉庫的方法有兩種:一種是建立全新的倉庫,另外一種是克隆遠程倉庫。

4.2.一、建立全新倉庫

須要用GIT管理的項目的根目錄執行:

# 在當前目錄新建一個Git代碼庫
$ git init

執行:

 

結果:

 

執行後能夠看到,僅僅在項目目錄多出了一個.git目錄,關於版本等的全部信息都在這個目錄裏面。

固然若是使用以下命令,能夠把建立目錄與倉庫一塊兒完成:

# 新建一個目錄,將其初始化爲Git代碼庫
$ git init [project-name]

4.2.二、克隆遠程倉庫

 另外一種方式是克隆遠程目錄,因爲是將遠程服務器上的倉庫徹底鏡像一份至本地,而不是取某一個特定版本,因此用clone而不是checkout,語法格式以下:

# 克隆一個項目和它的整個代碼歷史(版本信息)
$ git clone [url]

4.三、GIT文件操做

版本控制就是對文件的版本控制,要對文件進行修改、提交等操做,首先要知道文件當前在什麼狀態,否則可能會提交了如今還不想提交的文件,或者要提交的文件沒提交上。GIT不關心文件兩個版本之間的具體差異,而是關心文件的總體是否有改變,若文件被改變,在添加提交時就生成文件新版本的快照,而判斷文件總體是否改變的方法就是用SHA-1算法計算文件的校驗和。

4.3.一、文件4種狀態

  • Untracked: 未跟蹤, 此文件在文件夾中, 但並無加入到git庫, 不參與版本控制. 經過git add 狀態變爲Staged.

  • Unmodify: 文件已經入庫, 未修改, 即版本庫中的文件快照內容與文件夾中徹底一致. 這種類型的文件有兩種去處, 若是它被修改, 而變爲Modified. 若是使用git rm移出版本庫, 則成爲Untracked文件

  • Modified: 文件已修改, 僅僅是修改, 並無進行其餘的操做. 這個文件也有兩個去處, 經過git add可進入暫存staged狀態, 使用git checkout 則丟棄修改過, 返回到unmodify狀態, 這個git checkout即從庫中取出文件, 覆蓋當前修改

  • Staged: 暫存狀態. 執行git commit則將修改同步到庫中, 這時庫中的文件和本地文件又變爲一致, 文件爲Unmodify狀態. 執行git reset HEAD filename取消暫存, 文件狀態爲Modified

4.3.二、查看文件狀態

上面說文件有4種狀態,經過以下命令能夠查看到文件的狀態:

#查看指定文件狀態
git status [filename]

#查看全部文件狀態
git status

命令:

結果:

紅色文件的狀態爲untracked(未跟蹤),提示經過git add(文件名,.本文件夾全部的)能夠暫存

GIT在這一點作得很好,在輸出每一個文件狀態的同時還說明了怎麼操做,像上圖就有怎麼暫存、怎麼跟蹤文件、怎麼取消暫存的說明。

4.3.三、添加文件與目錄

工做區(Working Directory)就是你在電腦裏能看到的目錄。

版本庫(Repository)工做區有一個隱藏目錄.git,這個不算工做區,而是Git的版本庫。

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

將untracked狀態的文件添加到暫存區,語法格式以下:

# 添加指定文件到暫存區
$ git add [file1] [file2] ...

# 添加指定目錄到暫存區,包括子目錄
$ git add [dir]

# 添加當前目錄的全部文件到暫存區
$ git add .

執行:

 

4.3.四、移除文件與目錄(撤銷add)

當執行以下命令時,會直接從暫存區刪除文件,工做區則不作出改變

#直接從暫存區刪除文件,工做區則不作出改變
git rm --cached <file>

經過重寫目錄樹移除add文件:

#若是已經用add 命令把文件加入stage了,就先須要從stage中撤銷
git reset HEAD <file>...

當執行 「git reset HEAD」 命令時,暫存區的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,可是工做區不受影響。

移除全部未跟蹤文件

#移除全部未跟蹤文件
#通常會加上參數-df,-d表示包含目錄,-f表示強制清除。
git clean [options] 

 

#只從stage中刪除,保留物理文件
git rm --cached readme.txt 

#不但從stage中刪除,同時刪除物理文件
git rm readme.txt 

#把a.txt更名爲b.txt
git mv a.txt b.txt 

當執行提交操做(git commit)時,暫存區的目錄樹寫到版本庫(對象庫)中,master 分支會作相應的更新。即 master 指向的目錄樹就是提交時暫存區的目錄樹。

當執行 「git reset HEAD」 命令時,暫存區的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,可是工做區不受影響。

當執行 「git rm –cached <file>」 命令時,會直接從暫存區刪除文件,工做區則不作出改變。

當執行 「git checkout .」 或者 「git checkout — <file>」 命令時,會用暫存區所有或指定的文件替換工做區的文件。這個操做很危險,會清除工做區中未添加到暫存區的改動。

當執行 「git checkout HEAD .」 或者 「git checkout HEAD <file>」 命令時,會用 HEAD 指向的 master 分支中的所有或者部分文件替換暫存區和以及工做區中的文件。這個命令也是極具危險性的,由於不但會清除工做區中未提交的改動,也會清除暫存區中未提交的改 動。

4.3.五、查看文件修改後的差別

git diff用於顯示WorkSpace中的文件和暫存區文件的差別

用"git status"只能查看對哪些文件作了改動,若是要看改動了什麼,能夠用:

#查看文件修改後的差別
git diff [files]

---a表示修改以前的文件,+++b表示修改後的文件

#比較暫存區的文件與以前已經提交過的文件
git diff --cached

也能夠把WorkSpace中的狀態和repo中的狀態進行diff,命令以下:

#比較repo與工做空間中的文件差別
git diff HEAD~n

4.3.六、簽出

若是倉庫中已經存在文件f4.txt,在工做區中對f4修改了,若是想撤銷可使用checkout,簽出覆蓋

檢出命令git checkout是git最經常使用的命令之一,同時也是一個很危險的命令,由於這條命令會重寫工做區

語法:

#用法一
git checkout [-q] [<commit>] [--] <paths>...
#用法二
git checkout [<branch>]
#用法三
git checkout [-m] [[-b]--orphan] <new_branch>] [<start_point>]

<commit>是可選項,若是省略則至關於從暫存區(index)進行檢出

$ git checkout branch
#檢出branch分支。要完成圖中的三個步驟,更新HEAD以指向branch分支,以及用branch  指向的樹更新暫存區和工做區。

$ git checkout
#彙總顯示工做區、暫存區與HEAD的差別。

$ git checkout HEAD
#同上

$ git checkout -- filename
#用暫存區中filename文件來覆蓋工做區中的filename文件。至關於取消自上次執行git add filename以來(若是執行過)的本地修改。

$ git checkout branch -- filename
#維持HEAD的指向不變。用branch所指向的提交中filename替換暫存區和工做區中相   應的文件。注意會將暫存區和工做區中的filename文件直接覆蓋。

$ git checkout -- . 或寫做 git checkout .
#注意git checkout 命令後的參數爲一個點(「.」)。這條命令最危險!會取消全部本地的  #修改(相對於暫存區)。至關於用暫存區的全部文件直接覆蓋本地文件,不給用戶任何確認的機會!

$ git checkout commit_id -- file_name
#若是不加commit_id,那麼git checkout -- file_name 表示恢復文件到本地版本庫中最新的狀態。

4.3.六、忽略文件

有些時候咱們不想把某些文件歸入版本控制中,好比數據庫文件,臨時文件,設計文件等

在主目錄下創建".gitignore"文件,此文件有以下規則:

  1. 忽略文件中的空行或以井號(#)開始的行將會被忽略。
  2. 可使用Linux通配符。例如:星號(*)表明任意多個字符,問號(?)表明一個字符,方括號([abc])表明可選字符範圍,大括號({string1,string2,...})表明可選的字符串等。
  3. 若是名稱的最前面有一個感嘆號(!),表示例外規則,將不被忽略。
  4. 若是名稱的最前面是一個路徑分隔符(/),表示要忽略的文件在此目錄下,而子目錄中的文件不忽略。
  5. 若是名稱的最後面是一個路徑分隔符(/),表示要忽略的是此目錄下該名稱的子目錄,而非文件(默認文件或目錄都忽略)。

如:

#爲註釋
*.txt #忽略全部 .txt結尾的文件
!lib.txt #但lib.txt除外
/temp #僅忽略項目根目錄下的TODO文件,不包括其它目錄temp
build/ #忽略build/目錄下的全部文件
doc/*.txt #會忽略 doc/notes.txt 但不包括 doc/server/arch.txt

更多規則請點這裏

4.3.七、提交

經過add只是將文件或目錄添加到了index暫存區,使用commit能夠實現將暫存區的文件提交到本地倉庫。

# 提交暫存區到倉庫區
$ git commit -m [message]

# 提交暫存區的指定文件到倉庫區
$ git commit [file1] [file2] ... -m [message]

# 提交工做區自上次commit以後的變化,直接到倉庫區,跳過了add,對新文件無效
$ git commit -a

# 提交時顯示全部diff信息
$ git commit -v

# 使用一次新的commit,替代上一次提交
# 若是代碼沒有任何新變化,則用來改寫上一次commit的提交信息
$ git commit --amend -m [message]

# 重作上一次commit,幷包括指定文件的新變化
$ git commit --amend [file1] [file2] ...

修訂提交

若是咱們提交事後發現有個文件改錯了,或者只是想修改提交說明,這時能夠對相應文件作出修改,將修改過的文件經過"git add"添加到暫存區,而後執行如下命令:

#修訂提交
git commit --amend

撤銷提交(commit)

原理就是放棄工做區和index的改動,同時HEAD指針指向前一個commit對象

#撤銷上一次的提交
git reset --hard HEAD~1

 要經過git log查看提交日誌,也可直接指定提交編號或序號

撤銷提交
git revert <commit-id>
這條命令會把指定的提交的全部修改回滾,並同時生成一個新的提交。

4.3.八、日誌與歷史

查看提交日誌可使用git log指令,語法格式以下:

#查看提交日誌
git log [<options>] [<revision range>] [[\--] <path>…​]

 

幾乎全部輸入過的都被記錄下來的,不愧是作版本控制的。

查看全部分支日誌

"git reflog"中會記錄這個倉庫中全部的分支的全部更新記錄,包括已經撤銷的更新。

4.3.九、查看文件列表

使用git ls-files指令能夠查看指定狀態的文件列表,格式以下:

#查看指定狀態的文件
git ls-files [-z] [-t] [-v] (--[cached|deleted|others|ignored|stage|unmerged|killed|modified])* (-[c|d|o|i|s|u|k|m])*

4.3.十、撤銷更新

1)、撤銷暫存區更新

使用"git add"把更新提交到了暫存區。這時"git status"的輸出中提示咱們能夠經過"git reset HEAD <file>..."把暫存區的更新移出到WorkSpace中

 

2)、撤銷本地倉庫更新

使用git log查看提交日誌

撤銷提交有兩種方式:使用HEAD指針使用commit id

在Git中,有一個HEAD指針指向當前分支中最新的提交。當前版本,咱們使用"HEAD^",那麼再錢一個版本可使用"HEAD^^",若是想回退到更早的提交,可使用"HEAD~n"。(也就是,HEAD^=HEAD~1,HEAD^^=HEAD~2)

git reset --hard HEAD^
git reset --hard HEAD~1
git reset --59cf9334cf957535cb328f22a1579b84db0911e5

回退後

 

如今又想恢復被撤銷的提交可用"git reflog"查看倉庫中全部的分支的全部更新記錄,包括已經撤銷的更新,撤銷方法與前面同樣。

git reset --hard HEAD@{7}
git reset --hard e0e79d7

--hard:撤銷並刪除相應的更新

--soft:撤銷相應的更新,把這些更新的內容放到Stage中

4.3.十一、刪除文件

1)、刪除未跟蹤文件

若是文件仍是未跟蹤狀態,直接刪除文件就可了,bash中使用rm能夠刪除文件

2)、刪除已提交文件

 -f 強制刪除,物理刪除了,同時刪除工做區和暫存區中的文件

撤銷刪除:

#to discard changes in working directory
git checkout -- <file>...

3)、刪除暫存區的文件,不刪除工做區的文件

使用git reset HEAD <file>...一樣能夠實現上面的功能

4.3.十二、文件操做小結

 Git很強大,很靈活,這是毋庸置疑的。但也正由於它的強大形成了它的複雜,所以會有不少奇奇怪怪的問題出現,多用就行了。

4.四、GIT分支

分支在GIT中相對較難

分支就是科幻電影裏面的平行宇宙,當你正在電腦前努力學習Git的時候,另外一個你正在另外一個平行宇宙裏努力學習SVN。

若是兩個平行宇宙互不干擾,那對如今的你也沒啥影響。不過,在某個時間點,兩個平行宇宙合併了,結果,你既學會了Git又學會了SVN!

learn-branches

分支在實際中有什麼用呢?假設你準備開發一個新功能,可是須要兩週才能完成,第一週你寫了50%的代碼,若是馬上提交,因爲代碼還沒寫完,不完整的代碼庫會致使別人不能幹活了。若是等代碼所有寫完再一次提交,又存在丟失天天進度的巨大風險。

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

Git分支的速度很是快。

截止到目前,只有一條時間線,在Git裏,這個分支叫主分支,即master分支。HEAD嚴格來講不是指向提交,而是指向master,master纔是指向提交的,因此,HEAD指向的就是當前分支。

特性分支的圖示

git分支中經常使用指令:

# 列出全部本地分支
$ git branch

# 列出全部遠程分支
$ git branch -r

# 列出全部本地分支和遠程分支
$ git branch -a

# 新建一個分支,但依然停留在當前分支
$ git branch [branch-name]

# 新建一個分支,並切換到該分支
$ git checkout -b [branch]

# 新建一個分支,指向指定commit
$ git branch [branch] [commit]

# 新建一個分支,與指定的遠程分支創建追蹤關係
$ git branch --track [branch] [remote-branch]

# 切換到指定分支,並更新工做區
$ git checkout [branch-name]

# 切換到上一個分支
$ git checkout -

# 創建追蹤關係,在現有分支與指定的遠程分支之間
$ git branch --set-upstream [branch] [remote-branch]

# 合併指定分支到當前分支
$ git merge [branch]

# 選擇一個commit,合併進當前分支
$ git cherry-pick [commit]

# 刪除分支
$ git branch -d [branch-name]

# 刪除遠程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]

4.4.一、新建分支與切換分支

默認分支是這樣的,master是主分支

git-br-initial

1)、新建一個分支,但依然停留在當前分支,使用:$ git branch [branch-name]

切換分支到dev1後的結果:

當咱們建立新的分支,例如dev時,Git新建了一個指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上:

git-br-create

你看,Git建立一個分支很快,由於除了增長一個dev指針,改改HEAD的指向,工做區的文件都沒有任何變化!

不過,從如今開始,對工做區的修改和提交就是針對dev分支了,好比新提交一次後,dev指針往前移動一步,而master指針不變:

git-br-dev-fd

假如咱們在dev上的工做完成了,就能夠把dev合併到master上。Git怎麼合併呢?最簡單的方法,就是直接把master指向dev的當前提交,就完成了合併:

git-br-ff-merge

因此Git合併分支也很快!就改改指針,工做區內容也不變!

合併完分支後,甚至能夠刪除dev分支。刪除dev分支就是把dev指針給刪掉,刪掉後,咱們就剩下了一條master分支:

git-br-rm

2)、切換分支,git branch <name>,若是name爲-則爲上一個分支

3)、新建一個分支,並切換到該分支,$ git checkout -b [branch]

4)、新建一個分支,指向指定commit使用命令:$ git branch [branch] [commit]

master上原本有兩個提交記錄的,此時的dev3指向的是第1次提交的位置

 5)、新建一個分支,與指定的遠程分支創建追蹤關係使用命令:$ git branch --track [branch] [remote-branch]

4.4.二、查看分支

1)、列出全部本地分支使用$ git branch

2)、列表全部遠程分支使用$ git branch -r

3)、列出全部本地分支和遠程分支使用$ git branch -a

4.4.三、分支合併

合併指定分支到當前分支使用指令$ git merge [branch]

4.4.四、解決衝突

若是同一個文件在合併分支時都被修改了則會引發衝突,

Git用<<<<<<<,=======,>>>>>>>標記出不一樣分支的內容,其中<<<HEAD是指主分支修改的內容,

解決的辦法是咱們能夠修改衝突文件後從新提交,請注意當前的狀態產master | MERGING:

手動解決完衝突後就能夠把此文件添 加到索引(index)中去,用git commit命令來提交,就像平時修改了一個文件 同樣。

git log --graph命令能夠看到分支合併圖。

分支策略

master主分支應該很是穩定,用來發布新版本,通常狀況下不容許在上面工做,工做通常狀況下在新建的dev分支上工做,工做完後,好比上要發佈,或者說dev分支代碼穩定後能夠合併到主分支master上來。

4.4.五、刪除分支

刪除本地分支可使用命令:$ git branch -d [branch-name],-D(大寫)強制刪除

刪除遠程分支可使用以下指令:

$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]

-d表示刪除分支。分支必須徹底合併在其上游分支,或者在HEAD上沒有設置上游

-r表示遠程的意思remotes,若是-dr則表示刪除遠程分支

5、遠程倉庫

Git是分佈式版本控制系統,同一個Git倉庫,能夠分佈到不一樣的機器上,但開發參與者必須在同一個網絡中,且必須有一個項目的原始版本,一般的辦法是讓一臺電腦充當服務器的角色,天天24小時開機,其餘每一個人都從這個「服務器」倉庫克隆一份到本身的電腦上,而且各自把各自的提交推送到服務器倉庫裏,也從服務器倉庫中拉取別人的提交。徹底能夠本身搭建一臺運行Git的服務器但如今更適合的作法是使用免費的託管平臺。

同時相較於傳統的代碼都是管理到本機或者內網。 一旦本機或者內網機器出問題,代碼可能會丟失,使用遠端代碼倉庫將永遠存在一個備份。同時也免去了搭建本地代碼版本控制服務的繁瑣。 雲計算時代 Git 以其強大的分支和克隆功能,更加方便了開發者遠程協做。

5.一、託管平臺

Git代碼託管平臺,首先推薦的是GitHub,好多好的開源項目都來自GitHub,可是GitHub只能新建公開的Git倉庫,私有倉庫要收費,有時候訪問比較卡,若是你作的是一個開源項目,能夠首選GitHub。下面推薦幾個比較好的Git代碼託管平臺:

5.1.一、GitHub

關於GItHub相信你們都有耳聞,我就不詳細介紹了。GitHub地址: https://github.com/,其首頁如圖:

5.1.二、Gitlab

對於有些人,提到GitHub就會天然的想到Gitlab,Gitlab支持無限的公有項目和私有項目。Gitlab地址: https://about.gitlab.com/,其首頁截圖如圖:

5.1.三、Bitbucket

bitbucket免費支持5個開發成員的團隊建立無限私有代碼託管庫。bitbucket地址:

5.1.四、開源中國代碼託管

開源中國一個帳號最多能夠建立1000個項目,包含公有和私有,開源中國代碼託管地址: http://git.oschina.net/,其首頁如圖:

5.1.五、(推薦)coding.net

談到coding.net,首先必須提的是速度快,功能與開源中國類似,一樣一個帳號最多能夠建立1000個項目(5個私有),也支持任務的建立等。coding.net地址: https://coding.net/

我我的比較推薦Coding.net、GItHub。

固然還有許多,如CSDN,百度,阿里等,歡迎你們比較後推薦。

選擇國外的主機請考慮網速,選擇國內的主機請考慮穩定與安全性。

5.二、遠程倉庫操做

申請到了Git遠程倉庫的賬號並建立了一個空的遠程倉庫如今咱們就能夠結合本地的倉庫與遠程倉庫一塊兒協同工做了,模擬多人協同開發,這裏咱們所有使用命令完成。

5.2.一、經常使用操做指令

# 下載遠程倉庫的全部變更
$ git fetch [remote]

# 顯示全部遠程倉庫
$ git remote -v

# 顯示某個遠程倉庫的信息
$ git remote show [remote]

# 增長一個新的遠程倉庫,並命名
$ git remote add [shortname] [url]

# 取回遠程倉庫的變化,並與本地分支合併
$ git pull [remote] [branch]

# 上傳本地指定分支到遠程倉庫
$ git push [remote] [branch]

# 強行推送當前分支到遠程倉庫,即便有衝突
$ git push [remote] --force

# 推送全部分支到遠程倉庫
$ git push [remote] --all

#簡單查看遠程---全部倉庫
git remote  (只能查看遠程倉庫的名字)
#查看單個倉庫 git remote show [remote-branch-name] #新建遠程倉庫 git remote add [branchname] [url] #修改遠程倉庫 git remote rename [oldname] [newname] #刪除遠程倉庫 git remote rm [remote-name] #獲取遠程倉庫數據 git fetch [remote-name] (獲取倉庫全部更新,但不自動合併當前分支) git pull (獲取倉庫全部更新,並自動合併到當前分支) #上傳數據,如git push origin master git push [remote-name] [branch]

5.2.二、git clone 克隆

遠程操做的第一步,一般是從遠程主機克隆一個版本庫,這時就要用到git clone命令。

$ git clone <版本庫的網址>

好比,克隆一個上課示例的版本庫。

$ git clone https://github.com/zhangguo5/AngularJS04_BookStore.git

該命令會在本地主機生成一個目錄,與遠程主機的版本庫同名。若是要指定不一樣的目錄名,能夠將目錄名做爲git clone命令的第二個參數。

$ git clone <版本庫的網址> <本地目錄名>

git clone支持多種協議,除了HTTP(s)之外,還支持SSH、Git、本地文件協議等,下面是一些例子。

$ git clone http[s]://example.com/path/to/repo.git/
$ git clone ssh://example.com/path/to/repo.git/
$ git clone git://example.com/path/to/repo.git/
$ git clone /opt/git/project.git 
$ git clone file:///opt/git/project.git
$ git clone ftp[s]://example.com/path/to/repo.git/
$ git clone rsync://example.com/path/to/repo.git/

SSH協議還有另外一種寫法。

$ git clone [user@]example.com:path/to/repo.git/

一般來講,Git協議下載速度最快,SSH協議用於須要用戶認證的場合。各類協議優劣的詳細討論請參考 官方文檔

5.2.三、git remote

爲了便於管理,Git要求每一個遠程主機都必須指定一個主機名。git remote命令就用於管理主機名。

不帶選項的時候,git remote命令列出全部遠程主機。

$ git remote

使用-v選項,能夠參看遠程主機的網址。

$ git remote -v

上面命令表示,當前只有一臺遠程主機,叫作origin,以及它的網址。

克隆版本庫的時候,所使用的遠程主機自動被Git命名爲origin。若是想用其餘的主機名,須要用git clone命令的-o選項指定。

$ git clone -o WeUI https://github.com/Tencent/weui.git
$ git remote

git remote show命令加上主機名,能夠查看該主機的詳細信息。

$ git remote show <主機名>

git remote add命令用於添加遠程主機。

$ git remote add <主機名> <網址>

git remote rm命令用於刪除遠程主機。

$ git remote rm <主機名>

git remote rename命令用於遠程主機的更名。

$ git remote rename <原主機名> <新主機名>

5.2.四、git fetch

一旦遠程主機的版本庫有了更新(Git術語叫作commit),須要將這些更新取回本地,這時就要用到git fetch命令。

$ git fetch <遠程主機名>

上面命令將某個遠程主機的更新,所有取回本地。

git fetch命令一般用來查看其餘人的進程,由於它取回的代碼對你本地的開發代碼沒有影響。

默認狀況下,git fetch取回全部分支(branch)的更新。若是隻想取回特定分支的更新,能夠指定分支名。

$ git fetch <遠程主機名> <分支名>

 

好比,取回origin主機的master分支。

$ git fetch origin master

所取回的更新,在本地主機上要用"遠程主機名/分支名"的形式讀取。好比origin主機的master,就要用origin/master讀取。

git branch命令的-r選項,能夠用來查看遠程分支,-a選項查看全部分支。

$ git branch -r
origin/master

$ git branch -a
* master
  remotes/origin/master

上面命令表示,本地主機的當前分支是master,遠程分支是origin/master

取回遠程主機的更新之後,能夠在它的基礎上,使用git checkout命令建立一個新的分支。

$ git checkout -b newBrach origin/master

上面命令表示,在origin/master的基礎上,建立一個新分支。

此外,也可使用git merge命令或者git rebase命令,在本地分支上合併遠程分支。

$ git merge origin/master
# 或者
$ git rebase origin/master

上面命令表示在當前分支上,合併origin/master

5.2.五、git pull

git pull命令的做用是,取回遠程主機某個分支的更新,再與本地的指定分支合併。它的完整格式稍稍有點複雜。

$ git pull <遠程主機名> <遠程分支名>:<本地分支名>

好比,取回origin主機的next分支,與本地的master分支合併,須要寫成下面這樣。

$ git pull origin next:master

若是遠程分支是與當前分支合併,則冒號後面的部分能夠省略。

$ git pull origin next

上面命令表示,取回origin/next分支,再與當前分支合併。實質上,這等同於先作git fetch,再作git merge

$ git fetch origin
$ git merge origin/next

在某些場合,Git會自動在本地分支與遠程分支之間,創建一種追蹤關係(tracking)。好比,在git clone的時候,全部本地分支默認與遠程主機的同名分支,創建追蹤關係,也就是說,本地的master分支自動"追蹤"origin/master分支。

Git也容許手動創建追蹤關係。

git branch --set-upstream master origin/next

上面命令指定master分支追蹤origin/next分支。

若是當前分支與遠程分支存在追蹤關係,git pull就能夠省略遠程分支名。

$ git pull origin

上面命令表示,本地的當前分支自動與對應的origin主機"追蹤分支"(remote-tracking branch)進行合併。

若是當前分支只有一個追蹤分支,連遠程主機名均可以省略。

$ git pull

上面命令表示,當前分支自動與惟一一個追蹤分支進行合併。

若是合併須要採用rebase模式,可使用--rebase選項。

$ git pull --rebase <遠程主機名> <遠程分支名>:<本地分支名>

若是遠程主機刪除了某個分支,默認狀況下,git pull 不會在拉取遠程分支的時候,刪除對應的本地分支。這是爲了防止,因爲其餘人操做了遠程主機,致使git pull不知不覺刪除了本地分支。

可是,你能夠改變這個行爲,加上參數 -p 就會在本地刪除遠程已經刪除的分支。

$ git pull -p
# 等同於下面的命令
$ git fetch --prune origin 
$ git fetch -p

5.2.六、git push

git push命令用於將本地分支的更新,推送到遠程主機。它的格式與git pull命令相仿。

$ git push <遠程主機名> <本地分支名>:<遠程分支名>

注意,分支推送順序的寫法是<來源地>:<目的地>,因此git pull是<遠程分支>:<本地分支>,而git push是<本地分支>:<遠程分支>。

若是省略遠程分支名,則表示將本地分支推送與之存在"追蹤關係"的遠程分支(一般二者同名),若是該遠程分支不存在,則會被新建。

$ git push origin master

上面命令表示,將本地的master分支推送到origin主機的master分支。若是後者不存在,則會被新建。

若是省略本地分支名,則表示刪除指定的遠程分支,由於這等同於推送一個空的本地分支到遠程分支。

$ git push origin :master
# 等同於
$ git push origin --delete master

上面命令表示刪除origin主機的master分支。

若是當前分支與遠程分支之間存在追蹤關係,則本地分支和遠程分支均可以省略。

$ git push origin

上面命令表示,將當前分支推送到origin主機的對應分支。

若是是新建分支第一次push,會提示:
  fatal: The current branch dev1 has no upstream branch.
  To push the current branch and set the remote as upstream, use
  git push --set-upstream origin dev1
  輸入這行命令,而後輸入用戶名和密碼,就push成功了。

  之後的push就只須要輸入git push origin

緣由是:

#由於在git的全局配置中,有一個push.default屬性,其決定了git push操做的默認行爲。在Git 2.0以前,這個屬性的默認被設爲'matching',2.0以後則被更改成了'simple'。

#咱們能夠經過git version肯定當前的git版本(若是小於2.0,更新是個更好的選擇),經過git config --global push.default 'option'改變push.default的默認行爲(或者也可直接編輯~/.gitconfig文件)。

push.default 有如下幾個可選值:
nothing, current, upstream, simple, matching

其用途分別爲:
nothing - push操做無效,除非顯式指定遠程分支,例如git push origin develop(我以爲。。。能夠給那些不肯學git的同事配上此項)。
current - push當前分支到遠程同名分支,若是遠程同名分支不存在則自動建立同名分支。
upstream - push當前分支到它的upstream分支上(這一項其實用於常常從本地分支push/pull到同一遠程倉庫的情景,這種模式叫作central workflow)。
simple - simple和upstream是類似的,只有一點不一樣,simple必須保證本地分支和它的遠程
upstream分支同名,不然會拒絕push操做。
matching - push全部本地和遠程兩端都存在的同名分支。
所以若是咱們使用了git2.0以前的版本,push.default = matching,git push後則會推送當前分支代碼到遠程分支,而2.0以後,push.default = simple,若是沒有指定當前分支的upstream分支,就會收到上文的fatal提示。

 

若是當前分支只有一個追蹤分支,那麼主機名均可以省略。

$ git push

若是當前分支與多個主機存在追蹤關係,則可使用-u選項指定一個默認主機,這樣後面就能夠不加任何參數使用git push

$ git push -u origin master

上面命令將本地的master分支推送到origin主機,同時指定origin爲默認主機,後面就能夠不加任何參數使用git push了。

不帶任何參數的git push,默認只推送當前分支,這叫作simple方式。此外,還有一種matching方式,會推送全部有對應的遠程分支的本地分支。Git 2.0版本以前,默認採用matching方法,如今改成默認採用simple方式。若是要修改這個設置,能夠採用git config命令。

$ git config --global push.default matching
# 或者
$ git config --global push.default simple

還有一種狀況,就是無論是否存在對應的遠程分支,將本地的全部分支都推送到遠程主機,這時須要使用--all選項。

$ git push --all origin

上面命令表示,將全部本地分支都推送到origin主機。

若是遠程主機的版本比本地版本更新,推送時Git會報錯,要求先在本地作git pull合併差別,而後再推送到遠程主機。這時,若是你必定要推送,可使用--force選項。

$ git push --force origin 

上面命令使用--force選項,結果致使遠程主機上更新的版本被覆蓋。除非你很肯定要這樣作,不然應該儘可能避免使用--force選項。

最後,git push不會推送標籤(tag),除非使用--tags選項。

$ git push origin --tags

 

6、資源與資料下載

資料連接: https://pan.baidu.com/s/1c20DVOW  密碼: p9ri

Git教程下載_王亮(大神)

相關文章
相關標籤/搜索