一、版本控制概要
1.1、什么是版本控制
版本控制(Revision control)是一種在開發的過程中用於管理我們對文件、目錄或工程等內容的修改歷史,方便查看更改歷史記錄,備份以便恢復以前的版本的軟件工程技術。
- 實現跨區域多人協同開發
- 追蹤和記載一個或者多個文件的歷史記錄
- 組織和保護你的源代碼和文檔
- 統計工作量
- 並行開發、提高開發效率
- 跟蹤記錄整個軟件的開發過程
- 減輕開發人員的負擔,節省時間,同時降低人為錯誤
簡單說就是用於管理多人協同開發項目的技術。
沒有進行版本控制或者版本控制本身缺乏正確的流程管理,在軟件開發過程中將會引入很多問題,如軟件代碼的一致性、軟件內容的冗余、軟件過程的事物性、軟件開發過程中的並發性、軟件源代碼的安全性,以及軟件的整合等問題。
1.2、常用術語
1)、倉庫(Repository)
受版本控制的所有文件修訂歷史的共享數據庫(.git)
2)、工作空間(Workspace)
本地硬盤或Unix 用戶帳戶上編輯的文件副本(也就是是你在電腦里能看到的目錄)
3)、工作樹/區(Working tree)
工作區中包含了倉庫的工作文件。您可以修改的內容和提交更改作為新的提交到倉庫。
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.3、常見的版本控制器
主流的版本控制器有如下這些:
- 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與SVN
1.4、版本控制分類
1.4.1、本地版本控制
記錄文件每次的更新,可以對每個版本做一個快照,或是記錄補丁文件,適合個人用,如RCS。
1.4.2、集中版本控制
所有的版本數據都保存在服務器上,協同開發者從服務器上同步更新或上傳自己的修改
所有的版本數據都存在服務器上,用戶的本地只有自己以前所同步的版本,如果不連網的話,用戶就看不到歷史版本,也無法切換版本驗證問題,或在不同分支工作。而且,所有數據都保存在單一的服務器上,有很大的風險這個服務器會損壞,這樣就會丟失所有的數據,當然可以定期備份。代表產品:SVN、CVS、VSS
1.4.3、分布式版本控制
所有版本信息倉庫全部同步到本地的每個用戶,這樣就可以在本地查看所有版本歷史,可以離線在本地提交,只需在連網時push到相應的服務器或其他用戶那里。由於每個用戶那里保存的都是所有的版本數據,只要有一個用戶的設備沒有問題就可以恢復所有的數據,但這增加了本地存儲空間的占用。
1.5、Git與SVN最主要區別
SVN是集中式版本控制系統,版本庫是集中放在中央服務器的,而工作的時候,用的都是自己的電腦,所以首先要從中央服務器得到最新的版本,然后工作,完成工作后,需要把自己做完的活推送到中央服務器。集中式版本控制系統是必須聯網才能工作,對網絡帶寬要求較高。
Git是分布式版本控制系統,沒有中央服務器,每個人的電腦就是一個完整的版本庫,工作的時候不需要聯網了,因為版本都在自己電腦上。協同的方法是這樣的:比如說自己在電腦上改了文件A,其他人也在電腦上改了文件A,這時,你們兩之間只需把各自的修改推送給對方,就可以互相看到對方的修改了。
二、Git安裝與配置
2.1、什么是Git
Git是目前世界上最先進的分布式版本控制系統。
Git是免費、開源的
最初Git是為輔助 Linux 內核開發的,來替代 BitKeeper
作者:Linux和Git之父李納斯·托沃茲(Linus Benedic Torvalds)1969、芬蘭
優點:
- 適合分布式開發,強調個體。
- 公共服務器壓力和數據量都不會太大。
- 速度快、靈活。
- 任意兩個開發者之間可以很容易的解決沖突。
- 離線工作。
缺點:
- 模式上比SVN更加復雜。
- 不符合常規思維。
- 代碼保密性差,一旦開發者把整個庫克隆下來就可以完全公開所有代碼和版本信息。
官網: git-scm.com/
2.2、搭建Git工作環境
Mac OS中無需下載安裝,安裝xcode時自帶安裝了git環境。以下主降Windows下git的環境搭建
2.2.1、下載Git
打開 git官網,下載git對應操作系統的版本。
選擇版本:
這里我選擇下載64-bit Git for Windows Setup
2.2.2、安裝Git
選擇安裝配置信息
一直Next默認就好了,如果需要設置就要仔細讀一下安裝界面上的選項。
2.2.3、啟動Git
安裝成功后在開始菜單中會有Git項,菜單下有3個程序:
- Git Bash:Unix與Linux風格的命令行,使用最多,推薦最多
與DOS風格的命令有些區別,不習慣可以選擇Git CMD - Git CMD:Windows風格的命令行
- Git GUI:圖形界面的Git,不建議初學者使用,盡量先熟悉常用命令
點擊Create New Repository可以直接創建一個新的倉庫。
2.2.4、Linux與Mac OS安裝Git
Linux安裝Git:sudo apt-get install git 命令行就可以安裝了。
Mac OS安裝Git: git-scm.com/download/ma…,下載雙擊.pkg安裝
2.2.5、Bash基本操作命令
- cd : 改變目錄。
- cd . . 回退到上一個目錄,直接cd進入默認目錄
- pwd : 顯示當前所在的目錄路徑。
- ls(ll): 都是列出當前目錄中的所有文件,只不過ll(兩個ll)列出的內容更為詳細。
- touch : 新建一個文件 如 touch index.js 就會在當前目錄下新建一個index.js文件。
- rm: 刪除一個文件, rm index.js 就會把index.js文件刪除。
- mkdir: 新建一個目錄,就是新建一個文件夾。
- rm -r : 刪除一個文件夾, rm -r src 刪除src目錄, 好像不能用通配符。
- mv 移動文件, mv index.html src index.html 是我們要移動的文件, src 是目標文件夾,當然, 這樣寫,必須保證文件和目標文件夾在同一目錄下。
- reset 重新初始化終端/清屏。
- clear 清屏。
- history 查看命令歷史。
- help 幫助。
- exit 退出。
- # 表示注釋
- echo輸出與注釋
- cat 顯示文件內容
2.3、Git配置 - git config
2.3.1、查看配置 - git config -l
使用git config -l 可以查看現在的git環境詳細配置
- Windows
- Mac
查看不同級別的配置文件:
#查看系統config git config --system --list
#查看當前用戶(global)配置 git config --global --list
#查看當前倉庫配置信息 git config --local --list
2.3.2、Git配置文件分類
- Windows
在Windows系統中,Git在$HOME目錄中查找.gitconfig文件(一般位於C:\Documents and Settings\$USER下)
Git相關的配置文件有三個:
- /etc/gitconfig:包含了適用於系統所有用戶和所有項目的值。(Win:C:\Program Files\Git\mingw64\etc\gitconfig) --system 系統級
- ~/.gitconfig:只適用於當前登錄用戶的配置。(Win:C:\Users\Administrator\.gitconfig) --global 全局
- 位於git項目目錄中的.git/config:適用於特定git項目的配置。(Win:C:\gitProject) --local當前項目
- /etc/gitconfig:包含了適用於系統所有用戶和所有項目的值。(Win:C:\Program Files\Git\mingw64\etc\gitconfig) --system 系統級
- Mac
Git相關的配置文件也有三個:
- /etc/gitconfig:包含了適用於系統所有用戶和所有項目的值。--system 系統級
- ~/.gitconfig:只適用於當前登錄用戶的配置。(/Users/個人賬戶) --global 全局
- 位於git項目目錄中的.git/config:適用於特定git項目的配置。(/Users/用戶名/desktop/git倉庫/.git) --local當前項目
- /etc/gitconfig:包含了適用於系統所有用戶和所有項目的值。--system 系統級
注意:對於同一配置項,三個配置文件的優先級是1<2<3
這里可以直接編輯配置文件,通過命令設置后會響應到這里。
2.3.3、設置用戶名與郵箱(用戶標識,必要)
當你安裝Git后首先要做的事情是設置你的用戶名稱和e-mail地址。這是非常重要的,因為每次Git提交都會使用該信息。它被永遠的嵌入到了你的提交中:
$ git config --global user.name "zhangguo" #名稱 $ git config --global user.email zhangguo@qq.com #郵箱
只需要做一次這個設置,如果你傳遞了--global 選項,因為Git將總是會使用該信息來處理你在系統中所做的一切操作。如果你希望在一個特定的項目中使用不同的名稱或e-mail地址,你可以在該項目中運行該命令而不要--global選項。 總之--global為全局配置,不加為某個項目的特定配置。
2.3.4、添加或刪除配置項
git config [--local|--global|--system] section.key value
[--local|--global|--system] #可選的,對應本地,全局,系統不同級別的設置,請看2.3.2
section.key #區域下的鍵
value #對應的值
--local 項目級
--global 當前用戶級
--system 系統級
例如我們要在student區域下添加一個名稱為height值為198的配置項,執行結果如下:
2)、刪除配置項
將系統級的height配置項移除
2.3.5、更多配置項
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) 顯示配置(文件、標准輸入、數據塊、命令行)的來源
三、Git理論基礎
3.1、工作區域
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.2、工作流程
git的工作流程一般是這樣的:
1、在工作目錄中添加、修改文件;
2、將需要進行版本管理的文件放入暫存區域;
3、將暫存區域的文件提交到git倉庫。
因此,git管理的文件有三種狀態:已修改(modified),已暫存(staged),已提交(committed)
3.3、圖解教程
個人認為Git的原理相比別的版本控制器還是復雜一些的,有一份圖解教程比較直觀:
四、Git操作
4.1、創建工作目錄與常用指令
工作目錄(WorkSpace)一般就是你希望Git幫助你管理的文件夾,可以是你項目的目錄,也可以是一個空目錄,建議不要有中文。
日常使用只要記住下圖6個命令:
4.2、獲得GIT倉庫
創建本地倉庫的方法有兩種:一種是創建全新的倉庫,另一種是克隆遠程倉庫。
4.2.1、創建全新倉庫
使用如下命令,可以把創建目錄與倉庫一起完成:
# 新建一個目錄,將其初始化為Git代碼庫 $ git init [project-name]
執行:
結果:
執行后可以看到,僅僅在項目目錄多出了一個.git目錄,關於版本等的所有信息都在這個目錄里面。
如果不需要一起創建,在已有的文件夾里進行創建倉庫的方法:
# 在當前目錄新建一個Git代碼庫 $ git init
4.2.2、克隆遠程倉庫
另一種方式是克隆遠程目錄,由於是將遠程服務器上的倉庫完全鏡像一份至本地,而不是取某一個特定版本,所以用clone而不是checkout,語法格式如下:
# 克隆一個項目和它的整個代碼歷史(版本信息) $ git clone [url]
執行:
比如我們要從克隆的遠程倉庫托管在github上,地址為:https://github.com/zhangguo5/SuperPlus.git,這是一個公開的項目
結果:
4.3、GIT文件操作
版本控制就是對文件的版本控制,要對文件進行修改、提交等操作,首先要知道文件當前在什么狀態,不然可能會提交了現在還不想提交的文件,或者要提交的文件沒提交上。GIT不關心文件兩個版本之間的具體差別,而是關心文件的整體是否有改變,若文件被改變,在添加提交時就生成文件新版本的快照,而判斷文件整體是否改變的方法就是用SHA-1算法計算文件的校驗和。
4.3.1、文件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.2、查看文件狀態
上面說文件有4種狀態,通過如下命令可以查看到文件的狀態:
#查看指定文件狀態
git status [filename]
#查看所有文件狀態
git status
命令:
結果:
foo.htm文件的狀態為untracked(未跟蹤),提示通過git add可以暫存
GIT在這一點做得很好,在輸出每個文件狀態的同時還說明了怎么操作,像上圖就有怎么暫存、怎么跟蹤文件、怎么取消暫存的說明。
4.3.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.4、移除文件與目錄(撤銷add)
當執行如下命令時,會直接從暫存區刪除文件,工作區則不做出改變
#直接從暫存區刪除文件,工作區則不做出改變
git rm --cached <file>
執行命令
通過重寫目錄樹移除add文件:
#如果已經用add 命令把文件加入stage了,就先需要從stage中撤銷
git reset HEAD <file>...
當執行 “git reset HEAD” 命令時,暫存區的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,但是工作區不受影響。
示例:把f1.txt文件從暫存區撤回工作區
移除所有未跟蹤文件
#移除所有未跟蹤文件
#一般會加上參數-df,-d表示包含目錄,-f表示強制清除。
git clean [options]
示例:
移除前:
執行移除:
移除后:
當執行提交操作(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.5、查看文件修改后的差異
git diff用於顯示WorkSpace中的文件和暫存區文件的差異
用"git status"只能查看對哪些文件做了改動,如果要看改動了什么,可以用:
#查看文件修改后的差異
git diff [files]
命令:
---a表示修改之前的文件,+++b表示修改后的文件
#比較暫存區的文件與之前已經提交過的文件
git diff --cached
也可以把WorkSpace中的狀態和repo中的狀態進行diff,命令如下:
#比較repo與工作空間中的文件差異
git diff HEAD~n
4.3.6、簽出
如果倉庫中已經存在文件f4.txt,在工作區中對f4修改了,如果想撤銷可以使用checkout,簽出覆蓋
檢出命令git checkout是git最常用的命令之一,同時也是一個很危險的命令,因為這條命令會重寫工作區
語法:
<commit>是可選項,如果省略則相當於從暫存區(index)進行檢出
示例:
4.3.6、忽略文件
有些時候我們不想把某些文件納入版本控制中,比如數據庫文件,臨時文件,設計文件等
在主目錄下建立".gitignore"文件,此文件有如下規則:
- 忽略文件中的空行或以井號(#)開始的行將會被忽略。
- 可以使用Linux通配符。例如:星號(*)代表任意多個字符,問號(?)代表一個字符,方括號([abc])代表可選字符范圍,大括號({string1,string2,...})代表可選的字符串等。
- 如果名稱的最前面有一個感嘆號(!),表示例外規則,將不被忽略。
- 如果名稱的最前面是一個路徑分隔符(/),表示要忽略的文件在此目錄下,而子目錄中的文件不忽略。
- 如果名稱的最后面是一個路徑分隔符(/),表示要忽略的是此目錄下該名稱的子目錄,而非文件(默認文件或目錄都忽略)。
如:
示例:
創建一個.gitignore文件忽視所有的日志文件
查看狀態:
從上圖中可以看出2個日志文件並沒有添加到暫存區,直接被忽視了。
針對各種語言與項目的Git忽視文件: https://github.com/kaedei/gitignore https://github.com/github/gitignore
通用的java忽視文件:
通用的Visual Studio開發項目忽視文件:
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Typescript v1 declaration files
typings/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
idea忽視文件:
.idea/ *.iml out/ gen/ idea-gitignore.jar resources/templates.list resources/gitignore/* build/ build.properties junit*.properties IgnoreLexer.java~ .gradle /verification
4.3.7、提交
通過add只是將文件或目錄添加到了index暫存區,使用commit可以實現將暫存區的文件提交到本地倉庫。
示例:
提交前的狀態
提交:
提交后的狀態:
從上圖中可以看出暫存區中沒有了bar.htm
修訂提交
如果我們提交過后發現有個文件改錯了,或者只是想修改提交說明,這時可以對相應文件做出修改,將修改過的文件通過"git add"添加到暫存區,然后執行以下命令:
#修訂提交
git commit --amend
撤銷提交(commit)
原理就是放棄工作區和index的改動,同時HEAD指針指向前一個commit對象
#撤銷上一次的提交 git reset --hard HEAD~1
要通過git log查看提交日志,也可直接指定提交編號或序號
示例:
撤銷提交
git revert <commit-id>
這條命令會把指定的提交的所有修改回滾,並同時生成一個新的提交。
4.3.8、日志與歷史
查看提交日志可以使用git log指令,語法格式如下:
#查看提交日志
git log [<options>] [<revision range>] [[\--] <path>…?]
示例:
"git log --graph"以圖形化的方式顯示提交歷史的關系,這就可以方便地查看提交歷史的分支信息,當然是控制台用字符畫出來的圖形。
"git log -1"則表示顯示1行。
使用history可以查看您在bash下輸入過的指令:
幾乎所有輸入過的都被記錄下來的,不愧是做版本控制的。
查看所有分支日志
"git reflog"中會記錄這個倉庫中所有的分支的所有更新記錄,包括已經撤銷的更新。
4.3.9、查看文件列表
使用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.10、撤銷更新
1)、撤銷暫存區更新
使用"git add"把更新提交到了暫存區。這時"git status"的輸出中提示我們可以通過"git reset HEAD <file>..."把暫存區的更新移出到WorkSpace中
示例:f6已經提交,工作區修改,暫存區修改,撤銷
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
示例:回退到添加f6
回退前:
回退后:
現在又想恢復被撤銷的提交可用"git reflog"查看倉庫中所有的分支的所有更新記錄,包括已經撤銷的更新,撤銷方法與前面一樣。
git reset --hard HEAD@{7} git reset --hard e0e79d7
--hard:撤銷並刪除相應的更新
--soft:撤銷相應的更新,把這些更新的內容放到Stage中
4.3.11、刪除文件
1)、刪除未跟蹤文件
如果文件還是未跟蹤狀態,直接刪除文件就可了,bash中使用rm可以刪除文件,示例如下:
2)、刪除已提交文件
-f 強制刪除,物理刪除了,同時刪除工作區和暫存區中的文件
撤銷刪除:
#to discard changes in working directory git checkout -- <file>...
3)、刪除暫存區的文件,不刪除工作區的文件
使用git reset HEAD <file>...同樣可以實現上面的功能
4.3.12、文件操作小結
Git很強大,很靈活,這是毋庸置疑的。但也正因為它的強大造成了它的復雜,因此會有很多奇奇怪怪的問題出現,多用就好了。
4.4、GIT分支
分支在GIT中相對較難
分支就是科幻電影里面的平行宇宙,當你正在電腦前努力學習Git的時候,另一個你正在另一個平行宇宙里努力學習SVN。
如果兩個平行宇宙互不干擾,那對現在的你也沒啥影響。不過,在某個時間點,兩個平行宇宙合並了,結果,你既學會了Git又學會了SVN!
分支在實際中有什么用呢?假設你准備開發一個新功能,但是需要兩周才能完成,第一周你寫了50%的代碼,如果立刻提交,由於代碼還沒寫完,不完整的代碼庫會導致別人不能干活了。如果等代碼全部寫完再一次提交,又存在丟失每天進度的巨大風險。
現在有了分支,就不用怕了。你創建了一個屬於你自己的分支,別人看不到,還繼續在原來的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到開發完畢后,再一次性合並到原來的分支上,這樣,既安全,又不影響別人工作。
Git分支的速度非常快。
截止到目前,只有一條時間線,在Git里,這個分支叫主分支,即master分支。HEAD嚴格來說不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是當前分支。
git分支中常用指令:
4.4.1、新建分支與切換分支
每次提交,Git都把它們串成一條時間線,這條時間線就是一個分支。截止到目前,只有一條時間線,在Git里,這個分支叫主分支,即master分支。HEAD嚴格來說不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是當前分支。
一開始的時候,master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能確定當前分支,以及當前分支的提交點:
每次提交,master分支都會向前移動一步,這樣,隨着你不斷提交,master分支的線也越來越長:
默認分支是這樣的,master是主分支
1)、新建一個分支,但依然停留在當前分支,使用:$ git branch [branch-name]
切換分支到dev1后的結果:
當我們創建新的分支,例如dev
時,Git新建了一個指針叫dev
,指向master
相同的提交,再把HEAD
指向dev
,就表示當前分支在dev
上:
你看,Git創建一個分支很快,因為除了增加一個dev
指針,改改HEAD
的指向,工作區的文件都沒有任何變化!
不過,從現在開始,對工作區的修改和提交就是針對dev
分支了,比如新提交一次后,dev
指針往前移動一步,而master
指針不變:
假如我們在dev
上的工作完成了,就可以把dev
合並到master
上。Git怎么合並呢?最簡單的方法,就是直接把master
指向dev
的當前提交,就完成了合並:
所以Git合並分支也很快!就改改指針,工作區內容也不變!
合並完分支后,甚至可以刪除dev
分支。刪除dev
分支就是把dev
指針給刪掉,刪掉后,我們就剩下了一條master
分支:
動畫演示:
2)、切換分支,git branch <name>,如果name為-則為上一個分支
切換為上一個分支
3)、新建一個分支,並切換到該分支,$ git checkout -b [branch]
4)、新建一個分支,指向指定commit使用命令:$ git branch [branch] [commit]
上面創建了dev3分支且指向了master中首次提交的位置,切換到dev3查看日志如下:
master上本來有兩個提交記錄的,此時的dev3指向的是第1次提交的位置
5)、新建一個分支,與指定的遠程分支建立追蹤關系使用命令:$ git branch --track [branch] [remote-branch]
4.4.2、查看分支
1)、列出所有本地分支使用$ git branch
2)、列表所有遠程分支使用$ git branch -r
3)、列出所有本地分支和遠程分支使用$ git branch -a
4.4.3、分支合並
合並指定分支到當前分支使用指令$ git merge [branch]
這里的合並分支就是對分支的指針操作,我們先創建一個分支再合並到主分支:
這里的file11.txt主分支與dev6的內容現在是不同的,因為在dev6中已被修改過,我們可以使用指令查看:
現在我們將dev6合並到主分支中去,從下圖中可以看出dev6中有一次提交,而master並沒有
合並后在master上查看file11.txt文件內容與dev6上的內容就一樣了,合並后dev6中多出的提交在master也擁有了。
4.4.4、解決沖突
如果同一個文件在合並分支時都被修改了則會引起沖突,如下所示:
提交前兩個分支的狀態
在dev6分支中同樣修改file11.txt
dev6與master分支中file11.txt文件都被修改且提交了,現在合並分支
提示沖突,現在我們看看file11.txt在master分支中的狀態
Git用<<<<<<<,=======,>>>>>>>標記出不同分支的內容,其中<<<HEAD是指主分支修改的內容,>>>>>dev6 是指dev6上修改的內容
解決的辦法是我們可以修改沖突文件后重新提交,請注意當前的狀態產master | MERGING:
重新提交后沖突解決:
手動解決完沖突后就可以把此文件添 加到索引(index)中去,用git commit命令來提交,就像平時修改了一個文件 一樣。
用git log --graph命令可以看到分支合並圖。
分支策略
master主分支應該非常穩定,用來發布新版本,一般情況下不允許在上面工作,工作一般情況下在新建的dev分支上工作,工作完后,比如上要發布,或者說dev分支代碼穩定后可以合並到主分支master上來。
4.4.5、刪除分支
刪除本地分支可以使用命令:$ git branch -d [branch-name],-D(大寫)強制刪除
刪除遠程分支可以使用如下指令:
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]
-d表示刪除分支。分支必須完全合並在其上游分支,或者在HEAD上沒有設置上游
-r表示遠程的意思remotes,如果-dr則表示刪除遠程分支
五、資源與資料下載
- 權威Git書籍 ProGit(中文版)
- git官網: http://git-scm.com
- git手冊: http://git-scm.com/docs
- 網友整理的Git@osc教程,請 點擊這里;
- 一份很好的 Git 入門教程,請 點擊這里;
- Git圖解教程
- 一個小時學會git