Git reset、revert、rebase的简单使用

Git reset、revert、rebase的简单使用

回滚提示

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

git reset

git reset [-q] [] [--] …​
git reset (--patch | -p) [] [--] […​]
EXPERIMENTAL: git reset [-q] [--stdin [-z]] []
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] []

说明:回退HEAD到某一个

  • git reset
    这是git add 的反向用法。

    • git add 是将修改后的文件添加到暂存区。
    • git reset 则是将暂存区内的文件移出。如果没有指定路径文件,则会将暂存区内修改的文件全部移出。
  • git reset -p
    这个是git add -p 的反向用法。-p是对文件修改变动的区块处理,这个操作比较高级。暂时不管。

  • git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] []
    主要讲这个命令,具体功能是将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 二者是一样的
    

    这个时候可以发现,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 revert

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

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

  • git revert [--[no-]edit] [-n] [-m parent-number] [-s] [-S[]] …​
    • --edit or --no-edit是否弹出commit message窗口
    • **-n **是 --no-commit的缩写
    • -m parent-number 存在merge是,指定父系分支号?这个还不怎么懂,暂时略过。

假设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之间的提交,假设中间还有很多提交时可以用这种

git rebase

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

  • 用法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里消失了

你可能感兴趣的:(Git reset、revert、rebase的简单使用)