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

你们在用 git 合并时但不担心自己操作失误把代码弄丢?

  •  2
     
  •   yuann72 · 49 天前 · 4132 次点击
    这是一个创建于 49 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这几天用 rebase 的 2 个事例

    事例 1:

    rebase 前的提交历史大概这样:

    提交时间 commit message
    10:01 A1
    10:02 B
    10:03 A2
    10:04 C

    我想把 A1 和 A2 合并, 用 webstorm 进行 rebase:

    action commit message
    pick A1
    squash A2
    pick B
    pick C

    然后点 start rebase, rebase 完只剩下 A1, B, C 3 个 commit, 这时 npm 开始报错提示有个文件不存在, 看了 A1 commit 的内容发现这个文件在 A1 commit 里被删了, 但是原本的 A1, A2 commit 里并没有删这个文件 接着就是 git reflog 找回 rebase 前的 commit id, git reset 恢复到 git rebase 前, 再试一次 rebase 还是一样 试了几次后发现下面这样进行 rebase 就能达到我的目的, 只剩下 A1, B, C 3 个 commit, 文件也没丢

    action commit message
    pick A2
    squash A1
    pick B
    pick C

    事例 2:

    使用 webstorm 右下角 git 分支里的 "Rebase Current onto Selected" 将服务器端的分支内容用 rebase 的方式合并到当前分支 结果合并一半右下角弹出红色感叹号, 报错信息大概这样"文件路径 Permission XXXX", 接着还是 git reflog 找回 rebase 前的 commit id 恢复后再试一次就没报错了 rebase 合并是合并完了, 但我暂存区那些修改完还没提交的文件都不见了! 查了搜索引擎后用 git stash pop 恢复出来

    事例 1 可能是我操作失误或文件冲突导致, 也就还好是一个完整的文件被合并丢了, rebase 完立马就发现了, 如果是某几行代码合并丢了, 那以我这的测试程度可能要到生产环境出 bug 报错才会发现。也还好我是提交完 C commit 后就进行 rebase 事例 2 我就担心要是 git stash 里没有我的文件, 或者被我瞎操作把 git stash 清空了那就完了

    所以我现在用 git 命令时会很谨慎, 生怕有些代码给我弄丢了. 特别是合并冲突处理文件冲突的时候, 面对这几个月前编辑的代码, 我也不知道哪边的版本是正确的代码

    41 条回复    2021-09-05 01:34:49 +08:00
    af463419014
        1
    af463419014   49 天前
    tar -zcvf xxx
    合并前直接打个本地压缩包,弄乱就删掉重新解压操作
    yuann72
        2
    yuann72   49 天前
    @af463419014 #1 我担心代码合并丢了自己都没发现😳
    ayase252
        3
    ayase252   49 天前   ❤️ 4
    不可能弄丢的。git reflog 里面有所有的操作历史,搞坏了 reset --hard 回来就行了,跟撤回一样的
    yuann72
        4
    yuann72   49 天前
    @ayase252 #3 合并丢的时候没发现,等到发现的时候可能已经产生线上 BUG 了。我担心的是这一点
    renmu123
        5
    renmu123   49 天前 via Android   ❤️ 1
    我从来没有弄丢过文件,我都是 commit 之后再进行 merge
    revlis7
        6
    revlis7   49 天前   ❤️ 1
    那你有没有想过即便没有操作失误,git 的 auto merge 也是有可能导致代码出现 Bug 的?

    这个不是你如何操作的问题,你需要的是 Review 和 Test
    wudicgi
        7
    wudicgi   49 天前
    基本不用 rebase, 而且一般 merge 都是强制 no fast-forward

    另外怕丢历史的话,可以创建一个新分支再操作
    没创建的话其实 reflog 也能找回来,就是还得人工核对一下
    bwt
        8
    bwt   49 天前 via Android   ❤️ 1
    自从 git 用熟练后就没丢过了,rebase 我比较习惯命令行,合并冲突代码时比较直观🤣
    creanme
        9
    creanme   49 天前
    我之前有次 git pull (rebase) 下来,发现有个文件处于被删除状态,不太明白为啥会这样。
    Mutoo
        10
    Mutoo   49 天前
    既然你用的是 webstorm 那就完全没并要担心了,因为 webstorm 还提供 local history,就算你整个 commit 都原地消失,通过 local history 也可以还原。
    yuann72
        11
    yuann72   49 天前
    @creanme #9 这问题有遇到过
    yuann72
        12
    yuann72   49 天前
    @revlis7 #6 啊这,我一直以为 GIT 是个很成熟的软件,原来自动合并是会出 bug 的
    beidounanxizi
        13
    beidounanxizi   49 天前
    @yuann72 那叫 fast foward
    自己如果不懂什么叫做 git conflict 的话
    去了解下 什么样的情况 才会产生 conflict ,
    自己在不同的分支 对同文件 修改也会 conflict 呢
    reflog + reset --hard 时光隧道局了解下?!
    QingStone
        14
    QingStone   49 天前 via iPhone
    @creanme #9 可能是远程上有人提交了一个删除该文件的提交记录
    ampedee
        15
    ampedee   49 天前 via Android
    面对未知当然容易恐惧,弄懂 git 每一次 merge,rebase 背后的原理这些都是日常操作。
    可以看下我写的关于 git 原理和撤销操作的博客: https://www.waynerv.com/posts/git-undo-intro/

    另外需要合并几个月前编辑的代码说明你们需要改进工作流,一个分支不应该存在这么久
    msg7086
        16
    msg7086   49 天前   ❤️ 4
    @yuann72 #12


    就算不用 Git 也会出 bug 呢,这管 Git 啥事。
    一个人改了文件 A,另一个人改了文件 B,你怎么知道这两个文件分别改完以后程序能正常运行?

    至于这个帖子里的问题:
    如果你提交记录里 A2 和 B 有冲突的话,那么 A2 和 B 是不能随便交换位置的。
    换句话说,交换 A2 和 B 是需要手动处理的。
    所以如果这个操作我来做的话,会是

    1. 在 A1 上新建一个分支 tmp 。
    2. 把 A2 cherry pick 到 tmp 上,然后解决冲突。
    3. 把 A1 和 A2 squash 成 A 。
    4. 把 B cherry pick 到 tmp 上,然后解决冲突。
    5. 把 C cherry pick 到 tmp 上。
    6. 把原来的分支指向 C 。
    这样得到一个 A-B-C 。这么操作应该是最稳妥的方案了。

    然后关于在还没有提交的时候去 Rebase 的问题:

    不!要!这!么!做!

    Rebase 是在提交链上的操作。处理提交链的时候本地文件夹是要清空的。
    (其实不需要完全清空,无冲突 untracked 文件可以保留,但是很多 Git 软件为了安全,是要完全清空的。)
    当你点击 Rebase 按钮的时候,其实就是在告诉 Git,

    清空我本地的文件夹,以便修改提交,做 Rebase 。

    所以你修改的文件当然会消失掉,因为他们被自动 Stash 了。
    然后如果 Rebase 出现了任何问题,Stash 就不会被自动 pop 。
    另外 Stash pop 的时候也可能出现问题。
    这些时候都要手动 Stash apply 并修复潜在的问题。

    但是这种操作是很容易出错的,如果没有特殊需求,还是建议先 commit 成提交,永久写入 Git 数据库,然后再做 Rebase 之类的操作。然后可以像解决问题 1 里我提到的方法一样,建一个 tmp 分支来操作,操作完以后再把分支切过去。
    临时 commit 在操作完以后还可以 undo 回 staged (相当于 reset soft HEAD~1 ),所以这个操作是没有副作用的。
    muzuiget
        17
    muzuiget   49 天前
    有 git reflog,养成良好习惯就行,开新分支写新特性,真要大操作,整个仓库打包备份。
    xuanbg
        18
    xuanbg   49 天前
    代码结构没毛病就不太会发生合并冲突。
    youmilk
        19
    youmilk   48 天前
    先 commit 再 merge/rebase,然后 idea 还有 localHistory 也能找回代码。
    vicnicLight007
        20
    vicnicLight007   48 天前
    用 sourceTree,合并之后不提交,发现问题贮藏一下变动,然后删除贮藏,美滋滋
    Felldeadbird
        21
    Felldeadbird   48 天前
    不会丢代码啊。怕丢就开多 2 个分支各自留底。或者额外开一个临时分支,两者合并。整理好临时分支后,在合并主分支。
    Euthpic
        22
    Euthpic   48 天前 via Android
    不担心,合出问题的话可以 revert,或者 merge 前开个 backup branch 。丢代码会出问题,不丢代码难道就不会出问题吗?重要的是有改动的地方测试有没有回归到
    wangsd
        23
    wangsd   48 天前
    WebStorm 有本地历史记录
    Hstar
        24
    Hstar   48 天前
    以前团队内有人经常合并出错,我们复盘了下发现都是因为 merge 时根本不看 diff 无脑合并
    bugsnail
        25
    bugsnail   48 天前
    1. 先 commit 再合并
    2. 尽量用图形化界面, 如 sourcetree + beyond compare
    fregie
        26
    fregie   48 天前
    只要 commit 了,几乎就没什么可能会丢。
    应该加自动化测试防止合并分支错误导致的问题
    chenmobuys
        27
    chenmobuys   48 天前
    合并时有冲突,就不要强制合并。
    ooxiaoming
        28
    ooxiaoming   48 天前
    只要 git 了就没有找不到的时候...
    mangoDB
        29
    mangoDB   48 天前
    只要保证操作流程正确,不轻易的 checkout/reset --hard,就不会丢代码。
    LemonK
        30
    LemonK   48 天前
    养成好习惯就不会有问题。1. 尽量不要两个分支改同一个地方,不要有长时间没合并的分支。2. 合并的时候认真看 diff 。
    oxromantic
        31
    oxromantic   48 天前
    不放心的话,合并代码这种事情交给专人负责,同时兼顾 review 代码
    xingheng
        32
    xingheng   48 天前
    1. 不能保证 rebase 能一步到位的话就用 cherry-pick
    2. 不要轻信那个 GUI 封装的 git 操作,亲力亲为
    Trim21
        33
    Trim21   48 天前 via Android
    你可以新建两个分支进行操作,合并之后 diff 合并之前的 commit…
    pocarisweat
        34
    pocarisweat   48 天前
    @msg7086
    他理解错了,他以为是 Git 会出 bug,而不是代码库出现 bug
    Huelse
        35
    Huelse   48 天前
    保持 add .和经常 stash save "...",就没遇到过问题,除非有个小兔崽子偷偷动我电脑了
    CokeMine
        36
    CokeMine   48 天前 via Android
    一般能通过 reflog 找回来
    suzic
        37
    suzic   48 天前 via Android
    有丢过两次 git reflog 找回了
    QHKZ
        38
    QHKZ   48 天前 via iPhone
    理解 git 数据模型很重要,操作 git 数据历史库唯一完全可控的方式是使用 CLI 而不是使用 GUI 按钮,虽然 CLI 的设计很 horrible 。推荐看一下 linus 在 Google 的 git 推销演讲( 0 几年的视频)以及 MIT 的 missing.csail.mit.edu 的系列课程,里面推荐的一些资源有一定的帮助。
    EastLord
        39
    EastLord   48 天前
    我怕别人把我的代码弄丢
    shadowfish0
        40
    shadowfish0   47 天前
    害,多人开发时代码统一格式化还是太重要了,很多时候合并冲突我一看满页的空格、换行区别,直接懒得看了跳过,但是有时候往往一些业务修改就混在这里面...搞得代码丢了都不知道
    2i2Re2PLMaDnghL
        41
    2i2Re2PLMaDnghL   47 天前
    是的,代码保证正确拷贝是本质难的,涉及多人必须要写测试。
    其实就像生物修改自己的 DNA 一样,也有简单的测试避免发生奇葩变异(会导致细胞死亡或癌变)。除了对 DNA 进行简单排除外,细胞也会被检查。
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1565 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:02 · PVG 08:02 · LAX 17:02 · JFK 20:02
    ♥ Do have faith in what you're doing.