zoukankan      html  css  js  c++  java
  • Git 实用操作:撤销 Commit 提交(动图讲解)

    有的时候,改完代码提交 commit 后发现写得实在太烂了,连自己的都看不下去,与其修改它还不如丢弃重写。怎么操作呢?

    使用 reset 撤销

    如果是最近提交的 commit 要丢弃重写可以用 reset 来操作。比如你刚写了一个 commit:

    写完回头看了看,你觉得不行这得重新写。那么你可以用 reset --hard 来撤销这条 commit。

    git reset --hard HEAD^
    

    HEAD^ 表示往回数一个位置的 commit`,上篇刚说过。

    因为你要撤销最新的一个 commit,所以你需要恢复到它的父 commit ,也就是 HEAD^。那么在这行之后,你要丢弃的最新一条就被撤销了:

    不过,就像图上显示的,你被撤销的那条提交并没有消失,只是你不再用到它了。如果你在撤销它之前记下了它的 SHA-1 码,那么你还可以通过 SHA-1 来找到他它。

    使用 rebase -i 撤销

    假如有一个 commit,你在刚把它写完的时候并没有觉得它不好,可是在之后又写了几个提交以后,你突然灵光一现:哎呀,那个 commit 不该写,我要撤销!

    不是最新的提交,就不能用 reset --hard 来撤销了。这种情况的撤销,就要用之前介绍过的一个指令交互式变基:rebase -i

    之前介绍过,交互式变基可以用来修改某些旧的 commit。其实除了修改提交,它还可以用于撤销提交。比如下面这种情况:

    你想撤销倒数第二条 commit,那么可以使用 rebase -i

    git rebase -i HEAD^^
    

    Git 引导到选择要操作的 commit 页面:

    pick 310154e 第 N-2 次提交
    pick a5f4a0d 第 N-1 次提交
    
    # Rebase 710f0f8..a5f4a0d onto 710f0f8
    #
    # Commands:
    # p, pick <commit> = use commit
    # r, reword <commit> = use commit, but edit the commit message
    # e, edit <commit> = use commit, but stop for amending
    # s, squash <commit> = use commit, but meld into previous commit
    # f, fixup <commit> = like "squash", but discard this commit's log message
    # x, exec <command> = run command (the rest of the line) using shell
    # b, break = stop here (continue rebase later with 'git rebase --continue')
    # d, drop <commit> = remove commit
    ...
    

    在上篇中,讲到要修改哪个 commit 就把哪个 commit 前面的 pick 改成 edit。而如果你要撤销某个 commit ,做法就更加简单粗暴一点:直接删掉这一行就好(使用 d 命令)。

    pick a5f4a0d 第 N-1 次提交
    
    # Rebase 710f0f8..a5f4a0d onto 710f0f8
    #
    # Commands:
    # p, pick <commit> = use commit
    # r, reword <commit> = use commit, but edit the commit message
    # e, edit <commit> = use commit, but stop for amending
    # s, squash <commit> = use commit, but meld into previous commit
    # f, fixup <commit> = like "squash", but discard this commit's log message
    # x, exec <command> = run command (the rest of the line) using shell
    # b, break = stop here (continue rebase later with 'git rebase --continue')
    # d, drop <commit> = remove commit
    ...
    

    把这一行删掉就相当于在 rebase 的过程中跳过了这个 commit,从而也就把这个 commit 丢弃了。

    如果你通过 git log 查看,就会发现之前的倒数第二条 commit 已经不在了。

    使用用 rebase --onto 撤销

    除了用交互式 rebase,你还可以用 rebase --onto 来更简便地撤销提交。

    rebase 加上 --onto 选项之后,可以指定 rebase 的「起点」。一般的 rebase, 的「起点」是自动选取的,选取的是当前 commit 和目标 commit 在历史上的交叉点。

    例如下面这种情况:

    如果在这里执行:

    git rebase 第3个commit
    

    那么 Git 会自动选取 35 的历史交叉点 2 作为 rebase 的起点,依次将 45 重新提交到 3 的路径上去。

    --onto 参数,就可以额外给 rebase 指定它的起点。例如同样以上图为例,如果我只想把 5 提交到 3 上,不想附带上 4,那么我可以执行:

    git rebase --onto 第3个commit 第4个commit branch1
    

    选项 --onto 参数后面有三个附加参数:目标 commit、起点 commit(注意:rebase 的时候会把起点排除在外)、终点 commit。所以上面这行指令就会从 4 往下数,拿到 branch1 所指向的 5,然后把 5 重新提交到 3 上去。

    同样的,你也可以用 rebase --onto 来撤销提交:

    git rebase --onto HEAD^^ HEAD^ branch1
    

    上面这行代码的意思是:以倒数第二个 commit 为起点(起点不包含在 rebase 序列里),branch1 为终点,rebase 到倒数第三个 commit 上。

    也就是这样:

    总结

    撤销最近一次的 commit 直接使用 reset --hard,撤销过往历史提交。方法有两种:

    1. git rebase -i 在编辑界面中删除想撤销的 commit
    2. git rebase --onto 在 rebase 命令中直接剔除想撤销的 commit

    这有两种理念是一样的,即在 rebase 的过程中去掉想撤销的 commit,让它消失在历史中。

  • 相关阅读:
    Html禁止粘贴 复制 剪切
    表单标签
    自构BeanHandler(用BeansUtils)
    spring配置中引入properties
    How Subcontracting Cockpit ME2ON creates SD delivery?
    cascadia code一款很好看的微软字体
    How condition value calculated in sap
    Code in SAP query
    SO Pricing not updated for partial billing items
    Javascript learning
  • 原文地址:https://www.cnblogs.com/willick/p/13643955.html
Copyright © 2011-2022 走看看