Skip to content




git add [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p]
          [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]
          [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] [--renormalize]
          [--chmod=(+|-)x] [--] [<pathspec>…​]


A gitignore file specifies intentionally untracked files that Git should ignore. Files already tracked by Git are not affected.

Each line in a gitignore file specifies a pattern.

Pattern Format

  • A blank line matches no files, so it can serve as a separator for readability.
  • If the pattern ends with a slash, it would only find a match with a directory. In other words, foo/ will match a directory foo and paths underneath it, but will not match a regular file or a symbolic link foo (this is consistent with the way how pathspec works in general in Git).
  • If the pattern does not contain a slash /, Git treats it as a shell glob pattern and checks for a match against the pathname relative to the location of the .gitignore file (relative to the toplevel of the work tree if not from a .gitignore file).
  • A leading slash matches the beginning of the pathname. For example, /*.c matches cat-file.c but not mozilla-sha1/sha1.c.

Two consecutive asterisks (**) in patterns matched against full pathname may have special meaning:

  • A leading ** followed by a slash means match in all directories. For example, **/foo matches file or directory foo anywhere, the same as pattern foo. **/foo/bar matches file or directory bar anywhere that is directly under directory foo.
  • A trailing /** matches everything inside. For example, abc/** matches all files inside directory abc, relative to the location of the .gitignore file, with infinite depth.
  • A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, a/**/b matches a/b, a/x/b, a/x/y/b and so on.


$ git status
# Untracked files:
#       Documentation/foo.html
#       Documentation/gitignore.html
#       file.o
#       lib.a
#       src/internal.o
$ cat .git/info/exclude
# ignore objects and archives, anywhere in the tree.
$ cat Documentation/.gitignore
# ignore generated html files,
# except foo.html which is maintained by hand
$ git status
# Untracked files:
#       Documentation/foo.html

如何优雅地在 Github 上贡献代码

swoole 为例:

1. Fork 项目并 Clone 到本地

2. 获取原项目代码

  • 进入 swoole-src 文件夹,添加 swoole 的远程地址
git remote add upstream
  • 获取 swoole 最新源码
git pull upstream master

现在我们在 fork 来的 master 分支上,这个 master 留作跟踪 upstream 的远程代码

3. 创建分支

按照国际惯例,我们一般不在 master 上提交新代码,而需要为新增的功能或者 fixbug 建立新分支,再合并到 master 上

  • 创建分支
git checkout -b branch1
  • 提交到代码库
git commit -a -m "new commit"

4. 合并修改

一个常见的问题是远程的 upstream (swoole/swoole-src) 有了新的更新,从而会导致我们提交的 Pull Request 时会导致冲突,因此我们可以在提交前先把远程其他开发者的 commit 和我们的 commit 合并

  • 切换到 master 分支
git checkout master
  • 拉出远程的最新代码
git pull upstream master
  • 切换回 branch1
git checkout branch1
  • 把 master 的 commit 合并到 branch1
git rebase master
  • 把更新代码提交到自己的 branch1 中
git push origin branch1

5. Pull Request

你可以在你的 github 代码仓库页面切换到 branches 页面点击 branch1 分支后点击 New pull request 按钮,添加相关注释后提交

或者切换到 branch1 分支的代码仓库点击 Compare & pull request 按钮,添加相关注释后提交