Git中特别的命令
Rebase
假设我们的分支结构如下:
rebase 会把从 Merge Base 以来的所有提交,以补丁的形式一个一个重新达到目标分支上。这使得目标分支合并该分支的时候会直接 Fast Forward,即不会产生任何冲突。提交历史是一条线,这对强迫症患者可谓是一大福音。
如果我们想要看 rebase 实际上做了什么,有一个方法,那就是用“慢镜头”来看rebase的整个操作过程。rebase 提供了交互式选项(参数 -i),我们可以针对每一个patch,选择你要进行的操作。
通过这个交互式选项,我们可以”单步调试”rebase操作。
经过测试,其实 rebase 主要在 .git/rebase-merge 下生成了两个文件,分别为 git-rebase-todo 和 done 文件,这两个文件的作用光看名字就可以看得出来。git-rebase-todo 存放了 rebase 将要操作的 commit。而 done 存放正在操作或已经操作完毕的 commit。比如我们这里,git-rebase-todo 存放了 4、5、6,三个提交。
首先 git 将 sha-1 为 4 的 commit 放入 done。表示正在操作 4,然后将 4 以补丁的形式打到 3 上,形成了新的提交 4’。这一步是可能产生冲突的,如果有冲突,需要解决完冲突之后才能继续操作。
接着讲 sha-1 为 5 的提交放入 done 文件,然后将 5 以补丁的形式打到 4’ 上,形成 5’。
再接着将 sha-1 为 6 的提交放入 done 文件,然后将 6 以补丁的形式打到 5’ 上,形成 6’。最后移动分支指针,使其指向最新的提交 6’ 上。这就完成了 rebase 的操作。
我们看一下真实的 rebase 文件。
pick e0f56d9 update gitignore
pick e370289 add a
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
该文件一共有三列,第一列表示要进行的操作,所有可以进行的操作,在下面注释里都列了出来,比如 pick 表示使用该提交,reword 表示使用该提交,但修改其提交的 message,edit 表示使用该提交,但是要对该提交进行一些修改,其它的就不一一说了。
而 done 文件的形式如下,和 git-rebase-todo 是一样的:
pick e0f56d9 update gitignore
pick e370289 add a
从刚才的图中,我们就可以看到 rebase 的一个缺点,那就是修改了分支的历史提交。如果已经将分支推送到了远程仓库,会导致无法将修改后的分支推送上去,必须使用 -f 参数(force)强行推送。
所以使用 rebase 最好不要在公共分支上进行操作。
stash
有时,我们在一个分支上做了一些工作,修改了很多代码,而这时需要切换到另一个分支干点别的事。但又不想将只做了一半的工作提交。在曾经这样做过,将当前的修改做一次提交,message 填写 half of work,然后切换另一个分支去做工作,完成工作后,切换回来使用 reset —soft 或者是 commit amend。
git 为了帮我们解决这种需求,提供了 stash 命令。
stash 将工作区与暂存区中的内容做一个提交,保存起来,然后使用reset hard选项恢复工作区与暂存区内容。我们可以随时使用 stash apply 将修改应用回来。
stash 实现思路将我们的修改提交到本地仓库,使用特殊的分支指针(.git/refs/stash)引用该提交,然后在恢复的时候,将该提交恢复即可。我们可以更进一步,看看 stash 做的提交是什么样的结构。
如图所示,如果我们提供了 —include-untracked 选项,git 会将 untracked 文件做一个提交,但是该提交是一个游离的状态,接着将暂存区的内容做一个提交。最后将工作区的修改做一个提交,并以untracked 的提交、暂存区 的提交、基础提交为父提交。
搞这么复杂,是为了提供更灵活地选项,我们可以选择性的恢复其中的内容。比如恢复 stash 时,可以选择是否重建 index,即与 stash 操作时完全一致的状态。
bisect
项目发布到线上的项目出现了bug,而经过排查,却找不到问 bug 的源头。我们还有一种方法,那就是先找到上一次好的版本,从上一次到本次之间的所有提交依次尝试,一一排查。直到找到出现问题的那一次提交,然后分析 bug 原因。
git 为我们想到了这样的场景,同样是刚才的思路,但是使用二分法进行查找。这就是 bisect 命令。
使用该命令很简单,
git bisect start
git bisect bad HEAD
git bisect good v4.1
git 会计算中间的一个提交,然后我们进行测试。
根据测试结果,使用 git bisect good or bad 进行标记,git 会自动切换到下一个提交。不断的重复这个步骤,直到找到最初引入 bug 的那一次提交。
我们知道二分法的效率是很高的,2的10次方就已经1024了,因此我们测试一般最多是10次,再多就是11次、12次。其实这就要求我们优化测试的方法,使得简单的操作就能使 bug 重现。如果重新的操作非常简单,简单到我们可以使用脚本就能测试,那就更轻松了,可以使用 git bisect run ./test.sh,一步到位。
如果某一个提交代码跑不起来,可以使用 git bisect skip 跳过当前提交或者使用 visualize 在 git 给出的列表中手动指定一个提交进行测试。
Git中特别的命令的更多相关文章
- Git中的merge命令实现中出现问题及其解决
Git中的merge命令实现和工作方式 2015年8月17日星期一 丹丹 git代码在合并两个分支的时候总是会出现一下的错误提示,不能正常的完成合并分支,错误提示如图所示: 但是在其他的终端是可以完成 ...
- GIT中常用的命令
最近项目中使用到了GIT,所以记录一下GIT中常用的命令. GIT使用的客户端有Git Bash:http://code.google.com/p/msysgit/ 还有乌龟TortoiseGit:h ...
- 总结下git中一些常用命令
一.目录操作 1.cd 即change directory,改变目录,如 cd d:/www,切换到d盘的www目录. 2.cd .. cd+空格+两个点,回退到上一目录. 3.pwd 即 print ...
- Git中的merge命令实现和工作方式
想象一下有例如以下情形:代码库中存在两个分支,而且每一个分支都进行了改动.最后你想要将当中的一个分支合并到其它的分支中.个人博客网址 http://swinghu.github.com/ 那么要问合并 ...
- 实用:Git 中的一些常见错误
无论是数据科学家.算法工程师还是普通开发人员,在每个团队协作开发任务中,Git 都是必不可少的版本控制工具,因此掌握它的基本操作十分有必要.但即便是教程满天飞的今天,开发人员在使用 Git 时也还是会 ...
- Git 日常工作中使用的命令记录
前言 这篇文章主要是介绍我在使用Git中的有一些忘记了,但是很重要的命令. 20190424 Git 历史信息 username 和 email 更改 git config alias.chang ...
- 关于Git中的一些常用的命令
深入了解git的checkout命令 检出命令(git checkout)是Git最常用的命令之一,同时也是一个很危险的命令. 因为这条命令会重写工作区.检出命令的用法如下: 用法一: git che ...
- git中常见的几个命令
git中常见的几个命令 本地仓库 三个区域 工作目录 暂存区 本地仓库 文件的四个状态 未跟踪 untracked 已暂存 staged 已提交commited 已修改 modified 基本命令 g ...
- Git中从远程的分支获取最新的版本到本地——两种命令
Git中从远程的分支获取最新的版本到本地有这样2个命令: 1. git fetch:相当于是从远程获取最新版本到本地,不会自动merge Git fetch origin master git log ...
随机推荐
- hdu 1069 DAG加权
题目: Monkey and Banana Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...
- UVA-12304 Race(递推)
题目大意:求n个人比赛的所有可能的名次种数.比如:n=2时,有A第一B第二.B第一A第二.AB并列第一三种名次. 题目解析:既然是比赛,总有第一名.第一名的人数可能是i (1≤i≤n),则剩下待定的人 ...
- k8s集群搭建指南
一.简介 Ansible Docker Docker compose,docker swarm,docker machine Mesos,marathon Kubernetes(占据80%的市场) D ...
- spring boot 学习(三)API注解记录及测试
spring boot API注解记录及测试 部分注解解析 @Controller : 修饰创建处理 http 处理对象,一般用于页面渲染时使用. @RestController : Json数据交互 ...
- @SpringBootApplication的使用
之前用户使用的是3个注解注解他们的main类.分别是@Configuration,@EnableAutoConfiguration,@ComponentScan.由于这些注解一般都是一起使用,spri ...
- Oracle sqlloader
一.SQL*LOADER简介 SQL*Loader是oracle提供的可以从多种平面文件中向数据库中加载数据的工具,使用sqlldr工具可以在很短的时间内向数据库中加载大量的数据,像把制作好的exce ...
- 微信分享自定义标题和图片的js
<script> document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() { window.sh ...
- Java通过继承外部类来建立该外部类的protected内部类的实例(转)
原文链接:http://blog.sina.com.cn/s/blog_7de00ff60102xffx.html 如果想要在外部类的导出类(子类)中建立该外部类的为protected权限的内部类的实 ...
- juery 安全加固 集合
来源 jquery升级坑 2 3 4 5 版本 相关源码分享 新建document jquery ajax使用说明 最近在iteye的新闻中看到jQuery已经更新到了1.6.1. 和 ...
- C# zedgraph利用另一窗口取得的串口数据绘图
C# zedgraph利用另一窗口获得的串口数据绘图第一次用zedgraph,非常不熟悉,网上很多内容看的云里雾里... 这个程序主界面接收串口数据,而另外一个窗口进行实时曲线绘图,要怎么样实现for ...