Xcode 合并冲突后 Discard All Changes 导致代码丢失问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
cielpy
V2EX    iDev

Xcode 合并冲突后 Discard All Changes 导致代码丢失问题

  •  
  •   cielpy
    EkkoG 2017-10-15 22:10:12 +08:00 6090 次点击
    这是一个创建于 2971 天前的主题,其中的信息可能已经有所发展或是发生改变。
    https://imciel.com/2017/10/13/xcode-discard-change-and-git-merge-issue/

    最近被这个问题坑的不轻,就写了下来,大家可以看看避免踩同样的坑
    13 条回复    2017-10-17 23:47:36 +08:00
    msg7086
        1
    msg7086  
       2017-10-16 04:48:14 +08:00
    这就是为什么我一直建议重度 Git 使用者挑选一个顺手的强大的 GUI。
    alang
        2
    alang  
       2017-10-16 06:14:37 +08:00 via iPhone
    必须命令行啊,gui 都是不靠谱的
    xpol
        3
    xpol  
       2017-10-16 08:40:42 +08:00
    Sourcetree 党表示 GUI 是必须的。
    cielpy
        5
    cielpy  
    OP
       2017-10-16 22:46:34 +08:00   1
    @xpol

    文章最后有 demo,有空的话你可以试一下

    stage 是空的

    合并前是这样的

    https://i.loli.net/2017/10/16/59e4c5a94bd96.png

    若有幸是刚打开 SourceTree

    合并后再 Discard 是这样的

    https://i.loli.net/2017/10/16/59e4c26462ecf.png

    可以看到 commit 输入框有内容,能引起注意

    若是已经用 SourceTree commit 过,并停留在 commit 后的界面没动,合并后是这样的

    https://i.loli.net/2017/10/16/59e4c32cf2bcb.png

    Discard 后是这样的

    https://i.loli.net/2017/10/16/59e4c369d9b3a.png

    修改后是这样的

    https://i.loli.net/2017/10/16/59e4c5004c2d2.png

    commit 后是这样的

    https://i.loli.net/2017/10/16/59e4c50048381.png

    请问最后一次 commit 哪里可以看出来有别的东西合并进来了
    cielpy
        6
    cielpy  
    OP
       2017-10-16 22:53:38 +08:00
    @msg7086
    @alang
    @xpol

    我个人觉得各有各的优势,GUI 在查看历史记录合并历史等等操作的时候比较直观,命令行强在各种功能组合,如果理解每一个选项的作用,一个命令的效果是比 GUI 鼠标点起来更直观,GUI 不够透明,不知道做了什么隐藏的操作,对仓库有什么影响,不过刚发现 SourceTree 的命令历史,这方面的缺陷可以查看命令弥补,我是配置用的,大部分操作用命令,偶尔用 SourceTree 查看历史记录,切换分支之类的
    msg7086
        7
    msg7086  
       2017-10-17 06:21:24 +08:00
    @cielpy 我自己是用的 SmartGit,而且我在我司团队里推广使用过,效果很好。
    GUI 是不够透明,不过幸好 SmartGit 里几乎所有的操作都会在 Log 里打出使用过的命令,有些时候我甚至是在跟着 GUI 学 Git。
    如果只是轻度使用 Git 的话倒是无所谓,我对源代码管理要求比较高,Branching Rebasing Merging 非常频繁,而且要求 Interactive Rebase 整理源代码历史记录以方便后期 Blame 和 Revert,没有 GUI 感觉是如履薄冰。
    cielpy
        8
    cielpy  
    OP
       2017-10-17 09:41:04 +08:00
    @msg7086 嗯嗯,根据使用场景选合适的工具就好啦
    xpol
        9
    xpol  
       2017-10-17 20:40:36 +08:00
    没有验证过 Xcode 里面的 Discard all changes 做了哪些操作。但是放弃 merge 的正确的命令行应该是 git merge --abort ( git > 1.7.4 https://stackoverflow.com/questions/5741407/how-to-undo-a-git-merge-with-conflicts ) 。

    我看了一下 demo,了解了:

    1. 当前在 master,将 test 合并过来
    2. 合并发现冲突
    3. 用 Xcode 的 Discard all changes 或者 git reset --hard HEAD,重置 index 和 orking copy 到 HEAD 的状态(即 master 分支在合并前的状态,也就是 demo 中 test 0 这个提交的状态)
    4. 提交,由于当前还处于 merge 状态,所以这个提交的状态被当成合并后结果

    简言之,由于 Xcode 的 Discard all changes 或者命令行的 git reset --hard HEAD 都终止 merge 状态。稍后的提交会被当成合并的结果。
    xpol
        10
    xpol  
       2017-10-17 20:44:22 +08:00
    你可以本地退回到 master 上的 test 0 这个版本,然后和 test 上的 test 2 版本进行合并,然后选择 test 2 的版本,然后提交。最后 git push origin +master 强制 push。
    xpol
        11
    xpol  
       2017-10-17 21:05:55 +08:00
    另外,代码并没有丢失。正确的版本依然安安静静地躺在 test 分支上。

    问题的根源是下面这一个错误的认识:

    『若想丢弃此次合并,可以使用命令重置,回到当前分支的 HEAD,命令如下:git reset --hard HEAD 』

    正确的认识是:

    若想丢弃此次合并,可以使用命令放弃合并,命令如下:

    git merge --abort,

    或者 Sourcetree 里面选中合并前当前分支合并前的版本 -> 右键 -> Reset <branch_name> to this commit -> using mode 选择 hard 』
    xpol
        12
    xpol  
       2017-10-17 21:39:01 +08:00
    @cielpy 我是来认错的。我上一条关于 git reset --hard HEAD 不能放弃合并的说法才是错误的,对不起~~

    根据 https://git-scm.com/book/tr/v2/Git-Tools-Advanced-Merging 的描述 git reset --hard HEAD 确实也可以用来放弃合并。

    你说的对,应该只是 Xcode 中的 Discard all changes 不能放弃合并。
    cielpy
        13
    cielpy  
    OP
       2017-10-17 23:47:36 +08:00
    @xpol 根据实际操作结果来看的话,git reset --hard HEAD 是会放弃合并的,而 Discard all changes 不会,造成了这个问题

    当然我说的「代码丢失」意思其实不是真正的丢了,因为 commit 记录还在嘛,只是在合并后的分支上,看不到了这个 commit 相关的修改的一种异常状态
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     934 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 20:09 PVG 04:09 LAX 12:09 JFK 15:09
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86