gitignore 忽略文件和目录


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

git合并分支时如何忽略某些文件不合并(保持原样)? .drone.yml

https://stackoverflow.com/questions/332528/is-it-possible-to-exclude-specific-commits-when-doing-a-git-merge/3970442#3970442
首先git merge大致是这样的逻辑(可以去看英文原文):git在merge分支时,有一个默认的merge驱动,这个驱动会去检查每个文件的每一行,如果按照一定规则发现两个分支的同一个文件有不同,那么认为两个分支都对这个文件做了修改,会merge两个文件,此时有可能产生冲突;那么如果我们自定义一个merge驱动,在里面定义一些不会被检查的文件,那git就会直接跳过这些文件,因此就不会merge,而我们自定义的这个merge驱动就是 ours。

1:创建我们的自定义merge driver:

git config --global merge.ours.driver true

这样选定了ours驱动,至于为什么不选择其它驱动,可以详看官方文档。
不管在A分支怎么修改a.js,
B分支合并A分支时,B分支的a.js保持原样,就需要 定义merge driver

注意:如果仅仅设置了.gitattributes中a.js merge=ours,他们还是会合并,只是有冲突时以当前分支的为准.

2:在要被merge的分支上创建 .gitattributes 文件,并且在文件中置顶不merge的文件名:

echo '.drone.yml merge=ours' >> .gitattributes
git add .gitattributes
git commit -m 'chore: Preserve .drone.yml during merges'

.gitattributes文件内容如下:
.drone.yml merge=ours

3:在合并的时候选择驱动要选择ours,这样就可以了。
如果是命令行合并:

git checkout master

git merge -s ours newbranch

git 分支合并时如何手动忽略某个文件

我通过使用git merge命令与 –no-commit 选项来解决这个问题,然后明确删除暂存文件并忽略对文件的更改。
例如:说我想忽略对 .drone.yml 的任何更改我继续如下:

git merge --no-ff --no-commit develop
git reset HEAD .drone.yml 
git checkout -- .drone.yml 
git commit -m "merged "


git checkout origin/master .drone.yml

你可以把语句2 3在for循环中,如果你有一个文件列表要跳过。

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

已经维护起来的文件,即使加上了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 \;

`