git 的高级使用教程
记录一些 git 的高级用法
修改 tag 代码
在项目中我们会有这样的要求,发布了一个 tag v1.0 现在这个 tag 有 bug 需要修复应该如何操作呢
tag 其实是一个快照是不能修改代码的但是可以基于 tag 新建一个分支来修改,这样修改完毕基于新的分支再打 tag 即可得到修复后的 tag
1 2 3 4 5 6
| $ git fetch origin v1.0
$ git checkout -b branch_name tag_name //这样会从 tag 创建一个分支,然后就和普通的 git 操作一样了,该分支是基于tag的而不是基于master的
$ git push origin branch_name //直接将修改好的分支推上去 或者重新打tag
|
回滚错误的修改
建议仔细阅读git-revert
该命令只回滚了一个单独的提交,并没有移除后面的提交,并且保留了提交历史。 但是 reset 直接把状态回调 bug 之前之后所有的提交都会遗弃,这样并不安全。
1 2 3 4 5 6 7 8 9 10
| $ git revert <commit>
$ git commit -m "Make some changes that will be undone"
$ git revert HEAD
|
确保你只对本地的修改使用 git reset,而不是公共更改。如果你需要修复一个公共提交,git revert 命令正是被设计来做这个的
重写项目历史
git commit –amend
git commit –amend 命令是修复最新提交的便捷方式,如有需要请在本地使用不要修改公共历史。
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
| $ git log
commit eeeab2ca5f30d70667d6d12ab71f19dd7b958d1c (HEAD -> master) Author: xxx <xxx@xxx.com> Date: Mon Nov 6 15:30:43 2017 +0800
fix(测试): 测试提交
测试提交
Signed-off-by: xxx <xxx@xxx.com>
$ git commit
# 该命令修改后再使用git log得到如下
commit eeeab2ca5f30d70667d6d12ab71f19dd7b958d1c (HEAD -> master) Author: xxx <xxx@xxx.com> Date: Mon Nov 6 15:30:43 2017 +0800
fix(测试): 测试提交sss
测试提交sss
Signed-off-by: xxx <xxx@xxx.com>
|
git rebase
变基(rebase, 事实上这个名字十分诡异, 所以在大多数时候直接用英文术语)是将分支移到一个新的基提交的过程。事实上重写了你的项目历史,过程一般如下所示

用法:
1 2 3
| git rebase <base>
# 将当前分支 rebase 到 <base>,这里可以是任何类型的提交引用(ID、分支名、标签,或是 HEAD 的相对引用)
|
一个 🌰
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| $ git checkout -b feat master # 编辑文件 $ git commit -a -m "Start developing a feature"
$ git checkout -b bug master # 编辑文件 $ git commit -a -m "Fix security hole"
$ git checkout master $ git merge bug $ git branch -d bug
$ git checkout feat $ git rebase master
$ git checkout master $ git merge feat
|
另一个 🌰
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
| $ git checkout -b feat master # 编辑文件 $ git commit -a -m "Start developing a feature"
$ git commit -a -m "Fix something from the previous commit"
$ git checkout master # 编辑文件 $ git commit -a -m "Fix security hole"
$ git checkout feat $ git rebase -i master
最后的那个命令会打开一个编辑器,包含 feat 的两个提交,和一些指示:
pick 32618c4 Start developing a feature pick 62eed47 Fix something from the previous commit
pick 32618c4 Start developing a feature squash 62eed47 Fix something from the previous commit
git checkout master git merge feat
|
通常情况下建议使用 rebase 而非 merge 来拉取上游代码。这样所有的记录会被合并为一次 commit,而且没有一些不重要的合并来污染提交的时间线
本地清理
1 2 3 4
| $ git rebase -i HEAD~3
$ git rebase -i HEAD~~~ //这两条一个意思合并注释
|
参考代码合并:Merge、Rebase 的选择
合并分支 commit
当你在新的 feat 功能开发时可能会有各种 commit 最后功能完成我可能想将所有 commit 合成一个,这样历史会比较简洁。这是可能会使用这条命令
1 2 3 4 5 6
| $ git merge-base feat master //该命令找出feat 分支开始分叉的基 返回基提交的ID,然后可以酱紫
$ git rebase -i IDXXX //此时选择suqash 就可以重新写历史了 当然合并后最后一次的历史也可以使用 git commit --amend改写
|
git pull
在基于 Git 的协作工作流中,将上游更改合并到你的本地仓库是一个常见的工作。我们已经知道应该使用 git fetch,然后是 git merge,但是 git pull 将这两个命令合二为一。
基于 Rebase 的 Pull
1 2 3 4 5
| $ git pull --rebase <remote>
$ git checkout master $ git pull --rebase origin
|
分离 HEAD
1 2 3 4
| // 可以直接使用 -f 选项让分支指向另一个提交 该命令会将 master 分支强制指向 HEAD 的第 3 级父提交。 $ git branch -f master HEAD~3
|
Reset 还是 Checkout
参考此文章
| 命令 |
作用域 |
常用情景 |
| git reset |
提交层面 |
在私有分支上舍弃一些没有提交的更改 |
| git reset |
文件层面 |
将文件从缓存区中移除 |
| git checkout |
提交层面 |
切换分支或查看旧版本 |
| git checkout |
文件层面 |
舍弃工作目录中的更改 |
| git revert |
提交层面 |
在公共分支上回滚更改 |
| git revert |
文件层面 |
(然而并没有) |
git cherry-pick
git cherry-pick 命令「复制」一个提交节点并在当前分支做一次完全一样的新提交。
只想将远程仓库的一个特定提交合并到自己的分支中该怎么做呢?可以使用 git cherry-pick 来选择给定 SHA 值的提交,然后将其合并到当前分支中:
参考此文章总结一下工具
Git flow 工具
- Git-flow 是一个 git 扩展集,按 Vincent Driessen 的分支模型提供高层次的库操作;使用 git-flow 工具可以以更加简单的命令完成对 Vincent Driessen 分支模型的实践
- 另一个工具是 Git-extras,该工具没有 git-flow 那么简单化,不过其提供更加强大的命令支持
Git Commit Message
我们遵循 Angular 社区规范格式来提交代码
1 2 3 4 5
| <type>(<scope>): <subject> <BLANK LINE> <body> <BLANK LINE> <footer>
|
- type: 本次提交类型
- scope: 本次提交影响范围,一般标明影响版本号或者具体的范围如 $browser, $compile, $rootScope, ngHref, ngClick, ngView, etc…
- subject: 本次提交简短说明
关于 type 提交类型,有如下几种值:
- feat:新功能(feature)
- fix:修补 bug
- docs:文档(documentation)
- style: 格式(不影响代码运行的变动)
- refactor:重构(即不是新增功能,也不是修改 bug 的代码变动)
- test:增加测试
- chore:构建过程或辅助工具的变动
Commit 小工具
参考文章