Git 代码管理中 .gitignore 文件无效的解决方法

在用 Git 进行代码管理的过程中,我们会发现后添加进去的 .gitignore 文件,或者是中途修改了 .gitignore 文件后,.gitignore 文件没有生效,我们需要通过清除 track 缓存和 强制 track 来解决问题。
Runtime Environment
OS: Mac OS X 10.10.3
Git: 2.3.2 (Apple Git-55)
SourceTree: 2.0.5.2
在用 Git 进行代码管理的时候,我们会用 .gitignore 文件来描述哪些文件是不需要进行版本管理的,也就是被忽略掉。如果我们在第一次提交的时候,忘记添加 .gitignore 文件或者在首次添加了 .gitignore 文件之后,又对 .gitignore 文件进行了修改,你会发现这两种情况下,.gitignore 文件是不生效的!

我们可以用 Git 命令行来解决以上问题。

先以一个 Android 项目作为演示,创建一个 Android 项目,然后不添加 .gitignore 文件,直接提交到本地:

Git 代码管理中 .gitignore 文件无效的解决方法

从以上提交的结果可以看出,没有添加 Android 工程应有的 .gitignore 文件,比如 .class 文件没有被忽略掉。现在我们去下载 Android 工程对应的 .gitignore 文件:
https://github.com/github/gitignore
找到 Android 工程对应的 .gitignore 文件,下载保存起来。

备注:请保存文件的后缀名为 [.gitignore],另外:保存下来的文件名中,请将 [Android.gitignore] 修改成 [.gitignore],如果你还是 Android.gitignore 这样的文件名,会造成 .gitignore 文件无效!Windows 下面可能会出现修改失败的情况,可以用 [rename Android.gitignore .gitignore] CMD 命名来修改名字!

然后我们将此 .gitignore 文件添加到这个仓库中:

Git 代码管理中 .gitignore 文件无效的解决方法

注意:如果你发现你添加了 .gitignore 文件之后,.gitignore 文件的变化没有被 track,那么你需要去 SourceTree 的全局 .gitignore_global 文件中查看 .gitignore 文件是不是被声明了不被 track!

SourceTree –> Preferences –> Git –> Global Ignore List

Git 代码管理中 .gitignore 文件无效的解决方法

我们尝试的修改一下 .java 文件,并保存:

Git 代码管理中 .gitignore 文件无效的解决方法

从上图中我们可以看到 .java 文件编译产生的 .class 文件依然被 track。而我们的 .gitignore 文件中是有 .class 文件的,说明这个时候添加的 .gitignore 文件是无效果的。

由于缓存的原因,当在提交之后添加 .gitignore 文件,或者在 .gitignore 文件中增加或者删除,都是无效的。

我们可以通过命令行的方式,解决以上问题!首先我们可以通过 SourceTree 界面中的 Terminal 打开 Git 命令行终端。或者你可以通过 Git 终端进入到当前项目的根目录:

Git 代码管理中 .gitignore 文件无效的解决方法

我们首先在里面输入:”git rm -r –cached .”,此命令为清除缓存!

Last login: Fri Aug 21 07:23:26 on ttys000
cd /Users/ifeegoo/mobile\_development/Android/workspace/GitignoreFileDemo
ifeegoo:~ ifeegoo$ cd /Users/ifeegoo/mobile\_development/Android/workspace/GitignoreFileDemo
ifeegoo:GitignoreFileDemo ifeegoo$ git rm -r --cached .
rm '.classpath'
rm '.gitignore'
rm '.project'
rm '.settings/org.eclipse.jdt.core.prefs'
rm 'AndroidManifest.xml'
rm 'bin/AndroidManifest.xml'
rm 'bin/classes/com/ifeegoo/demo/gitignorefile/BuildConfig.class'
rm 'bin/classes/com/ifeegoo/demo/gitignorefile/MainActivity.class'
rm 'bin/classes/com/ifeegoo/demo/gitignorefile/R$attr.class'
rm 'bin/classes/com/ifeegoo/demo/gitignorefile/R$dimen.class'
rm 'bin/classes/com/ifeegoo/demo/gitignorefile/R$drawable.class'
rm 'bin/classes/com/ifeegoo/demo/gitignorefile/R$id.class'
rm 'bin/classes/com/ifeegoo/demo/gitignorefile/R$layout.class'
rm 'bin/classes/com/ifeegoo/demo/gitignorefile/R$menu.class'
rm 'bin/classes/com/ifeegoo/demo/gitignorefile/R$string.class'
rm 'bin/classes/com/ifeegoo/demo/gitignorefile/R$style.class'
rm 'bin/classes/com/ifeegoo/demo/gitignorefile/R.class'
rm 'gen/com/ifeegoo/demo/gitignorefile/BuildConfig.java'
rm 'gen/com/ifeegoo/demo/gitignorefile/R.java'
rm 'ic_launcher-web.png'
rm 'libs/android-support-v4.jar'
rm 'proguard-project.txt'
rm 'project.properties'
rm 'res/drawable-hdpi/ic_launcher.png'
rm 'res/drawable-mdpi/ic_launcher.png'
rm 'res/drawable-xhdpi/ic_launcher.png'
rm 'res/drawable-xxhdpi/ic_launcher.png'
rm 'res/layout/activity_main.xml'
rm 'res/menu/main.xml'
rm 'res/values-v11/styles.xml'
rm 'res/values-v14/styles.xml'
rm 'res/values-w820dp/dimens.xml'
rm 'res/values/dimens.xml'
rm 'res/values/strings.xml'
rm 'res/values/styles.xml'
rm 'src/com/ifeegoo/demo/gitignorefile/MainActivity.java'

然后输入:”git add .”,此命令为添加更改变化!备注:此命令,你可以通过 SourceTree 这样的可视化客户端来通过勾选 unstaged files 来操作。

ifeegoo:GitignoreFileDemo ifeegoo$ git add .

最后:”git commit -m”,此命令为添加更改变化!备注:此命令,你可以提过 SourceTree 这样的可视化客户端来通过点击 commit 来操作。

ifeegoo:GitignoreFileDemo ifeegoo$ git commit -m "Refresh .gitignore file added."
[master 3b766ce] Refresh .gitignore file added.
 14 files changed, 102 deletions(-)
 delete mode 100644 bin/AndroidManifest.xml
 delete mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/BuildConfig.class
 delete mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/MainActivity.class
 delete mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$attr.class
 delete mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$dimen.class
 delete mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$drawable.class
 delete mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$id.class
 delete mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$layout.class
 delete mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$menu.class
 delete mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$string.class
 delete mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$style.class
 delete mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R.class
 delete mode 100644 gen/com/ifeegoo/demo/gitignorefile/BuildConfig.java
 delete mode 100644 gen/com/ifeegoo/demo/gitignorefile/R.java

我们可以看到这样一操作的结果是:

Git 代码管理中 .gitignore 文件无效的解决方法

我们看到上面删除了很多文件,而这些类型的文件正是 .gitignore 文件中声明的不需要被 track 的文件。这种删除是逻辑删除,非物理删除!

我们来测试下刚才的操作,是否让 .gitignore 文件重新生效:

Git 代码管理中 .gitignore 文件无效的解决方法

从上图我们可以看出,修改了 .java 文件并保存,并没有出现编译文件 .class 被 track,这说明,这次的重新使 .gitignore 文件生效的操作是可行的!

如果说,我们现在又要添加某一类型的文件到 .gitignore 文件中,比如 .txt 文件,不让 .txt 文件被 track,我们还是按照刚才的步骤来操作即可!

Git 代码管理中 .gitignore 文件无效的解决方法

Git 代码管理中 .gitignore 文件无效的解决方法

但是,如果你想要从 .gitignore 文件中移除某一类型的文件,让这种类型的文件重新被 track 起来,以上方法是不行的!

Git 代码管理中 .gitignore 文件无效的解决方法

比如,我们现在移除 .class 类型的文件:

Git 代码管理中 .gitignore 文件无效的解决方法

对于以上情况,我们需要用到强制提交的命令:
git add -f *.class

ifeegoo:GitignoreFileDemo ifeegoo$ git add -f *.class
ifeegoo:GitignoreFileDemo ifeegoo$ git commit -m "Force add .class file."
[master 9503b83] Force add .class file.
 11 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/BuildConfig.class
 create mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/MainActivity.class
 create mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$attr.class
 create mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$dimen.class
 create mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$drawable.class
 create mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$id.class
 create mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$layout.class
 create mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$menu.class
 create mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$string.class
 create mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R$style.class
 create mode 100644 bin/classes/com/ifeegoo/demo/gitignorefile/R.class

Git 代码管理中 .gitignore 文件无效的解决方法

我们修改一下 .java 文件然后保存,看看产生的编译文件 .class 是否再次被 track,答案是肯定的!如果你又想将 .class 文件添加到 .gitignore 文件中,我们采取第一种方式即可生效!

Git 代码管理中 .gitignore 文件无效的解决方法

Git 代码管理中,我们在没有添加 .gitignore 文件的前提下提交了代码之后再提交 .gitignore 文件,或者是中途添加某一文件类型到 .gitignore 文件中,需要通过以下命令行的方式,让 .gitignore 文件生效:
git rm -r --cached .
git add .
git commit -m "Refresh adding .gitignore file."

如果是中途从 .gitignore 文件中移除某一文件类型,想要这个文件类型重新被 track,需要通过以下命令行的方式,让 .gitignore 文件生效:

git add -f *.class
git commit -m "Refresh removing .class from .gitignore file."

备注:注意你所处的分支,如果你在当前分支修改,切换到其他分支是不生效的,如果多人开发,注意合并修改!本人的这个答案在 Stack Overflow 上获得了较高的 Vote:
http://stackoverflow.com/questions/11451535/gitignore-not-working/32377642#32377642 如果大家觉得这个答案对于你来说有帮助,也欢迎你给我的这个答案投个赞同票,谢谢!

2017-04-14(Fri) 追加:感谢读者提出来的本文中的一个显示错误:

git rm -r --cached .

以上命令行中 cached 前面有两个 “-“,这个主要是格式显示的问题。现已经修改!由于后台堆积了大量的垃圾评论,一不小心清除了提出本文中的一个显示错误的读者,在此表示感谢,如果这个读者看到了,可以告知我一下,谢谢!

打赏
Git

在 Mac OS X 上关联 GitHub

2014-12-10 6:50:42

Git

CentOS 服务器 GitLab 的 Git SSH 远程登录失败问题解决过程

2020-2-23 16:25:27

搜索