-2

Look at the following example:

git log --all --oneline --graph

*   fc89735 (HEAD -> master) Merge branch 'feature'
|\
| * 034f1de (feature) modify the calculate function
| * 57aaea2 added another calculation function
* | 382de62 just add a comment
|/
* 303a4ed initial commit

Here is what I did:

1. Initial commit (feature.php) (303a4ed):

<?php
function calculate($a) {
    return ($a + 500) * 0.4 + 10;
}

2. I've created a branch FEATURE where I just added another function, a feature... (57aaea2):

<?php
function calculate($a) {
    return ($a + 500) * 0.4 + 10;
}

function anotherCaluclation($b) {
    return ($b - 500) * 0.2 + 5;
}

3. I've modified the calculation in the calculate function to fit the requirements of the FEATURE (034f1de):

<?php
function calculate($a) {
    $a += 1243028;
    return ($a + 500) * 0.4 + 10;
}

function anotherCaluclation($b) {
    return ($b - 500) * 0.2 + 5;
}

4. In MASTER I've added a comment to the calculate function (382de62)

<?php
//a crazy calculation function calculate($a) {
    return ($a + 500) * 0.4 + 10;
}

5. The Feature is finished and I want to intergate it. At this time MASTER and FEATURE have diverged, a fast-forward merge is impossible. In FEATURE the calculation was heavily modified which is correct for the branch, but incorrect for the rest of the project, including MASTER. However, imagine, the problem is unknown and I'm doing a git merge, merging FEATURE into MASTER (fc89735):

git merge feature

I get the following log:

Auto-merging feature.php
Merge made by the 'recursive' strategy.
 feature.php | 5 +++++
 1 file changed, 5 insertions(+)

And this is the resulting content:

<?php
//a crazy calculation function
function calculate($a) {
    $a += 1243028;
    return ($a + 500) * 0.4 + 10;
}

function anotherCaluclation($b) {
    return ($b - 500) * 0.2 + 5;
}

As you can see: The added line $a += 1243028; from the FEATURE branch (which is correct for that branch but not for the rest of the project) was merged into MASTER.

That means, from this moment on there is a bug in the project, introduced by GITs auto-merge.

How do you deal with that sort of problem? What are possible strategies? From this example I'd plead: All automatic merge actions need to be reviewed manually!

Is there a way to force a manual review of all changes when doing a merge?

musicman
  • 475
  • 6
  • 15
  • 5
    If you don't want code from feature in master, you don't merge it. You merge a branch when you want all of the changes from that branch ("correct for that branch but not for..." makes no sense). I see no issues with what has happened here. – crashmstr Aug 28 '17 at 13:47
  • 1
    _Anything_ is dangerous if you don't understand it. Take the time to learn how Git works internally; it is very helpful (much more so than with most other tools) and surprisingly simple. – Chris Aug 28 '17 at 13:51
  • 1
    The bug was not introduced by Git's auto-merge. The bug was introduced by the person who decided to merge code that was "correct for that branch but not for the rest of the project" into master. – jwodder Aug 28 '17 at 13:53
  • 1
    maybe change this question from 'is git merge dangerous' to something like 'how can I force a manual review of all changes in a merge' – Scott Newson Aug 28 '17 at 13:54
  • 1
    Also, once a merge is complete, *and before the changes are pushed*, it is a must for the developer to review *all* the changes introduced and make sure that code compiles, tests pass, etc. Another way of doing this is with pull requests to complete merges and/or continuous integration that can run tests and fail a pull request if things don't run. – crashmstr Aug 28 '17 at 13:57
  • @ScottNewson Yes, you got the problem. I've changed the question – musicman Aug 28 '17 at 14:01
  • @crashmstr To clarify that: Let's say the person who wrote the feature forgot to take care of that one problematic line and is going to merge. GIT just does that and the bug would be out there. That's why I would like to have a final manual check when merging. At the merge process I want to review all changes which will happen (I suppose with the mergetool) – musicman Aug 28 '17 at 14:15
  • @musicman then require a pull request to be approved before the merge can be completed (i.e. no one can merge to master directly and must create a pull request to get branches merged into it). Many Git hosts provide for this. – crashmstr Aug 28 '17 at 14:17
  • @crashmstr The question is about a local repository and I'm looking for a git solution, not a host-only solution. – musicman Aug 28 '17 at 14:22
  • @musicman then on a "local repository" it is only you, and you don't want you to cause you problems? Or do you mean on an internal network (then it is not just local)? If it is on an internal network, *that* server can have software running that can do pull requests (and pull requests are the normal way of requiring approval for code changes with Git). – crashmstr Aug 28 '17 at 14:28
  • @crashmstr yes, it's only me. – musicman Aug 28 '17 at 14:29
  • @musicman you can always easily undo a merge if it has not been pushed to any remote, so you can merge, make sure everything is good, then move on. – crashmstr Aug 28 '17 at 14:31

2 Answers2

1

After doing further research, I guess at the moment the best solution for this problem is following:

(* HEAD is a reference to the latest MASTER commit)

  1. git merge --no-commit feature Do the merge, but don't commit, so the changes can be reviewed.

Now it would be nice to do a threeway-diff with the working directory, HEAD and FEATURE. But that's unfortunatley not possible with GIT at the moment. So:

  1. git difftool HEAD Compare Working Directory with the last commit of the MASTER branch, correct errors if necessary
  2. git difftool FEATURE Compare Working Directory with the last commit of the FEATURE branch, correct errors if necessary
  3. Commit the (corrected) merge
musicman
  • 475
  • 6
  • 15
0

Look into creating a custom merge driver for git. Here is an example: https://stackoverflow.com/a/5091756/346912

Basically, create a custom merge script that always fails the merge and then tell git to use that script for all files, or just for a specific set of files. Then the merge will always fail, and you can manually merge everything.

Scott Newson
  • 2,415
  • 1
  • 22
  • 25