How to let git ignore some commited file

随之而来的问题是:为什么我增加了 .gitignore 里的规则却没有效果?
这是因为我们误解了 .gitignore 文件的用途,该文件只能作用于 Untracked Files,也就是那些从来没有被 Git 记录过的文件(自添加以后,从未 add 及 commit 过的文件)。

1. git rm --cached logs/xx.log // if file is traced
2. 然后更新 .gitignore 忽略掉目标文件,
3. 最后 git commit -m "We really don't want Git to track this anymore!"

之所以你的规则不生效,是因为那些 .log 文件曾经被 Git 记录过,因此 .gitignore 对它们完全无效。这也正是开头那段简短答案所做的事情:

1. 从 Git 的数据库中删除对于该文件的追踪;
2. 把对应的规则写入 .gitignore,让忽略真正生效;
3. 提交+推送。

最后有一点需要注意的,git rm --cached 删除的是追踪状态,而不是物理文件;如果你真的是彻底不想要了,你也可以直接rm+忽略+提交

About Another Command

git update-index --assume-unchanged logs/*.log的真正用法是这样的:

你正在修改一个巨大的文件,你先对其 git update-index --assume-unchanged,这样 Git 暂时不会理睬你对文件做的修改;
当你的工作告一段落决定可以提交的时候,重置改标识:git update-index --no-assume-unchanged,于是 Git 只需要做一次更新,这是完全可以接受的了;
提交+推送
另外,根据文档的进一步描述:

This option can be also used as a coarse file-level mechanism to ignore uncommitted changes in tracked files (akin to what .gitignore does for untracked files).

这段描述告诉我们两个事实:

虽然可以用其来达成楼主想要的结果,但这是不讲究的做法(coarse);
同样的事情更应该用 .gitignore 文件来实现(针对未追踪的文件)。

git update-index --assume-unchanged logs/*.log虽然能达到(暂时的)目的,但并非最正确的做法,这样做是误解了 git update-index 的含义,而且这样做带来的最直接(不良)后果是这样的:

所有的团队成员都必须对目标文件执行:
git update-index --assume-unchanged <PATH>。
这是因为即使你让 Git 假装看不见目标文件的改变,
但文件本身还是在 Git 的历史记录里的,
所以团队的每个人在 fetch 的时候都会拉到目标文件的变更。
(但实际上目标文件是根本不想被 Git 记录的,
而不是假装看不见它发生了改变)
一旦有人改变目标文件之后没有
 git update-index --assume-unchanged <PATH> 就直接 push 了,
那么接下来所有拉取了最新代码的成员必须重新执行 update-index,
否则 Git 又会开始记录目标文件的变化。
这一点实际上很常见的,比如说某成员换了机器或者硬盘,重新 clone 了一份代码库,
由于目标文件还在 Git 的历史记录里,
所以他/她很可能会忘记 update-index。

reference

推荐阅读更多精彩内容

  • git常用命令 GIT常用命令备忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章阅读 4,572评论 0 24
  • 本系列为《Git权威指南》的读书笔记,分为两个部分:Part 1 涵盖了书中第 1~3 篇共 20 章的内容,Pa...
    yestyle阅读 8,052评论 0 51
  • Git 基础 基本原理 客户端并不是只提取最新版本的文件快照,而是把代码仓库完整的镜像下来。这样一来,任何一处协同...
    __silhouette阅读 10,745评论 5 136
  • Git 命令行学习笔记 Git 基础 基本原理 客户端并不是只提取最新版本的文件快照,而是把代码仓库完整的镜像下来...
    sunnyghx阅读 2,300评论 0 11
  • 理解OAuth 2.0
    abyte阅读 70评论 0 0