在使用Git的過程當中,咱們喜歡有的文件好比日誌,臨時文件,編譯的中間文件等不要提交到代碼倉庫,這時就要設置相應的忽略規則,來忽略這些文件的提交。簡單來講一個場景:在你使用git add .的時候,遇到了把你不想提交的文件也添加到了緩存中去的狀況,好比項目的本地配置信息,若是你上傳到Git中去其餘人pull下來的時候就會和他本地的配置有衝突,因此這樣的個性化配置文件咱們通常不把它推送到git服務器中,可是又爲了偷懶每次添加緩存的時候都想用git add .而不是手動一個一個文件添加,該怎麼辦呢?很簡單,git爲咱們提供了一個.gitignore文件只要在這個文件中申明那些文件你不但願添加到git中去,這樣當你使用git add .的時候這些文件就會被自動忽略掉。php
有三種方法能夠實現忽略Git中不想提交的文件:
1)在Git項目中定義.gitignore文件
對於常用Git的朋友來講,.gitignore配置必定不會陌生。這種方式經過在項目的某個文件夾下定義.gitignore文件,在該文件中定義相應的忽略規則,來管理當前文件夾下的文件的Git提交行爲。.gitignore 文件是能夠提交到公有倉庫中,這就爲該項目下的全部開發者都共享一套定義好的忽略規則。在.gitingore 文件中,遵循相應的語法,在每一行指定一個忽略規則。如:java
1
2
3
|
*.log
*.temp
/vendor
|
2)在Git項目的設置中指定排除文件
這種方式只是臨時指定該項目的行爲,須要編輯當前項目下的 .git/info/exclude文件,而後將須要忽略提交的文件寫入其中。須要注意的是,這種方式指定的忽略文件的根目錄是項目根目錄。linux
3)定義Git全局的 .gitignore 文件
除了能夠在項目中定義 .gitignore 文件外,還能夠設置全局的git .gitignore文件來管理全部Git項目的行爲。這種方式在不一樣的項目開發者之間是不共享的,是屬於項目之上Git應用級別的行爲。這種方式也須要建立相應的 .gitignore 文件,能夠放在任意位置。而後在使用如下命令配置Git:ios
1
|
# git config --global core.excludesfile ~/.gitignore
|
首先要強調一點,這個文件的完整文件名就是".gitignore",注意最前面有個「.」。通常來講每一個Git項目中都須要一個「.gitignore」文件,這個文件的做用就是告訴Git哪些文件不須要添加到版本管理中。實際項目中,不少文件都是不須要版本管理的,好比Python的.pyc文件和一些包含密碼的配置文件等等。這個文件的內容是一些規則,Git會根據這些規則來判斷是否將文件添加到版本控制中。git
Git忽略文件的原則
- 忽略操做系統自動生成的文件,好比縮略圖等;
- 忽略編譯生成的中間文件、可執行文件等,也就是若是一個文件是經過另外一個文件自動生成的,那自動生成的文件就不必放進版本庫,好比Java編譯產生的.class文件;
- 忽略你本身的帶有敏感信息的配置文件,好比存放口令的配置文件。github
.gitignore文件的使用方法
首先,在你的工做區新建一個名稱爲.gitignore的文件。
而後,把要忽略的文件名填進去,Git就會自動忽略這些文件。
不須要從頭寫.gitignore文件,GitHub已經爲咱們準備了各類配置文件,只須要組合一下就可使用了。正則表達式
有時對於git項目下的某些文件,咱們不須要歸入版本控制,好比日誌文件或者IDE的配置文件,此時能夠在項目的根目錄下創建一個隱藏文件 .gitignore(linux下以.開頭的文件都是隱藏文件),而後在.gitignore中寫入須要忽略的文件。shell
1
2
3
4
|
[root@kevin ~]
# cat .gitignore
*.xml
*.log
*.apk
|
.gitignore註釋用'#', *表示匹配0個或多個任意字符,因此上面的模式就是要忽略全部的xml文件,log文件和apk文件。緩存
.gitignore配置文件用於配置不須要加入版本管理的文件,配置好該文件能夠爲版本管理帶來很大的便利。bash
.gitignore忽略規則的優先級
在 .gitingore 文件中,每一行指定一個忽略規則,Git檢查忽略規則的時候有多個來源,它的優先級以下(由高到低):
1)從命令行中讀取可用的忽略規則
2)當前目錄定義的規則
3)父級目錄定義的規則,依次遞推
4)$GIT_DIR/info/exclude 文件中定義的規則
5)core.excludesfile中定義的全局規則
.gitignore忽略規則的匹配語法
在 .gitignore 文件中,每一行的忽略規則的語法以下:
1)空格不匹配任意文件,可做爲分隔符,可用反斜槓轉義
2)以「#」開頭的行都會被 Git 忽略。即#開頭的文件標識註釋,可使用反斜槓進行轉義。
3)可使用標準的glob模式匹配。所謂的glob模式是指shell所使用的簡化了的正則表達式。
4)以斜槓"/"開頭表示目錄;"/"結束的模式只匹配文件夾以及在該文件夾路徑下的內容,可是不匹配該文件;"/"開始的模式匹配項目跟目錄;若是一個模式不包含斜槓,則它匹配相對於當前 .gitignore 文件路徑的內容,若是該模式不在 .gitignore 文件中,則相對於項目根目錄。
5)以星號"*"通配多個字符,即匹配多個任意字符;使用兩個星號"**" 表示匹配任意中間目錄,好比`a/**/z`能夠匹配 a/z, a/b/z 或 a/b/c/z等。
6)以問號"?"通配單個字符,即匹配一個任意字符;
7)以方括號"[]"包含單個字符的匹配列表,即匹配任何一個列在方括號中的字符。好比[abc]表示要麼匹配一個a,要麼匹配一個b,要麼匹配一個c;若是在方括號中使用短劃線分隔兩個字符,表示全部在這兩個字符範圍內的均可以匹配。好比[0-9]表示匹配全部0到9的數字,[a-z]表示匹配任意的小寫字母)。
8)以歎號"!"表示不忽略(跟蹤)匹配到的文件或目錄,即要忽略指定模式之外的文件或目錄,能夠在模式前加上驚歎號(!)取反。須要特別注意的是:若是文件的父目錄已經被前面的規則排除掉了,那麼對這個文件用"!"規則是不起做用的。也就是說"!"開頭的模式表示否認,該文件將會再次被包含,若是排除了該文件的父級目錄,則使用"!"也不會再次被包含。可使用反斜槓進行轉義。
須要謹記:git對於.ignore配置文件是按行從上到下進行規則匹配的,意味着若是前面的規則匹配的範圍更大,則後面的規則將不會生效;
.gitignore忽略規則簡單說明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
# 表示此爲註釋,將被Git忽略
*.a 表示忽略全部 .a 結尾的文件
!lib.a 表示但lib.a除外
/TODO
表示僅僅忽略項目根目錄下的 TODO 文件,不包括 subdir
/TODO
build/ 表示忽略 build/目錄下的全部文件,過濾整個build文件夾;
doc/*.txt 表示會忽略doc
/notes
.txt但不包括 doc
/server/arch
.txt
bin/: 表示忽略當前路徑下的bin文件夾,該文件夾下的全部內容都會被忽略,不忽略 bin 文件
/bin
: 表示忽略根目錄下的bin文件
/*.c: 表示忽略
cat
.c,不忽略 build
/cat
.c
debug/*.obj: 表示忽略debug
/io
.obj,不忽略 debug
/common/io
.obj和tools
/debug/io
.obj
**
/foo
: 表示忽略
/foo
,a
/foo
,a
/b/foo
等
a/**
/b
: 表示忽略a
/b
, a
/x/b
,a
/x/y/b
等
!
/bin/run
.sh 表示不忽略bin目錄下的run.sh文件
*.log: 表示忽略全部 .log 文件
config.php: 表示忽略當前路徑的 config.php 文件
/mtk/
表示過濾整個文件夾
*.zip 表示過濾全部.zip文件
/mtk/do
.c 表示過濾某個具體文件
被過濾掉的文件就不會出如今git倉庫中(gitlab或github)了,固然本地庫中還有,只是push的時候不會上傳。
須要注意的是,gitignore還能夠指定要將哪些文件添加到版本管理中,以下:
!*.zip
!
/mtk/one
.txt
惟一的區別就是規則開頭多了一個感嘆號,Git會將知足這類規則的文件添加到版本管理中。爲何要有兩種規則呢?
想象一個場景:假如咱們只須要管理
/mtk/
目錄中的one.txt文件,這個目錄中的其餘文件都不須要管理,那麼.gitignore規則應寫爲::
/mtk/
*
!
/mtk/one
.txt
假設咱們只有過濾規則,而沒有添加規則,那麼咱們就須要把
/mtk/
目錄下除了one.txt之外的全部文件都寫出來!
注意上面的
/mtk/
*不能寫爲
/mtk/
,不然父目錄被前面的規則排除掉了,one.txt文件雖然加了!過濾規則,也不會生效!
----------------------------------------------------------------------------------
還有一些規則以下:
fd1/*
說明:忽略目錄 fd1 下的所有內容;注意,無論是根目錄下的
/fd1/
目錄,仍是某個子目錄
/child/fd1/
目錄,都會被忽略;
/fd1/
*
說明:忽略根目錄下的
/fd1/
目錄的所有內容;
/*
!.gitignore
!
/fw/
/fw/
*
!
/fw/bin/
!
/fw/sf/
說明:忽略所有內容,可是不忽略 .gitignore 文件、根目錄下的
/fw/bin/
和
/fw/sf/
目錄;注意要先對bin/的父目錄使用!規則,使其不被排除。
|
舒適提示:
若是你不慎在建立.gitignore文件以前就push了項目,那麼即便你在.gitignore文件中寫入新的過濾規則,這些規則也不會起做用,Git仍然會對全部文件進行版本管理。簡單來講出現這種問題的緣由就是Git已經開始管理這些文件了,因此你沒法再經過過濾規則過濾它們。因此你們必定要養成在項目開始就建立.gitignore文件的習慣,不然一單push,處理起來會很是麻煩。
.gitignore忽略規則經常使用示例
1)示例
好比你的項目是java項目,.java文件編譯後會生成.class文件,這些文件多數狀況下是不想被傳到倉庫中的文件。這時候你能夠直接適用github的.gitignore文件模板。https://github.com/github/gitignore/blob/master/Java.gitignore 將這些忽略文件信息複製到你的.gitignore文件中去:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.
tar
.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
|
能夠看到github爲咱們提供了最流行的.gitignore文件配置。保存.ignore文件後咱們查看下git status,檢查下是否還有咱們不須要的文件會被添加到git中去:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$ git status
On branch master
Initial commit
Changes to be committed:
(use
"git rm --cached <file>..."
to unstage)
new
file
: .gitignore
new
file
: HelloWorld.java
Untracked files:
(use
"git add <file>..."
to include
in
what will be committed)
Config.ini
|
好比個人項目目錄下有一個Config.ini文件,這個是個本地配置文件我不但願上傳到git中去,咱們能夠在gitignore文件中添加這樣的配置:
1
|
Config.ini
|
或者你想忽略全部的.ini文件你能夠這樣寫:
1
|
*.ini
|
若是有些文件已經被你忽略了,當你使用git add時是沒法添加的,好比我忽略了*.class,如今我想把HelloWorld.class添加到git中去:
1
2
3
4
|
$ git add HelloWorld.class
The following paths are ignored by one of your .gitignore files:
HelloWorld.class
Use -f
if
you really want to add them.
|
git會提示咱們這個文件已經被咱們忽略了,須要加上-f
參數才能強制添加到git中去:
1
2
3
4
5
6
7
8
9
10
11
|
$ git status
On branch master
Initial commit
Changes to be committed:
(use
"git rm --cached <file>..."
to unstage)
new
file
: .gitignore
new
file
: HelloWorld.class
new
file
: HelloWorld.java
|
這樣就能強制添加到緩存中去了。若是咱們意外的將想要忽略的文件添加到緩存中去了,咱們可使用rm命令將其從中移除:
1
2
|
$ git
rm
HelloWorld.class --cached
rm
'HelloWorld.class'
|
若是你已經把不想上傳的文件上傳到了git倉庫,那麼你必須先從遠程倉庫刪了它,咱們能夠從遠程倉庫直接刪除而後pull代碼到本地倉庫這些文件就會本刪除,或者從本地刪除這些文件而且在.gitignore文件中添加這些你想忽略的文件,而後再push到遠程倉庫。
2)示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
下面是曾經線上使用過的一個gerrit裏項目代碼的.gitignore的配置(在項目中添加.gitignore過濾文件,在git push到gerrit裏便可)
[wangshibo@gerrit-server hq_ios]$
cat
.gitignore
#Built application files
*.apk
*.ap_
# Files for the Dalvik VM
*.dex
# Java class files
*.class
# Generated files
*
/bin/
*
/gen/
*
/out/
# Gradle files
.gradle/
build/
*
/build/
gradlew
gradlew.bat
# Local configuration file (sdk path, etc)
local
.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# Intellij
*.iml
*/*.iml
# Keystore files
#*.jks
#gradle wrapper
gradle/
#some local files
*/.settings/
*/.DS_Store
.DS_Store
*/.idea/
.idea/
gradlew
gradlew.bat
unused.txt
|
3)示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
[wangshibo@gerrit-server hq_ios$
cat
.gitignore
# Lines that start with '#' are comments.
# IntelliJ IDEA Project files
.idea
*.iml
*.ipr
*.iws
out
# Eclipse Project files
.classpath
.project
.settings/
bin/
gen/
local
.properties
.DS_Store
Thumbs.db
*.bak
*.tem
*.temp
#.swp
*.*~
~*.*
|
.gitignor忽略規則查看
若是你發下.gitignore寫得有問題,須要找出來到底哪一個規則寫錯了,能夠用git check-ignore命令檢查:
1
2
|
$ git check-ignore -
v
HelloWorld.class
.gitignore:1:*.class HelloWorld.class
|
能夠看到HelloWorld.class匹配到了咱們的第一條*.class的忽略規則因此文件被忽略了。
簡單來講,要實現過濾掉Git裏不想上傳的文件,如上介紹三種方法能達到這種目的,只不過適用情景不同:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
============第一種方法===========
針對單一工程排除文件,這種方式會讓這個工程的全部修改者在克隆代碼的同時,也能克隆到過濾規則,而不用本身再寫一份,
這就能保證全部修改者應用的都是同一份規則,而不是張三本身有一套過濾規則,李四又使用另外一套過濾規則,我的比較喜歡這個。
配置步驟以下:
在工程根目錄下創建.gitignore文件,將要排除的文件或目錄 寫到.gitignore這個文件中,其中有兩種寫入方法:
a)使用命令行增長排除文件
排除以.class結尾的文件
echo
"*.class"
>.gitignore (>> 是在文件尾增長,> 是刪除已經存在的內容再增長),以後會在當前目錄下
生成一個.gitignore的文件。排除bin目錄下的文件
echo
"bin/"
>.gitignore
b)最方便的辦法是,用記事本打開,增長鬚要排除的文件或目錄,一行增長一個,例如:
*.class
*.apk
bin/
gen/
.settings/
proguard/
===========第二種方法===========
全局設置排除文件,這會在全局起做用,只要是Git管理的工程,在提交時都會自動排除不在控制範圍內的文件或目錄。這種方法對開發者來講,
比較省事,只要一次全局配置,不用每次創建工程都要配置一遍過濾規則。可是這不保證其餘的開發者在克隆你的代碼後,他們那邊的規則跟你
的是同樣的,這就帶來了代碼提交過程當中的各類衝突問題。
配置步驟以下:
a)像方法(1)同樣,也須要創建一個.gitignore文件,把要排除的文件寫進去。
b)但在這裏,咱們不規定必定要把.gitnore文件放到某個工程下面,而是任何地方,好比咱們這裏放到了Git默認的Home路徑下,好比:
/home/wangshibo/hqsb_ios
c)使用命令方式能夠配置全局排除文件:
# git config --global core.excludesfile ~/.gitignore
你會發如今~/.gitconfig文件中會出現excludesfile =
/home/wangshibo/hqsb_ios/
.gitignore。
說明Git把文件過濾規則應用到了Global的規則中。
===========第三種方法===========
單個工程設置排除文件,在工程目錄下找到.git
/info/exclude
,把要排除的文件寫進去:
*.class
*.apk
bin/
gen/
.settings/
proguard/
這種方法就不提倡了,只能針對單一工程配置,並且還不能將過濾規則同步到其餘開發者,跟方法一和方法二比較起來沒有一點優點。
|
Git忽略規則(.gitignore配置)不生效緣由和解決
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
第一種方法:
.gitignore中已經標明忽略的文件目錄下的文件,git push的時候還會出如今push的目錄中,或者用git status查看狀態,想要忽略的文件仍是顯示被追蹤狀態。
緣由是由於在git忽略目錄中,新建的文件在git中會有緩存,若是某些文件已經被歸入了版本管理中,就算是在.gitignore中已經聲明瞭忽略路徑也是不起做用的,
這時候咱們就應該先把本地緩存刪除,而後再進行git的提交,這樣就不會出現忽略的文件了。
解決方法: git清除本地緩存(改變成未track狀態),而後再提交:
[root@kevin ~]
# git rm -r --cached .
[root@kevin ~]
# git add .
[root@kevin ~]
# git commit -m 'update .gitignore'
[root@kevin ~]
# git push -u origin master
須要特別注意的是:
1).gitignore只能忽略那些原來沒有被track的文件,若是某些文件已經被歸入了版本管理中,則修改.gitignore是無效的。
2)想要.gitignore起做用,必需要在這些文件不在暫存區中才能夠,.gitignore文件只是忽略沒有被staged(cached)文件,
對於已經被staged文件,加入ignore文件時必定要先從staged移除,才能夠忽略。
第二種方法:(推薦)
在每一個clone下來的倉庫中手動設置不要檢查特定文件的更改狀況。
[root@kevin ~]
# git update-index --assume-unchanged PATH //在PATH處輸入要忽略的文件
|
在使用.gitignore文件後如何刪除遠程倉庫中之前上傳的此類文件而保留本地文件
在使用git和github的時候,以前沒有寫.gitignore文件,就上傳了一些沒有必要的文件,在添加了.gitignore文件後,就想刪除遠程倉庫中的文件卻想保存本地的文件。這時候不能夠直接使用"git rm directory",這樣會刪除本地倉庫的文件。可使用"git rm -r –cached directory"來刪除緩衝,而後進行"commit"和"push",這樣會發現遠程倉庫中的沒必要要文件就被刪除了,之後能夠直接使用"git add -A"來添加修改的內容,上傳的文件就會受到.gitignore文件的內容約束。
額外說明:git庫所在的文件夾中的文件大體有4種狀態
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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
Git 狀態 untracked 和 not staged的區別
1)untrack 表示是新文件,沒有被add過,是爲跟蹤的意思。
2)not staged 表示add過的文件,即跟蹤文件,再次修改沒有add,就是沒有暫存的意思
|