V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
0x47
V2EX  ›  程序员

小白问题: git 咋还原提交和提交者?

  •  
  •   0x47 · 2021-04-09 18:52:26 +08:00 · 2454 次点击
    这是一个创建于 1324 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景是这样的

    1. 原始文件 A
    2. 对 A 修改了第 2-10 行,90-100 行,并提交。
    3. 中间又有若干个提交,单独或一起修改 2-10 和 90-100 行。

    现在我想保留 2-10 行的修改,让 90-100 行回到原始状态,而且让这几行的最后提交仍然原作者。

    这要怎么做到?我们是代码谁修改谁负责,所以不想留下自己的名字。。。

    第 1 条附言  ·  2021-04-09 22:01:56 +08:00

    这个场景是本地开发分支下进行的,所有代码都是我一个人提交的,没有合并到主分支上。只是改了好多内容后后悔了,想把部分代码恢复成原样。

    22 条回复    2021-04-10 18:06:49 +08:00
    SenLief
        1
    SenLief  
       2021-04-09 19:05:06 +08:00   ❤️ 5
    这明明是修改的,你为啥不写名字。
    ch2
        2
    ch2  
       2021-04-09 19:08:19 +08:00
    只能把 3 过程的所有提交都撤销,直接 git reset 到 2 的状态(提前备份当前的代码),然后重新做 3 过程对其它代码的修改
    crayygy
        3
    crayygy  
       2021-04-09 19:29:28 +08:00
    从原始分支上重新拉一个分支出来,然后把你现在的分支上所有的 commit 同时 squash merge 上去。
    no1xsyzy
        4
    no1xsyzy  
       2021-04-09 19:38:57 +08:00
    同意 #1,确实就是你动手改回去的,原作者怎么知道你这一改回去是不是会有问题?指不定哪儿依赖了 L90-L100 的行为,然后一搞变成原作者把行为改回去了,岂不是锅从天上来?
    当然,不爽可以把这几行重写一遍。

    还有一种方法,就是干脆找原作者把 L90-L100 改回去。
    0x47
        5
    0x47  
    OP
       2021-04-09 20:51:13 +08:00 via iPhone
    @SenLief 第 90-100 行我没改动啊,恢复回原来的样子了,自然最后提交者的名字也不想变成我。
    0x47
        6
    0x47  
    OP
       2021-04-09 20:53:58 +08:00 via iPhone
    @no1xsyzy 那把这些提交都当成是在我本地分支上进行的,没有合并到主分支里。所以暂且认为,没有其他地方依赖 90-100 行的变动,只是想改回去。
    0x47
        7
    0x47  
    OP
       2021-04-09 20:55:36 +08:00 via iPhone
    @ch2 那就是纯手工操作。。。即使 2-10 行和 90-100 行的改动各自独立,不会发生冲突,也没有更智能的办法了么。。。
    0x47
        8
    0x47  
    OP
       2021-04-09 20:56:55 +08:00 via iPhone
    @SenLief @no1xsyzy 那把这个分支当作是我本地的 develop 分支。我做了好多个提交后,后悔了,想把 90-100 行改回原样。
    SenLief
        9
    SenLief  
       2021-04-09 20:58:58 +08:00 via Android
    @0x47 那你就不要改动这一处,git 会留痕的,你没改动他自然不会记录。
    hundan
        10
    hundan  
       2021-04-09 21:32:38 +08:00 via iPhone
    搞笑 恢复等于没修改? 把补丁给恢复没了找谁去?
    GeruzoniAnsasu
        11
    GeruzoniAnsasu  
       2021-04-09 21:41:15 +08:00
    rebase -i 到你第二步的开头
    所有 commit 重新 edit
    只修改 2-10 行

    这样后面的历史里 90-100 就完全不会有修改的痕迹
    0x47
        12
    0x47  
    OP
       2021-04-09 21:56:34 +08:00 via iPhone
    @hundan 这是本地开发分支,全部的提交都是我做的。我改了这几行后,后悔了,想改回原样。这样说你能理解吧?
    0x47
        13
    0x47  
    OP
       2021-04-09 21:57:40 +08:00 via iPhone
    @GeruzoniAnsasu rebase 是可以。但如果第二步后有很多提交,那就需要一步步解冲突,会很痛苦。。。
    不过貌似没有啥好办法。
    0x47
        14
    0x47  
    OP
       2021-04-09 21:59:28 +08:00 via iPhone
    @crayygy squash merge 会把很多提交都合并成一个吧。可能丢一些提交信息,不过这个貌似是最方便的办法了。多谢老哥。
    GeruzoniAnsasu
        15
    GeruzoniAnsasu  
       2021-04-09 21:59:55 +08:00
    @0x47 你要一次性改掉一堆历史还能咋 要不就先 squash
    0x47
        16
    0x47  
    OP
       2021-04-09 22:03:25 +08:00 via iPhone
    @GeruzoniAnsasu 就是想问问有没有更黑科技的办法😅 谢谢老哥。
    GuuJiang
        17
    GuuJiang  
       2021-04-09 22:39:12 +08:00   ❤️ 1
    这不就是 rebase 的典型使用场景嘛
    首先确认你的修改还没有 push 到远程分支(如果已经 push 了但是确认这个远程仓库只有你一个人在使用的话也可以,只不过最后需要进行一次 push -f 操作)
    1. 确认 git status 处于 clean 状态
    2. 找到修改第 2-10 行和 90-100 行的那次提交,记下 commit hash
    3. 执行 git rebase -i "commit hash"^,commit hash 为上一步中记录的值,注意不要漏了最后的^
    4. 在出现的界面中把那次提交前面的 pick 修改为 edit,其他的提交保持 pick
    5. 保存退出
    6. 修改文件,把对 90-100 的修改还原
    7. 使用 git commit --amend 提交,此时有需要的话可以顺便修改提交说明
    8. 执行 git rebase --continue,如果后面的提交中没有再修改过 90-100 行,那么就到此结束,否则就会停下来提示你产生冲突,此时再次修改文件解决冲突(把对 90-100 行的修改还原),然后执行 git add,git rebase --continue,重复这个过程直到没有冲突为止

    到这一步后就达到了你想要的效果了,既保持了完整的提交历史,同时 90-100 行就好像从来没有动过一样
    0x47
        18
    0x47  
    OP
       2021-04-09 23:22:06 +08:00 via iPhone
    @GuuJiang 对对,是 rebase 的典型应用场景。不过我是在寻找更方便的办法,因为要解冲突。。。不过这个也够用了。谢谢老哥!
    codehz
        19
    codehz  
       2021-04-10 09:38:50 +08:00 via Android
    不是有那个 git blame someone else 的脚本吗,应该可以很方便的改写吧)
    AoEiuV020
        20
    AoEiuV020  
       2021-04-10 14:08:40 +08:00
    第一反应 rebase,添加一个 commit 把代码改到想要的模样,然后把 2 和 3 提到的所有 commit 包含刚提交的一个 rebase 合并成一个 commit,
    最终只有这一个 commit,只修改了 2-10,没修改 90-100,
    zhuweiyou
        21
    zhuweiyou  
       2021-04-10 16:26:11 +08:00
    rebase 太麻烦, 最简单的办法:

    git reset --soft 某个历史 commit id

    这样代码会保持当前的不变, 并且提交记录会清掉.
    缺点是需要 --force 强推一下 (由于分支是你自己的 ,所以强推无所谓)
    no1xsyzy
        22
    no1xsyzy  
       2021-04-10 18:06:49 +08:00
    如果这几行及相邻行没改的话你直接 rebase 是不会有冲突的
    git 要慎重。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2764 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 09:55 · PVG 17:55 · LAX 01:55 · JFK 04:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.