How to split file into ours and theirs on conflict











up vote
0
down vote

favorite












I there a way to get 2 copies of file where first will have remote content and the second with local content










share|improve this question




























    up vote
    0
    down vote

    favorite












    I there a way to get 2 copies of file where first will have remote content and the second with local content










    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I there a way to get 2 copies of file where first will have remote content and the second with local content










      share|improve this question















      I there a way to get 2 copies of file where first will have remote content and the second with local content







      git merge-conflict-resolution






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 11 at 8:18









      Flimzy

      36.5k96496




      36.5k96496










      asked Nov 11 at 6:53









      Herrgott

      171420




      171420
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          3
          down vote













          I don't think that there is a git option to keep both versions of the file in two copies.



          But you can easily acheive this goal with the following commands :





          git merge the_branch
          git checkout --theirs -- path/to/file ; mv path/to/file path/to/file.theirs
          git checkout --ours -- path/to/file ; mv path/to/file path/to/file.ours
          git checkout -m -- path/to/file


          In the end you have three files :





          • file.theirs, with their version;


          • file.ours, with your version;


          • file, with both versions and conflicts marks.






          share|improve this answer





















          • Upvoted, especially because if you do have line-ending or other (e.g., git-lfs) filters going on, this method works with those. (The git checkout-index method does too, it's mostly git show that doesn't. Note that git mergetool uses git checkout-index internally.)
            – torek
            Nov 11 at 9:12


















          up vote
          1
          down vote













          TL;DR



          Consider using git mergetool (though I never do it this way myself), or git show (I sometimes do this). Also consider setting merge.conflictStyle to diff3, which makes Git write, into the conflicted work-tree copy, the base version as well as the left and right side versions. I find that with this turned on, I almost never need to see the two inputs. (But only almost never.)



          Long(ish)



          In fact, the file is already present in all three versions, but they are all in the index, not in the work-tree. The trick is therefore to get them out of the index, where they're in the special Git-only format, into your work-tree where you can see and work on / with them.



          Let's look briefly, yet in detail, at how git merge works when there are conflicts. For conflicts to occur, we must have done something like this:



          $ git checkout ours
          Switched to branch 'ours'
          $ git merge theirs


          Git will have looked at the commit graph and found that ours and theirs have diverged, but have a common merge base commit:1



                    o--...--L   <-- ours (HEAD)
          /
          ...--o--B

          o--...--R <-- theirs


          Commit L is the left side or local or --ours commit. Commit R is the right side or remote or --theirs commit. Commit B here is the merge base. Git then did, in effect, two git diff commands, one to find out what we changed since the merge base:



          git diff --find-renames <hash-of-B> <hash-of-L>   # what we changed
          git diff --find-renames <hash-of-B> <hash-of-R> # what they changed


          The merge then attempted to combine these two sets of changes, using the contents associated with commit B as the base for the combined changes. However, we changed some file, they changed the same file, and our changes collided with their changes, so that we got a merge conflict.



          What Git has done, at this point, is to put all three copies of the file into the index, at nonzero staging slot numbers:




          • Stage 1 contains the merge base: file B:P, where B is the base commit and P is the path name of the file (as found in that commit anyway—we might have renamed the file!).

          • Stage 2 contains our version of the file: file L:P.

          • Stage 3 contains their version of the file: file R:P.


          The work-tree contains Git's attempt to merge the two sets of changes, with conflict markers. Note that this version is not the same as any of the three input versions! Some part(s) of the merge may already be resolved. The default style for conflicting changes is merge, which shows only the left (B-vs-L) and right (B-vs-R) changes without showing you the section that was in B itself. In many cases that's enough, but when the changes are purely deletions, it's often very helpful to know what line(s) in B is / are being deleted, and that's not something you can just deduce. Setting the conflict style to diff3 makes Git record the B code section as well, in between the two change-sections.





          1It's possible for there to be multiple merge base commits. In this case, Git defaults to constructing a new merge base commit by merging the merge bases. This process is a little bit messy, but fortunately it's rare, and even when it does happen, it rarely makes anything worse.



          Extracting the three versions





          • You can extract any of the three versions using git checkout-index, although this command is a bit of a pain to use:



            git checkout-index --all -- path/to/file


            This writes all three to files with funky temporary names, which you then have to rename. (There are several variations on this theme but they're all a bit annoying.)



          • You can use git mergetool, which automatically extracts all three versions, then invokes your chosen merge tool command on all of them.



          • Or, you can manually extract one or both files. The method in DogEata's answer will work, but if you have no concerns over line-ending issues, this way is shorter:



            git show :1:path/to/file > path/to/file.base
            git show :2:path/to/file > path/to/file.ours
            git show :3:path/to/file > path/to/file.theirs


            This uses the git show command along with the gitrevisions syntax for accessing the index copies, showing them to standard output, and redirecting the output to new files.




          Note that git add writes to slot zero



          Git knows that a merge is in progress, and has not yet been finished, in several ways, but the most important is that there are these files in slots 1, 2, and/or 3 for some path in the index. When you've figured out the correct contents for that path, and written them to that path in your work-tree, you run:



          git add path/to/file


          to copy the file back into the index, taking the normal-format work-tree copy and compressing in into the special Git-only format that goes in the index.



          If the file were in the index at slot zero, the way it normally is, that would just overwrite the old index copy with the fixed-up work-tree version. When there are multiple copies of the file in the index using the higher numbered slots, git add still writes to slot zero, but this time, it also removes the higher-numbered entries entirely. Now the file is resolved.



          If you use git mergetool, the git mergetool command can automatically run git add for you, hiding the extra step. Some people find this especially convenient.






          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














             

            draft saved


            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246498%2fhow-to-split-file-into-ours-and-theirs-on-conflict%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            3
            down vote













            I don't think that there is a git option to keep both versions of the file in two copies.



            But you can easily acheive this goal with the following commands :





            git merge the_branch
            git checkout --theirs -- path/to/file ; mv path/to/file path/to/file.theirs
            git checkout --ours -- path/to/file ; mv path/to/file path/to/file.ours
            git checkout -m -- path/to/file


            In the end you have three files :





            • file.theirs, with their version;


            • file.ours, with your version;


            • file, with both versions and conflicts marks.






            share|improve this answer





















            • Upvoted, especially because if you do have line-ending or other (e.g., git-lfs) filters going on, this method works with those. (The git checkout-index method does too, it's mostly git show that doesn't. Note that git mergetool uses git checkout-index internally.)
              – torek
              Nov 11 at 9:12















            up vote
            3
            down vote













            I don't think that there is a git option to keep both versions of the file in two copies.



            But you can easily acheive this goal with the following commands :





            git merge the_branch
            git checkout --theirs -- path/to/file ; mv path/to/file path/to/file.theirs
            git checkout --ours -- path/to/file ; mv path/to/file path/to/file.ours
            git checkout -m -- path/to/file


            In the end you have three files :





            • file.theirs, with their version;


            • file.ours, with your version;


            • file, with both versions and conflicts marks.






            share|improve this answer





















            • Upvoted, especially because if you do have line-ending or other (e.g., git-lfs) filters going on, this method works with those. (The git checkout-index method does too, it's mostly git show that doesn't. Note that git mergetool uses git checkout-index internally.)
              – torek
              Nov 11 at 9:12













            up vote
            3
            down vote










            up vote
            3
            down vote









            I don't think that there is a git option to keep both versions of the file in two copies.



            But you can easily acheive this goal with the following commands :





            git merge the_branch
            git checkout --theirs -- path/to/file ; mv path/to/file path/to/file.theirs
            git checkout --ours -- path/to/file ; mv path/to/file path/to/file.ours
            git checkout -m -- path/to/file


            In the end you have three files :





            • file.theirs, with their version;


            • file.ours, with your version;


            • file, with both versions and conflicts marks.






            share|improve this answer












            I don't think that there is a git option to keep both versions of the file in two copies.



            But you can easily acheive this goal with the following commands :





            git merge the_branch
            git checkout --theirs -- path/to/file ; mv path/to/file path/to/file.theirs
            git checkout --ours -- path/to/file ; mv path/to/file path/to/file.ours
            git checkout -m -- path/to/file


            In the end you have three files :





            • file.theirs, with their version;


            • file.ours, with your version;


            • file, with both versions and conflicts marks.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 11 at 8:17









            DogEata

            55337




            55337












            • Upvoted, especially because if you do have line-ending or other (e.g., git-lfs) filters going on, this method works with those. (The git checkout-index method does too, it's mostly git show that doesn't. Note that git mergetool uses git checkout-index internally.)
              – torek
              Nov 11 at 9:12


















            • Upvoted, especially because if you do have line-ending or other (e.g., git-lfs) filters going on, this method works with those. (The git checkout-index method does too, it's mostly git show that doesn't. Note that git mergetool uses git checkout-index internally.)
              – torek
              Nov 11 at 9:12
















            Upvoted, especially because if you do have line-ending or other (e.g., git-lfs) filters going on, this method works with those. (The git checkout-index method does too, it's mostly git show that doesn't. Note that git mergetool uses git checkout-index internally.)
            – torek
            Nov 11 at 9:12




            Upvoted, especially because if you do have line-ending or other (e.g., git-lfs) filters going on, this method works with those. (The git checkout-index method does too, it's mostly git show that doesn't. Note that git mergetool uses git checkout-index internally.)
            – torek
            Nov 11 at 9:12












            up vote
            1
            down vote













            TL;DR



            Consider using git mergetool (though I never do it this way myself), or git show (I sometimes do this). Also consider setting merge.conflictStyle to diff3, which makes Git write, into the conflicted work-tree copy, the base version as well as the left and right side versions. I find that with this turned on, I almost never need to see the two inputs. (But only almost never.)



            Long(ish)



            In fact, the file is already present in all three versions, but they are all in the index, not in the work-tree. The trick is therefore to get them out of the index, where they're in the special Git-only format, into your work-tree where you can see and work on / with them.



            Let's look briefly, yet in detail, at how git merge works when there are conflicts. For conflicts to occur, we must have done something like this:



            $ git checkout ours
            Switched to branch 'ours'
            $ git merge theirs


            Git will have looked at the commit graph and found that ours and theirs have diverged, but have a common merge base commit:1



                      o--...--L   <-- ours (HEAD)
            /
            ...--o--B

            o--...--R <-- theirs


            Commit L is the left side or local or --ours commit. Commit R is the right side or remote or --theirs commit. Commit B here is the merge base. Git then did, in effect, two git diff commands, one to find out what we changed since the merge base:



            git diff --find-renames <hash-of-B> <hash-of-L>   # what we changed
            git diff --find-renames <hash-of-B> <hash-of-R> # what they changed


            The merge then attempted to combine these two sets of changes, using the contents associated with commit B as the base for the combined changes. However, we changed some file, they changed the same file, and our changes collided with their changes, so that we got a merge conflict.



            What Git has done, at this point, is to put all three copies of the file into the index, at nonzero staging slot numbers:




            • Stage 1 contains the merge base: file B:P, where B is the base commit and P is the path name of the file (as found in that commit anyway—we might have renamed the file!).

            • Stage 2 contains our version of the file: file L:P.

            • Stage 3 contains their version of the file: file R:P.


            The work-tree contains Git's attempt to merge the two sets of changes, with conflict markers. Note that this version is not the same as any of the three input versions! Some part(s) of the merge may already be resolved. The default style for conflicting changes is merge, which shows only the left (B-vs-L) and right (B-vs-R) changes without showing you the section that was in B itself. In many cases that's enough, but when the changes are purely deletions, it's often very helpful to know what line(s) in B is / are being deleted, and that's not something you can just deduce. Setting the conflict style to diff3 makes Git record the B code section as well, in between the two change-sections.





            1It's possible for there to be multiple merge base commits. In this case, Git defaults to constructing a new merge base commit by merging the merge bases. This process is a little bit messy, but fortunately it's rare, and even when it does happen, it rarely makes anything worse.



            Extracting the three versions





            • You can extract any of the three versions using git checkout-index, although this command is a bit of a pain to use:



              git checkout-index --all -- path/to/file


              This writes all three to files with funky temporary names, which you then have to rename. (There are several variations on this theme but they're all a bit annoying.)



            • You can use git mergetool, which automatically extracts all three versions, then invokes your chosen merge tool command on all of them.



            • Or, you can manually extract one or both files. The method in DogEata's answer will work, but if you have no concerns over line-ending issues, this way is shorter:



              git show :1:path/to/file > path/to/file.base
              git show :2:path/to/file > path/to/file.ours
              git show :3:path/to/file > path/to/file.theirs


              This uses the git show command along with the gitrevisions syntax for accessing the index copies, showing them to standard output, and redirecting the output to new files.




            Note that git add writes to slot zero



            Git knows that a merge is in progress, and has not yet been finished, in several ways, but the most important is that there are these files in slots 1, 2, and/or 3 for some path in the index. When you've figured out the correct contents for that path, and written them to that path in your work-tree, you run:



            git add path/to/file


            to copy the file back into the index, taking the normal-format work-tree copy and compressing in into the special Git-only format that goes in the index.



            If the file were in the index at slot zero, the way it normally is, that would just overwrite the old index copy with the fixed-up work-tree version. When there are multiple copies of the file in the index using the higher numbered slots, git add still writes to slot zero, but this time, it also removes the higher-numbered entries entirely. Now the file is resolved.



            If you use git mergetool, the git mergetool command can automatically run git add for you, hiding the extra step. Some people find this especially convenient.






            share|improve this answer

























              up vote
              1
              down vote













              TL;DR



              Consider using git mergetool (though I never do it this way myself), or git show (I sometimes do this). Also consider setting merge.conflictStyle to diff3, which makes Git write, into the conflicted work-tree copy, the base version as well as the left and right side versions. I find that with this turned on, I almost never need to see the two inputs. (But only almost never.)



              Long(ish)



              In fact, the file is already present in all three versions, but they are all in the index, not in the work-tree. The trick is therefore to get them out of the index, where they're in the special Git-only format, into your work-tree where you can see and work on / with them.



              Let's look briefly, yet in detail, at how git merge works when there are conflicts. For conflicts to occur, we must have done something like this:



              $ git checkout ours
              Switched to branch 'ours'
              $ git merge theirs


              Git will have looked at the commit graph and found that ours and theirs have diverged, but have a common merge base commit:1



                        o--...--L   <-- ours (HEAD)
              /
              ...--o--B

              o--...--R <-- theirs


              Commit L is the left side or local or --ours commit. Commit R is the right side or remote or --theirs commit. Commit B here is the merge base. Git then did, in effect, two git diff commands, one to find out what we changed since the merge base:



              git diff --find-renames <hash-of-B> <hash-of-L>   # what we changed
              git diff --find-renames <hash-of-B> <hash-of-R> # what they changed


              The merge then attempted to combine these two sets of changes, using the contents associated with commit B as the base for the combined changes. However, we changed some file, they changed the same file, and our changes collided with their changes, so that we got a merge conflict.



              What Git has done, at this point, is to put all three copies of the file into the index, at nonzero staging slot numbers:




              • Stage 1 contains the merge base: file B:P, where B is the base commit and P is the path name of the file (as found in that commit anyway—we might have renamed the file!).

              • Stage 2 contains our version of the file: file L:P.

              • Stage 3 contains their version of the file: file R:P.


              The work-tree contains Git's attempt to merge the two sets of changes, with conflict markers. Note that this version is not the same as any of the three input versions! Some part(s) of the merge may already be resolved. The default style for conflicting changes is merge, which shows only the left (B-vs-L) and right (B-vs-R) changes without showing you the section that was in B itself. In many cases that's enough, but when the changes are purely deletions, it's often very helpful to know what line(s) in B is / are being deleted, and that's not something you can just deduce. Setting the conflict style to diff3 makes Git record the B code section as well, in between the two change-sections.





              1It's possible for there to be multiple merge base commits. In this case, Git defaults to constructing a new merge base commit by merging the merge bases. This process is a little bit messy, but fortunately it's rare, and even when it does happen, it rarely makes anything worse.



              Extracting the three versions





              • You can extract any of the three versions using git checkout-index, although this command is a bit of a pain to use:



                git checkout-index --all -- path/to/file


                This writes all three to files with funky temporary names, which you then have to rename. (There are several variations on this theme but they're all a bit annoying.)



              • You can use git mergetool, which automatically extracts all three versions, then invokes your chosen merge tool command on all of them.



              • Or, you can manually extract one or both files. The method in DogEata's answer will work, but if you have no concerns over line-ending issues, this way is shorter:



                git show :1:path/to/file > path/to/file.base
                git show :2:path/to/file > path/to/file.ours
                git show :3:path/to/file > path/to/file.theirs


                This uses the git show command along with the gitrevisions syntax for accessing the index copies, showing them to standard output, and redirecting the output to new files.




              Note that git add writes to slot zero



              Git knows that a merge is in progress, and has not yet been finished, in several ways, but the most important is that there are these files in slots 1, 2, and/or 3 for some path in the index. When you've figured out the correct contents for that path, and written them to that path in your work-tree, you run:



              git add path/to/file


              to copy the file back into the index, taking the normal-format work-tree copy and compressing in into the special Git-only format that goes in the index.



              If the file were in the index at slot zero, the way it normally is, that would just overwrite the old index copy with the fixed-up work-tree version. When there are multiple copies of the file in the index using the higher numbered slots, git add still writes to slot zero, but this time, it also removes the higher-numbered entries entirely. Now the file is resolved.



              If you use git mergetool, the git mergetool command can automatically run git add for you, hiding the extra step. Some people find this especially convenient.






              share|improve this answer























                up vote
                1
                down vote










                up vote
                1
                down vote









                TL;DR



                Consider using git mergetool (though I never do it this way myself), or git show (I sometimes do this). Also consider setting merge.conflictStyle to diff3, which makes Git write, into the conflicted work-tree copy, the base version as well as the left and right side versions. I find that with this turned on, I almost never need to see the two inputs. (But only almost never.)



                Long(ish)



                In fact, the file is already present in all three versions, but they are all in the index, not in the work-tree. The trick is therefore to get them out of the index, where they're in the special Git-only format, into your work-tree where you can see and work on / with them.



                Let's look briefly, yet in detail, at how git merge works when there are conflicts. For conflicts to occur, we must have done something like this:



                $ git checkout ours
                Switched to branch 'ours'
                $ git merge theirs


                Git will have looked at the commit graph and found that ours and theirs have diverged, but have a common merge base commit:1



                          o--...--L   <-- ours (HEAD)
                /
                ...--o--B

                o--...--R <-- theirs


                Commit L is the left side or local or --ours commit. Commit R is the right side or remote or --theirs commit. Commit B here is the merge base. Git then did, in effect, two git diff commands, one to find out what we changed since the merge base:



                git diff --find-renames <hash-of-B> <hash-of-L>   # what we changed
                git diff --find-renames <hash-of-B> <hash-of-R> # what they changed


                The merge then attempted to combine these two sets of changes, using the contents associated with commit B as the base for the combined changes. However, we changed some file, they changed the same file, and our changes collided with their changes, so that we got a merge conflict.



                What Git has done, at this point, is to put all three copies of the file into the index, at nonzero staging slot numbers:




                • Stage 1 contains the merge base: file B:P, where B is the base commit and P is the path name of the file (as found in that commit anyway—we might have renamed the file!).

                • Stage 2 contains our version of the file: file L:P.

                • Stage 3 contains their version of the file: file R:P.


                The work-tree contains Git's attempt to merge the two sets of changes, with conflict markers. Note that this version is not the same as any of the three input versions! Some part(s) of the merge may already be resolved. The default style for conflicting changes is merge, which shows only the left (B-vs-L) and right (B-vs-R) changes without showing you the section that was in B itself. In many cases that's enough, but when the changes are purely deletions, it's often very helpful to know what line(s) in B is / are being deleted, and that's not something you can just deduce. Setting the conflict style to diff3 makes Git record the B code section as well, in between the two change-sections.





                1It's possible for there to be multiple merge base commits. In this case, Git defaults to constructing a new merge base commit by merging the merge bases. This process is a little bit messy, but fortunately it's rare, and even when it does happen, it rarely makes anything worse.



                Extracting the three versions





                • You can extract any of the three versions using git checkout-index, although this command is a bit of a pain to use:



                  git checkout-index --all -- path/to/file


                  This writes all three to files with funky temporary names, which you then have to rename. (There are several variations on this theme but they're all a bit annoying.)



                • You can use git mergetool, which automatically extracts all three versions, then invokes your chosen merge tool command on all of them.



                • Or, you can manually extract one or both files. The method in DogEata's answer will work, but if you have no concerns over line-ending issues, this way is shorter:



                  git show :1:path/to/file > path/to/file.base
                  git show :2:path/to/file > path/to/file.ours
                  git show :3:path/to/file > path/to/file.theirs


                  This uses the git show command along with the gitrevisions syntax for accessing the index copies, showing them to standard output, and redirecting the output to new files.




                Note that git add writes to slot zero



                Git knows that a merge is in progress, and has not yet been finished, in several ways, but the most important is that there are these files in slots 1, 2, and/or 3 for some path in the index. When you've figured out the correct contents for that path, and written them to that path in your work-tree, you run:



                git add path/to/file


                to copy the file back into the index, taking the normal-format work-tree copy and compressing in into the special Git-only format that goes in the index.



                If the file were in the index at slot zero, the way it normally is, that would just overwrite the old index copy with the fixed-up work-tree version. When there are multiple copies of the file in the index using the higher numbered slots, git add still writes to slot zero, but this time, it also removes the higher-numbered entries entirely. Now the file is resolved.



                If you use git mergetool, the git mergetool command can automatically run git add for you, hiding the extra step. Some people find this especially convenient.






                share|improve this answer












                TL;DR



                Consider using git mergetool (though I never do it this way myself), or git show (I sometimes do this). Also consider setting merge.conflictStyle to diff3, which makes Git write, into the conflicted work-tree copy, the base version as well as the left and right side versions. I find that with this turned on, I almost never need to see the two inputs. (But only almost never.)



                Long(ish)



                In fact, the file is already present in all three versions, but they are all in the index, not in the work-tree. The trick is therefore to get them out of the index, where they're in the special Git-only format, into your work-tree where you can see and work on / with them.



                Let's look briefly, yet in detail, at how git merge works when there are conflicts. For conflicts to occur, we must have done something like this:



                $ git checkout ours
                Switched to branch 'ours'
                $ git merge theirs


                Git will have looked at the commit graph and found that ours and theirs have diverged, but have a common merge base commit:1



                          o--...--L   <-- ours (HEAD)
                /
                ...--o--B

                o--...--R <-- theirs


                Commit L is the left side or local or --ours commit. Commit R is the right side or remote or --theirs commit. Commit B here is the merge base. Git then did, in effect, two git diff commands, one to find out what we changed since the merge base:



                git diff --find-renames <hash-of-B> <hash-of-L>   # what we changed
                git diff --find-renames <hash-of-B> <hash-of-R> # what they changed


                The merge then attempted to combine these two sets of changes, using the contents associated with commit B as the base for the combined changes. However, we changed some file, they changed the same file, and our changes collided with their changes, so that we got a merge conflict.



                What Git has done, at this point, is to put all three copies of the file into the index, at nonzero staging slot numbers:




                • Stage 1 contains the merge base: file B:P, where B is the base commit and P is the path name of the file (as found in that commit anyway—we might have renamed the file!).

                • Stage 2 contains our version of the file: file L:P.

                • Stage 3 contains their version of the file: file R:P.


                The work-tree contains Git's attempt to merge the two sets of changes, with conflict markers. Note that this version is not the same as any of the three input versions! Some part(s) of the merge may already be resolved. The default style for conflicting changes is merge, which shows only the left (B-vs-L) and right (B-vs-R) changes without showing you the section that was in B itself. In many cases that's enough, but when the changes are purely deletions, it's often very helpful to know what line(s) in B is / are being deleted, and that's not something you can just deduce. Setting the conflict style to diff3 makes Git record the B code section as well, in between the two change-sections.





                1It's possible for there to be multiple merge base commits. In this case, Git defaults to constructing a new merge base commit by merging the merge bases. This process is a little bit messy, but fortunately it's rare, and even when it does happen, it rarely makes anything worse.



                Extracting the three versions





                • You can extract any of the three versions using git checkout-index, although this command is a bit of a pain to use:



                  git checkout-index --all -- path/to/file


                  This writes all three to files with funky temporary names, which you then have to rename. (There are several variations on this theme but they're all a bit annoying.)



                • You can use git mergetool, which automatically extracts all three versions, then invokes your chosen merge tool command on all of them.



                • Or, you can manually extract one or both files. The method in DogEata's answer will work, but if you have no concerns over line-ending issues, this way is shorter:



                  git show :1:path/to/file > path/to/file.base
                  git show :2:path/to/file > path/to/file.ours
                  git show :3:path/to/file > path/to/file.theirs


                  This uses the git show command along with the gitrevisions syntax for accessing the index copies, showing them to standard output, and redirecting the output to new files.




                Note that git add writes to slot zero



                Git knows that a merge is in progress, and has not yet been finished, in several ways, but the most important is that there are these files in slots 1, 2, and/or 3 for some path in the index. When you've figured out the correct contents for that path, and written them to that path in your work-tree, you run:



                git add path/to/file


                to copy the file back into the index, taking the normal-format work-tree copy and compressing in into the special Git-only format that goes in the index.



                If the file were in the index at slot zero, the way it normally is, that would just overwrite the old index copy with the fixed-up work-tree version. When there are multiple copies of the file in the index using the higher numbered slots, git add still writes to slot zero, but this time, it also removes the higher-numbered entries entirely. Now the file is resolved.



                If you use git mergetool, the git mergetool command can automatically run git add for you, hiding the extra step. Some people find this especially convenient.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 11 at 9:10









                torek

                178k16228305




                178k16228305






























                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246498%2fhow-to-split-file-into-ours-and-theirs-on-conflict%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Full-time equivalent

                    さくらももこ

                    13 indicted, 8 arrested in Calif. drug cartel investigation