---
title: '为咩向 GIT 添加文件时你不看一眼'
date: '2017-06-13'
slug: git-add
---

[前面](/cn/2017/05/blank-line/)无情挑了第三届靠谱厮奖得主的刺，问 Markdown 源文件中为咩不空行。今日[看见](https://github.com/cosname/uploads/commit/e284444d)第四届靠谱厮奖得主又触碰到我的一个地雷，于是也唠叨几句。哦，对了，我还没空给这二位颁奖，待我写完 blogdown 的书、搬完 COS 的家、能有空喘口气了再仔细着颁吧。

其实我已经在《[GIT 子模块](/cn/2017/03/git-submodule/)》一文的脚注 1 中说明过了：向 GIT 里添加文件时，不要全选然后看也不看就全部添加。两个原因：一方面，这样可能会添加一些垃圾文件进来，比如 `.DS_Store` 或 `Thumbs.db` 之类的操作系统产生的无用文件；另一方面，这样可能无意添加包含敏感信息的文件，比如密码或密钥。如果你想要“借用”一下别人的诸如 AWS 之类的付费账户，你可以试试在 GitHub 上[搜索密钥](https://github.com/search?q=production+SECRET_ACCESS_KEY%3A+%22A&type=Code&ref=searchresults)，没准儿能找到几个能用的。

我看大为同志提交的文件中并没有什么特别敏感的信息，所以才敢公开说这事，然而 `.Rhistory` 文件还是一定程度上无情出卖了他（大家不要告诉他，快点快点捉住他，捉住他）。

有时候我会否定我自己以前的观点，但关于用 GIT 时尽量用一个图形界面这个观点，我基本上从 [2013 年](https://github.com/jtleek/rpackages/issues/12)就坚定下来了。命令行夜太黑，尽管再危险，总有人黑着眼眶熬着夜；在图形界面里，一切都亮堂得多：

![GIT 差异界面](https://db.yihui.org/images/git-diff-gui.png)

最近几周我脑子里总是在回荡那句话：我们创造了工具，然后工具反过来塑造了我们。[UNIX 命令行至上](/cn/2017/03/unix-philosophy/)的现象大概就是一个很好的例证。两周前我在墨尔本的[报告](https://slides.yihui.org/2017-DSM-Journal-Yihui-Xie.html)中再次引用了这句话，说的是 LaTeX 塑造了我们。看看 2013 年我跟那二位的辩论就可以知道，捍卫命令行的人抱着命令行就像考拉抱着树一样。可在 GIT 问题上，`git add` 既不方便，又容易出错，在日常工作中用它究竟有何意义？

我自己用 git 命令行一般只有如下几种情况：

- `git pull --rebase origin master` 保证 GIT 历史干净，不要无意创建一个合并的记录；这种合并记录也并不是什么错，只是个人偏好而已，我偏好纯线性的 GIT 历史。隔三差五我就会看见一个合并记录，比如[这里](https://github.com/cosname/cosx.org/commit/15c8b100#commitcomment-22505271)和[这里](https://github.com/cosname/uploads/commit/4c82c0db)。当然，我这种懒人是不会重复敲 `--rebase` 参数的，所以设置一下全局选项：

    ```bash
    git config --global pull.rebase true
    ```

- `git rebase -i master~N` 交互式调整还没提交的 GIT 记录，其中 master 可以是别的分支名，也可以是 HEAD，N 表示从现在往回倒退几个记录，默认情况下我用 nano 编辑（此处我允许 Emacs/Vi/Vim 党们笑出声来，对，我就是这么弱鸡，还用 nano）；调整包括移动记录，合并记录，或暂停在某个记录上添补一些修改，让 GIT 记录更加轻便明了，免得将来回头看历史，就跟开碰碰车似的：哦，这里错了，那里又倒车改回来了，好不容易看懂了这次提交里的修改，那里又给撤销了。某种情况下，GIT 历史就是精神分裂的自己跟自己的对话，为了六个月甚至更久之后的自己还能明白当时在干啥。说到这儿，我又忍不住吐槽那些用一个词作为 GIT 提交消息的行为了，放眼望去，历史记录中就一个单词在不断重复：update（废话，我当然知道你在更新，可更新了啥以及为什么更新呢）。当然，这个有时候也可以理解，尤其是无关紧要的私人项目，随便写写 GIT 消息也无妨。如果做一个想要后继有人的项目，每一次更改最好是写上一条完整的消息。

- `git checkout -b` 创建一个新分支并切换到该分支，这个命令现在已经没有必要了，因为最新开发版的 RStudio 的 GIT 栏里添加了创建分支的按钮。

除此之外，我基本上就很少用 GIT 命令行了。

前面提到了 `.DS_Store` 文件，这种文件也可以全局忽略，把文件名添加到用户根目录下的 `.gitignore_global` 文件中即可，比如这是我的文件：

```bash
$ cat ~/.gitignore_global
*~
.DS_Store
```

