本文主要记录了在使用Git过程中遇到的一个问题,也就是标题所说的在.gitignore
文件里添加的忽略规则没有生效,导致本应该被忽略的文件/文件夹和目录总是不断的被Git纳入版本管理,每当项目文件修改都会重复引发跟踪!
首先要说明下,本文所提及的问题,Git官方是有很详细的文档进行说明的,包括具体的情景和解决办法,所以后面会引用Git官方中文文档的说明,本文算是一篇记录笔记,会结合我自己的理解和案例来写,这里建议先看Git文档的这一章节:2.2 Git 基础 - 记录每次更新到仓库,重点在文档底部的移除文件节点,如果对Git比较不熟悉的朋友,强烈建议读完整个章节。
一、.gitignore规则无效的原因
据我所知导致.gitignore
里的忽略规则失效只有两种情况,当然我对Git的使用和理解比较浅薄,也只能想到这两个方面:一种是忽略规则的语法错误,这种情形好处理,只要修正错误的语法就可以了。PS:本文不对语法错误的问题详细说明,毕竟每个人情况不同。排查语法问题这事我也不知道怎么举例,总之只要符合官方规范的就可以了,需要注意的好像也就一个路径问题吧?!
另一种则是本文要重点说明的情况:项目中的文件或目录已经被纳入到Git的版本管理里面/跟踪文件清单,此时你再往.gitignore
里添加此文件/目录的忽略规则就会发现毫无作用,因为已经被Git跟踪(track)的文件/目录无法被.gitignore
忽略掉!。
这里再对上面一段所说的进行详细说明,所谓“已经被纳入到Git的版本管理里面/跟踪文件清单”,大体上指的是下面的三种情况:
- 已使用
add
命令开始跟踪项目文件或者将修改的文件放入暂存区/索引 - 已使用
commit
命令提交更新到本地仓库 - 已使用
push
命令将项目文件推送到了Git远程仓库了(例如GitHub)
上述的三种操作只要进行了其中一项,再添加对应文件的忽略规则都是不生效的!PS:这三个命令在GUI客户端上一般都可以找到对应的按钮和操作。
这里额外提下,如果按照反向理解,也就是说只要是文件/目录还没有被Git跟踪,那么你添加的忽略规则都是有效的,重点在于文件的是否属于被跟踪(track)状态。
二、具体的解决方法-配合案例演示
先说使用Git命令处理的方法,这也是我比较推荐的方式,后面还会讲一个简单的方法但并不推荐,因为不利于Git的学习与掌握,而且有部分限制。这里额外再提醒下,官方文档是有详细的解决方法的,建议阅读官方文档,接下来会结合一个案例来进行说明。
2.1 案例背景说明
这里我在VS里新建了一个ASP.NET MVC项目并进行生成,项目生成后会创建bin
文件夹(注意这时候还未添加对应的忽略规则,bin
文件夹里都是编译生成的文件):
此时由于疏忽大意或操作失误不小心使用add
命令对bin
文件夹以及里面所有文件进行了跟踪(例如使用git add -A
,或者直接用GUI客户端批量操作),发现后想要亡羊补牢在.gitignore
里添加了[Bb]in/
这条规则([Bb]in/
=Bin/
+bin/
,也就是大小写都能匹配到),但是发现并没什么用,在命令行窗口使用git status
可以看到bin文件夹里的文件无法被忽略:
GUI界面截图:
2.2 未进行提交操作的处理方式
如果此时还未进行提交操作,赶紧使用如下命令可及时挽救:git rm --cached <file>
,其中<file>
表示要从暂存区移除出去的文件名或者目录路径,注意可以使用通配符。不过Git有自己的通配符规则,所以要注意下差异,例如官方文档有提到在*
号前面是需要加反斜杠\
的(我有测试过不加也没事但是最好按照规范来),结合上面的案例,因为我们要移除bin
文件夹下的所有文件,所以完整的Git命令为(注意路径一定要正确):
git rm --cached WebApplication1/WebApplication1/bin/\*
这里要留意忽略规则的添加时机,在命令执行后会有不同的影响,假设忽略规则是在git rm --cached <file>
命令执行前就设置了,那么当命令执行完成后马上就可以看到效果,bin
文件夹及里面的所有文件会被Git直接忽略。如果在命令执行后还没有添加忽略规则,你会发现bin
文件夹下的文件变成未被跟踪的状态,也就是最初的状态,此时你再添加忽略规则这些文件就会被忽略了。
2.3 文件已经进行提交操作的处理方式
如果bin
文件夹已经被Git跟踪并提交到了本地版本库甚至远程版本库(例如GitHub),解决方法和上一小节2.2中的方法是一样的,依然是使用git rm --cached <file>
这个命令。PS:在执行此命令前Git最好能保持干净的状态,也就是"nothing to commit, working tree clean"。
注意!!!在命令执行后受影响的文件都会变成未跟踪状态,此时一定要马上使用git commit -m '备注信息'
命令提交这部分修改,如果还未设置.gitignore
文件则可以设置后一并提交此次更新到本地仓库。这里千万不要使用任何GUI客户端去操作!因为不同GUI客户端可能有不一样的执行结果(例如可能会将文件重新纳入跟踪,等于刚刚的操作白费了)。
2.4 简单的解决方法:直接删除物理文件
在上面两小节2.2-2.3中使用git rm --cached <file>
命令最终只是将文件从暂存区移除而不删除物理文件(也就是只删除Git对文件或目录的跟踪状态),这样的好处是一些项目开发或调试需要的文件都可以保留下来,例如本地日志文件、编译文件、本地数据库、测试图片之类的。
如果遇到实在依赖GUI客户端或者对Git命令不熟悉,也没有时间去查阅官方文档的情况,也只能通过简单的方法去处理了,大体操作流程如下:
- 先将文件进行备份,除非能确定文件删除后不需要还原回来,否则一定要做好备份
- 备份完成后直接从硬盘/本地工作目录里删除这些无法被忽略掉的文件或文件夹
- 然后马上提交这部分修改到Git版本库里(通过GUI客户端进行操作或者使用Git命令都可以)
- 接着在
.gitignore
文件中添加忽略规则并提交到Git版本库里 - 最后将之前删除的文件拷贝回来(注意第一步已经做了备份)
完成上面5个步骤可以测试下忽略规则是否有重新生效。
最后附上官方文档的截图:
三、总结
先来一段碎碎念,作为一名轻度的Git使用者,总是为了图方便而使用类似GitHub DeskTop的GUI客户端。偷懒的结果就是对Git的掌握处于半桶水的水平,只知道怎么用而没有深入理解和搞懂,也就是所谓的“只知其然,而不知其所以然”。最近遇到了这个小问题彻底暴露了隐藏的缺陷,只好静下心来好好读一遍官方文档,从头理解Git并学习命令行的使用方式。
最后总结下两点:
- 良好的开发习惯还是要有的,在项目添加到Git版本控制库之前,一定要先设置好忽略规则。
- 已经被Git跟踪(track)的文件是不受
.gitignore
影响的。
转载:由十有三创作**
来源 https://shiyousan.com/post/636470505667009340