git 基本操作
概述
本文介绍使用 git 版本控制系统过程中所涉的各种基本命令。
书写
git命令时,如果参数使用[]括起来,则表明其可使用也可不使用;如果参数使用/进行分隔,则表示两者等价,可任选一个使用;如果某个参数使用<>括起来,则表明此为一个取值。
获取仓库
通常有两种方式用于获取 git 仓库:
将尚未进行版本控制的本地目录转换为 Git 仓库。
进入到指定的本地目录,执行
git init命令即可将当前目录转换为git仓库。从其它服务器克隆一个已存在的 Git 仓库。
使用
git clone <url> [folderName]命令可将位于url位置的 Git 仓库克隆至本地,并将其文件夹名更改为folderName。
git init命令将会在本地创建一个.git文件夹,克隆得到的git仓库中同样存在.git文件夹。对于git仓库而言,此文件夹是十分重要的,它存放着当前git仓库的各种信息。关于此文件夹的详细信息,具体见 git 基本原理。
文件追踪
Git 仓库所在目录中的文件共有五种状态 —— 未追踪 (untracked)、未修改 (unmodified)、已修改 (modified)、已暂存 (staged)、已提交 (commited)。如果一个文件处于未追踪状态,则表明其尚未被 Git 仓库所管理;如果一个文件处于未修改状态,则表明自上次提交后,该文件尚未被修改;如果一个文件处于已修改状态,则表明自上次提交后,该文件已被修改;如果一个文件处于已暂存状态,则表明其位于暂存区;如果一个文件处于已提交状态,则表明其刚被提交。
文件状态间转换关系及所涉操作具体如下图所示 (未修改和已提交其实是一种状态,之所以如此写,希望与上篇文章中所提文件状态保持一致):
首先,我们介绍用于查看文件状态的两个命令:
git status [--short]此命令用于查看当前目录中各文件所处状态 (如果文件处于未追踪、已修改、已暂存状态,则会列出其文件名)。添加
--short参数后,该命令将会以一种简洁方式查看当前目录中各文件所处状态。
如图所示,输入
git status命令后,它指出333.txt处于未追踪状态、222.txt处于已修改状态、111.txt处于已暂存状态。git diff [--staged/--cached]此命令用于查看工作区中文件与暂存区中文件的差异、暂存区中文件与仓库区中文件的差异 (此时需要使用
--staged参数)。
如图所示,输入
git diff命令后,它就指出工作区中222.txt与暂存区中222.txt的差异 (diff命令输出中,使用a/、b/标识不同区内的文件,a用于标识具有较旧内容的文件,b用于标识具有较新内容的文件)。
接下来,我们介绍与状态转换相关的命令:
git checkout -- <fileNmae>此命令用于将处于已修改状态的文件回退为未修改状态的文件,即撤销工作区中文件的已有修改。如此操作,工作区中文件的已有修改将被完全覆盖,并永远不可恢复。
git add此命令用于将处于未追踪或已修改状态的文件加入暂存区,从而将文件状态转换为已暂存。
此命令通常有三种用法:
git add .:将当前目录中所有符合条件的文件加入暂存区。git add *.xxx:将当前目录中满足*.xxx通配符匹配规则的文件加入暂存区。git add xxx:将当前目录中指定文件xxx加入暂存区。
git reset HEAD <fileName>此命令用于将处于已暂存状态的文件放回至工作区,从而将文件状态转换为已修改。该命令含有与
git add命令含义刚好相反。git commit[-m "xxx"]此命令用于将处于已暂存状态的文件提交到仓库区,这便形成一次快照。
如果直接输入
git commit命令,则其会跳转到编辑器页面,需要你输入提交说明,随后退出编辑器页面以完成提交;如果输入git commit -m "xxx"命令,则xxx作为提交说明并完成提交。如果我们希望跳过暂存操作,直接执行提交操作,可使用
git comit -am "xxx"命令,它等价于git add .,git commit -m "xxx"命令。如果我们提交完一次快照后,发现若干文件忘记提交获取提交说明书写错误,此时可输入
git commit --amend命令,它会将暂存区中内容提交至最新快照之中,同时启动编辑器页面,以允许你修改最新快照的提交说明。
git rm [-r] [--cached] xxx如果直接输入
git rm xxx,则其会将文件xxx从暂存区中删除,同时删除工作区中文件xxx。
如果输入
git rm --cached xxx,则其仅会将文件xxx从暂存区中删除,此时文件状态变更为未追踪 (将文件从暂存区中删除,此操作将等待被提交给仓库区,故而会出现于Changes to be commit)。
参数
-r表明所删内容为文件夹。如果工作区中文件与暂存区中文件不一致,则系统报错,此时可使用
git rm -f xxx强制删除,这种操作的后果便是:工作区中修改部分将会永远不可恢复。
如果我们直接使用
rm xxx命令,则其仅会删除工作区中文件xxx,暂存区中的文件xxx仍然保留存在。git mv [-r]此命令用于移动或重命名文件或文件夹。
Git 并不显式跟踪文件移动,为实现跟踪文件移动功能,实际上我们需要借由如下三条命令加以实现:
mv old new,git rm old,git add new。git rm命令则是此三者命令的集合版本,可帮助简化跟踪文件移动操作。git
最后我们介绍一下 .gitignore 文件。
对于一个项目而言,当前目录中的编译结果、日志输出等文件都是无需交由 Git 管理的,而且我们也不会希望它们处于未追踪状态,此时便可使用 Git 提供的 .gitignore 文件记录它们。如此操作,Git 便会忽略其中文件。
文件 .gitignore 的格式规范如下:
- 所有空行或者以 
#开头的行都会被 Git 忽略。 - 可以使用标准的 glob 模式(正则表达式的阉割版) 匹配,它会递归地应用在整个工作区中。
 - 匹配模式可以 (/) 开头防止递归。
 - 匹配模式可以 (/) 结尾指定目录。
 - 要忽略指定模式以外的文件或目录,可以在模式前加上叹号 (!),以示取反。
 
.gitignore 所匹配文件集合应当为:前四条规范所示集合取并集,随后与第五条规范所示集合取交集 (个人理解)。假定存在 .gitignore 文件如下:
1  | *.a  | 
此文件表示忽略除 lib.a 以外的所有以 .a 结尾的文件。
.gitignore位于哪个文件夹之中,它就仅对此文件夹中所有文件起作用。网址 https://github.com/github/gitignore 提供针对数十种项目及语言的
.gitignore文件模板。
历史记录
我们可使用 git log 命令获取已提交的历史记录,其默认按照时间顺序排列。对于每条历史记录而言,它会列出此次记录的 SHA-1 校验值、提交人、提交人的电子邮件、提交时间及提交说明。

对于 git log 命令而言,它存在很多参数可以选择,我们在此列出若干经常使用的参数:
-p/--patch使用此参数后,除显示基本记录信息外,它还会显示每次提交所引入的差异 (类似于
git diff 当前记录 上次记录)。
-<n>此参数用于限制显示的历史记录条数。如果输入
git log -2命令,它将仅显示最近的两条历史记录。另外还有若干用于筛选历史记录的参数,我们在此简单介绍一二:
--since=<date>,筛选时间节点date之后的历史记录;--until=<date>,筛选时间节点date之前的历史记录。--stat使用此参数后,除显示基本记录信息外,它还会显示每次提交的一些统计信息。

--pretty此参数存在若干选值:
online、short、full、fuller等,选择不同选值,可以不同于默认格式的方式显示历史记录。如果输入
git log --pretty=online命令,它会简化记录信息,并将每个记录放在一行进行显示。
此参数存在一个特殊选值
format,它允许自定义显示方式 (具体比较麻烦,点到为止)。--graph使用此参数后,除显示基本记录信息外,它狐疑在日志旁以 ASCII 图形显示分支与合并历史。

远程仓库
远程仓库是指托管在因特网或其他网络中你的项目的版本库。借助于远程仓库,我们可方便实现多人合作项目开发。
为完成协作开发,我们需要管理此远程仓库。此节首先给出管理仓库命令之间的关系,随后详细介绍他们。

git remote [-v]此命令用于查看你所配置的远程服务器名。如果使用参数
-v,则不仅可看到远程服务器名,也可看到远程服务器的具体 URL。
git remote命令除查看配置的远程服务器信息外,也可执行与远程服务器配置相关的若干功能。git remote add <serverName> <serverUrl>:添加远程服务器。git remote show <serverName>:显示指定远程服务器的详细信息。git remote rm <serverName>:删除指定远程服务器。git remote rename <oldserverName> <newserverName>:指定远程服务器重命名。
git fetch <serverName>此命令用于从远程服务器
serverName中拉取本地仓库中所没有的数据。需要注意的是:该命令只会拉取数据至本地仓库,而不会将其合并至工作区。git pull命令不仅会拉取数据至本地仓库,同时将其合并至工作区。git push <serverName> <branch>此命令用于将本地仓库当前分支推送至远程服务器
serverName的branch分支。
其他操作
与其他版本控制系统一样,Git 可以给本地仓库历史记录中的某一个提交打上标签,以示其重要性。实际使用中,人们常用此功能标记发布的不同版本。
我们这里介绍与标签相关的若干命令:
git tag [-l/--list "通配模式"]此命令用于查看已有标签,其按照字母顺序列出。如果添加参数
-l,则其会列出与通配模式匹配的标签。git tag ...Git 支持两种标签 —— 轻量标签和附注标签。轻量标签只是某个特定提交的引用;附注标签则是存储于 Git 数据库中的完整对象,它包含打标签者的姓名、打标签者的电子邮件、打标签日期及标签信息 (可以看到,附注标签信息与提交快照信息基本一致)。通常情况下,建议使用附注标签。
git tag <tagName>命令用于创建最新提交的轻量标签;git tag -a <tagName> -m <tagMessage>命令则用于创建最新提交的附注标签。如果需要对以往提交打标签,则需使用
git tag <tagName> <以往提交的校验和>或git tag -a <tagName> -m <tagMessage> <以往提交的校验和>命令。git show <tagName>此命令用于显示指定标签对应的详细信息。
git push <serverName> [<tagName>/--tags]默认情况下,
git push命令并不会将标签信息传送至远程服务器。创建完标签后,我们需要显式推送标签至远程服务器。git push <serverName> <tagName>便可做到这件事。如果希望一次性推送很多标签,可使用
git push <serverName> --tags命令,它会将远程服务器中不存在的标签全部传送过去 (两种标签都会传送过去)。git tag -d <tagName>此命令用于删除指定标签。
此命令仅会删除本地仓库中的标签,而不会删除远程服务器中的标签 (如果远程服务器中有此标签的话),为删除远程服务器中的标签,我们可使用
git push <serverName> :refs/tags/<tagName>(将冒号前的空值推送至远程服务器中的指定标签名) 或git push <serverName> --delete <tagName>。git checkout <tagName>此命令用于查看特定标签所指代的文件版本。此命令会使得本地仓库处于
detachecd HEAD状态,它会存在一定副作用。
由于某些命令比较复杂,具体使用比较繁琐,Git 提供 别名 功能以允许用户自定义简洁命令以替代复杂命令。我们在此举一个例子:git config --global alias.unstage 'reset HEAD',它将 unstage 定义为 reset HEAD -- 的别名。以往取消暂存区文件至工作区,需要使用命令 git reset HEAD <fileName>,现在可使用命令 git unstage <fileName>。