简体   繁体   English

如何解决在git rebase期间重播历史记录时发生的冲突?

[英]How to fix conflicts that occur when replaying history during git rebase?

This seems to be a not uncommon occurrence for me (in that it occurs frequently when I do need to rewrite history, which luckily is rare). 这对我来说似乎并不罕见(因为当我确实需要重写历史记录时,这种情况经常发生,幸运的是,这种情况很少见)。 Unlike rebasing on another branch, the conflicts do not seem to resolve after manually resolving them (they reoccur in future commits). 与在另一个分支上重新部署不同,在手动解决冲突后,冲突似乎无法解决(它们会在以后的提交中再次发生)。 Furthermore, it is a mystery why this happens at all: 此外,为什么会发生这种情况是一个谜:

I was trying to add a new commit, then move it earlier in my history by changing pick -> fixup for the moved commit. 我试图添加一个新的提交,然后通过改变先前在我的历史将它pick - > fixup为移动提交。 Everything related to this change, and all the commits surrounding these seemed to be fine, so I don't think that is the issue (also I had just performed the same procedure with success on another repo, and I've had similar issues in the past when doing different procedures). 与此更改相关的所有内容以及围绕这些更改的所有提交似乎都很好,所以我认为这不是问题所在(同样,我刚刚在另一个存储库中成功执行了相同的过程,并且在过去做其他程序时)。 The issue seems to be related to replaying the history itself. 问题似乎与重演历史本身有关。 Here is an example: 这是一个例子:

$ git rebase --continue                                                                                                                                      
Auto-merging services-core/src/main/java/edu/ncrn/cornell/service/CodebookService.scala
CONFLICT (content): Merge conflict in services-core/src/main/java/edu/ncrn/cornell/service/CodebookService.scala
error: could not apply a2fbc99... refactored details service return types, added pagination calls for var list services

Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

Could not apply a2fbc99... refactored details service return types, added pagination calls for var list services
brandon@beb82dell0-DevContainer:~/workspace/ced2ar-core-services
$ git status
interactive rebase in progress; onto f3bd89d
Last commands done (97 commands done):
   pick 1228f8d fixing pom (which was fixed, but didn't make it into last few commits)
   pick a2fbc99 refactored details service return types, added pagination calls for var list services
  (see more in file .git/rebase-merge/done)
Next commands to do (23 remaining commands):
   pick 1b686a9 cleaned up codebookservice file
   pick a81a2ff updating to scala 2.12.x; adding circe library for JSON
  (use "git rebase --edit-todo" to view and edit)
You are currently rebasing branch 'master' on 'f3bd89d'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

        both modified:   services-core/src/main/java/edu/ncrn/cornell/service/CodebookService.scala

no changes added to commit (use "git add" and/or "git commit -a")
brandon@beb82dell0-DevContainer:~/workspace/ced2ar-core-services
$ git diff
diff --cc services-core/src/main/java/edu/ncrn/cornell/service/CodebookService.scala
index 02826ea,dbbdf12..0000000
--- a/services-core/src/main/java/edu/ncrn/cornell/service/CodebookService.scala
+++ b/services-core/src/main/java/edu/ncrn/cornell/service/CodebookService.scala
@@@ -126,41 -176,17 +176,51 @@@ class CodebookService 
      * @param handle
      * @return
      */
++<<<<<<< HEAD
 +  def getCodebookVariables(handle: String): Map[String, String] = {
 +    //hashmap with varnames as keys and corresponding varlabls as values
 +    val variables: mutable.Map[String, String] = mutable.Map()
 +    //get all varname instances for a given codebook
 +    val varnames: List[FieldInst] = fieldInstDao.findByRawDocIdAndFieldId(handle, "varname")
 +      .asScala.toList
 +    //for each varname find the labl and add to hashmap
 +    for (varname <- varnames) {
 +      val varnameId: Long = varname.getId
 +      val varIndices: List[FieldIndice] = fieldIndiceDao.findById_FieldInstId(varnameId).asScala.toList
 +      val varIndex: FieldIndice = varIndices.head
 +      val varIndexValue: String = varIndex.getIndexValue
 +      val lablMaps: List[Mapping] = mappingDao.findById_FieldId("varlabel").asScala.toList
 +      val lablMap: Mapping = lablMaps.head
 +      var lablXpath: String = lablMap.getXpath
 +      lablXpath = lablXpath.replace("*", varIndexValue)
 +      //find corresponding varlabl by canonical xpath
 +      val varlabls: List[FieldInst] = fieldInstDao.findByRawDocIdAndCanonicalXpath(handle, lablXpath)
 +        .asScala.toList
 +      //check that xpath was mapped correctly
 +      if (varlabls.size != 1) {
 +        println("failed to properly map xpath from varname to varlabl: " + lablXpath)
 +      }
 +      else {
 +        val varlabl: FieldInst = varlabls.head
 +        //insert into hashmap
 +        variables.put(varname.getValue, varlabl.getValue)
 +      }
 +    }
 +    variables.toMap
 +  }
++=======
+   def getCodebookVariables(handle: String): Map[String, (String, String)] =
+     getVarList(List(handle), 0)
+     
+   def getCodebookVariables(handle: String, page: Int): Map[String, (String, String)] =
+     getVarList(List(handle), page)
++>>>>>>> a2fbc99... refactored details service return types, added pagination calls for var list services

-   private def getVarList(handles: List[String]): Map[String, (String, String)] = {
+   private def getVarList(handles: List[String], pageNumber: Integer): Map[String, (String, String)] = {
      val variables: mutable.Map[String, (String, String)] = mutable.Map()
-     val varnames: List[FieldInst] = fieldInstDao.findByFieldId("varname").asScala.toList
+     val request: Pageable = new PageRequest(pageNumber, PAGE_SIZE, Sort.Direction.ASC, "value")
+     val varnamesPage: Page[FieldInst] = fieldInstDao.findByFieldIdAndRawDocIdIn("varname", handles.asJava, request)
+     val varnames: List[FieldInst] = varnamesPage.getContent.asScala.toList
      //for each varname find the labl and add to hashmap
      for (varname <- varnames) {
        val handle: String = varname.getRawDocId

I can try to patch this up by editing and running git rebase --continue , but invariably, the very next commit will have the same issue, but usually with even more code differences. 我可以尝试通过编辑和运行git rebase --continue来对此进行修补,但总是,下一个提交将具有相同的问题,但通常会有更多的代码差异。

After cloning, what I did was to just do git rebase -i --root , move the second to last commit (about licensing) to the second commit, changing pick to fixup , then try to proceed with the rebase. 克隆之后,我要做的就是git rebase -i --root ,将第二个到最后一个提交(关于许可)移动到第二个提交,将pick更改为fixup ,然后尝试进行重新设置。

Since you are using interactive rebase, Git is using git cherry-pick to copy each commit. 由于您使用的是交互式资源库,因此Git使用git cherry-pick复制每个提交。

A cherry-pick is literally a merge (well, it is ever since Git 1.5.1 anyway). 樱桃拾取实际上是一种合并(嗯,无论如何从Git 1.5.1开始)。 But it's a merge with a peculiar merge base. 但这是具有特殊合并基础的合并。 A normal merge looks like this, graph-wise: 普通合并如下图所示:

          o--...--o--L   <-- ours (HEAD)
         /
...--o--B
         \
          o--...--o--R   <-- theirs

Here, Git finds the changes in our branch by running (in effect) git diff --find-renames <hash-of-B> <hash-of-L> , and finds the changes in their branch using git diff --find-renames <hash-of-B> <hash-of-R> , and combines them. 在这里,Git通过运行(实际上) git diff --find-renames <hash-of-B> <hash-of-L>查找分支中的更改,并使用git diff --find-renames <hash-of-B> <hash-of-R>查找其分支中的更改。 git diff --find-renames <hash-of-B> <hash-of-R> ,并将它们组合。

For a cherry-pick, however, even if the branching looks much the same, our goal is to copy (the changes of) one particular commit, so what Git does looks instead like this: 但是,对于一个分支来说,即使分支看起来很像,我们的目标是复制 (更改) 一个特定的提交,所以Git所做的看起来像这样:

          o--B--R--...--o   <-- theirs
         /
...--o--o
         \
          o--...--o--L   <-- ours (HEAD)

Here R is the commit being copied, L is our current (ie, HEAD ) commit, and B is the rather peculiar merge base. 这里R是要复制的提交, L是我们当前的提交(即HEAD ), B是比较特殊的合并基础。 At this point Git does the same thing it does for any merge, diffing B (the merge base) against both R (theirs) and L (ours), and combines the changes. 此时,Git对任何合并执行相同的操作,将B (合并基础)与R (他们的)和L (我们的)进行比较,并合并更改。

If there is a merge conflict, you must resolve it. 如果存在合并冲突,则必须解决它。 When this is done you have: 完成后,您将:

          o--*--R--S--...--o   <-- theirs
         /
...--o--o
         \
          o--...--o--L--R'   <-- ours (HEAD)

as the next cherry-pick: the merge base is now R , their commit is S , and our commit is R' . 作为下一个选择:合并基数现在为R ,其提交为S ,我们的提交为R' There is a very good chance that the same merge conflict you just resolved, will recur. 有一个非常好的机会,你只是解决了同一合并冲突,会复发。 This is what you are seeing. 这就是您所看到的。

(For cases like this, git rerere is helpful.) (对于这种情况, git rerere很有帮助。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM