title: Revert reversion in git with branch, and readably
body: <p>This question is about how to revert a revert in git, and to do it in a way that makes sense to future readers and never puts the repository in a bad state.</p>
  
  <p>My git repository had for a while HEAD (on master) pointing to a very Good commit:</p>
  
  <pre><code>HEAD
     |
     G
  </code></pre>
  
  <p>And then some development happened, on branches, and those commits looked good, so they got merged into master.</p>
  
  <pre><code>               HEAD
                    |
  G -- C1 -- ... -- Ck
  </code></pre>
  
  <p>But then we found a subtle bug somewhere in those commits.  It was clear that we could just roll back to G and then take some time to think this through.  So we did that.  Commit R is a revert that came about by typing something like</p>
  
  <pre><code>$ git checkout -b B
  $ git checkout master
  $ git revert --no-commit G..HEAD
  </code></pre>
  
  <p>That put my repository in a state like this, where being at R and being at G look the same except for history:</p>
  
  <pre><code>                     HEAD
                          |
  G -- C1 -- ... -- Ck -- R
                    |
                    B
  </code></pre>
  
  <p>Then some more development happened: some emergency commits on master (E1, E2) and some additional development on B (D1, ..., Dj) that corrected the problems we had at Ck and continued some other important work.  Now the repository looks like this:</p>
  
  <pre><code>                                HEAD
                                     |
  G -- C1 -- ... -- Ck -- R -- E1 -- E2
                    |
                     \ -- D1 -- ... -- Dj
                                       |
                                       B
  </code></pre>
  
  <p>Good, it's only been a day, but it's time to put things back in order.  What I want is a repository that looks something like this:</p>
  
  <pre><code>                                                           HEAD
                                                                |
  G -- C1 -- ... -- Ck -- R -- E1 -- E2 -- (-R) -- D1 -- ... -- Dj
  </code></pre>
  
  <p>where (-R) is a commit that undoes R.  And I'd like to do this in some reasonable way so that it's clear to future readers what has happened.</p>
  
  <p>The best way I've thought of to do this is this:</p>
  
  <pre><code>$ git checkout B
  $ git rebase master
  $ git revert R
  # Use the rebase -i to change ordering so that R happens before D1:
  $ git rebase -i master
  $ git checkout master
  $ git merge --ff-only B
  $ git push
  </code></pre>
  
  <p>I'm reasonably sure that will work, but I feel like I'm missing something.  Any suggestions to help me improve my git-fu?</p>