Git恢复不能按预期工作 [英] Git revert does not work as expected

查看:124
本文介绍了Git恢复不能按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了 git revert 命令的问题。我使用Ubuntu 12.04 Linux和Git 1.7.9.5版本。


  1. 我创建了一个全新的 b_test_repo 在我的本地PC上运行,并从远程 origin b_test_repo 进行跟踪。

  2. 本地创建了一个文件在两行文本中提交 A ),并且只在本地 master 分支中成功提交。 b

    $ b

    为了试用 git revert 我生成了3个更多的提交,每个提交一行的文字。因此,我的 master 提交历史记录如下所示:

      A  -  B  -  C -  D 

    其中


    • A - 包含第1行和第1行的新文件2

    • B - 添加了一行

    • C - 添加了一行

    • D - 添加了一行


    完成所有这些提交后,文件包含5行:

      line1 
    line2
    line3
    line4
    line5

    然后,我想恢复提交 B ,这将呈现没有 line3 的文件,该文件由提交 B添加

      git status 
    #分支master
    没有提交工作目录干净)

    我输入:

      git revert -n master〜2 

    可恢复效果提交 B 而不提交更改,但得到以下内容:

     错误:无法恢复1a13ad6 ...添加一行
    提示:解决冲突后,标记更正的路径
    hint:with'git add& hint:并提交结果'git commit'

    我很困惑为什么我会发生冲突,也就是说为什么Git会在文件中找出需要更改的问题。



    我在这里想念吗?请赐教!

    删除该行会导致与更新版本发生冲突,这会改变 > line。



    所以如在git恢复时应该怎么做中止与错误消息?,你需要解决合并,添加和提交。



    更简单的方式来恢复该提交将是一个交互式转换:

      git rebase -i< SHA1 commit a> 

    然后您放弃提交 b 。<
    但是,只有当您尚未将分支推送到
    上游回购 ,因为它会重写提交历史记录。



    如果您确实已经推送了,那么 git revert 是正确的方法,为了生成一个新的提交取消 b (并在上游回购中推送新的提交)。




    详细信息:您的示例生成以下合并冲突:

      C:\ Users \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 
    * 3d888c4 - b
    * 8c7155f - a

    git lg 是一个别名花哨的 git log

    如果存在冲突,我更愿意在合并或还原之前同时查看原始部分的来源(他们的),目标(我们的)

      git config merge.conflictstyle diff3 

    然后恢复:

      git revert -n master〜2 

    这会给:

      line1 
    line2
    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< HEAD
    line3
    line4
    line5
    ||||||| 3d888c4 ... b
    line3
    =======
    >>>>>>>父母的3d888c4 ... b

    这样,你会看到 git revert does:合并之间:




    • 提交的父 b (它显然不包含 b 修改)
    • HEAD



    合并无法确定以开头的部分第三行:


    • 该部分不存在于 a 中( ===>>>>< / code>部分:'他们'一方) < b (原始部分在 |||| ==== 之间,如前所述 revert ,只是 line3

    • ,它也是 修改于 HEAD <<< |||| 部分,添加 line4 line5 ,即使 line3 的外观不变)





      如果以commit a 开头,合并冲突更加明显:

        line1 
      line2
      line3
      line4
      line5

      结束提交 d 为:

        line1 
      line2
      line3b
      line4c
      line5d

      (提交 b 添加' d '到第3行,提交 c 在第4行添加了' c ',提交 d 添加' d

      然后一个回复会给你:

        git config merge.conflictstyle diff3 
      git revert -n master〜2

      cat afile.txt

      line1
      line2
      <<<<< HEAD
      line3b
      line4c
      line5d
      ||||||| 4ddccc1 ... b
      line3b
      line4
      line5
      =======
      line3
      line4
      line5
      >>>>>>>父母的4ddccc1 ... b

      这里是从第3行开始的部分:




      • 等于 line3 -line4 -line5 in'theirs' ===>> ;> ,它是 b 或提交 a 的父项) li>
      • 等于 line3b-line4 -line5 在提交 b (original section <$ c
      • 等于 line3b-line4c-line5d ,在merge / revert之前) c> HEAD '我们的'<<< |||



      三种不同的内容,合并无法知道该怎么做。 / p>

      I am having trouble with the git revert command. I use Ubuntu 12.04 Linux and Git version 1.7.9.5.

      1. I have created a brand new b_test_repo on my local PC, having it tracked from a remote origin b_test_repo.
      2. I have created locally a single file (commit A) with two lines of text and successfully committed it only in the local master branch.

      In order to try out git revert I generated 3 more commits, each of them adding one line of text. So my master commit history looks like:

      A - B - C - D
      

      Where

      • A - new file with lines 1 & 2
      • B - one line added
      • C - one line added
      • D - one line added

      After all these commits the file contained 5 lines:

      line1
      line2
      line3
      line4
      line5
      

      Then, I wanted to revert commit B, which would render the file without line3, which was added by commit B:

      git status
      # On branch master
      nothing to commit (working directory clean)
      

      I type:

      git revert -n master~2
      

      to revert the effect of commit B without committing the changes, but get the following:

      error: could not revert 1a13ad6... Adding one line
      hint: after resolving the conflicts, mark the corrected paths
      hint: with 'git add <paths>' or 'git rm <paths>'
      hint: and commit the result with 'git commit'
      

      I am puzzled why I am getting a conflict, i.e. why does Git have a problem figuring out what it needs to change in the file.

      What am I missing here? Please enlighten me!

      解决方案

      Removing that line will generate a conflict with later versions which would change the same line.

      So as mention in "What should I do when git revert aborts with an error message?", you need to resolve the merge, add and commit.

      A simpler way to revert that commit would be an interactive rebase:

      git rebase -i <SHA1 commit a>
      

      And you drop the commit b.
      But that is valid only if you didn't already pushed your branch to an upstream repo, because it does rewrite the history of commits.

      If you did already push, then git revert is the right approach, in order to generate a new commit cancelling b (and push that new commit on the upstream repo).


      In details: your example generates the following merge conflict:

      C:\Users\VonC\prog\git\tests\18779372\r1>git lg
      
      * 10b9953  - (HEAD)
      * 07fff99  - c
      * 3d888c4  - b
      * 8c7155f  - a
      

      (git lg is an alias for a fancy git log)

      If there is a conflict, I prefer seeing both the source (theirs), destination (ours) and the original section as before a merge or revert:

      git config merge.conflictstyle diff3
      

      Then revert:

      git revert -n master~2
      

      That would give:

      line1
      line2
      <<<<<<< HEAD
      line3
      line4
      line5
      ||||||| 3d888c4... b
      line3
      =======
      >>>>>>> parent of 3d888c4... b
      

      That way, you see what git revert does: a merge between:

      • the parent of commit b (which obviously doesn't contain b modification)
      • and HEAD

      The merge cannot decide what do for the section starting with third line:

      • the section doesn't exist in a (the === >>>> part: 'theirs' side)
      • it is modified in b (original part between |||| and ====, as before revert, with just line3)
      • and it is also modified in HEAD (the <<<< |||| part, with the addition of line4 and line5, even though line3 looks unchanged)

      The merge conflict is even clearer if you start with commit a as:

      line1
      line2
      line3
      line4
      line5
      

      And end up with commit d as:

      line1
      line2
      line3b
      line4c
      line5d
      

      (commit b add 'd' to line3, commit c adds 'c' to line 4, commit d adds 'd' to line 5)

      Then a revert will give you:

      git config merge.conflictstyle diff3
      git revert -n master~2
      
      cat afile.txt
      
      line1
      line2
      <<<<<<< HEAD
      line3b
      line4c
      line5d
      ||||||| 4ddccc1... b
      line3b
      line4
      line5
      =======
      line3
      line4
      line5
      >>>>>>> parent of 4ddccc1... b
      

      Here the section starting at line3:

      • equals line3 -line4 -line5 in 'theirs' === >>>, which is the parent of b, or commit a)
      • equals line3b-line4 -line5 in commit b (original section ||| ===, before merge/revert)
      • equals line3b-line4c-line5d in HEAD 'ours' <<< |||

      Three different contents, and no way for the merge to know what to do.

      这篇关于Git恢复不能按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆