git reset、revert、rebase、amend、HEAD用法汇总

\color{#ff4500}{ 之前因为一直使用sourcetree,所以自己把自己坑了这么多年,虽然界面化操作简单,}
\color{#ff4500}{ 但终究是条不归路, 最近使用gerrit的时候,真的很惭愧,很多用法都不会,于是专心}
\color{#ff4500}{ 研读各路大神git文章,汇总出自己需要的东西来.简单的pull,push不再介绍,}
\color{#ff4500}{ 这里说一下项目中常用场景使用的命令.}


1.1 reset \color{#0099ff}{ 回滚提交(后悔药)}

本地或者自己单独的仓库使用reset 或者revert都可以
涉及到远程仓库(公用仓库)时,不要使用reset,而使用revert回滚

git reset
git reset [-q] [<tree-ish>] [--] <paths>…​
git reset (--patch | -p) [<tree-ish>] [--] [<paths>…​]
EXPERIMENTAL: git reset [-q] [--stdin [-z]] [<tree-ish>]
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]

说明:回退HEAD到某一个<commit>

git reset <paths> //git add <paths> 的反向用法。
git add <paths>   是将修改后的文件添加到暂存区。
git reset <paths> 则是将暂存区内的文件移出。如果没有指定路径文件,则会将暂存区内修改的文件全部移出。
git reset -p <paths> // git add -p <paths> 的反向用法

-p是对文件修改变动的区块处理,这个操作比较高级。暂时不管。

git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]

主要讲这个命令,具体功能是将HEAD移动到某一个commit。
假设master分支上的提交记录如下:
A->B->C->D
目前HEAD指向commit D,我们要将代码回退到B提交时的状态

方法1

git reset --soft B 

这个时候可以发现,C,D两次提交做的修改依然存在,并且在索引区内,这个时候如果直接调用git commit ,可以生成一个新的提交E,E包含C、D两次提 交的修改。

方法2

git reset --mixed B     //等价于 git reset B   默认用法是 --mixed的

这个时候可以发现,C,D两次提交做的修改依然存在,但是不在索引区内,,记如果需要重新提交,则需要先调用git add。

方法3

git reset --hard B

和--soft、--mixed不同的是,C,D两次提交做的修改以及D以后做的一些没有提交的修改都不复存在

--merge说明
这个参数使用的有一定的前提,需要保证没有添加到索引区的修改文件在新旧两个HEAD直接的提交中没有过修改。如果下面命令调用成功

git reset --merge B

则会保留没有添加到索引区的修改。即,假设commit C 和 commit D都只修改了a.txt,而在D后我们又修改了b.txt,但是没有调用git add b.txt保存修改到索引区,则调用git reset --merge B 成功后,原来对b.txt做的修改还会存在,但是C、D提交中的修改将会回滚消失

--keep说明
和--merge有一些类似。使用成功的前提是:在D后有本地修改的文件在C、D两次提交中没有修改过,即C、D两次提交中没有它的修改记录。
假设我们在D后修改了a.txt文件,而且C、D两次提交中我们都没有修改a.txt文件,这样我们调用

git reset --keep B 可以成功,并且a.txt文件中的修改依然会保留。

git HEAD和~和^ 区别

  • ^:表示第几个父/母亲 —— git存在多个分支合并的情况,所以不只有1对父母亲
  • ~:表示向上找第几代,相当于连续几个 ^
** 如下示例: G-D-B-A可以认为是主干,其他都是merge进来的其他分支节点。A是当前HEAD节点**
  
G   H   I   J
 \ /     \ /
  D   E   F
   \  |  / \
    \ | /   |
     \|/    |
      B     C
       \   /
        \ /
         A
A =      = A^0
B = A^   = A^1     = A~1 = A~   //特别注意这个等式
C = A^2  = A^2
D = A^^  = A^1^1   = A~2
E = B^2  = A^^2
F = B^3  = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2  = B^^2    = A^^^2  = A~2^2
I = F^   = B^3^    = A^^3^
J = F^2  = B^3^2   = A^^3^2
-----------------------------------------
总结:
^x:抬头走1步,入x号岔路口。主要是控制merge之后回退的方向
~y:低头走y步,无视岔路口。HEAD~才是回退的步数
------------------------------------------
A^表示A的第一个父提交,A^2表示A的第二个父提交
A~1表示A的父提交,A~2表示A的父提交的父提交,相当于A^^和A^1^1
A~2^2表示A的父提交的父提交的第二个父提交,即为H
1.“^”代表父提交,当一个提交有多个父提交时,可以通过在”^”后面跟上一个数字,表示第几个父提交,”^”相当于”^1”.
2. ~<n>相当于连续的<n>个”^”.

1.2. revert \color{#0099ff}{ 回滚提交(后悔药)}

git revert
git revert [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<keyid>]] <commit>…​
git revert --continue
git revert --quit
git revert --abort

说明:放弃一个或多个提交,并生成一个或多个新的提交来记录这些放弃操作。

git revert [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<keyid>]] <commit>…​
--edit or --no-edit是否弹出commit message窗口

1.2.1.

-n  是 --no-commit的缩写

假设master分支上的提交记录如下:
A->B->C->D
目前HEAD指向commit D,我们要将代码revert到B提交时的状态

方法1

git revert C D

会生成2个新的commit分别覆盖C、D的提交
方法2

git revert -n C D

不会生成新的提交,但是回滚变动会作为修改变动添加到了索引区,可以直接调用git commit保存或者git revert --conitnue弹出commit页面

方法3

git revert -n C..D  //git revert C..D

类似方法1,revert从C到D之间的提交,假设中间还有很多提交时可以用这种.


1.2.2

-m parent-number 存在merge是,指定父系分支id.

大部分时候,你直接revert就好了,不用指定-m参数
不过当你要revert的的commit的上面有两个commit节点的时候,问题就来了

A -> B ->

                      E->F

C -> D ->

比如这里的E节点,它是AC两个分支合并的节点,这里假设是你在A分支使用命令merge C,那么E就有两个上游节点了,当你在新的分支F(其实就是之前的A分支)revert E 时,你就需要加上-m参数了,当你指定1时,就是revert 掉 B到E的改动,当你指定2时,你也可以revert 掉 D到E的改动,其实大部分时候我们都是选1就好了.如下:

git revert -m 1  B

2.rebase \color{#0099ff}{ 多个commit记录合并成一个}

说明:变基操作。
简单的举例说明几种用法

用法1
假设如下:
master分支提交历史为:A->B->C->D
你后面发现commit C和D有些问题,需要做一些变动,比如
将C、D两次提交合并成一次提交 squash D //将D合并到C提交 或者用fixup D,但是这样会丢弃D的提交message
删除D提交 drop D //删除D
修改D提交的message reword D//修改D提交的message
等等。
则可以调用

git rebase -i B

然后会弹出编辑窗口,相应的做修改即可。也就是变更修改pick、reword、squash、fixup、drop等命令。
用法2
假设origin/master 分支上的提交历史为 A->B->C->D;你在本地新添加了一个提交E,则master为A->B->C->D->E。此时队友新推送一个提交N到origin/master,则origin/master 分支上提交历史为A->B->C->D->N。如果你在本地采用merge的方式,则提交历史会在分叉变成A->B->C-D->(E,N)->M(表示Merge后的新提交)。而才有rebase方式的话

git fetch origin master //更新代码
git rebase origin/master    //变基操作

则本地master提交历史可能变成A->B->C->D->N->E不会存在分叉。

用法3
假设如下:
master分支提交历史为:A->B->C
server分支提交历史为:A->B->D->E
client分支提交历史为:A->B->D->F
调用

git rebase --onto master server client

这样会取出client分支,找出处于client分支和server分支的共同祖先之后的修改,然后把他们在master分支上重演一遍
这样client分支会变成A->B->C->F,注意server和client共同拥有的D提交记录在client里消失了.


3. amend\color{#0099ff}{ 保留上次的提交}

针对当前项目

git add -A
git commit -m "finish the project"

此时尴尬的地方出现了, 你发现了项目中某个地方有个bug, 这可怎么办
修改项目中的bug

git add bugFileName
git commit -m "fix: bug"

这种方式是一种解决方法, 但是提交到远程仓库, git log日志里面就会多很多无效的fix日志信息, 不美观, 这个时候就要使用 --amend, 保留上次的commit提交日志

--amend --no-edit

修改项目中的bug

git add bugFileName
git commit --amend --no-edit 会保留上次的提交信息
git push --no-thin origin HEAD:refs/for/master 重新push到远端服务器

部分内容参考链接:
顾小浪:https://www.jianshu.com/p/7e513b302d47
sayok_why: https://blog.csdn.net/sayoko06/article/details/79471173
还有其他的记不得哪里整理的笔记,如有侵权,请私信!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容