git的一些常用高层命令
原文链接
git config
- git config --system:系统配置
- git config --global:全局配置
- git config --local:本地配置
- git config -e:编辑配置文件(可与--system, --global, --local组合使用)
- git config --unset:删除某个配置
- git config --get:显示某个配置的值
- git config -l --list:列出所有配置
- git config alias
- git config push.default
- git config pull.rebase
git log
- git log --stat:简要显示增改行数统计
- git log -p --patch:展开每次提交的差异
- git log --name-status:显示新增、修改、删除的文件清单
- git log --graph:以一些ASCII字符串表示的简单图形,形式地展示了每个提交所在分支及其分化衍合的过程
- git log --oneline:以单行的简要方式显示log
- git log --format=:格式化输出日志
- git log --grep=:搜索匹配关键字的提交
- git log --author=:过滤出对应作者的提交
- git log --pretty=:[oneline, short, full, fuller, raw]
- git log --since=:某个日期之后的提交
- git log --until=:某个日期之前的提交
git status
- git status -s:简化方式输出当前状态信息
- git status --ignored:显示被忽略的文件
git stage, git add
- git stage -a:暂存所有文件
- git stage -u:暂存更新文件(包括删除)
- git stage -i:以互动方式暂存文件
- git stage -p:暂存文件的部分改动
git checkout
- git checkout:汇总显示所有状态
- git checkout path:对于path使用暂存区的内容覆盖工作区
- git checkout commit -- path:对于path使用commit的内容覆盖工作区
- git checkout branch:切换分支
- git checkout -b branch [start-point]:以start-point创建新的分支branch(默认的start-point是HEAD)
git reset
- git reset path [reset-point]:使用reset-point的内容覆盖暂存区
- git reset --mixed [reset-point]:重置版本库的内容为reset-point,暂存区内容也被重置,工作区内容不变(git reset的默认动作)
- git reset --soft [reset-point]:重置版本库的内容为reset-point,暂存区和工作区的内容都不改变
- git reset --hard [reset-point]:重置版本库的内容为reset-point,暂存区和工作区的内容均被重置
一个神奇而有用的工具(diff&patch)
diff, patch是*nix系统的工具
- diff用来对比两个文件的差异
- patch可以看成是patch的反操作
git diff, git apply
- 使用git diff和git apply本质上是git对diff, patch的一次再封装
- 使用git diff生成补丁文件
- 使用git apply应用补丁文件
- git diff, git apply面向的补丁文件有一个实际意义上的标准,可以在不同的版本控制软件中交流使用
- 分别对应git diff, git apply的批量操作
- 使用git format-patch可以对一批commit生成多个对应的补丁文件
- 使用git send-mail可以将这些补丁文件发送给项目管理员
- 项目管理员可以使用git am批量应用补丁
- 实际上这就是开源软件一种工作流
修改提交历史
使用上一次提交历史git commit --amend
在上一次提交的基础上继续修改、删除、新增文件,提交时加上--amend选项,新提交的内容就会与上次提交的更新进行合并。也可以不做任何改动,直接使用git commit --amend来修改上次提交的说明信息
修改多次提交git rebase -i
git rebase -i [start-commit]..[end-commit]可以对指定范围内的提交进行合并、修改、切割等操作
注意:不管是git commit --amend还是git rebase -i,修改过的commit都会重新计算校验和,所以一定要注意不要去修改已经推送到公共版本库的提交,否则会引起人民群众的公愤。版本库管理员为了安全起见,也可以禁止使用--force选项进行推送,避免这种情况的发生
git的一些常用的工作流
集中式工作流
搭建一个中心版本库,所有成员从这个版本库里面克隆代码。
只使用一个分支master,所有提交均推送到这个分支。
所有成员设置pull.rebase为true,避免非快进式提交。
管理员在中心版本库配置receive.denyNonfastforwards为true,拒绝非快进式的推送。
这种工作流本质上是把git当成svn这种集中式版本控制系统来使用。
- 优点:项目提交历史完全线性化,因此项目条理十分清晰,管理也十分简单
- 缺点:模式过于简单,无法适应复杂的开发情景与多变的项目需求
- 很少有项目只使用这种工作流,但这种工作流常常用来与其它工作流来配合使用
金字塔式工作流
项目有多个版本库,但有一个核心的、权威的版本库。
这个核心的版本库有一小批核心管理员,这些管理员有权限直接向核心版本库推送更新。
这个核心的版本库有一大批项目贡献者,每个贡献者者隶属于某个或某几个核心管理员,核心版本库对这些贡献者开放只读权限。
项目贡献者可以克隆核心库来创建自己的版本库,然后在此版本库上生成贡献代码,或通过pull requests,或通过send mail patch将贡献代码发给核心管理员
核心管理员在审核完贡献代码后,如果代码质量通过,管理员就会将贡献代码合并到核心库的某个分支上
- 优点:结构灵活多变,可以从横向和纵向上来拓展工作流的结构,可以适应大型项目的复杂情景
- 缺点:对核心管理员的要求极高
- 几乎所有的大型开源项目都是使用这种工作流或这种工作流的变种
git-flow
搭建一个中心版本库,中心版本库保持一个长期的、稳定的分支。一般是master,也有项目是stable
中心版本库还会保持一个长期的、但经常更新的分支。一般分支名称是develop
平常情况下都是develop分支在演进,如果有某个特性需要开发,便从develop上分出一条分支feature/xxx。待特性基本开发完成后并入develop分支
如果要准备发布,可以从develop上分出一条分支release/xxx。后期所有和发布相关的提交均推送到这个release分支上。待release分支开发完成,并入develop和master分支。用master分支进行部署
如果生产环境发现紧急bug,从master上切出hotfix/xxx分支,修正后将该分支并入master和develop分支,必要时也并入release分支
定期清除一些过期的feature, release, hotfix分支
- 优点:中心版本库的主分支只有两条,条理相较简单清晰,起码在人的能力控制范围内,项目成员可以直接参与项目贡献。同时,通过feature, release, hotfix三类分支的配合使用,也能适应复杂的情景
- 缺点:工作流流程比较复杂,上手不是很容易,同时对项目成员的能力要求比较高。如果项目部署后,经常出现紧急bug,就要频繁的建立hotfix分支,甚至是release分支,一样会扰乱分支历史,难于管理。
- 适用于小团队的项目开发管理,能适应项目成员能力平均和不平均的情景。同时,sourcetree这款git的图形界面软件也对这种工作流进行了一定程度的封装
cherry-pick
项目中心版本库维持多个长期支持分支,每个分支对应一个测试用例,即平常我们说的测服、真服
用于部署真服的分支一般是master,其它分支名字随意,假定部署测服的分支为develop
平常代码在develop上演进,每个提交必须基于一个主题,这个主题可以是一个特性、一个bug、一个模块、一个功能等等
每个主题必须要有一个唯一性标识,并且这个唯一性标识必须体现在提交说明上
在发布时基于要发布的主题,从develop上筛选出对应的提交,把这些提交分别并入master上,然后进行部署、测试、发布
- 优点:中心版本库只有若干条主线,并且这些主线的提交历史是完全线性的。条理十分清晰。
- 缺点:在开发分支的演进模式偏于简单,如果项目成员数过多,会有点适应不了。同时,对提交说明的书写要求很严格,如果漏掉说明,就很难基于主题定位到这个提交。这个可以通过git的钩子系统来检查
- 这种工作流的单个分支上其实就是集中式工作流,适用于小团队的项目开发管理
git的一些底层命令
- git rev-parse
- git cat-file
- git read-tree
- git commit-tree
- git ls-tree
- git update-index
- git update-ref
- git hash-object
- git reflog