平方X 发表于 2017-11-3 10:46:30

.gitignore 忽略已暂存的文件



之前只是知道这么做,一直不知道为什么(敏哥面试时就问了我,然而我根本不懂,笑哭~)
最近再学习和汉化 git ,终于可以对其解释了。

# 0x01 命令
```
git rm -r --cached .
git add .
git commit -m 'update .gitignore'
```

# 0x02 测试
添加 1.txt,提交
修改 1.txt,.gitignore 中忽略 1.txt,发现仍记录 1.txt 的修改
此时用 `$ git ls-files --cached` ,查看所有暂存的文件,其中有 1.txt
执行 `git rm -r --cached .` ,再查看暂存的文件,已被清空。

# 0x03 解释
## git rm -r --cached .
* rm 从索引中删除文件,或从工作树和索引中删除文件。
* -r 当给出开头目录名时允许递归删除。
* --cached 使用此选项可以从索引中取消暂存和移除文件。工作树文件(无论是否修改)将被留下。
* . 见下文

## git add .
添加到暂存区

## git commit -m 'update .gitignore'
* -m 提交信息

# 0x04 更多问题
## 4.1 git add . 中的 “.” 是什么意思
为什么 “.” 就表示所有的文件,一直对这个念念不忘,如果是一个选项,为什么 git-add 手册中没有对其进行解释。
stackoverflow 上只找到讨论 git add -A 和 git add . 的区别,没找到对 “.” 关心的,难道是我漏了什么显而易见的东西?
指定路径用的 pathspec ,可是在 pathspec 中也没有找到 “.” 的解释。
提到的 glob 也没有 “.” 的用法。
在目录中搜索 “git add .”,找到不少用法,其中在 user-manual 里面看到
> $ git add . # include everything below ./ in the first commit:

终于看到 . 是表示目录 ./ ,现在知道了是什么显而易的东西了。
这里的 “.” 即为 pathspec 参数,表示当前目录。
于是我们试一下。
```

$ git add a #添加 a/ 中的所有文件,包括子文件夹


$ cd a/b/
$ git add .
$ git add ./ #添加 a/b/ 中的所有文件



$ cd a/b/
$ git add .. #添加 a/ 中的所有文件
```

## 4.2 如何删除仓库中的记录
添加 1.txt,2,txt
修改 1.txt
修改 2.txt
修改 .gitignore ,rm 然后 add ,使忽略 1.txt

接下来,我们可以使用
git log <path>
git reflog <path>
可以查看哪些提交里包含该文件。
```
git filter-branch --index-filter 'git rm --cached --ignore-unmatch 1.txt' -f --prune-empty
git filter-branch -f --tree-filter 'rm -f 1.txt' --all
```
删除后 git log <path> 看不到文件了。
但是 git reflog <path> 还有,仓库里也还有。
参考[白 杨《Git从库中移除已删除大文件》](http://blog.csdn.net/zcf1002797280/article/details/50723783)
>现在历史记录中已经不包含对那个文件的引用了。不过 reflog 以及运行 filter-branch 时 Git 往.git/refs/original 添加的一些 refs 中仍有对它的引用,因此需要将这些引用删除并对仓库进行 repack 操作。在进行 repack 前需要将所有对这些 commits 的引用去除。
```
$ rm -rf .git/refs/original/
$ rm -rf .git/logs/
$ git gc
```
## 4.3 上面的 .git/logs/ 能不能删
## 4.4 update-index 的使用
(https://segmentfault.com/q/1010000000430426)



页: [1]
查看完整版本: .gitignore 忽略已暂存的文件