又是一个 GIT 问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
yueyoum
V2EX    程序员

又是一个 GIT 问题

  •  
  •   a href="/member/yueyoum">yueyoum
    yueyoum 2014-06-06 19:14:06 +08:00 4232 次点击
    这是一个创建于 4155 天前的主题,其中的信息可能已经有所发展或是发生改变。
    本地仓库A 中心仓库B 远端仓库C

    流程就是 A 开发好, push 到 B, C 再 从B pull 下来。

    但 A 不小心删了个文件,然后就 commit push 到B了,
    此时 A B 的 commit log 大概是这样的,

    aaaaaaa
    |
    bbbbbbb


    aaaaaa 就是这个最新的commit

    发现不对, 在A执行了 git reset HEAD^ , 然后把误删除的文件checkout 回来,再commit

    此时push 就提示和B冲突了, 这个很好理解

    但我 git push -f ,强制推送了

    A B 的 commit log 成了这样

    ccccccc
    |
    bbbbbbb

    因为 aaaa 的commit 被reset 并且 强制推送覆盖了。


    但现在到 C来操作, 从 B pull 下来的 commit log 是

    aaaaaaa
    |
    bbbbbbb

    并且 提示 此时的状态和B 是 already up-to-date

    但 C 中还是 文件被删除的状态……
    9 条回复    2014-06-08 01:01:59 +08:00
    delo
        1
    delo  
       2014-06-06 19:28:33 +08:00 via iPhone
    C处clone一份是怎样的?一般push到中心仓库的commit就不要再改动了吧,宁愿重新把文件手动加回来再commit一次。看看大家有啥好办法
    wwqgtxx
        2
    wwqgtxx  
       2014-06-06 19:30:55 +08:00 via Android
    强制覆盖push貌似是不能直接pull更新的吧
    你可以试试在C端重新clone一遍
    czheo
        3
    czheo  
       2014-06-06 19:56:27 +08:00 via iPhone
    push到中心的commit不应该被删除,你应该在aaaa的基础上添加回被删除的文件,然后做新的commit push上去
    xxxx <==添加回被删文件
    |
    aaaa
    |
    bbbb
    123123
        4
    123123  
       2014-06-06 20:08:23 +08:00
    如果只有两个人用仓库还好。
    B 只要 fetch 一下,然后直接 reset hard 到最新节点就好了
    xcatliu
        5
    xcatliu  
       2014-06-06 20:11:44 +08:00
    C 直接重新 clone 吧。。

    别用 force push 了,要回退就 revert 再提交
    skydiver
        6
    skydiver  
       2014-06-07 00:06:48 +08:00
    @123123 应该是 C 只要 fetch 一下,然后直接 reset hard 到最新节点就好了
    neevek
        7
    neevek  
       2014-06-07 01:18:32 +08:00   1
    根据你的描述不应该会出现aleady up-to-date。

    如果B的log是:
    ccccccc
    |
    bbbbbbb

    C的log是:
    aaaaaaa
    |
    bbbbbbb

    意味着这时候B和C的common ancestor是bbbbbbb,也就是当C从B pull的时候不是fast-forward,原来A提交的aaaaaaa会被当成是C提交的,换言之,文件(假设文件名为file.txt)是在C中被删除的,A没有对file.txt做任何修改。这时候merge B和C最终会导致file.txt文件被删除,并且会产生一个merge commit,这个时候C的log应该是这样的:
    Merge commit
    |
    ccccccc
    |
    aaaaaaa
    |
    bbbbbbb

    楼主没有直接问问题,我假设楼主希望C跟B合并之后,C中的file.txt没被删除。假设当前在C,这时候需要执行以下命令(执行命令之前,如果你已经执行过git merge或者不带任何参数的git pull,那请回退到合并之前的历史,如:git reset --hard HEAD@{1}):

    注:假设upstream是origin,分支名是master

    git pull --rebase origin master
    或者
    git fetch origin master
    git rebase --onto origin/master HEAD~0 master

    上面这两组命令在这个场景下是等价的,但是用下面这一组命令来解释会更加容易理解。
    这里第一个参数origin/master表示我想基于origin/master来replay当前分支的commit,这个时候origin/master其实就是B。HEAD~0实际上等价于HEAD,写成HEAD~0只是为了强调我只有当前分支最新1个commit(这个commit就是aaaaaaa)需要replay到origin/master上。最后的master表示rebase的结果是应用到master分支上的,最终的结果就是file.txt回来了,commit历史会变成:
    ccccccc
    |
    bbbbbbb

    没错,aaaaaaa不见了,因为rebase origin/master(等价于based on B中的ccccccc)实际上就是拿C中的aaaaaaa和B中的ccccccc做比较,最终发现ccccccc中增加了file.txt,所以保留了file.txt,所以相当于aaaaaaa这个提交神马都没做,所以这个commit就被去除了。

    另外,假设在rebase B之前,在C上面做过一次提交,那上面的HEAD~0改成HEAD~1就可以了。


    oh, my god....好长
    neevek
        8
    neevek  
       2014-06-07 09:44:47 +08:00
    发现不能编辑回复。。。只能再写一个回复更正上一个回复了。

    前面关于HEAD~0的描述是错误的(最后3段),HEAD~0在这里实际上exclusive的,也就是HEAD~N往回数N个commit(这里HEAD~0就是0个commit,即完全忽略),然后对这些commit生成patch,replay到origin/master上,所以下面这个命令的意思是:完全忽略在C上面的从HEAD数到与B的common ancestor的位置的所有commit,楼主的情况就只有那个删除file.txt的commit,然后replay到origin/master上面,最终结果就是把B那个checkout回file.txt的commit合并回来了,丢掉已在C上面的删除file.txt的commit。

    git rebase --onto origin/master HEAD~0 master
    undeadking
        9
    undeadking  
       2014-06-08 01:01:59 +08:00
    在多人协作的情况下还用git push -f ,纯粹作死,会把其他人都害了的.

    让远端回滚到强制push之前吧,冲突必须要解决,别想偷懒
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3272 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 11:35 PVG 19:35 LAX 04:35 JFK 07:35
    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