Using git rerere to merge known conflicts

While working on a feature branch, you probably like to merge daily or maybe more often, but often when you work on long-living feature branches, you end up in a situation where you have the same conflict occurring repeatedly.

Here, you can use git rerere which stands for reuse recorded resolution. Git rerere is not enabled by default but can be enabled with the following command:

$ git config rerere.enabled true

Tip

You can configure it globally by adding --global to the git config command.

How to do it…

Perform the following steps to merge the known conflicts:

  1. In the jgit repository folder, start by checking out a branch that tracks origin/stable-2.2:
    git checkout -b rerereExample --track origin/stable-2.2
    
  2. Now, change the maven-compiler-plugin version to something personalized such as 2.5.2 like this is in line 211. If you run git diff, you should get a result very similar to the following:
    $ git diff
    diff --git a/pom.xml b/pom.xml
    index 085e00f..d5aec17 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -208,7 +208,7 @@
    
             <plugin>
               <artifactId>maven-compiler-plugin</artifactId>
    -          <version>2.5.1</version>
    +          <version>2.5.2</version>
             </plugin>
    
             <plugin>
    
  3. Now add the file and create a commit:
    $ git add pom.xml
    $ git commit -m "Update maven-compiler-plugin to 2.5.2"
    [rerereExample d474848] Update maven-compiler-plugin to 2.5.2
     1 file changed, 1 insertion(+), 1 deletion(-)
    
  4. Store you current commit in a backup branch named rerereExample2:
    $ git branch rerereExample2
    

    Here, git branch rerereExample2 is just storing the current commit as a branch, as we need to use that for rerere example number 2.

  5. Now, we need to perform the first merge that will fail on auto merge. Then, we can solve that. After solving it, we can reuse the merge resolution to solve the same problem in the future:
    $ git merge --no-ff v3.0.2.201309041250-rc2
    A lot of output …
    Automatic merge failed; fix conflicts and then commit the result.
    
  6. As we have git rerere enabled, we can use git rerere status to see which files or paths will be recorded:
    $ git rerere status
    pom.xml
    
  7. Edit the pom.xml file and solve the merge conflict so that you can get the diff output shown as follows. You have to remove the line with 2.5.1 and the merge markers:

    Tip

    Merge markers are lines that begin with <<<<<<, >>>>>>, or ======; these lines indicate the points where Git could not perform an auto merge.

    $ git diff v3.0.2.201309041250-rc2 pom.xml
    diff --git a/pom.xml b/pom.xml
    index 60cb0c8..faa7618 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -226,7 +226,7 @@
    
             <plugin>
               <artifactId>maven-compiler-plugin</artifactId>
    -          <version>3.1</version>
    +          <version>2.5.2</version>
             </plugin>
    
             <plugin>
    
  8. Mark the merge as complete by adding pom.xml to the staging area and run git commit to finish the merge:
    $ git commit
    Recorded resolution for 'pom.xml'.
    [rerereExample 9b8725f] Merge tag 'v3.0.2.201309041250-rc2' into rerereExample
    
  9. Note the recorded resolution for the pom.xml output from Git; this will not be here without enabling git rerere. Git has recorded this resolution to this particular merge conflict and will also record how to solve this. Now, we can try and rebase the change to another branch.
  10. Start by checking out the rerereExample2 branch from our repository:
    $ git checkout rerereExample2
    Switched to branch 'rerereExample2'
    
  11. Try to rebase your change on top of the origin/stable-3.2 branch:
    $ git rebase origin/stable-3.2
    First, rewinding head to replay your work on top of it...
    Applying: Update maven-compiler-plugin to 2.5.2
    Using index info to reconstruct a base tree...
    M       pom.xml
    Falling back to patching base and 3-way merge...
    Auto-merging pom.xml
    CONFLICT (content): Merge conflict in pom.xml
    Resolved 'pom.xml' using previous resolution.
    Failed to merge in the changes.
    Patch failed at 0001 Update maven-compiler-plugin to 2.5.2
    The copy of the patch that failed is found in:
       c:/Users/Rasmus/repos/jgit/.git/rebase-apply/patch
    
    When you have resolved this problem, run "git rebase --continue".
    If you prefer to skip this patch, run "git rebase --skip" instead.
    To check out the original branch and stop rebasing, run "git rebase --abort".
    
  12. You should notice the following output:
    CONFLICT (content): Merge conflict in pom.xml
    Resolved 'pom.xml' using previous resolution
    
  13. As the merge conflict is the same in pom.xml, Git can solve the conflict in the file for you. This is very clear when you open the file and see there are no merge markers, as the resolution Git had recorded has been applied. Finish the merge by adding pom.xml and continue the rebase:
    $ git add pom.xml 
    $ git rebase --continue
    Applying: Update maven-compiler-plugin to 2.5.2
    
  14. Start Gitk to see that the commit has been rebased on top of the origin/stable-3.2 branch:
    How to do it…

You can try the same scenario with merging and it would merge the file automatically for you.

There's more...

When you merge different branches often and you are not sure which branch a specific error fix is a part of, it is actually quite easy to find out.

  1. You need to find a commit you are interested in getting this information for. Then, use the --contains flag for the git branch command:
    $ git branch --contains 06ddee1
      anotherBugFix
      lastBugFix
      master
      newBugFix
      remoteBugFix
      remoteBugFix2
      remoteOldbugFix
    * rerereExample2
    
  2. The previous command lists all the branches that have the specific commit. If you leave out the <commit> option, Git will check HEAD. So, for instance, checking out the rerereExample2 branch and executing the following command, you will see the commit is present only on that branch:
    $ git checkout rerereExample2
    Switched to branch 'rerereExample2'
    $ git branch -a --contains
    * rerereExample2
    

    Tip

    The -a option indicates that you wish to check all the remote branches as well. If you leave this out, it will check only local branches.

    However, as you can see, our commit is not on any remote branch as the commit has just been created locally and has not been pushed to any remotes yet.

    Tip

    You can use tags, branch names, or commit hashes while using the git branch -a --contains command.

  3. Let's try to see the branches where the v2.3.0.201302130906 tag is present:
    $ git branch -a --contains v2.3.0.201302130906
      anotherBugFix
      lastBugFix
      master
      newBugFix
      remoteBugFix
      remoteBugFix2
      remoteOldbugFix
      remotePartlyMerge
    * rerereExample2
      remotes/origin/HEAD -> origin/master
      remotes/origin/master
      remotes/origin/stable-2.3
      remotes/origin/stable-3.0
      remotes/origin/stable-3.1
      remotes/origin/stable-3.2
    

    That tag is in quite a lot of branches.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset