最后编辑于: 2015-04-15 17:49 | 分类: 软件使用技巧 | 标签: git | 浏览数: 1023 | 评论数: 0
本文是15年时网上搜集来的2篇的合集,加上了一点自己的理解。
第一篇segmentfault回答中,对
git update-index --assume-unchanged
的详解,看似有点跑题但很有价值!
Original address:http://segmentfault.com/q/1010000000430426
Q:
现在项目的根目录放了.gitignore
文件,并且git远程仓库的项目根目录已经有了logs文件夹。
由于每次本地运行项目,都会生成新的log文件,但是我并不想提交logs文件夹里面的内容,所以要在.gitignore写logs的规则。
我尝试过添加以下规则
logs/*.log
logs/
/logs/
但是运行git status的时候,始终能看到modified:logs/xx.log 。
请问是我的规则编写错误,还是我某个地方有理解错误?
A:
正确的做法应该是:
git rm --cached logs/xx.log
,.gitignore
忽略掉目标文件,git commit -m "We really don't want Git to track this anymore!"
具体的原因如下:
被采纳的答案虽然能达到(暂时的)目的,但并非最正确的做法,这样做是误解了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
。为什么会这样?答案就在 Git 的man pages里:
首先,git update-index
的定义是:
Register file contents in the working tree to the index(把工作区下的文件内容注册到索引区)
这句话暗含的意思是:update-index
针对的是 Git 数据库里被记录的文件,而不是那些需要忽略的文件。
接着看关于--assume-unchanged
的几句相关的描述:
When the "assume unchanged" bit is on, Git stops checking the working tree files for possible modifications, so you need to manually unset the bit to tell Git when you change the working tree file. This is sometimes helpful when working with a big project on a filesystem that has very slow lstat(2) system call (e.g. cifs).
大致意思是:
应用了该标识之后,Git 停止查看工作区文件可能发生的改变,所以你必须手动重置该标识以便 Git 知道你想要恢复对文件改变的追踪。当你工作在一个大型项目中,这在文件系统的
lstat
系统调用非常迟钝的时候会很有用。
我们知道 Git 不仅仅是用来做代码版本管理的,很多其他领域的项目也会使用 Git。比如说我公司曾经一个客户的项目涉及到精密零件图纸文档的版本管理,他们也用 Git。有一种使用场景是对一些体积庞大的文件进行修改,但是每一次保存 Git 都要计算文件的变化并更新工作区,这在硬盘慢的时候延迟卡顿非常明显。
git update-index --assume-unchanged
的真正用法是这样的:
另外,根据文档的进一步描述:
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).
这段描述告诉我们两个事实:
.gitignore
文件来实现(针对未追踪的文件)。随之而来的问题是:为什么我增加了.gitignore
里的规则却没有效果?
这是因为我们误解了.gitignore
文件的用途,该文件只能作用于Untracked Files,也就是那些从来没有被 Git 记录过的文件(自添加以后,从未 add 及 commit 过的文件)。
之所以你的规则不生效,是因为那些 .log 文件曾经被 Git 记录过,因此.gitignore
对它们完全无效。这也正是开头那段简短答案所做的事情:
.gitignore
,让忽略真正生效;只有这样做,所有的团队成员才会保持一致而不会有后遗症,也只有这样做,其他的团队成员根本不需要做额外的工作来维持对一个文件的改变忽略。
最后有一点需要注意的,git rm --cached
删除的是追踪状态,而不是物理文件;如果你真的是彻底不想要了,你也可以直接rm+忽略+提交
My的理解:在添加 .gitignore 文件之前,已经track的文件,是不可能再被ignore的了,只有从git的数据库中删除掉 欲被忽略的文件 的追踪,才可让.gitignore文件中的配置生效。
Original address: http://niltor.net/index.php/Home/Blog/showblog?id=5
点评: 这是一种比较简单直接粗暴的作法,从git库中删除目录下所有文件的记录,再重新add。
NilTor @ 2014-08-08 16:50:55 | 最后编辑:2014-08-08 16:50:55
摘要: 前段时间gitignore文件不起作用的问题让我很头疼,我需要在不同的电脑上,不同的操作系统中同步代码.必须会忽略一些文件的.经过搜索,终于找到了解决的办法.
直接上解决方法:
git rm -r --cached .
git add .
git commit -m 'update .gitignore'
解释:
.gitignore文件,具体的规则一搜就有.
我在使用GIT的过程中,明明写好了规则,但问题不起作用,每次还是重复提交,无法忍受.
其实这个文件里的规则对已经追踪的文件是没有效果的.
所以我们需要使用rm命令清除一下相关的缓存内容. 这样文件将以未追踪的形式出现.
然后再重新添加提交一下, .gitignore文件里的规则就可以起作用了.