git 是一个流行的开源的分布式版本控制系统。包含了150多个子命令,常用的只有 30 个左右。下面 按照常见的开发工作流介绍 git 在日常工作中的可能使用到的命令以及一些极有帮助的选项。
克隆或者新建仓库
git clone <repo-url>git clone -b <name>: 检出 name 分支,而不是默认的 mastergit init
配置
git 的配置分为三个等级:system,global 和 local,分别代表系统级配置,用户全局配置,仓库
独立的配置。优先级递增。高优先级的配置会重载低优先级的配置。这三个等级的配置分别通过指定
--system, --global 和 --local 选项进行设定。
git config --global user.name <your-name>git config --global user.email <your-email>git config --global alias.st statusgit config --global alias.graph "log --graph --oneline --all --decorate"git config --global core.editor vimgit config --global core.fileMode falsegit config --listgit config --unset --global user.name
前两项配置 git 的用户名和邮箱地址,当大家用同一账号工作于同一主机的时候,不要指定
global选项,否则在你提交代码的时候,你的工作成果就成了别人的,或者别人的工作成果成了你的。
应该进入你的仓库,在设置的时候指定 local 选项: git config --local ...
跟踪文件、添加修改、检查状态与提交
git add <path>git add .git statusgit commitgit commit -a:跳过添加到暂存区的步骤,直接提交git commit -v:在提交时显示详细(统一 diff 格式)的文件变化信息git commit -m <message>git commit --amend:修订提交git commit --amend --reset-author:修改提交者信息
检查修改
git diff:对比工作区与暂存区git diff --staged | --cached:对比暂存区与仓库git diff <commit>:对比工作区和某一次提交git diff <path> <path>:对比两个文件git diff <commit> <commit> [path...]:对比两次提交
查看提交日志
git log [path...]git log -p -n [path...]:显示最新的 n 次提交,并列出详细的对比git log --pretty=fullergit log --oneline --graph --decorate --allgit log --author=<pattern> --committer=<pattern>git log --after=<date> --before=<date>git log --grep=<pattern>
移除、移动文件
git rm <file>...git mv <src>... <dst>
撤销操作
git checkout -- <file>...:取消工作区文件的修改git reset HEAD <path>...:取消暂存git reset --soft <commit>:重置当前分支指向某次 commitgit reset --mixed <commit>:并重置暂存区git reset --hard <commit>:并重置工作区
远程仓库
git remote -v:显示远程仓库git remote show <remote-name>:显示远程仓库的所有引用git ls-remote -h -t:同上git fetch <remote-repo> <branch-name>git push <remote-repo> <src>:<dst>git pull <remote-repo>
分支
git branch [-r] [-a]:列出本地分支,远程跟踪分支,所有分支git branch <branch-name>:创建分支git checkout <branch-name>:切换分支git checkout -b <branch-name> [start-point]:新建分支并切换git branch --track <branch-name> [start-point]:创建分支并跟踪远程分支git checkout -b <branch-name> --track <remote>/<branch-name>git branch --set-upstream-to=<upstream> [branch-name]:设置跟踪分支git push origin --delete branch-name:删除远程分支git merge <branch-name>
打标签
git taggit tag -l <pattern>:列出 taggit tag <tag-name> [commit]:针对 commit (默认HEAD)打一个 tag (轻量级)git tag -a -m <message> <tag-name> [commit]:会创建一个 tag 对象,需要提交信息git tag -d <tagname>...: 删除
其它有用命令
git rev-parse --git-dir:显示 git 仓库路径git rev-parse --show-toplevel:显示 git 工作区路径git push -f:即使不能快进合并,也强制更新远程仓库的引用,修改提交信息时很有用。-
git archive --format=tgz --prefix=linux-2.6.34/ --verbose -o linux-2.6.34.tgz HEAD将 HEAD 指向的代码树打包为文件 linux-2.6.34.tgz
更改历史
有时候,可能在我们完成某一个功能,修改某一个 bug 的时候由于某些原因,创建了多次提交。 这样是不太合理的。解一个 bug 最好是创建一次提交。此时就需要更改历史。下面分两种情况 说明。
-
合并多次提交为一次分以下两步进行
1. git reset --soft <rev> 2. git commit第一步使用
git reset --soft将 HEAD 重置为指向想要合并的几次提交前面的那一次提交。 因为使用了--soft选项,提交历史已经丢失,要合并的那几次提交的 index 将合并到一块 儿。此时提交,即可合并他们。 -
从历史提交中删除某一次提交
1. git check <rev> 2. git cherry-pick <rev> 3. git checkout master 4. git reset --hard HEAD@{1}
忽略文件
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些 自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建 一个名为 .gitignore 的文件,列出要忽略的文件模式。 来看一个实际的例子:
$ cat .gitignore
*.[oa]
*~
第一行告诉 Git 忽略所有以 .o 或 .a 结尾的文件。一般这类对象文件和存档文件都是编译过程中 出现的。 第二行告诉 Git 忽略所有以波浪符(~)结尾的文件,许多文本编辑软件(比如 Emacs)都 用这样的文件名保存副本。 此外,你可能还需要忽略 log,tmp 或者 pid 目录,以及自动生成的 文档等等。 要养成一开始就设置好 .gitignore 文件的习惯,以免将来误提交这类无用的文件。
文件 .gitignore 的格式规范如下:
- 所有空行或者以 # 开头的行都会被 Git 忽略。
- 可以使用标准的 glob 模式匹配。
- 匹配模式可以以(/)开头防止递归。
- 匹配模式可以以(/)结尾指定目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
gerrit 代码提交 sop
git clone ssh://YOU-ACCOUNT@10.195.229.38:29418/QC/platform/frameworks/av-
git checkout -b C5F/dev/MSM89xx/04710/PFAM --track origin/C5F/dev/MSM89xx/04710/PFAM这一步是在本地新建一个工作分支跟踪远程分支并检出。其实,前两步可以合并为:
git clone ssh://YOU-ACCOUNT@10.195.229.38:29418/QC/platform/frameworks/av` -b C5F/dev/MSM89xx/04710/PFAM`。分两步走可以让我们更加清楚自己在干什么。 - 修改代码
git add; git commit:添加修改并提交git push origin HEAD:refs/for/C5F/dev/MSM89xx/04710/PFAM:推送到远程并等待审核
为什么要加 refs/for/?
根据 git 的语法,就上面的例子而言,将本地分支的最新修改推送到远程仓库,需要这样做:
git push origin HEAD:C5F/dev/MSM89xx/04710/PFAM,但是对于 gerrit 来说,必须加上
refs/for/,这是 gerrit 的特殊语法,加上 refs/for/ 之后,实际推送过去的分支并没有
合并,而是处于等待 review 的状态。
可以在 这里 找到关于 gerrit 提交代码的详细资料。