简体   繁体   中英

Is it possible to revise the resolution to a merge conflict in git?

I am working on a tex file together with a collaborator using git (using gitkraken). We work on the same branch, and at some point there were some merge conflicts when one of us pushed our latest work onto that branch. Since then we have continued working on this file, but we have realized that we would like to "redo" resolving the merge conflicts from a couple of commits back.

Is there a clean way to do this?

One thing I though of was to copy the version of the file in question (there is only one file of interest) and then just overwrite the current version of the file and then push that file onto the current branch, but I'm afraid this will overwrite some of the changes (that we'd like to keep) since the original conflict in question. Another way could be to copy the old version that has some of the changes we'd like to keep and then use a diff tool to merge in selectively the things we'd like to change.

This last option is the best thing I could come up with. Is there a better way?

Every commit—including merge commits—simply holds a full and complete snapshot of all of your files.

Once you're collaborating with other people, it's usually not worth a lot of effort to go back and "fix" previous commits. In fact, that's technically impossible: you can't change any existing commits. What you end up doing is providing new-and-improved alternative commits, in place of the originals. For instance, suppose:

...--I--J
         \
          M--N--O   <-- branch (HEAD)
         /
...--K--L

is the current situation, ie, existing commits up through J and up through L got merged to make M , and you and they have since built N and O atop M . You now discover that there's a "bug" in the snapshot stored in merge commit M due to some mis-resolution of conflicts.

The only way to make a corrected version of M is to make a new merge commit, M' . (There are several ways of doing that.) The result is:

...--I--J__
        |  \
        |   M--N--O   <-- branch
         \ /
          x
         / \
...--K--L---M'  <-- newbranch (HEAD)

That is, bad merge M still exists even though you have now made new-and-improved merge M' on this new replacement branch newbranch . You now need to copy N and O as well, to new-and-improved N' and O' :

...--I--J__
        |  \
        |   M--N--O   <-- branch
         \ /
          x
         / \
...--K--L---M'-N'-O'  <-- newbranch (HEAD)

Now you need to have everyone—you and everyone else— stop using the old chain, MNO as found by name branch , and start using instead the new chain, M'-N'-O' . In your Git, you can erase the name branch and rename newbranch to branch . In their Git, they'll have to do the same thing. Everyone must change over at the same time. This tends to be a lot of work.

It's usually better to just admit that the past has a bug in it. Make a new commit atop O that fixes the problem:

...--I--J
         \
          M--N--O--P   <-- branch (HEAD)
         /
...--K--L

Everyone can pick up new commit P as usual and just keep working as usual. Sure, commits MNO have bad snapshots ... but so what? Bad stuff happens all the time; version control is not about preventing bad stuff, but rather about letting you correct it. You've corrected it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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