学习 Git 命令,用于更好的操作 Git GUI 工具。
0 Getting Started
CVCS:Centralized Version Control Systems,集中化的版本控制系统;
DVCS:Distributed Version Control System,分布式版本控制系统简 --> Git。
直接记录快照,而非差异比较
1 初次运行
Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量。 这些变量存储在三个不同的位置:
- /etc/gitconfig 文件: 包含系统上每一个用户及他们仓库的通用配置。 如果在执行 git config 时带上 --system 选项,那么它就会读写该文件中的配置变量。 (由于它是系统配置文件,因此你需要管理员或超级用户权限来修改它。)
- ~/.gitconfig 或 ~/.config/git/config 文件:只针对当前用户。 你可以传递 --global 选项让 Git 读写此文件,这会对你系统上 所有 的仓库生效。
- 当前使用仓库的 Git 目录中的 config 文件(即 .git/config):针对该仓库。 你可以传递 --local 选项让 Git 强制读写此文件,虽然默认情况下用的就是它。。 (当然,你需要进入某个 Git 仓库中才能让该选项生效。)
每一个级别会覆盖上一级别的配置,所以 .git/config 的配置变量会覆盖 /etc/gitconfig 中的配置变量。
在 Windows 系统中,Git 会查找 $HOME 目录下(一般情况下是 C:\Users$USER )的 .gitconfig 文件。 Git 同样也会寻找 /etc/gitconfig 文件,但只限于 MSys 的根目录下,即安装 Git 时所选的目标位置。 你可以通过以下命令查看所有的配置以及它们所在的文件:
git config --list --show-origin
2 忽略文件
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件的模式。
GitHub 有一个十分详细的针对数十种项目及语言的 .gitignore 文件列表, 可以在https://github.com/github/gitignore 找到它。在最简单的情况下,一个仓库可能只根目录下有一个 .gitignore 文件,它递归地应用到整个仓库中。 然而,子目录下也可以有额外的 .gitignore 文件。子目录中的 .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 等。
F 常用指令
F.1 初次运行Git 前的配置
1、查看所有的配置以及它们所在的文件
Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量。 这些变量存储在三个不同的位置。
git config --list --show-origin
2、设置用户信息
设置用户名和邮件地址
git config --global user.name "xxxx"
git config --global user.email xxxx@example.com
3、配置默认文本编辑器
git config --global core.editor "'xxCxx:/xxxx/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
4、检查配置信息
git config --list
5、获取帮助
三种等价的方法可以找到 Git 命令的综合手册(manpage)
git help <verb>
git <verb> --help
man git-<verb>
F.2 Git 基础
1、获取 Git 仓库
克隆现有的仓库,如果想在克隆远程仓库的时候,自定义本地仓库的名字,可以通过额外的参数指定新的目录名
git clone <url> xxmynamexx
2、检查当前文件状态
git status
3、状态简览
git status -s
4、跟踪新文件
这是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等
git add <files>
5、查看已暂存和未暂存的修改
要查看尚未暂存的文件更新了哪些部分,不加参数直接输入
git diff
若要查看已暂存的将要添加到下次提交里的内容(下面两条指令都行)
git diff --staged
git diff --cached
在本书中,我们使用 git diff 来分析文件差异。 但是也可以使用图形化的工具或外部 diff 工具来比较差异。 可以使用 git difftool 命令来调用 emerge 或 vimdiff 等软件(包括商业软件)输出 diff 的分析结果。使用 git difftool --tool-help 命令来看系统支持哪些 Git Diff 插件。
6、提交更新
git commit -m "xxxx"
7、跳过使用暂存区域
git commit -a -m "xxxx"
8、移除文件
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。可以用 git rm 命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
git rm <files>
如果要删除之前修改过或已经放到暂存区的文件,则必须使用强制删除选项 -f(译注:即 force 的首字母)。 这是一种安全特性,用于防止误删尚未添加到快照的数据,这样的数据不能被 Git 恢复。
git rm -f <files>
另外一种情况是,我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。
git rm --cached <files>
9、移动文件
git mv <file_from> <file_to>
其实,运行 git mv 就相当于运行了下面三条命令:
mv README.md README
git rm README.md
git add README
10、查看提交历史
git log
11、撤销操作
修补最后的提交
有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend 选项的提交命令来重新提交:
git commit --amend
例如,你提交后发现忘记了暂存某些需要的修改,可以像下面这样操作:
git commit -m ‘initial commit’
git add forgotten_file
git commit --amend
最终你只会有一个提交——第二次提交将代替第一次提交的结果。
取消暂存的文件
git reset HEAD <file>
撤消对文件的修改:撤消修改——将它还原成上次提交时的样子(或者刚克隆完的样子,或者刚把它放入工作目录时的样子)
git checkout -- <file>
12、远程仓库的使用
查看远程仓库
git remote [-v]
添加远程仓库
git remote add <shortname> <url>
从远程仓库中抓取与拉取
git fetch <remote>
该命令会抓取克隆(或上一次抓取)后新推送的所有工作。 必须注意 git fetch 命令只会将数据下载到本地仓库——它并不会自动合并或修改当前的工作。 当准备好时你必须手动将其合并入你的工作。
git pull
如果你的当前分支设置了跟踪远程分支, 那么可以用 git pull 命令来自动抓取后合并该远程分支到当前分支。
推送到远程仓库
git push <remote> <branch>
查看某个远程仓库
git remote show <remote>
远程仓库的重命名
git remote rename <oldName> <newName>
远程仓库的移除
git remote rm
一旦你使用这种方式删除了一个远程仓库,那么所有和这个远程仓库相关的远程跟踪分支以及配置信息也会一起被删除。
13、打标签
列出标签
git tag [-l]
查看标签信息和与之对应的提交信息
git show <keyid>
创建标签
附注标签
git tag [-a <keyid>] [-m <msg>]
轻量标签
git tag <keyid>
后期打标签:
要在某个提交上打标签,需要在命令的末尾指定提交的校验和(或部分校验和):
git tag -a <v1.2> <9fceb02>
共享标签
在创建完标签后你必须显式地推送标签到共享服务器上:
git push origin <tagname>
一次性推送很多标签
git push <remote> --tags
删除标签
第一种变体,这种操作的含义是,将冒号前面的空值推送到远程标签名,从而高效地删除它:
git push <remote> :refs/tags/<tagname>
第二种更直观的删除远程标签的方式是:
git push origin --delete <tagname>
检出标签
git checkout -b <version2> <v2.0.0>
在“分离头指针”状态下,如果你做了某些更改然后提交它们,标签不会发生变化, 但你的新提交将不属于任何分支,并且将无法访问,除非通过确切的提交哈希才能访问。 因此,如果你需要进行更改,比如你要修复旧版本中的错误,那么通常需要创建一个新分支,如果在这之后又进行了一次提交,version2 分支就会因为这个改动向前移动, 此时它就会和 v2.0.0 标签稍微有些不同,这时就要当心了。
14、Git 别名
Git 并不会在你输入部分命令时自动推断出你想要的命令。 如果不想每次都输入完整的 Git 命令,可以通过 git config 文件来轻松地为每一个命令设置一个别名。 例如,为了解决取消暂存文件的易用性问题,可以向 Git 中添加你自己的取消暂存别名:
git config --global alias.unstage 'reset HEAD --'
这会使下面的两个命令等价:
git unstage fileA
git reset HEAD – fileA
可以看出,Git 只是简单地将别名替换为对应的命令。 然而,想要执行外部命令,而不是一个 Git 子命令,可以在命令前面加入 ! 符号。例如,将 git visual 定义为 gitk 的别名:
git config --global alias.visual '!gitk'