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 ...
随机推荐
- 利用nodeJs anywhere搭建本地服务器环境
1.npm install anywhere -g 如果是mac系统会提示你权限不够,需要在代码前加上 sudo获取管理员权限.即sudo npm install anywhere -g. 2.安装完 ...
- 关于初级dp的一些记忆
01背包和数塔都是寒假看的,数塔还算明白,但01背包虽然会做其实也是背下来的,一直不是很清楚它的可行性,昨天老师讲了以后恍然大悟,和数塔类似生成了一颗二叉树: 利用数组/dfs 自下而上/自上而下 ...
- 每天一个linux命令(3):pwd
Linux中用 pwd 命令来查看”当前工作目录“的完整路径. 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录. 在不太确定当前位置时,就会使用pwd来判定当前目录在文件系统内的确切位置. ...
- jQuery旋转插件—rotate-摘自网友
jQuery旋转插件—rotate 时间:2013年01月03日作者:愚人码头查看次数:5,660 views评论次数:6条评论 网上发现一个很有意思的jQuery旋转插件,支持Internet Ex ...
- Idea破解办法+idea免费生成注册码+jsp属性选择器+注解什么的都报错
Idea破解办法: http://blog.csdn.net/bitcarmanlee/article/details/54951589 idea免费生成注册码: http://idea.iteblo ...
- sublime text3的快捷键
Ctrl + Shift + P 调出命令板(Command Palette) Ctrl + ` 调出控制台 Ctrl + D 选择当前光标所在的词并高亮该词所有出现的位置,再次 C ...
- IoC基础例子
一个简单的例子: 一般新建一个com.dao包,存放一些dao接口. com.dao.impl里面存放具体的dao com.service存放service接口 com.service.impl具体的 ...
- spring事务管理及相关知识
最近在项目中遇到了spring事务的注解及相关知识,突然间感觉自己对于这部分知识只停留在表面的理解层次上,于是乎花些时间上网搜索了一些文章,以及对于源码的解读,整理如下: 一.既然谈到事务,那就先搞清 ...
- tunning-prime优化mysql建议
#!/bin/sh # set tabstop=8 ################################################################## ...
- Apple原装扫描二维码指定区域
之前记录了用Apple原装的AVFoundationo类库扫描二维码:http://www.cnblogs.com/foxting/p/4733226.html,此篇记录下如何设置扫描区域. AVCa ...