前几天公司有人做git培训,讲的枯燥乏味,观众们都睡着了。这不由的让我想起一个非常棒的可视化git学习工具。有了这个工具,公司内的git培训师,可以下岗了。
本文将详细介绍这个工具,文末会给出工具地址。
Git已经是程序员的必备技能,但是它有门槛。很多时候,只掌握了pull、push、commit等指令,并不能解决问题,尤其是在有冲突的时候。
根据你输入的git指令,这个过程,全部都是动画显示的。通过箭头的指向,你能很容易的看出git仓库的数据流,是如何变化的。
1. 提交相关
下图是提交了两次commit之后的动画。可以看到版本变了两次,而且是相同颜色的。
git commitgit commit
下图是执行了新建分支的指令。通过指定b参数,可以在不存在这个分支的时候,自动创建。
git checkout -b bugFix
下面创建了一个新的分支bugFix,分别在main和bugFix提交一次代码后,使用merge指令把bugfix合并到了main。
git checkout -b bugFixgit commit git checkout mastergit commit git merge bugFix
rebase会让代码变的更加清晰。下图演示了rebase命令的用法。
git checkout -b bugFixgit commitgit checkout maingit commitgit checkout bugFixgit rebase main
2. HEAD移动
HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的 Git 命令都是从改变 HEAD 的指向开始的。
通过HEAD能够上下移动,很方便的功能。
下图演示了可以直接通过hash值指定HEAD的指向。通过checkout可以在任意时候漫游到任意的提交。
git checkout c4
通过^
,~
等特殊符号,可以完成相对跳转。不用再到处找那串非常长的hash值了。看图说话。
git checkout bugFixgit checkout HEAD^
当然,你可以直接简化成
git checkout bugFix^
是不是很简单?
同样的,~
这个符号,后面可以带数字,用来实现连级跳。我们看一下它的效果。
git branch -f bugFix HEAD~2 git branch -f main c6git checkout HEAD^
reset和revert都是用来回退提交的。不过相对来说,reset是对于local的,revert是相对于remote的。
git reset c1git checkout pushedgit revert c2
以上的功能,已经涵盖了90%的git操作。但是,如果你玩不转另外10%的话,在某些情况下会变得非常困扰。
3. cherry-pick
如果你想将一些提交复制到当前所在的位置(HEAD)下面的话, Cherry-pick 是最直接的方式了。我个人非常喜欢 cherry-pick,因为它特别简单。
它和git rebase不同的是,可以只选取其中的部分提交,抓取过来。
git cherry-pick c3 c4 c7
另外,我们还可以使用交互式的rebase。比如,git rebase -i HEAD~n
会打开对话框进行调整,在此不再重复。
交互式 rebase 指的是使用带参数--interactive的 rebase 命令, 简写为-i。
4. 几个技巧
学完上面这些,可以说在工作中应该游刃有余了。下面是几个常用的技巧。
要完成上图的转换,只需要切换到main分支,然后执行git cherry-pick c4
即可。
git checkout maingit cherry-pick c4
下面这个例子更麻烦一些。你之前在 newImage 分支上进行了一次提交,然后又基于它创建了 caption 分支,然后又提交了一次。此时你想对的某个以前的提交记录进行一些小小的调整。比如设计师想修改一下 newImage 中图片的分辨率,尽管那个提交记录并不是最新的了。
git rebase -i HEAD~2 #修改C2和C3的顺序git commit --amendgit rebase -i HEAD~2 #修改C3'和C2''顺序git branch -f master
git commit --amend 相当于上次提交错误的信息被覆盖了,gitk图形化界面上看不到上次提交的信息,git log上也看不到之前的信息,而add 后再commit 相当于重新加了一个信息。
我们能够另外一种方式完成这个目标。可以利用 cherry-pick 可以将提交树上任何地方的提交记录取过来追加到 HEAD 上的特性。
git checkout maingit cherry-pick newImagegit commit --amendgit cherry-pick caption
使用git tag可以给记录打标签。
git tag v0 c1git tag v1 c2git checkout c2
5. 高级技巧
有时候,你为了把提交记录整理成好看的提交顺序,需要下点力气。这在有些追求卓越的团队是存在的,但一般团队并不会这么折腾。
所以它才叫高级技巧。比如下面这张图的转变,我们需要经过多次rebase。
git rebase main bugFixgit rebase bugFix sidegit rebase side anothergit branch -f master another
通过~、^等特殊符号可以快速跳转,它们级连起来更加富有魅力。
git branch bugWork HEAD~^2~
比如要完成上面的分支创建,我们只需要一条命令就可以。当然也可以直接用git brach bugWork c2
。
来个更复杂的例子。
git checkout onegit cherry-pick c4 c3 c2git checkout twogit cherry-pick c5 c4 c3 c2git branch -f three c2
6. 远程仓库
clone命令是最基本的拷贝远端仓库的命令。要达到下图的目标,只需要简单执行git clone
指令即可。
通过下面的命令,可以看出远程仓库和本地仓库的HEAD分离状态。
git commitgit checkout o/mastergit commit
下图演示了fetch指令的作用。git fetch并不会改变本地磁盘的文件,它只是同步了远程的数据,然后将远程分支的指针移动了一下。fetch只是下载动作。比如下面这张图的转换。
git pull是git fetch和git merge的缩写。下图可以展示这个过程。
git pull
下面是下面一关的答案,fakeTeamwork
是这个教程自己造的命令。
git clonegit fakeTeamwork 2git commitgit pull
git push也是非常简单的命令,所以也不再介绍。
git commitgit commit git push
下面的关卡会越来越复杂,直接看截图效果比较差。这里直接给出答案,可以实际操作一下。
07. 偏离的提交历史
git clonegit fakeTeamwork 1git commitgit pull --rebasegit push
08. 锁定的master
git reset --hard o/maingit checkout -b feature C2git push origin feature
工具地址
https://learngitbranching.js.org/?locale=zh_CN