1

We are working on a file on different branches.

After merging, the final code becomes erroneous, even though it works fine on each of the branches before merging.

I'm using the accepted answer given here as a branching/merging strategy: https://stackoverflow.com/a/5602109/4746692.

Is there a step that I'm missing?

I have file on master branch. Sample code

public class Test {
  public static void main(String[] args) {
    int a = 1;
    int b = 2;
    System.out.println(b);
  }
}

I branch out from here to newBranch.

git checkout -b newBranch

On the newBranch, I edit the code to print the value of a.

public class Test {
  public static void main(String[] args) {
    int a = 1;
    int b = 2;
    System.out.println(b);
    System.out.println(a);
  }
}

While on master, some other developer removes the statement declaring the variable a.

git checkout master
public class Test {
  public static void main(String[] args) {
    int b = 2;
    System.out.println(b);
  }
}

When I merge the newBranch back to master, the declaration of variable a will be missing, and the print statement will throw an error. Note that this merging doesn't give any merge conflict.

git checkout master
git pull origin master
git merge --no-ff newBranch

The merged code looks like

public class Test {
  public static void main(String[] args) {
    int b = 2;
    System.out.println(b);
    System.out.println(a);
  }
}

Is it a good practice to pull master into newBranch and test before merging it back to master?

Community
  • 1
  • 1
wittyameta
  • 375
  • 1
  • 3
  • 16
  • 1
    Yes, the crucial step is missing from all the answers to the question that you referenced. It's the step "compile and test the merge result, and fix any errors that come up before committing the merge". `git merge` is quite clever and is able to sort out most merges correctly, however, it is a text-based tool that does not understand your code. As such, there will always be situations where the result of `git merge` has to be fixed manually. – cmaster - reinstate monica Oct 22 '15 at 10:39
  • @cmaster But isn't it possible that the final merge back to the master will bring up another problem of this kind, if in the meanwhile there have been other modifications to master? To make this completely safe I think you should merge back with --ff-only. – gbr Oct 22 '15 at 13:24
  • @gbr With `git`, there is no such thing as a backmerge (unlike `svn`), and you can't push unless the remote can be fast-forwarded. Anytime you create a merge commit (whether directly or due to a diverged pull), it is your responsibility to sanity check the resulting commit. Simple as it is. – cmaster - reinstate monica Oct 22 '15 at 14:12
  • @cmaster You _can_ push a non-fast-forward, but most of all I thought the advice was to make a new local branch for the merge, and then to port it to the _local_ master branch. - ok wait I have to think this through, I _might_ be saying nonsense – gbr Oct 22 '15 at 15:07
  • @cmaster OK I wasn't, what I said was right. Ask me if you need explanations. – gbr Oct 22 '15 at 15:28
  • @gbr What I think is that it is irrelevant to history where you have which branches pointing to. After all, a branch in `git` is nothing more or less than a reference to a commit. And, of course, you are *technically* able to push when the remote cannot be forwarded, but that requires you to use the `--force` flag, and you get what you deserve when you do that. – cmaster - reinstate monica Oct 22 '15 at 15:35
  • @cmaster Yes, I agree to your last comment, but it's that too that seem irrelevant: in your previous comment you said some erroneous things and you didn't seem to have understood what the advice given to the OP was about. Have you understood now, and you agree that you should be careful to use --no-ff when you merge back? – gbr Oct 22 '15 at 15:41
  • @gbr Sorry, I'm lost. What erroneous things did I say? Btw: I've never used `--no-ff` and will likely never do. I believe that's an option that only looks interesting to people with an `svn` background, not to people who have been socialized with `git`. As I'm in the later category, I simply fail to see the value in introducing no-op commits into the history. – cmaster - reinstate monica Oct 22 '15 at 16:13
  • @cmaster I don't know anything about svn. If I understand what you're meaning, I too in general hate fast-forwards and have disabled them everywhere it's possible. But in this case they are perfect and wonderfully useful. Look, this probably measures up as an answer, there's actually very little specific advice as yet as to what to do exactly; I explain it in the answer, wait for it. – gbr Oct 22 '15 at 16:28
  • @cmaster Wait I read it wrong, you wrote `--no-ff`, did you mean that? I wrote `--ff-only` in the original comment. Do you generally use or avoid fast forwards? – gbr Oct 22 '15 at 16:31
  • @gbr I never use `--no-ff` which means that I never create a commit where a fast-forward is possible. As I see it, such a fast-forward-commit would contain no changes whatsoever, so it's worthless in my eyes. – cmaster - reinstate monica Oct 22 '15 at 16:55
  • @cmaster I think your ideas about git are a little confused. Did you mean 'merge' when you wrote 'commit' in the last comment? By the way, while writing the answer I realized that what I had in mind was not really wrong but unnecessary, but wait for it, I post you a comment when I'm done with that. – gbr Oct 22 '15 at 17:26
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/93093/discussion-between-gbr-and-cmaster). – gbr Oct 22 '15 at 17:29

2 Answers2

1

"Is it a good practice to pull master into newBranch and test before merging it back to master?"

Yes. And in this case, it makes perfect sense that the code doesn't work afterwards. After all, somebody removed some code, and you added a piece of code. The changes are not in the same locations, so there is no conflict. Git is not a compiler and is not aware of the relation between the changes, so both changes are applied, and you'll have to solve this manually.

GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • Thanks. Strangely I have never seen anyone suggesting to pull the changes from master, even though it looks like this should be a very common issue. – wittyameta Oct 22 '15 at 10:24
  • Maybe pulling first is not common, but I do that, so I can test the merge locally before bothering other people with it. After all, it's somebody elses change that is already merged vs my change which is still to be merged with the rest, so I consider it my job to make it work. But this particular issue is not that common. It doesn't happen all the time that one person removes something exactly when another person starts using that something. – GolezTrol Oct 22 '15 at 11:27
0

You can always use the git rerere to apply the merge results to all the givenm branches.

git rerere simply record the way you have resolved the conflict and then when the same conflicts appear on different branches it will simply apply the patch you created to resolve all the conflicts.

Read more

git rerere
Fix conflicts only once with git rerere

Community
  • 1
  • 1
CodeWizard
  • 128,036
  • 21
  • 144
  • 167