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 status
git config --global alias.graph "log --graph --oneline --all --decorate"
git config --global core.editor vim
git config --global core.fileMode false
git config --list
git config --unset --global user.name
前两项配置 git 的用户名和邮箱地址,当大家用同一账号工作于同一主机的时候,不要指定
global选项,否则在你提交代码的时候,你的工作成果就成了别人的,或者别人的工作成果成了你的。
应该进入你的仓库,在设置的时候指定 local 选项: git config --local ...
跟踪文件、添加修改、检查状态与提交
git add <path>
git add .
git status
git commit
git 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=fuller
git log --oneline --graph --decorate --all
git 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 tag
git 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 提交代码的详细资料。