Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git 在每一步更新工作目录时拆分最后提交和修改中间提交_Git - Fatal编程技术网

Git 在每一步更新工作目录时拆分最后提交和修改中间提交

Git 在每一步更新工作目录时拆分最后提交和修改中间提交,git,Git,我想将最近的提交C拆分为多个提交C(#=1,2,…等)。然而,每个中间提交C#都不能直接使用C中相应的部分更改来完成,但它们必须在某种程度上进行修改以“有意义”。此外,要确定提交C#“有意义”,工作目录需要处于表示此提交的状态,以便在提交前可以进行相应的更改,而不会丢失最终提交C的内容 就我而言,我有以下几点: 我提交了一些代码,其中包含太多要拆分的更改,因为 该程序在提交后被窃听,但不是在提交前,并且有太多的新特性使调试变得容易 我不能简单地删除一些特性而不破坏其他特性,因此我必须在对每个特

我想将最近的提交C拆分为多个提交C(#=1,2,…等)。然而,每个中间提交C#都不能直接使用C中相应的部分更改来完成,但它们必须在某种程度上进行修改以“有意义”。此外,要确定提交C#“有意义”,工作目录需要处于表示此提交的状态,以便在提交前可以进行相应的更改,而不会丢失最终提交C的内容

就我而言,我有以下几点:

  • 我提交了一些代码,其中包含太多要拆分的更改,因为
  • 该程序在提交后被窃听,但不是在提交前,并且有太多的新特性使调试变得容易
  • 我不能简单地删除一些特性而不破坏其他特性,因此我必须在对每个特性进行“部分提交”之前对其进行编辑
  • 为了确保提交有意义,我检查程序是否仅使用这一新功能进行编译
  • (显然)我不想丢失所有其他特性的代码,这样我就可以轻松地回到原来的commit C

所以我的问题是

  • 如何拆分最新的提交并创建多个新的提交(仅包含部分更改)
  • 如何在新提交之间编辑文件(在工作目录中),而不丢失组成原始提交的更改

    • 可能有很多解决方案,我试图找到一个“简单”的解决方案。特别是不应该有丑陋的临时提交,不需要解决冲突,也不需要总是从提交C的状态开始编辑文件。我将把提交B称为C之前的那个

      为此,我使用
      git diff
      创建补丁文件,并根据需要使用
      git apply
      应用它们。详细内容:

      • 首先,放弃最后一次提交并将更改保留在工作目录中

        git reset HEAD~
        
      • 为方便起见,请忽略修补程序文件

        echo "*.diff" >> .gitignore
        
      • 现在,在编辑文件之前,请创建一个修补程序,以便我们可以从C返回到版本。需要先将B中不存在的文件添加到索引中(否则修补程序将为空!),如下所示:

        git add -N file    #not needed for files that exist in B
        
      • 创建补丁并将工作目录版本设置为B中的版本

        git diff file >> file.diff
        git checkout file
        
      • 对从B更改为C的每个文件重复这些步骤。现在将部分更改应用于索引和工作目录。首先,对于B中不存在的文件,我们必须再次删除它们(或者之前不签出文件)

      • 然后进行部分更改并相应更新修补程序:

         git apply file.diff
         rm file.diff
         git add -i                  #interactively stage only partial changes
         git diff file >> file.diff
         git checkout file
        

      通过以上步骤,我可以进行部分更改,同时在工作目录中始终具有与部分提交相对应的版本(而不是C版本!)。相反,C版本“保存”在补丁中。通过一些额外的步骤,我可以编辑中间提交文件的版本

      • 编辑
        文件
        ,然后再次创建修补程序,但以后必须反向应用这些修补程序。命名这些修补程序,例如,每次编辑的修补程序数量都会增加

        git diff file >> file.reverse<#>.diff
        git add file
        
        git-diff-file>>file.reverse.diff
        git添加文件
        
      • 每次编辑都可以重复这些步骤,每次都创建一个额外的reverse.diff

      • 在N编辑后,可以通过按正确顺序应用修补程序来创建将此最新版本恢复为C版本的修补程序

        git apply -R file.reverse<N>.diff
        git apply -R file.reverse<N-1>.diff
        #...
        git apply -R file.reverse1.diff
        git apply file.diff
        rm file*.diff
        git diff file >> file.diff
        git checkout file
        
        git apply-R file.reverse.diff
        git apply-R file.reverse.diff
        #...
        git apply-R file.reverse1.diff
        git apply file.diff
        rm文件*.diff
        git diff file>>file.diff
        git签出文件
        
      同样,工作目录版本现在是当前中间提交的版本,可以应用补丁
      file.diff
      返回到C版本



      注意:我创建问题+答案是因为我的git不流利,我相信我下次一定会忘记我是如何做到这一点的。。我发现了一些类似的答案,但没有解决我的确切问题,所以可能其他人会觉得这很有用。

      我肯定会使用
      git reset--soft
      来处理这种情况。比如说,你有你的分支,它叫featA。您需要在featA和featA~1之间创建一些中间修订。这就是我要做的:

      git checkout -b temp featA # create branch temp from featA, check it out
      git reset soft --HEAD~1 # put all changes between featA and feat~1 in index, ready to be commited.
      # at this time you go to your files and edit them the way you want them to be on the first "new" revision. Revert changes at will, featA won't move no matter what
      # when you are done, add everything to index
      git commit -m "First new revision"
      
      # now, for every new revision you want to create:
      git checkout --detach featA
      git reset --soft temp
      # same thing.... set the files you want it for the following revision
      # add to index
      git commit "a new revision"
      git branch -f temp # move temp pointer
      
      # then in the _last_ revision, when you want this new revision to resemble featA
      git checkout featA
      git reset --soft temp
      git commit -m "Final new revision"
      
      或者,从配方的第二部分(第二次中间修订版和更高版本)开始,可以通过与tempA进行比较来处理,这样您就可以一点一点地进行更改,而不是针对每个新修订版返回完整的featA(如您在问题中所说,调整代码以使其有意义)

      git checkout -b temp featA # create branch temp from featA, check it out
      git reset soft --HEAD~1 # put all changes between featA and feat~1 in index, ready to be commited.
      # at this time you go to your files and edit them the way you want them to be on the first "new" revision. Revert changes at will, featA won't move no matter what
      # when you are done, add everything to index
      git commit -m "First new revision"
      
      # now, for every new revision you want to create:
      git checkout --detach featA
      git reset --soft temp
      # same thing.... set the files you want it for the following revision
      # add to index
      git commit "a new revision"
      git branch -f temp # move temp pointer
      
      # then in the _last_ revision, when you want this new revision to resemble featA
      git checkout featA
      git reset --soft temp
      git commit -m "Final new revision"