V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
git
Pro Git
Atlassian Git Tutorial
Pro Git 简体中文翻译
GitX
recall704
V2EX  ›  git

问几个 git 撤消的问题

  •  
  •   recall704 · 2015-07-29 14:53:01 +08:00 · 4188 次点击
    这是一个创建于 3384 天前的主题,其中的信息可能已经有所发展或是发生改变。
    git 的add .commit. branch,merge 都基本能用了.
    但是撤消,还是不太理解.

    求科普.

    我有一 branch 如下:

    dev5 -> dev4 -> dev3 -> dev2 -> dev1 -> dev0

    其中 dev0是最新提交的,现在我突然发现其中有段代码出错了,我想撤消 这次提交.
    即撤消 git add , git commit 这两个动作.
    同时我之前的修改要还在,不然我又得重新写代码,哭死啊.


    同时求解释 rebase, revert, reset 作用与区别.
    第 1 条附言  ·  2015-12-15 15:09:04 +08:00
    32 条回复    2015-07-30 11:33:53 +08:00
    limuxy
        1
    limuxy  
       2015-07-29 15:09:13 +08:00
    同时撤销的add和commit的话 应该git reset --hard HEAD~1 就可以了
    moe3000
        2
    moe3000  
       2015-07-29 15:16:27 +08:00
    楼上+1
    morethansean
        3
    morethansean  
       2015-07-29 15:26:52 +08:00
    。。。楼上的方法会丢掉你的改动的
    123123
        4
    123123  
       2015-07-29 15:27:42 +08:00
    用 git reset HEAD~1

    加 --hard 参数修改也没了
    networm
        5
    networm  
       2015-07-29 15:28:14 +08:00
    @limuxy 你这个操作会将文件弄丢的啊,楼主要求之前的修改都在,很显然去掉 --hard 参数调用这个就可以了:git reset HEAD~1

    在此,强烈推荐阅读 ProGit v2 http://git-scm.com/book/zh/v2,同时欢迎来审校中文版: https://github.com/progit/progit2-zh/issues/160
    lijinma
        6
    lijinma  
       2015-07-29 15:29:10 +08:00
    git reset --soft HEAD~1
    networm
        7
    networm  
       2015-07-29 15:29:19 +08:00
    链接发错了,链接和内容之间还必须隔一个半角空格。
    ProGit v2 http://git-scm.com/book/zh/v2
    lijinma
        8
    lijinma  
       2015-07-29 15:29:38 +08:00
    git reset HEAD~1 应该等同 git reset --soft HEAD~1
    morethansean
        9
    morethansean  
       2015-07-29 15:31:52 +08:00   ❤️ 3
    --mixed 回到 commit 和 add 之前的状态
    --soft 回到 commit 之前的状态
    --hard 回到 commit 和 add 之前的状态并且丢掉你的改动
    limuxy
        10
    limuxy  
       2015-07-29 15:32:20 +08:00
    @morethansean
    @networm 对不起我没看清LZ问题…… TAT
    --hard会删掉修改的,LZ你千万别听我的啊!!!!
    6楼正解 git reset --soft HEAD~1
    123123
        11
    123123  
       2015-07-29 15:38:02 +08:00
    @lijinma 不对 默认参数是 --mixed
    123123
        12
    123123  
       2015-07-29 15:38:25 +08:00
    @limuxy 为什么无视 4L
    123123
        13
    123123  
       2015-07-29 15:39:00 +08:00
    再说 6L 的也不对
    YoungShook
        14
    YoungShook  
       2015-07-29 15:42:43 +08:00
    @limuxy 楼主还需要保留修改,--hard 不得哭了....

    使用 git reset --mixed HEAD~1 才是正解。😄
    chuan2015
        15
    chuan2015  
       2015-07-29 15:46:20 +08:00
    给个思路,先stash,再reset,再stash pop
    limuxy
        16
    limuxy  
       2015-07-29 15:50:46 +08:00   ❤️ 2
    补张图,关于--mixed, --soft, --hard
    lijinma
        17
    lijinma  
       2015-07-29 15:53:10 +08:00
    @YoungShook
    @123123

    哈哈,我查了,也试验了,--mixed 和 --soft 有一点点差别,不过不大,都可以。

    --soft
    Does not touch the index file or the working tree at all (but resets the head to <commit>, just like all modes do). This leaves all your changed files "Changes to be committed", as git status would put it.

    --mixed
    Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated. This is the default action.

    If -N is specified, removed paths are marked as intent-to-add (see git-add(1)).



    @chuan2015 如果直接使用 reset --mixed 或 --soft 话,不会丢失现在的修改,所以没必要 stash.
    1ang
        18
    1ang  
       2015-07-29 16:07:53 +08:00
    如果你的dev0还没提交的话最简单的方法是先修改好改成你要的样子
    然后 git commit --amend 这个命令会直接修改你上一次的commit,加上你现在修改的东西,所以不需要stash 也不需要reset
    FrankFang128
        19
    FrankFang128  
       2015-07-29 16:10:13 +08:00
    hard reset 并不会把 commit 删掉,只是将其从 history 里删掉。
    lijinma
        20
    lijinma  
       2015-07-29 16:10:38 +08:00
    @1ang 哈哈,有道理,如果是刚好是上一次修改,amend 就可以,如果是上上次等修改,就需要 reset
    ZackYang
        21
    ZackYang  
       2015-07-29 16:11:37 +08:00   ❤️ 1
    sorcerer
        22
    sorcerer  
       2015-07-29 16:59:21 +08:00 via iPhone
    感谢楼主的问题楼上诸位的回答,终于把这一块弄明白了
    kchum
        23
    kchum  
       2015-07-29 17:02:22 +08:00
    不是应该不管它,这次提交修改好就 OK 了
    julyclyde
        24
    julyclyde  
       2015-07-29 18:00:08 +08:00
    lz把时间顺序明确一下吧,总觉得0是最早的,但看语义似乎0是最近的?

    reset应该只是把HEAD往古代方向挪了一下
    但所有commit都是存在repo里的,还可以checkout出被reset掉的那个。但只有 有名字(HEAD、branch、tag、或者与他们有历史关系等) 的commits才会通过clone、push、pull传输到其他repo
    bombless
        25
    bombless  
       2015-07-29 18:07:52 +08:00
    如果只是撤销到add动作之前,还是用soft吧
    CodingMonkey
        26
    CodingMonkey  
       2015-07-29 18:08:13 +08:00
    HEAD~1 中的 ~1 指什么?
    neoblackcap
        27
    neoblackcap  
       2015-07-29 18:11:13 +08:00
    @CodingMonkey HEAD的上一个commit
    proudzhu
        28
    proudzhu  
       2015-07-29 19:10:37 +08:00
    这种情况不是改好之后 git commit --amend 不就行了
    msg7086
        29
    msg7086  
       2015-07-29 23:05:32 +08:00 via Android
    也可以先再提交一次,然后interactive rebase把两个提交合并。
    当然amend最方便。
    reset也可以只不过意义不大。
    mcfog
        30
    mcfog  
       2015-07-30 00:14:58 +08:00
    想要保险,先commit 后 ammend/rebase是最保险的,因为有reflog保底绝对一行也不会丢
    18000rpm
        31
    18000rpm  
       2015-07-30 01:20:07 +08:00
    https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting/commit-level-operations
    https://www.atlassian.com/git/tutorials/rewriting-history/git-commit--amend

    被这个教程领进门的,Git 要用的淡定就得先把内部结构看完,然后还要把每个命令与那几个区域的变化关系理清楚。
    w359405949
        32
    w359405949  
       2015-07-30 11:33:53 +08:00
    一般不建议使用reset,这玩意会丢弃历史。

    如果只是个别文件和个别行出问题,git checkout commit_id /path/to/file 把该版本中该文件弄出来,进行修改调整后,再add, commit。

    如果对log有洁癖,等这部分工作结束后,使用rebase对提交历史进行集体处理,会好看很多。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   944 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:31 · PVG 04:31 · LAX 13:31 · JFK 16:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.