Git命令日益增多,发现自己竟不太认识这个工具了,今日翻阅Git官方手册,总结以下文章,供日后翻阅。

Git配置

Git配置文件

Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量。 这些变量存储在三个不同的位置:

  1. /etc/gitconfig 文件: 包含系统上每一个用户及他们仓库的通用配置。 如果在执行 git config 时带上 –system 选项,那么它就会读写该文件中的配置变量。 (由于它是系统配置文件,因此你需要管理员或 超级用户权限来修改它。)
  2. ~/.gitconfig 或 ~/.config/git/config 文件:只针对当前用户。 你可以传递 –global 选项让 Git 读写此文件,这会对你系统上 所有 的仓库生效。
  3. 当前使用仓库的 Git 目录中的 config 文件(即 .git/config):针对该仓库。 你可以传递 –local 选 项让 Git 强制读写此文件,虽然默认情况下用的就是它。。 (当然,你需要进入某个 Git 仓库中才能让该选 项生效。)

3 > 2 > 1,相同的配置3优先级最高。

在 Windows 系统中,Git 会查找 $HOME 目录下(一般情况下是 C:\Users$USER )的 .gitconfig 文件。 Git 同样也会寻找 /etc/gitconfig 文件,但只限于 MSys 的根目录下,即安装 Git 时所选的目标位置。 如果 你在 Windows 上使用 Git 2.x 以后的版本,那么还有一个系统级的配置文件,Windows XP 上在 C:\Documents and Settings\All Users\Application Data\Git\config ,Windows Vista 及更新 的版本在 C:\ProgramData\Git\config 。此文件只能以管理员权限通过 git config -f 来修改。

通过以下命令查看所有的配置以及它们所在的文件:

1
git config --list --show-origin

用户信息

安装完 Git 之后,要做的第一件事就是设置你的用户名和邮件地址。这一点很重要,因为每一个 Git 提交都会使用这些信息,它们会写入到你的每一次提交中,不可更改:

1
2
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

再次强调,如果使用了 –global 选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用那些信息。 当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有 –global 选项的命令来配置。很多 GUI 工具都会在第一次运行时帮助你配置这些信息。

检查配置信息

使用 git config –list 命令来列出所有 Git 当时能找到的配置。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
git config --list

core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.url=https://gitee.com/sunhuawei/git-test-private.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master

你可能会看到重复的变量名,因为 Git 会从不同的文件中读取同一个配置(例如:/etc/gitconfig 与 ~/.gitconfig)。 这种情况下,Git 会使用它找到的每一个变量的最后一个配置。

Git常用

常见命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# --------------------------------------------------------------------------------git add
# 添加文件到暂存区
git add *.c
# --------------------------------------------------------------------------------git status
# 查看git当前状态
git status
# git状态简览
git status -s
git status --short
# --------------------------------------------------------------------------------git diff
# 查看尚未暂存的文件更新了哪些部分
git diff
# 将比对已暂存文件与最后一次提交的文件差异
git diff --staged
git diff --cached
# 可以使用 git difftool 命令来调用 emerge 或 vimdiff 等软件(包括商业软件)输出 diff 的分析结果。 使用 git difftool --tool-help 命令来看你的系统支持哪些 Git Diff 插件。
# --------------------------------------------------------------------------------git commit
# 提交更新(使用设置的编辑器填写提交说明)
# 启动的编辑器是通过 Shell 的环境变量 EDITOR 指定的,一般为 vim 或 emacs。 当然也可以按照 起步 介绍的方式, 使用 git config --global core.editor 命令设置你喜欢的编辑器。
git commit
# 将你所作的更改的 diff 输出呈现在编辑器中,以便让你知道本次提交具体作出哪些修改。
git commit -v
# 提交说明一行搞定
git commit -m "first commit"
# 把所有已经跟踪过的文件暂存起来一并提交,跳过git add
git commit -a -m "first commit"
# --------------------------------------------------------------------------------git rm
# 删除暂存区中的文件,前提是该文件已被物理删除
git rm test.txt
# 强制删除暂存区文件,会删除文件本身
git rm -f test.txt
# 将文件从暂存区中删除,不恢复文件,可再次git add添加到暂存区
git rm --cached test.txt
# --------------------------------------------------------------------------------git mv
# 相当于运行了下面三条命令:mv README.md README + git rm README.md + git add README
git mv file_from file_to
# --------------------------------------------------------------------------------git tag
# 列出所有标签
git tag
# 根据标签名称搜索,使用-l或--list
git tag -l "v1.8.5*"
# 创建一个tag(轻量标签)
git tag v0.1
# 创建一个tag(附注标签)使用了-a就得有描述,不写-m也会弹出填写页面
git tag -a v0.1 -m "v0.1的描述"
# 根据之前提交记录创建tag,通过git log --pretty=oneline查看记录
git tag -a v1.2 9fceb02
# 提交tag到远程仓库,别人可同步
git push origin v0.1
# 把所有不在远程仓库的tag全部上传
git push origin --tags
# 删除本地tag
git tag -d v0.1
# 删除远程仓库tag(注意空格)
git push origin  :refs/tags/v0.1
# 删除远程仓库tag(第二种方式,更简单)
git push origin --delete v0.1
# 检出标签???

# --------------------------------------------------------------------------------git branch
# 创建一个新分支(在当前所在的提交对象上创建一个指针)
git branch <newbranchname>
# 创建一个新分支并切换过去(在当前所在的提交对象上创建一个指针)
git checkout -b <newbranchname>
# git log带--decorate查看各个分支和tag所在的提交位置
git log --oneline --decorate
# 删除一个分支
git branch -d <branchname>
# 查看每一个分支的最后一次提交
git branch -v
# 查看所有分支的跟踪分支、是否领先(或者落后)
git branch -vv
# 查看哪些分支已经合并到当前分支(在这个列表中分支名字前没有*号的分支通常可以使用git branch -d删除掉,因为已经合并)
git branch --merged <branchName>
# 查看哪些分支没有合并到当前分支(使用branchName可以不必切换到branchName分支便可以查看)
git branch --no-merged <branchName>
# --------------------------------------------------------------------------------git merge
# 将branchB合并至branchA中(当前位置在branchA时执行命令)
git merge <branchB>
# 当合并起冲突时,通过此命令撤回合并
git merge --abort
# --------------------------------------------------------------------------------git push
# git push <remote> <branch>,推送本地分支到远程仓库
git push origin test_branch
# git push <remote> <branchA>:<branchB>,推送本地分支branchA到远程仓库分支branchB
git push origin test_branch:awesomebranch
# 删除远程分支<branch>
git push origin --delete <branch>
# --------------------------------------------------------------------------------git fetch
# 更新前分支对应的远程仓库分支
git fetch
# 更新远程仓库origin的所有分支
git fetch origin
# 更新所有远程仓库的所有分支
git fetch --all

忽略文件

创建一个名为 .gitignore 的文件,列出要忽略的文件的模式。 来看一个实际的 .gitignore 例子:

1
2
3
4
cat .gitignore

*.[oa]
*~

第一行告诉 Git 忽略所有以 .o 或 .a 结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的。 第二行告诉 Git 忽略所有名字以波浪符(~)结尾的文件,许多文本编辑软件(比如 Emacs)都用这样的文件名保存 副本。 此外,你可能还需要忽略 log,tmp 或者 pid 目录,以及自动生成的文档等等。 要养成一开始就为你的 新仓库设置好 .gitignore 文件的习惯,以免将来误提交这类无用的文件。

文件 .gitignore 的格式规范如下:

  • 所有空行或者以 # 开头的行都会被 Git 忽略。
  • 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。
  • 匹配模式可以以(/)开头防止递归。 • 匹配模式可以以(/)结尾指定目录。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。

所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。 星号(*)匹配零个或多个任意字符;[abc] 匹配 任何一个列在方括号中的字符 (这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c); 问号(?)只 匹配一个任意字符;如果在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配 (比如 [0-9] 表示匹配所有 0 到 9 的数字)。 使用两个星号()表示匹配任意中间目录,比如 a//z 可以 匹配 a/z 、 a/b/z 或 a/b/c/z 等。 我们再看一个 .gitignore 文件的例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 忽略所有的 .a 文件
*.a
# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a
# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO
# 忽略任何目录下名为 build 的文件夹
build/
# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt
# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf

GitHub 有一个十分详细的针对数十种项目及语言的 .gitignore 文件列表, 你可以在 https://github.com/github/gitignore 找到它。

在最简单的情况下,一个仓库可能只根目录下有一个 .gitignore 文件,它递归地应用到整 个仓库中。 然而,子目录下也可以有额外的 .gitignore 文件。子目录中的 .gitignore 文件中的规则只作用于它所在的目录中。 (Linux 内核的源码库拥有 206 个 .gitignore 文 件。)

git log

git log非常强大

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 查看提交记录
git log
# 查看最近两条的提交记录 -p或者--patch显示提交的diff
git log -p -2
# --stat以+-显示改动文件的多少
git log --stat
# 使用不同的格式来展示提交历史,选项有oneline、short、full、fuller和format(自定义输出详见Table1)
git log --pretty=oneline
git log --pretty=format:"%h - %an, %ar : %s"
# --graph 在日志旁以 ASCII 图形显示分支与合并历史。
git log --pretty=format:"%h %s" --graph
# git log 的常用选项详见Table2
# 限制 git log 输出的选项详见Table3

Table1:git log –pretty=format 常用的选项

选项 说明
%H 提交的完整哈希值
%h 提交的简写哈希值
%T 树的完整哈希值
%t 树的简写哈希值
%P 父提交的完整哈希值
%p 父提交的简写哈希值
%an 作者名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以用 –date=选项 来定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 提交日期(距今多长时间)
%s 提交说明

Table2:git log 的常用选项

选项 说明
-p 按补丁格式显示每个提交引入的差异。
–stat 显示每次提交的文件修改统计信息。
–shortstat 只显示 –stat 中最后的行数修改添加移除统计。
–name-only 仅在提交信息后显示已修改的文件清单。
–name-status 显示新增、修改、删除的文件清单。
–abbrev-commit 仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。
–relative-date 使用较短的相对时间而不是完整格式显示日期(比如“2 weeks ago”)。
–graph 在日志旁以 ASCII 图形显示分支与合并历史。
–pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline、short、full、fuller 和 format(用来定义自己的格式)。
–oneline –pretty=oneline –abbrev-commit合用的简写。

Table3:限制 git log 输出的选项

选项 说明
-<n> 仅显示最近的 n 条提交。
–since, –after 仅显示指定时间之后的提交。
–until, –before 仅显示指定时间之前的提交。
–author 仅显示作者匹配指定字符串的提交。
–committer 仅显示提交者匹配指定字符串的提交。
–grep 仅显示提交说明中包含指定字符串的提交。
-S 仅显示添加或删除内容匹配指定字符串的提交。

撤消操作

合并提交

1
2
3
4
5
6
7
8
# 在push之前,commit之后,通过以下命令将新的改动和上次的commit合并
git commit --amend

# 具体操作步骤如下,此时两次的commit便可以合并一起push
git commit -m 'first commit'
git add forgotten_file
git commit --amend
git push

取消暂存(从add中移除)

1
git reset HEAD test.txt test2.txt

撤消对文件的修改

1
git checkout -- test.txt test2.txt

取消commit

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
git reset --soft HEAD^
# HEAD^的意思是上一个版本,也可以写成HEAD~1
# 如果你进行了2次commit,想都撤回,可以使用HEAD~2
# --mixed 
# 意思是:不删除工作空间改动代码,撤销commit,并且撤销git add . 操作
# 这个为默认参数,git reset --mixed HEAD^ 和 git reset HEAD^ 效果是一样的。
# --soft  
# 不删除工作空间改动代码,撤销commit,不撤销git add . 
# --hard
# 删除工作空间改动代码,撤销commit,撤销git add . 
# 注意完成这个操作后,就恢复到了上一次的commit状态。

# 顺便说一下,如果commit注释写错了,只是想改一下注释,只需要:
git commit --amend
#此时会进入默认vim编辑器,修改注释完毕后保存就好了。