title: How to perform a three-way diff in Git without merging?
body: <p>I want to perform a three-way diff between two git branches with a common merge base, and view it with kdiff3.</p>
  
  <p>I've found lots of guidance on SO (and a few very similar questions (<a href="https://stackoverflow.com/q/26301307/3380131">1</a>, <a href="https://stackoverflow.com/q/3635788/3380131">2</a>, <a href="https://stackoverflow.com/q/33440597/3380131">3</a>) ) but I haven't found a direct answer. Notably, a comment on <a href="https://stackoverflow.com/a/5818279/3380131">this answer</a> implies that what I want is possible, but it didn't work for me. Hopefully that user might chime in here :)</p>
  
  <p>For background, when I perform merges I use a "diff3" conflict style:</p>
  
  <p><code>git config --global merge.conflictstyle diff3</code></p>
  
  <p>And I have <code>git mergetool</code> configured to use kdiff3.</p>
  
  <p>When resolving merge conflicts this shows me four files:</p>
  
  <ol>
  <li>The current branch's file ($LOCAL)</li>
  <li>The other branch's file ($REMOTE)</li>
  <li>The file which is the common ancestor of the two branches ($BASE)</li>
  <li>The merged output file ($MERGED)</li>
  </ol>
  
  <p>However, <code>git difftool</code> only will pull up the two branch tips.  I want to see the base file, too.  <strong>To be clear, I want to be able to perform this diff <em>before</em> merging, including on files without merge conflicts</strong>. (<code>git mergetool</code> only shows the three-way diffs if there are conflicts).</p>
  
  <hr>
  
  <p><strong>Partial Solution #1:</strong></p>
  
  <p>With an individual file, I can export the three versions and manually call the diff:</p>
  
  <pre><code>git show local_branch:filename &gt; localfile
  git show remote_branch:filename &gt; remotefile
  git show `git merge-base local_branch remote_branch`:filename &gt; basefile
  
  {kdiff3_path}/kdiff3.exe --L1 "Base" --L2 "Local" --L3 "Remote" -o "outputfile" basefile localfile remotefile &amp;
  </code></pre>
  
  <p>There are two problems with this:</p>
  
  <ol>
  <li>I want it to work for the whole project, not just a specific file.</li>
  <li>This is ugly! I can script it, but I hope there's a much cleaner way using standard git processes.</li>
  </ol>
  
  <hr>
  
  <p><strong>Partial Solution #2:</strong></p>
  
  <p><sub>Thanks to <a href="https://stackoverflow.com/a/5091756/3380131">this answer</a> and <a href="https://stackoverflow.com/questions/5074452/git-how-to-force-merge-conflict-and-manual-merge-on-selected-file#comment40997817_5091756">comment</a> for the inspiration.</sub></p>
  
  <p>Create a custom merge driver that always returns "false", which creates a conflicted merge state without actually doing any auto-merging.  Then perform the diff using <code>git mergetool</code>.  Then abort the merge when you're finished.</p>
  
  <ol>
  <li><p>Add to <code>.git/config</code>:</p>
  
  <pre><code>[merge "assert_conflict_states"]
      name = assert_conflict_states
      driver = false
  </code></pre></li>
  <li><p>Create (or append to) <code>.git/info/attributes</code> to cause all merges to use the new driver:</p>
  
  <pre><code>* merge=assert_conflict_states
  </code></pre></li>
  <li><p>Perform the merge, which now doesn't do any automerging.</p></li>
  <li><p>Do the diff.  In my case: <code>git mergetool</code> which brings up the kdiff3 three-way merge.</p></li>
  <li><p>When done, abort the merge: <code>git merge --abort</code>.</p></li>
  <li><p>Undo step #2.</p></li>
  </ol>
  
  <p>This would (sorta) work except that kdiff3 performs an automerge when called, so I <strong>still can't</strong> see the pre-merged diffs.  I can fix this, though, by changing Git's stock kdiff3 driver file (<code>.../git-core/mergetools/kdiff3</code> by removing the <code>--auto</code> switch.</p>
  
  <p>Even so, this has the following show-stopping problems:</p>
  
  <ol>
  <li><em>This only works when both files have changed!</em> In the case where only one file changed, the updated file replaces the older file and the merge is never called.</li>
  <li>I have to modify the Git kdiff3 driver, which isn't portable at all.</li>
  <li>I have to modify <code>attributes</code> before and after doing the diff.</li>
  <li>And, of course, I was hoping to do this without merging :)</li>
  </ol>
  
  <hr>
  
  <p><strong>Information for the bounty:</strong></p>
  
  <p>According to answers given, this isn't possible with standard Git. So now I'm looking for a more out-of-the-box solution: How can I tweak Git to make this happen?</p>
  
  <p>Here's one lead: Apparently, if only one of the three files has changed, this newer file is used in the merge result without actually calling the merge driver. This means that my custom "conflict-creating" merge driver is never called in this case.  If it was, then my "Partial Solution #2" would actually function.</p>
  
  <p>Could this behavior be changed by tweaking files or configurations?  Or perhaps there's a way to create a custom diff driver?  I'm not ready to start playing with the Git source code...</p>
  
  <p>Any clever ideas?</p>