title: Git rebase duplicate patch detection implementation
body: <p>I have encountered an interesting issue in which I have my master trying to catch up with an upstream branch. However I want to test my master at specific points along the way so I ensure I only rebase upstream onto master at certain points.</p>
  
  <p>Assume the following state:</p>
  
  <pre><code>          --F--G--H--&gt; master
           /
          /
  ----A--B--C--D--E--I--J--&gt; upstream
  </code></pre>
  
  <p>I want first to rebase C and D and then test. So I do:</p>
  
  <pre><code>$ git checkout upstream
  $ git checkout D
  $ git checkout -b upstreamD
  $ git rebase -i master
  $ git checkout master
  $ git merge upstreamD
  </code></pre>
  
  <p>This shows me C and D to rebase. After successful rebase I have:</p>
  
  <pre><code>          --F--G--H--C--D--&gt; master
           /
          /
  ----A--B--C--D--E--I--J--&gt; upstream
               ^
           upstreamD
  </code></pre>
  
  <p>Then I removed upstream cause I didn't need it anymore while testing, etc (cause I can always get it).</p>
  
  <pre><code>$ git branch -d upstreamD
  $ git branch -d upstream
  $ git remote rm upstream
  </code></pre>
  
  <p>I do my testing and since everything is fine I go back and grab my upstream using a newly created remote and put its master in branch upstream.</p>
  
  <p>So, now I think I have something like (notice master and upstream have more commits):</p>
  
  <pre><code>          --F--G--H--C--D--K--L--&gt; master
           /
          /
  ----A--B--C--D--E--I--J--M--N--&gt; upstream
  </code></pre>
  
  <p>And I want to rebase a bit more so I execute the same procedure above:</p>
  
  <pre><code>$ git checkout upstream
  $ git checkout J
  $ git checkout -b upstreamJ
  $ git rebase -i master
  </code></pre>
  
  <p>However, now I get to rebase something like: C, E, I, J. The strange thing is that I was only expecting E, I, J. C is in master already (even if under a different SHA1, since history is different).</p>
  
  <p>In <a href="http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html" rel="nofollow">http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html</a> it says and I quote:</p>
  
  <blockquote>
    <p>If the upstream branch already contains a change you have made (e.g.,
    because you mailed a patch which was applied upstream), then that
    commit will be skipped.</p>
  </blockquote>
  
  <p>I couldn't find anywhere where it explains how git performs this skipping. How does it check that C is already in master or not, and why does it decide that C should be rebased again and D shouldn't?</p>