gitignore 忽略文件和目录


原文链接: gitignore 忽略文件和目录

如何忽略一个加入到索引的文件修改

已经维护起来的文件,即使加上了gitignore,也无济于事。
用下面这个命令:
git update-index --assume-unchanged logs/*.log
这样每次提交就不会出现logs下面的文件了

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

  1. 所有的团队成员都必须对目标文件执行:git update-index --assume-unchanged 。这是因为即使你让 Git 假装看不见目标文件的改变,但文件本身还是在 Git 的历史记录里的,所以团队的每个人在 fetch 的时候都会拉到目标文件的变更。(但实际上目标文件是根本不想被 Git 记录的,而不是假装看不见它发生了改变)

  2. 一旦有人改变目标文件之后没有 git update-index --assume-unchanged 就直接 push 了,那么接下来所有拉取了最新代码的成员必须重新执行 update-index,否则 Git 又会开始记录目标文件的变化。这一点实际上很常见的,比如说某成员换了机器或者硬盘,重新 clone 了一份代码库,由于目标文件还在 Git 的历史记录里,所以他/她很可能会忘记 update-index。

git update-index 的定义是:

把工作区下的文件内容注册到索引区

这句话暗含的意思是:update-index 针对的是 Git 数据库里被记录的文件,而不是那些需要忽略的文件

接着看关于 --assume-unchanged 的几句相关的描述:

应用了 --assume-unchanged 之后,Git 停止查看工作区文件可能发生的改变,所以你必须 *手动* 重置该标识以便 Git 知道你想要恢复对文件改变的追踪。当你工作在一个大型项目中,这在文件系统的 lstat 系统调用非常迟钝的时候会很有用。

git update-index --assume-unchanged 的真正用法是这样的:

有一种使用场景是对一些体积庞大的文件进行修改,但是每一次保存 Git 都要计算文件的变化并更新工作区,这在硬盘慢的时候延迟卡顿非常明显

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

有时不想删除本地的文件, 只是想让git不再track, 这时可以使用 git rm --cached logs/xx.log

本地忽略

.git/info/exclude 这里设置的 则是你自己本地需要排除的文件。 他不会影响到其他人。也不会提交到版本库中去。

全局忽略

另外 git 提供了一个全局的 .gitignore
你可以在你的用户目录下创建 ~/.gitignoreglobal 文件,以同样的规则来划定哪些文件是不需要版本控制的。
需要执行
git config --global core.excludesfile ~/.gitignoreglobal

为什么我增加了 .gitignore 里的规则却没有效果?

这是因为我们误解了 .gitignore 文件的用途,该文件只能作用于 Untracked Files,也就是那些从来没有被 Git 记录过的文件(自添加以后,从未 add 及 commit 过的文件)。

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

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

git rm -r --cached . #删除所有缓存
git checkout --track origin/develop #
git submodule update --init --recursive #ycmd

禁止 .drone.yml 文件从其他分之合并过来

echo .drone.yml >> .gitignore

Git合并branch上的指定文件

git checkout -p dev A.h //不切换branch,把RemLan上的A.h更新到当前分支
git checkout dev .drone* //去掉-p参数,新增 .drone.yml .drone.yml.sig 文件

touch .gitignore 井号开头的这行都是注释

  • .md #忽略根目录下所有.md后缀的文件
    !README.md #但README.md除外
    dir #忽略根目录dir目录
    dir/ #忽略根目录下的dir/目录下的所有文件
    */dir #忽略根目录下的dir目录及dir目录下的所有文件
    **/dir 忽略所有目录下的dir目录及dir目录下的所有文件 ** 忽略多层文件夹,git1.8.2及更高版本才支持


忽略空目录

find . -type d -empty -exec touch {}/.gitignore \;

`