>[info] 在git或github中有特殊作用,功能的文件,为了便于学习区分,我们先草率的称它们为功能文件吧。
## 下面就来看几个常用的功能文件:
### .gitignore文件
被git文件中的规则所匹配文件和目录不受git版本管理系统控制,具体表现在两点:
1. 第一在像版本库push时会自动忽略匹配文件。
2. 第二匹配文件不属于工作区,虽然它放在工作区,但是对它的修改,不会被git监视和记录,也就是git status会忽略它。
需要注意的一些问题:
[git .gitignore失效的解决办法](http://blog.csdn.net/andanlan/article/details/51114306)
[Git忽略规则及.gitignore规则不生效的解决办法](http://www.pfeng.org/archives/840)
```shell
git rm -r --cached .
git add .
git commit -m 'update .gitignore'
```
注意几个问题:
1 .gitignore的优先级后面的忽略前面的,也就是子目录会覆盖上层的。
2 .git默认不跟踪空目录,git add .不能跟踪空目录,需要手动指定跟踪空目录。
例如如果想要忽略data下面所有的文件和目录,只保留data这个空目录的话,只在外层这样设置是做不到的:
`.gitignore`
~~~
/data/*
~~~
需要在data下:
创建文件 .gitignore
~~~
*
!.gitignore
~~~
**`!.gitignore`是必须的,表示不会忽略自身,否则data被认为是空目录,只能被忽略了。**
上面的代码表示git忽略data目录下的所有文件,但是git又发现data下面也有一个.gitignore文件,并且这个.gitignore文件中的规则明确表示了这里有不能被忽略的文件,比如本例中它表示不能忽略自身。这就是上面说得优先级覆盖的情况。(注意:.gitignore表示不能忽略的文件必须真实存在才有效哦,否则随便填规则忽略本不存在的文件是没有效果的[忽略的是它自己,它自己肯定存在哈],data还是被认为是空目录的哦)
注意这个覆盖并不能控制父目录的规则,及子目录中只能影响它本身所在目录,并不能向上越级影响父目录,/就是相对于当前.gitignore所在目录,或者不写也表示.gitignore所在目录,./并没有用哦。.gitignore又可以影响当前目录下面的子目录,规则同上,同它的父对于它的关系一样。
>[danger] 注意这里的/data/\*这个*星号,如果不加\*星号,直接是data或者data/,则又是另一种情况了,没有星号,则表示忽略data这个目录,是彻底的忽略哦,连/data/.gitignore都给忽略掉了哦,**/data/.gitignore明确表示不忽略自身也没有用!**,在外层就已经把这个目录忽略掉了,git根本就不会进来看一眼,**所以这种情况不存在.gitignore文件优先级覆盖**,而有星号则表示忽略data下面的所有文件,但如果data/.gitignore中没有明确表示不能忽略的文件,那么data目录本身也会被忽略,这是因为当为空目录时也会自动忽略掉,请注意这一点哦。
正是应为这个问题,所以像Discuz这样的程序就有点不合理了,比如我们需要忽略一些日志和模板缓存文件,在根目录下面的
`.gitignore`中设置
~~~
/data/log/*
/data/cache/*
/data/template/*
~~~
这样会忽略整个目录,而不能保留我们想要的空目录(原因上面已经说了),我们必须在/data/template/里面也设置`.gitignore`(参考上面),这样才能做到仅保留空目录,但是显然Discuz清空缓存可能将`.gitignore`删除掉。这很令人苦恼,因为完全忽略目录了,那么这个目录就没有被跟踪,就没有这个目录了,但如果程序里面做好处理,比如不依赖于/data/template/必须存在,而是会自动创建,这样就好了,但是Discuz比较死板,这样造成的问题就是我们在这里无法实现忽略缓存文件的同时又保留(不忽略)缓存目录这个空目录,所以我们采用完全忽略的方式,克隆仓库后,运行程序,出错的话(因找不到缓存目录),我们需要手动创建缓存目录。显然如果程序做的智能一点自动创建目录的话就不会出现这样的情况了。如果采用第二种常规方案,则又担心程序情况缓存时将`.gitignore`删除掉,可想而知程序才没想到这个呢。
(这里注意:.gitignore一开始就要设计好,不然就算后期添加忽略这个文件夹,也还是没用,还是会显示出来,因为已经提交了,只有删除才能从仓库去掉,所以.gitignore从一开始就要设计好,不然后期处理就会比较麻烦。)
>[danger] 最后需要强调的一点是,如果你不慎在创建.gitignore文件之前就push了项目,那么即使你在.gitignore文件中写入新的过滤规则,这些规则也不会起作用,Git仍然会对所有文件进行版本管理。
简单来说,出现这种问题的原因就是Git已经开始管理这些文件了,所以你无法再通过过滤规则过滤它们。
所以大家一定要养成在项目开始就创建.gitignore文件的习惯,否则一旦push,处理起来会非常麻烦。
**(可能没说明白,其实git管理的是旧的文件,添加过滤之后,此后的更改就不会再被跟踪,但是先前的跟踪还在,所以需要需要删掉先前的那么只能清除缓存,重新建立跟踪索引。)**
[.gitignore详解](http://sentsin.com/web/666.html)
参考:
[忽略特殊文件](http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013758404317281e54b6f5375640abbb11e67be4cd49e0000)
[Git 中的文件忽略(转)或 git中要忽略某文件夹下的一部分文件或文件夹](http://cooliron.blog.163.com/blog/static/1247031382013023103231950/)
>[info] 如果忽略意图明确,目录前最好加上/,比如/data/表示忽略的该目录在此目录下,否则会递归子目录的。后面加上/表示忽略整个目录,但同名文件不忽略。没有/则代表的是文件或者目录。
~~~
若test下有多个文件和文件夹。若要ignore某些文件夹,应该这个配置.gitignore文件。若test下有test1,test2,test3文件。要track test3,则.gitignore文件为:
test/test1
test/test2
!test/test3
若为:
test/
!test/test3
则不能track test3。
~~~
>[danger] 上面的测试说明:.gitignore的优先级是后面的会覆盖前面的(**请注意上面讨论的覆盖情况**),但那是子文件夹,对于同一文件中,“小定义”并不能覆盖“大定义”。
### 需要注意的问题:
很多程序都有清理缓存的的功能,比如:
![](https://box.kancloud.cn/d68f7731799ef3ad65bcb240b24a7383_838x409.png)
在应用目录中的.gitignore文件
`app/.gitignore`
~~~
.idea
composer.lock
*.log
thinkphp
~~~
显然是不想忽略runtime目录
`app/runtime/.gitignore`
~~~
*
!.gitignore
~~~
忽略该运行时目录下所有文件,但不忽略.gitignore(让他人可以沿用),保留运行时目录(只要目录不为空就不会忽略),但是保留这是很常见的做法,但是很多程序清理缓存时根本没有考虑这些,下面就来改写清除缓存方法:
~~~
// 递归删除文件夹
function delFile($dir,$file_type='') {
if(is_dir($dir)){
$files = scandir($dir);
//打开目录 //列出目录中的所有文件并去掉 . 和 ..
foreach($files as $filename){
if($filename!='.' && $filename!='..' && $filename!='.gitignore'){
if(!is_dir($dir.'/'.$filename)){
if(empty($file_type)){
unlink($dir.'/'.$filename);
}else{
if(is_array($file_type)){
//正则匹配指定文件
if(preg_match($file_type[0],$filename)){
unlink($dir.'/'.$filename);
}
}else{
//指定包含某些字符串的文件
if(false!=stristr($filename,$file_type)){
unlink($dir.'/'.$filename);
}
}
}
}else{
delFile($dir.'/'.$filename);
rmdir($dir.'/'.$filename);
}
}
}
}else{
if(file_exists($dir)) unlink($dir);
}
}
~~~
这样就排除了.gitignore了。
### README.md文件
项目的自述文件,默认打开github项目主页就会显示这个自述。
### CONTRIBUTING.md文件
github规定的用于他人提issues时提示的指导说明文件,此文件可以帮助引导他人怎样为此开源项目做贡献。
还有一些其他功能文件,参考:[贡献内容的自动检查](http://www.kancloud.cn/thinkphp/github-tips/37899)
- [github上的.gitignore和.gitattributes这两个文件是干什么的?](github上的.gitignore和.gitattributes这两个文件是干什么的?)
- 说明
- git配置
- git与github的关系
- 基础概念
- git命令
- git init
- git status
- git diff
- git log
- git reflog
- git add
- git commit
- git reset
- git checkout
- git rm
- git stash
- git remote
- git push
- git clone
- git branch
- git fetch
- git merge
- git rebase
- git pull
- git tag
- 建立版本库
- 分支合并
- 远程库别名
- Pull requests
- 扩展知识
- 功能文件
- 差异看法
- 注意细节
- github移动端
- git工作系统理解
- 仓库嵌套问题
- 仓库的使用问题
- 常用命令
- 学习资料
- 学习总结
- 示例文件
- README.md
- CONTRIBUTING.md
- .gitignore
- coding
- 大小写问题
- 如何贡献
- 使用账号密码clone
- git目录分析
- HEAD
- 代码部署问题
- 开发流程
- 指定公钥文件