Rectangle 27 265

svn remove --force filename
svn resolve --accept=working  filename
svn commit

in svn 1.4 this is simply: svn resolved filename

you missed out the svn add after calling svn resolve

This is not the best answer. use svn resolved filename.

using svn 1.7.4, svn help resolved states that it "has been deprecated in favor of running 'svn resolve --accept working'."

SVN remains in conflict? - Stack Overflow

svn
Rectangle 27 152

svn resolve --accept=working PATH

thanks. that seems to be the right solution. (didn't know about "resolve" option before. I marked it as answer. Though, for some reason didn't work for me, probably because my working copy tree has been corrupted or whatnot... in the end i resolved it by just deleting the dir and do a update.

It didn't work for me initially, so I checked out another copy of the svn branch in a temporary folder. Then I deleted the PATH causing conflict and committed the changes. After that I went back to my original copy and ran this command. It worked with the message "Resolved conflicted state of PATH" This works, thanks :)

My understanding is that it would not have mattered if the original was deleted or not in the repository, because "resolve" works only on the working copy.

svn - how to resolve "local edit, incoming delete upon update" message...

svn
Rectangle 27 152

svn resolve --accept=working PATH

thanks. that seems to be the right solution. (didn't know about "resolve" option before. I marked it as answer. Though, for some reason didn't work for me, probably because my working copy tree has been corrupted or whatnot... in the end i resolved it by just deleting the dir and do a update.

It didn't work for me initially, so I checked out another copy of the svn branch in a temporary folder. Then I deleted the PATH causing conflict and committed the changes. After that I went back to my original copy and ran this command. It worked with the message "Resolved conflicted state of PATH" This works, thanks :)

My understanding is that it would not have mattered if the original was deleted or not in the repository, because "resolve" works only on the working copy.

svn - how to resolve "local edit, incoming delete upon update" message...

svn
Rectangle 27 349

Rebase workflow is not better for conflict resolution!

A git rebase workflow does not protect you from people who are bad at conflict resolution or people who are used to a SVN workflow, like suggested in Avoiding Git Disasters: A Gory Story. It only makes conflict resolution more tedious for them and makes it harder to recover from bad conflict resolution. Instead, use diff3 so that it's not so difficult in the first place.

I am very pro-rebase for cleaning up history. However if I ever hit a conflict, I immediately abort the rebase and do a merge instead! It really kills me that people are recommending a rebase workflow as a better alternative to a merge workflow for conflict resolution (which is exactly what this question was about).

If it goes "all to hell" during a merge, it will go "all to hell" during a rebase, and potentially a lot more hell too! Here's why:

When you rebase instead of merge, you will have to perform conflict resolution up to as many times as you have commits to rebase, for the same conflict!

I branch off of master to refactor a complicated method in a branch. My refactoring work is comprised of 15 commits total as I work to refactor it and get code reviews. Part of my refactoring involves fixing the mixed tabs and spaces that were present in master before. This is necessary, but unfortunately it will conflict with any change made afterward to this method in master. Sure enough, while I'm working on this method, someone makes a simple, legitimate change to the same method in the master branch that should be merged in with my changes.

git merge: I get a conflict. I see the change they made to master and merge it in with (the final product of) my branch. Done.

git rebase: I get a conflict with my first commit. I resolve the conflict and continue the rebase. I get a conflict with my second commit. I resolve the conflict and continue the rebase. I get a conflict with my third commit. I resolve the conflict and continue the rebase. I get a conflict with my fourth commit. I resolve the conflict and continue the rebase. I get a conflict with my fifth commit. I resolve the conflict and continue the rebase. I get a conflict with my sixth commit. I resolve the conflict and continue the rebase. I get a conflict with my seventh commit. I resolve the conflict and continue the rebase. I get a conflict with my eighth commit. I resolve the conflict and continue the rebase. I get a conflict with my ninth commit. I resolve the conflict and continue the rebase. I get a conflict with my tenth commit. I resolve the conflict and continue the rebase. I get a conflict with my eleventh commit. I resolve the conflict and continue the rebase. I get a conflict with my twelfth commit. I resolve the conflict and continue the rebase. I get a conflict with my thirteenth commit. I resolve the conflict and continue the rebase. I get a conflict with my fourteenth commit. I resolve the conflict and continue the rebase. I get a conflict with my fifteenth commit. I resolve the conflict and continue the rebase.

You have got to be kidding me if this is your preferred workflow. All it takes is a whitespace fix that conflicts with one change made on master, and every commit will conflict and must be resolved. And this is a simple scenario with only a whitespace conflict. Heaven forbid you have a real conflict involving major code changes across files and have to resolve that multiple times.

With all the extra conflict resolution you need to do, it just increases the possibility that you will make a mistake. But mistakes are fine in git since you can undo, right? Except of course...

I think we can all agree that conflict resolution can be difficult, and also that some people are very bad at it. It can be very prone to mistakes, which why it's so great that git makes it easy to undo!

When you merge a branch, git creates a merge commit that can be discarded or amended if the conflict resolution goes poorly. Even if you have already pushed the bad merge commit to the public/authoritative repo, you can use git revert to undo the changes introduced by the merge and redo the merge correctly in a new merge commit.

When you rebase a branch, in the likely event that conflict resolution is done wrong, you're screwed. Every commit now contains the bad merge, and you can't just redo the rebase*. At best, you have to go back and amend each of the affected commits. Not fun.

After a rebase, it's impossible to determine what was originally part of the commits and what was introduced as a result of bad conflict resolution.

Looking at the conflict, it's impossible to tell what each branch changed or what its intent was. This is the biggest reason in my opinion why conflict resolution is confusing and hard.

git config --global merge.conflictstyle diff3

When you use the diff3, each new conflict will have a 3rd section, the merged common ancestor.

<<<<<<< HEAD
TextMessage.send(:include_timestamp => true)
||||||| merged common ancestor
EmailMessage.send(:include_timestamp => true)
=======
EmailMessage.send(:include_timestamp => false)
>>>>>>> feature-branch

First examine the merged common ancestor. Then compare each side to determine each branch's intent. You can see that HEAD changed EmailMessage to TextMessage. Its intent is to change the class used to TextMessage, passing the same parameters. You can also see that feature-branch's intent is to pass false instead of true for the :include_timestamp option. To merge these changes, combine the intent of both:

TextMessage.send(:include_timestamp => false)
  • Compare the common ancestor with each branch, and determine which branch has the simplest change
  • Apply that simple change to the other branch's version of the code, so that it contains both the simpler and the more complex change
  • Remove all the sections of conflict code other than the one that you just merged the changes together into

Finally, some conflicts are terrible to understand even with diff3. This happens especially when diff finds lines in common that are not semantically common (eg. both branches happened to have a blank line at the same place!). For example, one branch changes the indentation of the body of a class or reorders similar methods. In these cases, a better resolution strategy can be to examine the change from either side of the merge and manually apply the diff to the other file.

Let's look at how we might resolve a conflict in a scenario where merging origin/feature1 where lib/message.rb conflicts.

Decide whether our currently checked out branch (HEAD, or --ours) or the branch we're merging (origin/feature1, or --theirs) is a simpler change to apply. Using diff with triple dot (git diff a...b) shows the changes that happened on b since its last divergence from a, or in other words, compare the common ancestor of a and b with b.

git diff HEAD...origin/feature1 -- lib/message.rb # show the change in feature1
git diff origin/feature1...HEAD -- lib/message.rb # show the change in our branch

Check out the more complicated version of the file. This will remove all conflict markers and use the side you choose.

git checkout --ours -- lib/message.rb   # if our branch's change is more complicated
git checkout --theirs -- lib/message.rb # if origin/feature1's change is more complicated

With the complicated change checked out, pull up the diff of the simpler change (see step 1). Apply each change from this diff to the conflicting file.

How would merging all conflicts at one go work better than individual commits? I already get problems from merging single commits (especially from people who don't break commits into logical portions AND provide sufficient tests for verification). Also, rebase is not any worse than merge when it comes to backup options, intelligent use of interactive rebase and tools like tortoisegit (which allows selection of which commits to include) will help a lot.

I feel like I addressed the reason in #1. If individual commits are not logically consistent, all the more reason to merge the logically consistent branch, so that you can actually make sense of the conflict. If commit 1 is buggy and commit 2 fixes it, merging commit 1 will be confusing. There are legitimate reasons you might get 15 conflicts in a row, like the one I outlined above. Also your argument for rebase not being worse is somewhat unfounded. Rebase mixes bad merges into the original good commits and doesn't leave the good commits around to let you try again. Merge does.

I completely agree with you nilbus. Great post; that clears some things up. I wonder if rerere would be any help here though. Also, thanks for the suggestion on using diff3, I'm definitely going to switch that one on right now.

agreed. rebase is not helpful especially if you have to share the branch with others

+1 for telling me about diff3 alone - how often was looking on an incomprehensible conflict cursing whoever is responsible for not telling me what the common ancestor had to say. Thank you very much.

version control - Git workflow and rebase vs merge questions - Stack O...

git version-control git-merge git-rebase
Rectangle 27 346

Rebase workflow is not better for conflict resolution!

A git rebase workflow does not protect you from people who are bad at conflict resolution or people who are used to a SVN workflow, like suggested in Avoiding Git Disasters: A Gory Story. It only makes conflict resolution more tedious for them and makes it harder to recover from bad conflict resolution. Instead, use diff3 so that it's not so difficult in the first place.

I am very pro-rebase for cleaning up history. However if I ever hit a conflict, I immediately abort the rebase and do a merge instead! It really kills me that people are recommending a rebase workflow as a better alternative to a merge workflow for conflict resolution (which is exactly what this question was about).

If it goes "all to hell" during a merge, it will go "all to hell" during a rebase, and potentially a lot more hell too! Here's why:

When you rebase instead of merge, you will have to perform conflict resolution up to as many times as you have commits to rebase, for the same conflict!

I branch off of master to refactor a complicated method in a branch. My refactoring work is comprised of 15 commits total as I work to refactor it and get code reviews. Part of my refactoring involves fixing the mixed tabs and spaces that were present in master before. This is necessary, but unfortunately it will conflict with any change made afterward to this method in master. Sure enough, while I'm working on this method, someone makes a simple, legitimate change to the same method in the master branch that should be merged in with my changes.

git merge: I get a conflict. I see the change they made to master and merge it in with (the final product of) my branch. Done.

git rebase: I get a conflict with my first commit. I resolve the conflict and continue the rebase. I get a conflict with my second commit. I resolve the conflict and continue the rebase. I get a conflict with my third commit. I resolve the conflict and continue the rebase. I get a conflict with my fourth commit. I resolve the conflict and continue the rebase. I get a conflict with my fifth commit. I resolve the conflict and continue the rebase. I get a conflict with my sixth commit. I resolve the conflict and continue the rebase. I get a conflict with my seventh commit. I resolve the conflict and continue the rebase. I get a conflict with my eighth commit. I resolve the conflict and continue the rebase. I get a conflict with my ninth commit. I resolve the conflict and continue the rebase. I get a conflict with my tenth commit. I resolve the conflict and continue the rebase. I get a conflict with my eleventh commit. I resolve the conflict and continue the rebase. I get a conflict with my twelfth commit. I resolve the conflict and continue the rebase. I get a conflict with my thirteenth commit. I resolve the conflict and continue the rebase. I get a conflict with my fourteenth commit. I resolve the conflict and continue the rebase. I get a conflict with my fifteenth commit. I resolve the conflict and continue the rebase.

You have got to be kidding me if this is your preferred workflow. All it takes is a whitespace fix that conflicts with one change made on master, and every commit will conflict and must be resolved. And this is a simple scenario with only a whitespace conflict. Heaven forbid you have a real conflict involving major code changes across files and have to resolve that multiple times.

With all the extra conflict resolution you need to do, it just increases the possibility that you will make a mistake. But mistakes are fine in git since you can undo, right? Except of course...

I think we can all agree that conflict resolution can be difficult, and also that some people are very bad at it. It can be very prone to mistakes, which why it's so great that git makes it easy to undo!

When you merge a branch, git creates a merge commit that can be discarded or amended if the conflict resolution goes poorly. Even if you have already pushed the bad merge commit to the public/authoritative repo, you can use git revert to undo the changes introduced by the merge and redo the merge correctly in a new merge commit.

When you rebase a branch, in the likely event that conflict resolution is done wrong, you're screwed. Every commit now contains the bad merge, and you can't just redo the rebase*. At best, you have to go back and amend each of the affected commits. Not fun.

After a rebase, it's impossible to determine what was originally part of the commits and what was introduced as a result of bad conflict resolution.

Looking at the conflict, it's impossible to tell what each branch changed or what its intent was. This is the biggest reason in my opinion why conflict resolution is confusing and hard.

git config --global merge.conflictstyle diff3

When you use the diff3, each new conflict will have a 3rd section, the merged common ancestor.

<<<<<<< HEAD
TextMessage.send(:include_timestamp => true)
||||||| merged common ancestor
EmailMessage.send(:include_timestamp => true)
=======
EmailMessage.send(:include_timestamp => false)
>>>>>>> feature-branch

First examine the merged common ancestor. Then compare each side to determine each branch's intent. You can see that HEAD changed EmailMessage to TextMessage. Its intent is to change the class used to TextMessage, passing the same parameters. You can also see that feature-branch's intent is to pass false instead of true for the :include_timestamp option. To merge these changes, combine the intent of both:

TextMessage.send(:include_timestamp => false)
  • Compare the common ancestor with each branch, and determine which branch has the simplest change
  • Apply that simple change to the other branch's version of the code, so that it contains both the simpler and the more complex change
  • Remove all the sections of conflict code other than the one that you just merged the changes together into

Finally, some conflicts are terrible to understand even with diff3. This happens especially when diff finds lines in common that are not semantically common (eg. both branches happened to have a blank line at the same place!). For example, one branch changes the indentation of the body of a class or reorders similar methods. In these cases, a better resolution strategy can be to examine the change from either side of the merge and manually apply the diff to the other file.

Let's look at how we might resolve a conflict in a scenario where merging origin/feature1 where lib/message.rb conflicts.

Decide whether our currently checked out branch (HEAD, or --ours) or the branch we're merging (origin/feature1, or --theirs) is a simpler change to apply. Using diff with triple dot (git diff a...b) shows the changes that happened on b since its last divergence from a, or in other words, compare the common ancestor of a and b with b.

git diff HEAD...origin/feature1 -- lib/message.rb # show the change in feature1
git diff origin/feature1...HEAD -- lib/message.rb # show the change in our branch

Check out the more complicated version of the file. This will remove all conflict markers and use the side you choose.

git checkout --ours -- lib/message.rb   # if our branch's change is more complicated
git checkout --theirs -- lib/message.rb # if origin/feature1's change is more complicated

With the complicated change checked out, pull up the diff of the simpler change (see step 1). Apply each change from this diff to the conflicting file.

How would merging all conflicts at one go work better than individual commits? I already get problems from merging single commits (especially from people who don't break commits into logical portions AND provide sufficient tests for verification). Also, rebase is not any worse than merge when it comes to backup options, intelligent use of interactive rebase and tools like tortoisegit (which allows selection of which commits to include) will help a lot.

I feel like I addressed the reason in #1. If individual commits are not logically consistent, all the more reason to merge the logically consistent branch, so that you can actually make sense of the conflict. If commit 1 is buggy and commit 2 fixes it, merging commit 1 will be confusing. There are legitimate reasons you might get 15 conflicts in a row, like the one I outlined above. Also your argument for rebase not being worse is somewhat unfounded. Rebase mixes bad merges into the original good commits and doesn't leave the good commits around to let you try again. Merge does.

I completely agree with you nilbus. Great post; that clears some things up. I wonder if rerere would be any help here though. Also, thanks for the suggestion on using diff3, I'm definitely going to switch that one on right now.

agreed. rebase is not helpful especially if you have to share the branch with others

+1 for telling me about diff3 alone - how often was looking on an incomprehensible conflict cursing whoever is responsible for not telling me what the common ancestor had to say. Thank you very much.

version control - Git workflow and rebase vs merge questions - Stack O...

git version-control git-merge git-rebase
Rectangle 27 346

Rebase workflow is not better for conflict resolution!

A git rebase workflow does not protect you from people who are bad at conflict resolution or people who are used to a SVN workflow, like suggested in Avoiding Git Disasters: A Gory Story. It only makes conflict resolution more tedious for them and makes it harder to recover from bad conflict resolution. Instead, use diff3 so that it's not so difficult in the first place.

I am very pro-rebase for cleaning up history. However if I ever hit a conflict, I immediately abort the rebase and do a merge instead! It really kills me that people are recommending a rebase workflow as a better alternative to a merge workflow for conflict resolution (which is exactly what this question was about).

If it goes "all to hell" during a merge, it will go "all to hell" during a rebase, and potentially a lot more hell too! Here's why:

When you rebase instead of merge, you will have to perform conflict resolution up to as many times as you have commits to rebase, for the same conflict!

I branch off of master to refactor a complicated method in a branch. My refactoring work is comprised of 15 commits total as I work to refactor it and get code reviews. Part of my refactoring involves fixing the mixed tabs and spaces that were present in master before. This is necessary, but unfortunately it will conflict with any change made afterward to this method in master. Sure enough, while I'm working on this method, someone makes a simple, legitimate change to the same method in the master branch that should be merged in with my changes.

git merge: I get a conflict. I see the change they made to master and merge it in with (the final product of) my branch. Done.

git rebase: I get a conflict with my first commit. I resolve the conflict and continue the rebase. I get a conflict with my second commit. I resolve the conflict and continue the rebase. I get a conflict with my third commit. I resolve the conflict and continue the rebase. I get a conflict with my fourth commit. I resolve the conflict and continue the rebase. I get a conflict with my fifth commit. I resolve the conflict and continue the rebase. I get a conflict with my sixth commit. I resolve the conflict and continue the rebase. I get a conflict with my seventh commit. I resolve the conflict and continue the rebase. I get a conflict with my eighth commit. I resolve the conflict and continue the rebase. I get a conflict with my ninth commit. I resolve the conflict and continue the rebase. I get a conflict with my tenth commit. I resolve the conflict and continue the rebase. I get a conflict with my eleventh commit. I resolve the conflict and continue the rebase. I get a conflict with my twelfth commit. I resolve the conflict and continue the rebase. I get a conflict with my thirteenth commit. I resolve the conflict and continue the rebase. I get a conflict with my fourteenth commit. I resolve the conflict and continue the rebase. I get a conflict with my fifteenth commit. I resolve the conflict and continue the rebase.

You have got to be kidding me if this is your preferred workflow. All it takes is a whitespace fix that conflicts with one change made on master, and every commit will conflict and must be resolved. And this is a simple scenario with only a whitespace conflict. Heaven forbid you have a real conflict involving major code changes across files and have to resolve that multiple times.

With all the extra conflict resolution you need to do, it just increases the possibility that you will make a mistake. But mistakes are fine in git since you can undo, right? Except of course...

I think we can all agree that conflict resolution can be difficult, and also that some people are very bad at it. It can be very prone to mistakes, which why it's so great that git makes it easy to undo!

When you merge a branch, git creates a merge commit that can be discarded or amended if the conflict resolution goes poorly. Even if you have already pushed the bad merge commit to the public/authoritative repo, you can use git revert to undo the changes introduced by the merge and redo the merge correctly in a new merge commit.

When you rebase a branch, in the likely event that conflict resolution is done wrong, you're screwed. Every commit now contains the bad merge, and you can't just redo the rebase*. At best, you have to go back and amend each of the affected commits. Not fun.

After a rebase, it's impossible to determine what was originally part of the commits and what was introduced as a result of bad conflict resolution.

Looking at the conflict, it's impossible to tell what each branch changed or what its intent was. This is the biggest reason in my opinion why conflict resolution is confusing and hard.

git config --global merge.conflictstyle diff3

When you use the diff3, each new conflict will have a 3rd section, the merged common ancestor.

<<<<<<< HEAD
TextMessage.send(:include_timestamp => true)
||||||| merged common ancestor
EmailMessage.send(:include_timestamp => true)
=======
EmailMessage.send(:include_timestamp => false)
>>>>>>> feature-branch

First examine the merged common ancestor. Then compare each side to determine each branch's intent. You can see that HEAD changed EmailMessage to TextMessage. Its intent is to change the class used to TextMessage, passing the same parameters. You can also see that feature-branch's intent is to pass false instead of true for the :include_timestamp option. To merge these changes, combine the intent of both:

TextMessage.send(:include_timestamp => false)
  • Compare the common ancestor with each branch, and determine which branch has the simplest change
  • Apply that simple change to the other branch's version of the code, so that it contains both the simpler and the more complex change
  • Remove all the sections of conflict code other than the one that you just merged the changes together into

Finally, some conflicts are terrible to understand even with diff3. This happens especially when diff finds lines in common that are not semantically common (eg. both branches happened to have a blank line at the same place!). For example, one branch changes the indentation of the body of a class or reorders similar methods. In these cases, a better resolution strategy can be to examine the change from either side of the merge and manually apply the diff to the other file.

Let's look at how we might resolve a conflict in a scenario where merging origin/feature1 where lib/message.rb conflicts.

Decide whether our currently checked out branch (HEAD, or --ours) or the branch we're merging (origin/feature1, or --theirs) is a simpler change to apply. Using diff with triple dot (git diff a...b) shows the changes that happened on b since its last divergence from a, or in other words, compare the common ancestor of a and b with b.

git diff HEAD...origin/feature1 -- lib/message.rb # show the change in feature1
git diff origin/feature1...HEAD -- lib/message.rb # show the change in our branch

Check out the more complicated version of the file. This will remove all conflict markers and use the side you choose.

git checkout --ours -- lib/message.rb   # if our branch's change is more complicated
git checkout --theirs -- lib/message.rb # if origin/feature1's change is more complicated

With the complicated change checked out, pull up the diff of the simpler change (see step 1). Apply each change from this diff to the conflicting file.

How would merging all conflicts at one go work better than individual commits? I already get problems from merging single commits (especially from people who don't break commits into logical portions AND provide sufficient tests for verification). Also, rebase is not any worse than merge when it comes to backup options, intelligent use of interactive rebase and tools like tortoisegit (which allows selection of which commits to include) will help a lot.

I feel like I addressed the reason in #1. If individual commits are not logically consistent, all the more reason to merge the logically consistent branch, so that you can actually make sense of the conflict. If commit 1 is buggy and commit 2 fixes it, merging commit 1 will be confusing. There are legitimate reasons you might get 15 conflicts in a row, like the one I outlined above. Also your argument for rebase not being worse is somewhat unfounded. Rebase mixes bad merges into the original good commits and doesn't leave the good commits around to let you try again. Merge does.

I completely agree with you nilbus. Great post; that clears some things up. I wonder if rerere would be any help here though. Also, thanks for the suggestion on using diff3, I'm definitely going to switch that one on right now.

agreed. rebase is not helpful especially if you have to share the branch with others

+1 for telling me about diff3 alone - how often was looking on an incomprehensible conflict cursing whoever is responsible for not telling me what the common ancestor had to say. Thank you very much.

version control - Git workflow and rebase vs merge questions - Stack O...

git version-control git-merge git-rebase
Rectangle 27 346

Rebase workflow is not better for conflict resolution!

A git rebase workflow does not protect you from people who are bad at conflict resolution or people who are used to a SVN workflow, like suggested in Avoiding Git Disasters: A Gory Story. It only makes conflict resolution more tedious for them and makes it harder to recover from bad conflict resolution. Instead, use diff3 so that it's not so difficult in the first place.

I am very pro-rebase for cleaning up history. However if I ever hit a conflict, I immediately abort the rebase and do a merge instead! It really kills me that people are recommending a rebase workflow as a better alternative to a merge workflow for conflict resolution (which is exactly what this question was about).

If it goes "all to hell" during a merge, it will go "all to hell" during a rebase, and potentially a lot more hell too! Here's why:

When you rebase instead of merge, you will have to perform conflict resolution up to as many times as you have commits to rebase, for the same conflict!

I branch off of master to refactor a complicated method in a branch. My refactoring work is comprised of 15 commits total as I work to refactor it and get code reviews. Part of my refactoring involves fixing the mixed tabs and spaces that were present in master before. This is necessary, but unfortunately it will conflict with any change made afterward to this method in master. Sure enough, while I'm working on this method, someone makes a simple, legitimate change to the same method in the master branch that should be merged in with my changes.

git merge: I get a conflict. I see the change they made to master and merge it in with (the final product of) my branch. Done.

git rebase: I get a conflict with my first commit. I resolve the conflict and continue the rebase. I get a conflict with my second commit. I resolve the conflict and continue the rebase. I get a conflict with my third commit. I resolve the conflict and continue the rebase. I get a conflict with my fourth commit. I resolve the conflict and continue the rebase. I get a conflict with my fifth commit. I resolve the conflict and continue the rebase. I get a conflict with my sixth commit. I resolve the conflict and continue the rebase. I get a conflict with my seventh commit. I resolve the conflict and continue the rebase. I get a conflict with my eighth commit. I resolve the conflict and continue the rebase. I get a conflict with my ninth commit. I resolve the conflict and continue the rebase. I get a conflict with my tenth commit. I resolve the conflict and continue the rebase. I get a conflict with my eleventh commit. I resolve the conflict and continue the rebase. I get a conflict with my twelfth commit. I resolve the conflict and continue the rebase. I get a conflict with my thirteenth commit. I resolve the conflict and continue the rebase. I get a conflict with my fourteenth commit. I resolve the conflict and continue the rebase. I get a conflict with my fifteenth commit. I resolve the conflict and continue the rebase.

You have got to be kidding me if this is your preferred workflow. All it takes is a whitespace fix that conflicts with one change made on master, and every commit will conflict and must be resolved. And this is a simple scenario with only a whitespace conflict. Heaven forbid you have a real conflict involving major code changes across files and have to resolve that multiple times.

With all the extra conflict resolution you need to do, it just increases the possibility that you will make a mistake. But mistakes are fine in git since you can undo, right? Except of course...

I think we can all agree that conflict resolution can be difficult, and also that some people are very bad at it. It can be very prone to mistakes, which why it's so great that git makes it easy to undo!

When you merge a branch, git creates a merge commit that can be discarded or amended if the conflict resolution goes poorly. Even if you have already pushed the bad merge commit to the public/authoritative repo, you can use git revert to undo the changes introduced by the merge and redo the merge correctly in a new merge commit.

When you rebase a branch, in the likely event that conflict resolution is done wrong, you're screwed. Every commit now contains the bad merge, and you can't just redo the rebase*. At best, you have to go back and amend each of the affected commits. Not fun.

After a rebase, it's impossible to determine what was originally part of the commits and what was introduced as a result of bad conflict resolution.

Looking at the conflict, it's impossible to tell what each branch changed or what its intent was. This is the biggest reason in my opinion why conflict resolution is confusing and hard.

git config --global merge.conflictstyle diff3

When you use the diff3, each new conflict will have a 3rd section, the merged common ancestor.

<<<<<<< HEAD
TextMessage.send(:include_timestamp => true)
||||||| merged common ancestor
EmailMessage.send(:include_timestamp => true)
=======
EmailMessage.send(:include_timestamp => false)
>>>>>>> feature-branch

First examine the merged common ancestor. Then compare each side to determine each branch's intent. You can see that HEAD changed EmailMessage to TextMessage. Its intent is to change the class used to TextMessage, passing the same parameters. You can also see that feature-branch's intent is to pass false instead of true for the :include_timestamp option. To merge these changes, combine the intent of both:

TextMessage.send(:include_timestamp => false)
  • Compare the common ancestor with each branch, and determine which branch has the simplest change
  • Apply that simple change to the other branch's version of the code, so that it contains both the simpler and the more complex change
  • Remove all the sections of conflict code other than the one that you just merged the changes together into

Finally, some conflicts are terrible to understand even with diff3. This happens especially when diff finds lines in common that are not semantically common (eg. both branches happened to have a blank line at the same place!). For example, one branch changes the indentation of the body of a class or reorders similar methods. In these cases, a better resolution strategy can be to examine the change from either side of the merge and manually apply the diff to the other file.

Let's look at how we might resolve a conflict in a scenario where merging origin/feature1 where lib/message.rb conflicts.

Decide whether our currently checked out branch (HEAD, or --ours) or the branch we're merging (origin/feature1, or --theirs) is a simpler change to apply. Using diff with triple dot (git diff a...b) shows the changes that happened on b since its last divergence from a, or in other words, compare the common ancestor of a and b with b.

git diff HEAD...origin/feature1 -- lib/message.rb # show the change in feature1
git diff origin/feature1...HEAD -- lib/message.rb # show the change in our branch

Check out the more complicated version of the file. This will remove all conflict markers and use the side you choose.

git checkout --ours -- lib/message.rb   # if our branch's change is more complicated
git checkout --theirs -- lib/message.rb # if origin/feature1's change is more complicated

With the complicated change checked out, pull up the diff of the simpler change (see step 1). Apply each change from this diff to the conflicting file.

How would merging all conflicts at one go work better than individual commits? I already get problems from merging single commits (especially from people who don't break commits into logical portions AND provide sufficient tests for verification). Also, rebase is not any worse than merge when it comes to backup options, intelligent use of interactive rebase and tools like tortoisegit (which allows selection of which commits to include) will help a lot.

I feel like I addressed the reason in #1. If individual commits are not logically consistent, all the more reason to merge the logically consistent branch, so that you can actually make sense of the conflict. If commit 1 is buggy and commit 2 fixes it, merging commit 1 will be confusing. There are legitimate reasons you might get 15 conflicts in a row, like the one I outlined above. Also your argument for rebase not being worse is somewhat unfounded. Rebase mixes bad merges into the original good commits and doesn't leave the good commits around to let you try again. Merge does.

I completely agree with you nilbus. Great post; that clears some things up. I wonder if rerere would be any help here though. Also, thanks for the suggestion on using diff3, I'm definitely going to switch that one on right now.

agreed. rebase is not helpful especially if you have to share the branch with others

+1 for telling me about diff3 alone - how often was looking on an incomprehensible conflict cursing whoever is responsible for not telling me what the common ancestor had to say. Thank you very much.

version control - Git workflow and rebase vs merge questions - Stack O...

git version-control git-merge git-rebase
Rectangle 27 375

I found the solution reading the link that Gary gave (and I suggest to follow this way).

Summarizing to resolve the tree conflict committing your working directory with SVN client 1.6.x you can use:

svn resolve --accept working -R .

where . is the directory in conflict.

In this way, we are suggesting SVN to resolve the conflict (--resolve), accepting the working copy inside your sandbox (--accept working), recursively (-R), starting from the current directory (.).

In TortoiseSVN, selecting "Resolved" on right click, actually resolves this issue.

In this way you are suggesting to svn to resolve the conflict (--resolve), accepting the working copy inside your sandbox (--accept working), recursively (-R), starting fron the current directory (.) HTH

in TortoiseSvn, selecting "Resolved" on right click, actually resolves this issue.

does this not blindly just accept the working copy? I mean I feel like I can't tell where issues exist with these conflicts, but if I just resolve and accept working will it not just erase other people's work?

One cause of this happening could be that you svn rm'd a directory that you thought was no longer needed, but somebody else added a new file that is needed. When you update your working copy you should get a tree conflict. If you just blindly accept your solution (deleting the directory) then you'll be removing that person's file. There is no magic "do the right thing" button. You have to understand what it is that you're doing, why that conflicted with the latest version, and how to properly resolve it.

@TWiStErRob, I'd argue this symptom is indicative of issues inherent in SVN as a version control tool. Personally, the way to 'avoid' this issue in the future would be to use git. Since that is most likely not a practical option for the asker, then dealing with the situation as this answer describes is the best option.

svn - Why am I getting tree conflicts in Subversion? - Stack Overflow

svn merge tree-conflict
Rectangle 27 35

What version(s) of subversion are you using on the client and server side? Version 1.4.x on the server and 1.6.x on the client may end up in 'tree errors'.

svn resolve --accept working

Unfortunately, this only 'resolves' the conflict. It does not make missing directory appear, absence of which naturally looks like merge defect to me.

svn status | grep ? | colrm 1 8 |xargs svn add
svn reslove --accept working *path/to/file*

svn - Subversion post-merge tree conflict - "local delete, incoming ed...

svn merge conflict
Rectangle 27 5

If the entire folder is removed and svn is throwing the error "admin file .svn is missing", the following will ve used to resolve the conflict to working state.

svn resolve --accept working "file / directory name "

SVN remains in conflict? - Stack Overflow

svn
Rectangle 27 1

svn resolve --accept theirs-full templates/Toto

This should bring it the folder from trunk w/out you having to manually copy it

That did not work for me. The resulting error message was: svn: warning: Tree conflicts can only be resolved to 'working' state; 'src/main/resources/config/dir' not resolved

svn - Subversion post-merge tree conflict - "local delete, incoming ed...

svn merge conflict
Rectangle 27 6

If the following doesn't work (it didn't for me), try it through the IDE. I tried it through Netbeans and it worked.

First select the directory and resolve conflicts. It automatically asks whether you want to accept your working directory structure.

svn resolve --accept working templates/Toto

svn - Subversion post-merge tree conflict - "local delete, incoming ed...

svn merge conflict
Rectangle 27 6

There is no really clean way to resolve structural tree conflicts like this in Subversion. Basically, what you need to do is the following:

trunk
branch-B
  • manually create a diff of the changes to file1 and file2 in branch-B and apply them to the corresponding files in the newly merged Folder1-Renamed directory
Folder1

Sorry, it does not get easier than that with svn. I am a big fan of using Subversion for certain kinds of team setups, but the nightmare of tree conflicts (and their arcane and error prone resolution mechanisms) regularly make we want to cry (and switch to git for good).

looks like that procedure did the trick. Thanks for spelling it out for me!

merge - svn tree conflict merging renamed folder - Stack Overflow

svn merge tortoisesvn tree-conflict
Rectangle 27 6

There is no really clean way to resolve structural tree conflicts like this in Subversion. Basically, what you need to do is the following:

trunk
branch-B
  • manually create a diff of the changes to file1 and file2 in branch-B and apply them to the corresponding files in the newly merged Folder1-Renamed directory
Folder1

Sorry, it does not get easier than that with svn. I am a big fan of using Subversion for certain kinds of team setups, but the nightmare of tree conflicts (and their arcane and error prone resolution mechanisms) regularly make we want to cry (and switch to git for good).

looks like that procedure did the trick. Thanks for spelling it out for me!

merge - svn tree conflict merging renamed folder - Stack Overflow

svn merge tortoisesvn tree-conflict
Rectangle 27 8

Update will update your checked out version to the latest version (or a specified other revision) in repository. If you have made changes to your working copy, they will still be there after the update. If files have been added or deleted to the repository, that will be reflected in your working copy. If there are changes both in your local copy and in the repository SVN will try to merge all changes for you, if that doesn't work it'll flag for a conflict that you resolve manually.

You can update to any revision, not just the latest.

Sure you can update to the latest. This is what svn update does if you specify HEAD as the revision, or if you do not specify a revision at all.

tortoisesvn - Subversion - What are the differences between the SVN ch...

svn tortoisesvn
Rectangle 27 8

Update will update your checked out version to the latest version (or a specified other revision) in repository. If you have made changes to your working copy, they will still be there after the update. If files have been added or deleted to the repository, that will be reflected in your working copy. If there are changes both in your local copy and in the repository SVN will try to merge all changes for you, if that doesn't work it'll flag for a conflict that you resolve manually.

You can update to any revision, not just the latest.

Sure you can update to the latest. This is what svn update does if you specify HEAD as the revision, or if you do not specify a revision at all.

tortoisesvn - Subversion - What are the differences between the SVN ch...

svn tortoisesvn
Rectangle 27 377

Note: the same procedure also work for the following situation:

$ svn st
!     C foo
      >   local delete, incoming delete upon update
!     C bar
      >   local delete, incoming delete upon update

This happens when you edit a file while someone else deleted the file and commited first. As a good svn citizen you do an update before a commit. Now you have a conflict. Realising that deleting the file is the right thing to do you delete the file from your working copy. Instead of being content svn now complains that the local files are missing and that there is a conflicting update which ultimately wants to see the files deleted. Good job svn.

Should svn resolve not work, for whatever reason, you can do the following:

Initial situation: Local files are missing, update is conflicting.

$ svn st
!  +  C foo
      >   local edit, incoming delete upon update
!  +  C bar
      >   local edit, incoming delete upon update
$ touch foo bar

New situation: Local files to be added to the repository (yeah right, svn, whatever you say), update still conflicting.

$ svn st
A  +  C foo
      >   local edit, incoming delete upon update
A  +  C bar
      >   local edit, incoming delete upon update

Revert the files to the state svn likes them (that means deleted):

$ svn revert foo bar

New situation: Local files not known to svn, update no longer conflicting.

$ svn st
?       foo
?       bar

Now we can delete the files:

$ rm foo bar

If the conflict is about directories then replace rm with rm -r.

$ svn st

This also works when the conflict is for a Directory. Instead of touch foo bar do mkdir foo and mkdir bar. Everything else is the same.

svn st | grep ! | cut -f 7 -d' ' | xargs touch

Remember for directories also do rm -r foo bar (or rmdir foo bar on Windows or if you like Windows).

svn - how to resolve "local edit, incoming delete upon update" message...

svn
Rectangle 27 376

Note: the same procedure also work for the following situation:

$ svn st
!     C foo
      >   local delete, incoming delete upon update
!     C bar
      >   local delete, incoming delete upon update

This happens when you edit a file while someone else deleted the file and commited first. As a good svn citizen you do an update before a commit. Now you have a conflict. Realising that deleting the file is the right thing to do you delete the file from your working copy. Instead of being content svn now complains that the local files are missing and that there is a conflicting update which ultimately wants to see the files deleted. Good job svn.

Should svn resolve not work, for whatever reason, you can do the following:

Initial situation: Local files are missing, update is conflicting.

$ svn st
!  +  C foo
      >   local edit, incoming delete upon update
!  +  C bar
      >   local edit, incoming delete upon update
$ touch foo bar

New situation: Local files to be added to the repository (yeah right, svn, whatever you say), update still conflicting.

$ svn st
A  +  C foo
      >   local edit, incoming delete upon update
A  +  C bar
      >   local edit, incoming delete upon update

Revert the files to the state svn likes them (that means deleted):

$ svn revert foo bar

New situation: Local files not known to svn, update no longer conflicting.

$ svn st
?       foo
?       bar

Now we can delete the files:

$ rm foo bar

If the conflict is about directories then replace rm with rm -r.

$ svn st

This also works when the conflict is for a Directory. Instead of touch foo bar do mkdir foo and mkdir bar. Everything else is the same.

svn st | grep ! | cut -f 7 -d' ' | xargs touch

Remember for directories also do rm -r foo bar (or rmdir foo bar on Windows or if you like Windows).

svn - how to resolve "local edit, incoming delete upon update" message...

svn
Rectangle 27 3

you should use svn status for reviewing the tree conflict. On treeconflicts the last line gives you the exakct information you need.

A tree conflict means 1 side deleted/removed a file while the other side modified its content. In 1 situation there is no "conflict file", because if you deleted/renamed the local file there is no file for conflicting. See both variants:

you got a tree conflict saying:

and you can either svn revert your deletion or keep the deletion(nothing to be done) After you decided, just use svn resolve and commit

2nd : Remote:deleted; local:modified you got a tree conflict again, this time saying:

If you svn revert your local modification now, keep in mind that svn will delete the file as it was renamed already. This also solves the treeconflict implicit. You can also delete the renamed file and say svn resolve [local_file] this keeping your file as new add in your working copy

The same goes for folders, however there are more files affected, but the basic principle is still the same.

So the option before me here is to svn revert the conflicted(deleted) files. Right?

svn - Cannot find the tree conflicted files after merge - Stack Overfl...

svn merge tortoisesvn tree-conflict