فهرست منبع

Add a family of git-commands to assist with the management of multiple CLs/branches.

git-rebase-update - ensure all branches are up to date
git-new-branch - create branches
git-rename-branch - rename a branch while preserving parentage relationships
git-reparent-branch - change the parent of a branch, including rebasing it correctly onto that new parent.
git-squash-branch - collapse a branch into a single commit
git-upstream-diff - show the diff between the current branch and it's upstream branch
git-mark-merge-base - explicitly set what you want the above tools to consider the merge-base for the current branch.

R=agable@chromium.org, hinoka@chromium.org, stip@chromium.org, szager@chromium.org
BUG=261738

Review URL: https://codereview.chromium.org/184253003

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@259520 0039d316-1c4b-4281-b951-d872f2087c98
iannucci@chromium.org 11 سال پیش
والد
کامیت
c050a5b2be
77فایلهای تغییر یافته به همراه9416 افزوده شده و 316 حذف شده
  1. 57 1
      docs/html/depot_tools.html
  2. 1 1
      docs/html/git-freeze.html
  3. 16 4
      docs/html/git-map-branches.html
  4. 15 10
      docs/html/git-map.html
  5. 826 0
      docs/html/git-mark-merge-base.html
  6. 13 1
      docs/html/git-nav-downstream.html
  7. 13 1
      docs/html/git-nav-upstream.html
  8. 919 0
      docs/html/git-new-branch.html
  9. 937 0
      docs/html/git-rebase-update.html
  10. 794 0
      docs/html/git-rename-branch.html
  11. 847 0
      docs/html/git-reparent-branch.html
  12. 873 0
      docs/html/git-squash-branch.html
  13. 1 1
      docs/html/git-thaw.html
  14. 887 0
      docs/html/git-upstream-diff.html
  15. 38 3
      docs/man1/depot_tools.1
  16. 3 3
      docs/man1/git-freeze.1
  17. 18 3
      docs/man1/git-map-branches.1
  18. 21 9
      docs/man1/git-map.1
  19. 69 0
      docs/man1/git-mark-merge-base.1
  20. 18 3
      docs/man1/git-nav-downstream.1
  21. 18 3
      docs/man1/git-nav-upstream.1
  22. 150 0
      docs/man1/git-new-branch.1
  23. 165 0
      docs/man1/git-rebase-update.1
  24. 53 0
      docs/man1/git-rename-branch.1
  25. 93 0
      docs/man1/git-reparent-branch.1
  26. 117 0
      docs/man1/git-squash-branch.1
  27. 3 3
      docs/man1/git-thaw.1
  28. 119 0
      docs/man1/git-upstream-diff.1
  29. 5 0
      docs/src/_aliases.txt
  30. 1 1
      docs/src/_footer.txt
  31. 1 1
      docs/src/_git-map-branches_desc.helper.txt
  32. 1 1
      docs/src/_git-map_desc.helper.txt
  33. 1 0
      docs/src/_git-mark-merge-base_desc.helper.txt
  34. 1 0
      docs/src/_git-new-branch_desc.helper.txt
  35. 1 0
      docs/src/_git-rebase-update_desc.helper.txt
  36. 1 0
      docs/src/_git-rename-branch_desc.helper.txt
  37. 1 0
      docs/src/_git-reparent-branch_desc.helper.txt
  38. 1 0
      docs/src/_git-squash-branch_desc.helper.txt
  39. 1 0
      docs/src/_git-upstream-diff_desc.helper.txt
  40. 1 1
      docs/src/depot_tools.txt
  41. 1 1
      docs/src/git-freeze.txt
  42. 11 4
      docs/src/git-map-branches.txt
  43. 12 11
      docs/src/git-map.txt
  44. 46 0
      docs/src/git-mark-merge-base.txt
  45. 9 1
      docs/src/git-nav-downstream.txt
  46. 8 1
      docs/src/git-nav-upstream.txt
  47. 113 0
      docs/src/git-new-branch.txt
  48. 130 0
      docs/src/git-rebase-update.txt
  49. 28 0
      docs/src/git-rename-branch.txt
  50. 61 0
      docs/src/git-reparent-branch.txt
  51. 92 0
      docs/src/git-squash-branch.txt
  52. 1 1
      docs/src/git-thaw.txt
  53. 81 0
      docs/src/git-upstream-diff.txt
  54. 8 0
      git-mark-merge-base
  55. 9 0
      git-new-branch
  56. 9 0
      git-rebase-update
  57. 9 0
      git-rename-branch
  58. 10 0
      git-reparent-branch
  59. 8 0
      git-squash-branch
  60. 9 0
      git-upstream-diff
  61. 316 51
      git_common.py
  62. 10 50
      git_freezer.py
  63. 23 0
      git_map.py
  64. 19 8
      git_map_branches.py
  65. 68 0
      git_mark_merge_base.py
  66. 1 0
      git_nav_downstream.py
  67. 53 0
      git_new_branch.py
  68. 245 0
      git_rebase_update.py
  69. 50 0
      git_rename_branch.py
  70. 74 0
      git_reparent_branch.py
  71. 20 0
      git_squash_branch.py
  72. 36 0
      git_upstream_diff.py
  73. 112 29
      testing_support/git_test_utils.py
  74. 296 9
      tests/git_common_test.py
  75. 0 99
      tests/git_freezer_test.py
  76. 1 1
      tests/git_number_test.py
  77. 337 0
      tests/git_rebase_update_test.py

+ 57 - 1
docs/html/depot_tools.html

@@ -799,6 +799,14 @@ Display history of all branches in a colorized terminal format.
 </dl></div>
 <div class="dlist"><dl>
 <dt class="hdlist1">
+<a href="git-mark-merge-base.html">git-mark-merge-base(1)</a>
+</dt>
+<dd>
+<p>
+Manually interact with depot_tools' merge-base markers.
+</p>
+</dd>
+<dt class="hdlist1">
 <a href="git-nav-downstream.html">git-nav-downstream(1)</a>
 </dt>
 <dd>
@@ -815,6 +823,46 @@ Checkout the upstream branch of the currently checked out branch.
 </p>
 </dd>
 <dt class="hdlist1">
+<a href="git-new-branch.html">git-new-branch(1)</a>
+</dt>
+<dd>
+<p>
+Create a new branch with correct tracking information.
+</p>
+</dd>
+<dt class="hdlist1">
+<a href="git-rebase-update.html">git-rebase-update(1)</a>
+</dt>
+<dd>
+<p>
+Updates all branches to have the latest changes from their upstreams.
+</p>
+</dd>
+<dt class="hdlist1">
+<a href="git-rename-branch.html">git-rename-branch(1)</a>
+</dt>
+<dd>
+<p>
+Rename a branch and correctly preserve all downstream relationships.
+</p>
+</dd>
+<dt class="hdlist1">
+<a href="git-reparent-branch.html">git-reparent-branch(1)</a>
+</dt>
+<dd>
+<p>
+Alter the parentage (upstream) for the current branch.
+</p>
+</dd>
+<dt class="hdlist1">
+<a href="git-squash-branch.html">git-squash-branch(1)</a>
+</dt>
+<dd>
+<p>
+Takes all commits in a single branch and replaces them with a single commit.
+</p>
+</dd>
+<dt class="hdlist1">
 <a href="git-thaw.html">git-thaw(1)</a>
 </dt>
 <dd>
@@ -822,6 +870,14 @@ Checkout the upstream branch of the currently checked out branch.
 Un-freeze all changes on a frozen branch.
 </p>
 </dd>
+<dt class="hdlist1">
+<a href="git-upstream-diff.html">git-upstream-diff(1)</a>
+</dt>
+<dd>
+<p>
+Print a diff of the current branch, compared to its upstream.
+</p>
+</dd>
 </dl></div>
 </div>
 </div>
@@ -829,7 +885,7 @@ Un-freeze all changes on a frozen branch.
 <div id="footnotes"><hr /></div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2014-03-14 13:12:40 PDT
+Last updated 2014-03-25 15:09:11 PDT
 </div>
 </div>
 </body>

+ 1 - 1
docs/html/git-freeze.html

@@ -841,7 +841,7 @@ from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">
 <div id="footnotes"><hr /></div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2014-03-14 14:01:10 PDT
+Last updated 2014-03-25 15:09:11 PDT
 </div>
 </div>
 </body>

+ 16 - 4
docs/html/git-map-branches.html

@@ -773,7 +773,7 @@ Current branch is <span class="aqua">cyan</span>.
 <li>
 <p>
 The branch which will be modified with git-commit is denoted with an asterisk
-         (<code>*</code>) after the name.
+   (<code>*</code>) after the name.
 </p>
 </li>
 </ul></div>
@@ -796,8 +796,8 @@ Remote branches are <span class="red">red</span> (usually, the root of all other
 <li>
 <p>
 Branches which have this as their parent are usually misconfigured, and
-         should be assigned a parent by checking out the branch and running git branch
-         --set-upstream-to=&lt;correct parent branch&gt;.
+   should be assigned a parent by checking out the branch and running git branch
+   --set-upstream-to=&lt;correct parent branch&gt;.
 </p>
 </li>
 </ul></div>
@@ -834,6 +834,18 @@ assuming that the <code>frozen_changes</code> branch was currently checked out,
 </div>
 </div>
 <div class="sect1">
+<h2 id="_suggested_aliases">SUGGESTED ALIASES</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Some common short-hand aliases. Feel free to add these to your <em>~/.gitconfig</em>
+file.</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>[alias]
+  git bmap = map-branches</code></pre>
+</div></div>
+</div>
+</div>
+<div class="sect1">
 <h2 id="_see_also">SEE ALSO</h2>
 <div class="sectionbody">
 <div class="paragraph"><p><a href="git-map.html">git-map(1)</a></p></div>
@@ -851,7 +863,7 @@ from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">
 <div id="footnotes"><hr /></div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2014-03-14 14:01:10 PDT
+Last updated 2014-03-25 15:09:11 PDT
 </div>
 </div>
 </body>

+ 15 - 10
docs/html/git-map.html

@@ -787,6 +787,11 @@ Tags are <span class="fuchsia">magenta</span>.
 </li>
 <li>
 <p>
+Merge Base markers are <span class="black-background white">white</span>.
+</p>
+</li>
+<li>
+<p>
 The currently checked out commit is highlighted with a <span class="yellow blue-background">blue background</span>.
 </p>
 </li>
@@ -804,11 +809,11 @@ windows.</p></div>
 </dt>
 <dd>
 <p>
-        Extra parameters to pass to the internal <a href="git-log.html">git-log(1)</a> invocation. This
-        can be used to restrict what refs <em>git map</em> operates on, etc.
+  Extra parameters to pass to the internal <a href="git-log.html">git-log(1)</a> invocation. This
+  can be used to restrict what refs <em>git map</em> operates on, etc.
 </p>
 <div class="paragraph"><p>If you run git map with a series of fixed arguments frequently, you can use
-the depot_tools.map_extra configuration variable to pre-set arguments (See
+the depot-tools.map-extra configuration variable to pre-set arguments (See
 <code>CONFIGURATION VARIABLES</code>)</p></div>
 </dd>
 </dl></div>
@@ -818,10 +823,10 @@ the depot_tools.map_extra configuration variable to pre-set arguments (See
 <h2 id="_configuration_variables">CONFIGURATION VARIABLES</h2>
 <div class="sectionbody">
 <div class="sect2">
-<h3 id="_depot_tools_map_extra">depot_tools.map_extra</h3>
-<div class="paragraph"><p>Each value of the <em>depot_tools.map_extra</em> config variable is applied as an
+<h3 id="_depot_tools_map_extra">depot-tools.map-extra</h3>
+<div class="paragraph"><p>Each value of the <em>depot-tools.map-extra</em> config variable is applied as an
 additional argument to <code>git log</code> during the execution of git map. If you wish to
-configure this, use git <code>config --add depot_tools.map_extra &lt;value&gt;</code> to do so.</p></div>
+configure this, use git <code>config --add depot-tools.map-extra &lt;value&gt;</code> to do so.</p></div>
 </div>
 </div>
 </div>
@@ -835,18 +840,18 @@ configure this, use git <code>config --add depot_tools.map_extra &lt;value&gt;</
 <span class="white blue-background">*</span>&#8203;<strong><span class="blue-background red"> 7dcfe47       </span></strong> <span class="green">(</span>&#8203;<strong><span class="aqua">frozen_changes</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-12</span> ~ FREEZE.unindexed
 * <strong><span class="red">4b0c180</span></strong>        <span class="yellow">2014-03-12</span> ~ modfile
 * <strong><span class="red">59a7cca</span></strong>        <span class="yellow">2014-03-12</span> ~ a deleted file
-* <strong><span class="red">6bec695</span></strong>        <span class="green">(</span>&#8203;<span class="red">origin/master</span>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Add neat feature
+* <strong><span class="red">6bec695</span></strong>        <span class="green">(</span>&#8203;<span class="red">origin/master</span>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Add neat feature    <strong><span class="white">&lt;(frozen_changes)</span></strong>
 * <strong><span class="red">d15a38a</span></strong>        <span class="yellow">2014-03-11</span> ~ Epic README update
 * <strong><span class="red">d559894</span></strong>        <span class="green">(</span>&#8203;<strong><span class="lime">master</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Important upstream change
 <span class="red">|</span> * <strong><span class="red">9c311fd</span></strong>      <span class="green">(</span>&#8203;<strong><span class="lime">cool_feature</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Respond to CL comments
 <span class="red">|</span> <span class="green">|</span> * <strong><span class="red">2a1eeb2</span></strong>    <span class="green">(</span>&#8203;<strong><span class="lime">subfeature</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ integrate with CoolService
 <span class="red">|</span> <span class="green">|</span> * <strong><span class="red">d777af6</span></strong>    <span class="yellow">2014-03-11</span> ~ slick commenting action
 <span class="red">|</span> <span class="green">|/</span>
-<span class="red">|</span> * <strong><span class="red">265803a</span></strong>      <span class="yellow">2014-03-11</span> ~ another improvement
+<span class="red">|</span> * <strong><span class="red">265803a</span></strong>      <span class="yellow">2014-03-11</span> ~ another improvement    <strong><span class="white">&lt;(subfeature)</span></strong>
 <span class="red">|</span> * <strong><span class="red">6d831ac</span></strong>      <span class="green">(</span>&#8203;<strong><span class="fuchsia">spleen_tag</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Refactor spleen
 <span class="red">|</span> * <strong><span class="red">82e74ab</span></strong>      <span class="yellow">2014-03-11</span> ~ Add widget
 <span class="red">|/</span>
-* <strong><span class="red">d08c5b3</span></strong>        <span class="green">(</span>&#8203;<strong><span class="lime">bogus_noparent</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Wonderful beginnings</code></pre>
+* <strong><span class="red">d08c5b3</span></strong>        <span class="green">(</span>&#8203;<strong><span class="lime">bogus_noparent</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Wonderful beginnings    <strong><span class="white">&lt;(cool_feature)</span></strong></code></pre>
 </div></div>
 <div class="paragraph"><p>As you can see, the structure of the commit history is visible, particularly
 what the parents of each commit are.  In order to see the <em>upstream</em>
@@ -872,7 +877,7 @@ from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">
 <div id="footnotes"><hr /></div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2014-03-14 14:01:55 PDT
+Last updated 2014-03-25 15:09:11 PDT
 </div>
 </div>
 </body>

+ 826 - 0
docs/html/git-mark-merge-base.html

@@ -0,0 +1,826 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.9" />
+<title>git-mark-merge-base(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+  font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+  font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+  margin: 1em 5% 1em 5%;
+}
+
+a {
+  color: blue;
+  text-decoration: underline;
+}
+a:visited {
+  color: fuchsia;
+}
+
+em {
+  font-style: italic;
+  color: navy;
+}
+
+strong {
+  font-weight: bold;
+  color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  color: #527bbd;
+  margin-top: 1.2em;
+  margin-bottom: 0.5em;
+  line-height: 1.3;
+}
+
+h1, h2, h3 {
+  border-bottom: 2px solid silver;
+}
+h2 {
+  padding-top: 0.5em;
+}
+h3 {
+  float: left;
+}
+h3 + * {
+  clear: left;
+}
+h5 {
+  font-size: 1.0em;
+}
+
+div.sectionbody {
+  margin-left: 0;
+}
+
+hr {
+  border: 1px solid silver;
+}
+
+p {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+  margin-top: 0;
+}
+ul > li     { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+  font-family: "Courier New", Courier, monospace;
+  font-size: inherit;
+  color: navy;
+  padding: 0;
+  margin: 0;
+}
+pre {
+  white-space: pre-wrap;
+}
+
+#author {
+  color: #527bbd;
+  font-weight: bold;
+  font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+  font-size: small;
+  border-top: 2px solid silver;
+  padding-top: 0.5em;
+  margin-top: 4.0em;
+}
+#footer-text {
+  float: left;
+  padding-bottom: 0.5em;
+}
+#footer-badges {
+  float: right;
+  padding-bottom: 0.5em;
+}
+
+#preamble {
+  margin-top: 1.5em;
+  margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.admonitionblock {
+  margin-top: 2.0em;
+  margin-bottom: 2.0em;
+  margin-right: 10%;
+  color: #606060;
+}
+
+div.content { /* Block element content. */
+  padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+  color: #527bbd;
+  font-weight: bold;
+  text-align: left;
+  margin-top: 1.0em;
+  margin-bottom: 0.5em;
+}
+div.title + * {
+  margin-top: 0;
+}
+
+td div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content + div.title {
+  margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+  background: #ffffee;
+  border: 1px solid #dddddd;
+  border-left: 4px solid #f0f0f0;
+  padding: 0.5em;
+}
+
+div.listingblock > div.content {
+  border: 1px solid #dddddd;
+  border-left: 5px solid #f0f0f0;
+  background: #f8f8f8;
+  padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+  padding-left: 1.0em;
+  margin-left: 1.0em;
+  margin-right: 10%;
+  border-left: 5px solid #f0f0f0;
+  color: #888;
+}
+
+div.quoteblock > div.attribution {
+  padding-top: 0.5em;
+  text-align: right;
+}
+
+div.verseblock > pre.content {
+  font-family: inherit;
+  font-size: inherit;
+}
+div.verseblock > div.attribution {
+  padding-top: 0.75em;
+  text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+  text-align: left;
+}
+
+div.admonitionblock .icon {
+  vertical-align: top;
+  font-size: 1.1em;
+  font-weight: bold;
+  text-decoration: underline;
+  color: #527bbd;
+  padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+  padding-left: 0.5em;
+  border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+  border-left: 3px solid #dddddd;
+  padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+dt {
+  margin-top: 0.5em;
+  margin-bottom: 0;
+  font-style: normal;
+  color: navy;
+}
+dd > *:first-child {
+  margin-top: 0.1em;
+}
+
+ul, ol {
+    list-style-position: outside;
+}
+ol.arabic {
+  list-style-type: decimal;
+}
+ol.loweralpha {
+  list-style-type: lower-alpha;
+}
+ol.upperalpha {
+  list-style-type: upper-alpha;
+}
+ol.lowerroman {
+  list-style-type: lower-roman;
+}
+ol.upperroman {
+  list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+  margin-top: 0.1em;
+  margin-bottom: 0.1em;
+}
+
+tfoot {
+  font-weight: bold;
+}
+td > div.verse {
+  white-space: pre;
+}
+
+div.hdlist {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+div.hdlist tr {
+  padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+  font-weight: bold;
+}
+td.hdlist1 {
+  vertical-align: top;
+  font-style: normal;
+  padding-right: 0.8em;
+  color: navy;
+}
+td.hdlist2 {
+  vertical-align: top;
+}
+div.hdlist.compact tr {
+  margin: 0;
+  padding-bottom: 0;
+}
+
+.comment {
+  background: yellow;
+}
+
+.footnote, .footnoteref {
+  font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+  vertical-align: super;
+}
+
+#footnotes {
+  margin: 20px 0 20px 0;
+  padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+  margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+  border: none;
+  border-top: 1px solid silver;
+  height: 1px;
+  text-align: left;
+  margin-left: 0;
+  width: 20%;
+  min-width: 100px;
+}
+
+div.colist td {
+  padding-right: 0.5em;
+  padding-bottom: 0.3em;
+  vertical-align: top;
+}
+div.colist td img {
+  margin-top: 0.3em;
+}
+
+@media print {
+  #footer-badges { display: none; }
+}
+
+#toc {
+  margin-bottom: 2.5em;
+}
+
+#toctitle {
+  color: #527bbd;
+  font-size: 1.1em;
+  font-weight: bold;
+  margin-top: 1.0em;
+  margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+div.toclevel2 {
+  margin-left: 2em;
+  font-size: 0.9em;
+}
+div.toclevel3 {
+  margin-left: 4em;
+  font-size: 0.9em;
+}
+div.toclevel4 {
+  margin-left: 6em;
+  font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.tableblock > table {
+  border: 3px solid #527bbd;
+}
+thead, p.table.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.table {
+  margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+  border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+  border-left-style: none;
+  border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+  border-top-style: none;
+  border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.tableblock {
+  margin-top: 0;
+}
+table.tableblock {
+  border-width: 3px;
+  border-spacing: 0px;
+  border-style: solid;
+  border-color: #527bbd;
+  border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+  border-width: 1px;
+  padding: 4px;
+  border-style: solid;
+  border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+  border-left-style: hidden;
+  border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+  border-top-style: hidden;
+  border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+  border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+  text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+  text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+  text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+  vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+  vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+  vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+  padding-top: 0.5em;
+  padding-bottom: 0.5em;
+  border-top: 2px solid silver;
+  border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+  border-style: none;
+}
+body.manpage div.sectionbody {
+  margin-left: 3em;
+}
+
+@media print {
+  body.manpage div#toc { display: none; }
+}
+
+
+div.listingblock > div.content {
+  background: rgb(28, 28, 28);
+}
+
+div.listingblock > div > pre > code {
+  color: rgb(187, 187, 187);
+}
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = {  // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+  function getText(el) {
+    var text = "";
+    for (var i = el.firstChild; i != null; i = i.nextSibling) {
+      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+        text += i.data;
+      else if (i.firstChild != null)
+        text += getText(i);
+    }
+    return text;
+  }
+
+  function TocEntry(el, text, toclevel) {
+    this.element = el;
+    this.text = text;
+    this.toclevel = toclevel;
+  }
+
+  function tocEntries(el, toclevels) {
+    var result = new Array;
+    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+    // Function that scans the DOM tree for header elements (the DOM2
+    // nodeIterator API would be a better technique but not supported by all
+    // browsers).
+    var iterate = function (el) {
+      for (var i = el.firstChild; i != null; i = i.nextSibling) {
+        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+          var mo = re.exec(i.tagName);
+          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+          }
+          iterate(i);
+        }
+      }
+    }
+    iterate(el);
+    return result;
+  }
+
+  var toc = document.getElementById("toc");
+  if (!toc) {
+    return;
+  }
+
+  // Delete existing TOC entries in case we're reloading the TOC.
+  var tocEntriesToRemove = [];
+  var i;
+  for (i = 0; i < toc.childNodes.length; i++) {
+    var entry = toc.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div'
+     && entry.getAttribute("class")
+     && entry.getAttribute("class").match(/^toclevel/))
+      tocEntriesToRemove.push(entry);
+  }
+  for (i = 0; i < tocEntriesToRemove.length; i++) {
+    toc.removeChild(tocEntriesToRemove[i]);
+  }
+
+  // Rebuild TOC entries.
+  var entries = tocEntries(document.getElementById("content"), toclevels);
+  for (var i = 0; i < entries.length; ++i) {
+    var entry = entries[i];
+    if (entry.element.id == "")
+      entry.element.id = "_toc_" + i;
+    var a = document.createElement("a");
+    a.href = "#" + entry.element.id;
+    a.appendChild(document.createTextNode(entry.text));
+    var div = document.createElement("div");
+    div.appendChild(a);
+    div.className = "toclevel" + entry.toclevel;
+    toc.appendChild(div);
+  }
+  if (entries.length == 0)
+    toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+  // Delete existing footnote entries in case we're reloading the footnodes.
+  var i;
+  var noteholder = document.getElementById("footnotes");
+  if (!noteholder) {
+    return;
+  }
+  var entriesToRemove = [];
+  for (i = 0; i < noteholder.childNodes.length; i++) {
+    var entry = noteholder.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+      entriesToRemove.push(entry);
+  }
+  for (i = 0; i < entriesToRemove.length; i++) {
+    noteholder.removeChild(entriesToRemove[i]);
+  }
+
+  // Rebuild footnote entries.
+  var cont = document.getElementById("content");
+  var spans = cont.getElementsByTagName("span");
+  var refs = {};
+  var n = 0;
+  for (i=0; i<spans.length; i++) {
+    if (spans[i].className == "footnote") {
+      n++;
+      var note = spans[i].getAttribute("data-note");
+      if (!note) {
+        // Use [\s\S] in place of . so multi-line matches work.
+        // Because JavaScript has no s (dotall) regex flag.
+        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+        spans[i].innerHTML =
+          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+        spans[i].setAttribute("data-note", note);
+      }
+      noteholder.innerHTML +=
+        "<div class='footnote' id='_footnote_" + n + "'>" +
+        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+        n + "</a>. " + note + "</div>";
+      var id =spans[i].getAttribute("id");
+      if (id != null) refs["#"+id] = n;
+    }
+  }
+  if (n == 0)
+    noteholder.parentNode.removeChild(noteholder);
+  else {
+    // Process footnoterefs.
+    for (i=0; i<spans.length; i++) {
+      if (spans[i].className == "footnoteref") {
+        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+        href = href.match(/#.*/)[0];  // Because IE return full URL.
+        n = refs[href];
+        spans[i].innerHTML =
+          "[<a href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+      }
+    }
+  }
+},
+
+install: function(toclevels) {
+  var timerId;
+
+  function reinstall() {
+    asciidoc.footnotes();
+    if (toclevels) {
+      asciidoc.toc(toclevels);
+    }
+  }
+
+  function reinstallAndRemoveTimer() {
+    clearInterval(timerId);
+    reinstall();
+  }
+
+  timerId = setInterval(reinstall, 500);
+  if (document.addEventListener)
+    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+  else
+    window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+git-mark-merge-base(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>git-mark-merge-base -
+   Manually interact with depot_tools' merge-base markers.
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>git mark-merge-base</em>
+<em>git mark-merge-base</em> &lt;commit hash&gt;
+<em>git mark-merge-base</em> [-d | --delete]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Inspect, set or delete the current merge-base marker for the current branch.
+This should not be needed, but is useful if things get into a snarled state.
+Pass no arguments to view the current value. If you provide &lt;commit hash&gt;, then
+<code>git mark-merge-base</code> will attempt to set that as the merge-base value.</p></div>
+<div class="paragraph"><p>It is invalid to pick a commit which is not an ancestor of the current branch.</p></div>
+<div class="paragraph"><p>See <a href="git-rebase-update.html">git-rebase-update(1)</a>'s description of the <code>branch.&lt;name&gt;.base</code>
+configuration variable for more info on what the merge base markers are for.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+-d
+</dt>
+<dt class="hdlist1">
+--delete
+</dt>
+<dd>
+<p>
+  Delete the merge-base marker for the current branch.
+</p>
+</dd>
+<dt class="hdlist1">
+&lt;commit hash&gt;
+</dt>
+<dd>
+<p>
+  The new value to set for the current branch&#8217;s merge-base marker.
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_see_also">SEE ALSO</h2>
+<div class="sectionbody">
+<div class="paragraph"><p><a href="git-rebase-update.html">git-rebase-update(1)</a>, <a href="git-reparent-branch.html">git-reparent-branch(1)</a>,
+<a href="git-rename-branch.html">git-rename-branch(1)</a>, <a href="git-upstream-diff.html">git-upstream-diff(1)</a></p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_chromium_depot_tools">CHROMIUM DEPOT_TOOLS</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the chromium <a href="depot_tools.html">depot_tools(1)</a> suite. These tools are meant to
+assist with the development of chromium and related projects. Download the tools
+from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">here</a>.</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2014-03-25 15:09:11 PDT
+</div>
+</div>
+</body>
+</html>

+ 13 - 1
docs/html/git-nav-downstream.html

@@ -801,6 +801,18 @@ Selection (0-2)[0]: 0
 </div>
 </div>
 <div class="sect1">
+<h2 id="_suggested_aliases">SUGGESTED ALIASES</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Some common short-hand aliases. Feel free to add these to your <em>~/.gitconfig</em>
+file.</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>[alias]
+  git down = nav-downstream</code></pre>
+</div></div>
+</div>
+</div>
+<div class="sect1">
 <h2 id="_see_also">SEE ALSO</h2>
 <div class="sectionbody">
 <div class="paragraph"><p><a href="git-map-branches.html">git-map-branches(1)</a>, <a href="git-nav-upstream.html">git-nav-upstream(1)</a></p></div>
@@ -818,7 +830,7 @@ from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">
 <div id="footnotes"><hr /></div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2014-03-14 14:24:49 PDT
+Last updated 2014-03-25 15:09:11 PDT
 </div>
 </div>
 </body>

+ 13 - 1
docs/html/git-nav-upstream.html

@@ -793,6 +793,18 @@ checks that out.</p></div>
 </div>
 </div>
 <div class="sect1">
+<h2 id="_suggested_aliases">SUGGESTED ALIASES</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Some common short-hand aliases. Feel free to add these to your <em>~/.gitconfig</em>
+file.</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>[alias]
+  git up = nav-upstream</code></pre>
+</div></div>
+</div>
+</div>
+<div class="sect1">
 <h2 id="_see_also">SEE ALSO</h2>
 <div class="sectionbody">
 <div class="paragraph"><p><a href="git-map-branches.html">git-map-branches(1)</a>, <a href="git-nav-downstream.html">git-nav-downstream(1)</a></p></div>
@@ -810,7 +822,7 @@ from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">
 <div id="footnotes"><hr /></div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2014-03-14 14:26:05 PDT
+Last updated 2014-03-25 15:09:11 PDT
 </div>
 </div>
 </body>

+ 919 - 0
docs/html/git-new-branch.html

@@ -0,0 +1,919 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.9" />
+<title>git-new-branch(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+  font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+  font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+  margin: 1em 5% 1em 5%;
+}
+
+a {
+  color: blue;
+  text-decoration: underline;
+}
+a:visited {
+  color: fuchsia;
+}
+
+em {
+  font-style: italic;
+  color: navy;
+}
+
+strong {
+  font-weight: bold;
+  color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  color: #527bbd;
+  margin-top: 1.2em;
+  margin-bottom: 0.5em;
+  line-height: 1.3;
+}
+
+h1, h2, h3 {
+  border-bottom: 2px solid silver;
+}
+h2 {
+  padding-top: 0.5em;
+}
+h3 {
+  float: left;
+}
+h3 + * {
+  clear: left;
+}
+h5 {
+  font-size: 1.0em;
+}
+
+div.sectionbody {
+  margin-left: 0;
+}
+
+hr {
+  border: 1px solid silver;
+}
+
+p {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+  margin-top: 0;
+}
+ul > li     { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+  font-family: "Courier New", Courier, monospace;
+  font-size: inherit;
+  color: navy;
+  padding: 0;
+  margin: 0;
+}
+pre {
+  white-space: pre-wrap;
+}
+
+#author {
+  color: #527bbd;
+  font-weight: bold;
+  font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+  font-size: small;
+  border-top: 2px solid silver;
+  padding-top: 0.5em;
+  margin-top: 4.0em;
+}
+#footer-text {
+  float: left;
+  padding-bottom: 0.5em;
+}
+#footer-badges {
+  float: right;
+  padding-bottom: 0.5em;
+}
+
+#preamble {
+  margin-top: 1.5em;
+  margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.admonitionblock {
+  margin-top: 2.0em;
+  margin-bottom: 2.0em;
+  margin-right: 10%;
+  color: #606060;
+}
+
+div.content { /* Block element content. */
+  padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+  color: #527bbd;
+  font-weight: bold;
+  text-align: left;
+  margin-top: 1.0em;
+  margin-bottom: 0.5em;
+}
+div.title + * {
+  margin-top: 0;
+}
+
+td div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content + div.title {
+  margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+  background: #ffffee;
+  border: 1px solid #dddddd;
+  border-left: 4px solid #f0f0f0;
+  padding: 0.5em;
+}
+
+div.listingblock > div.content {
+  border: 1px solid #dddddd;
+  border-left: 5px solid #f0f0f0;
+  background: #f8f8f8;
+  padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+  padding-left: 1.0em;
+  margin-left: 1.0em;
+  margin-right: 10%;
+  border-left: 5px solid #f0f0f0;
+  color: #888;
+}
+
+div.quoteblock > div.attribution {
+  padding-top: 0.5em;
+  text-align: right;
+}
+
+div.verseblock > pre.content {
+  font-family: inherit;
+  font-size: inherit;
+}
+div.verseblock > div.attribution {
+  padding-top: 0.75em;
+  text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+  text-align: left;
+}
+
+div.admonitionblock .icon {
+  vertical-align: top;
+  font-size: 1.1em;
+  font-weight: bold;
+  text-decoration: underline;
+  color: #527bbd;
+  padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+  padding-left: 0.5em;
+  border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+  border-left: 3px solid #dddddd;
+  padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+dt {
+  margin-top: 0.5em;
+  margin-bottom: 0;
+  font-style: normal;
+  color: navy;
+}
+dd > *:first-child {
+  margin-top: 0.1em;
+}
+
+ul, ol {
+    list-style-position: outside;
+}
+ol.arabic {
+  list-style-type: decimal;
+}
+ol.loweralpha {
+  list-style-type: lower-alpha;
+}
+ol.upperalpha {
+  list-style-type: upper-alpha;
+}
+ol.lowerroman {
+  list-style-type: lower-roman;
+}
+ol.upperroman {
+  list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+  margin-top: 0.1em;
+  margin-bottom: 0.1em;
+}
+
+tfoot {
+  font-weight: bold;
+}
+td > div.verse {
+  white-space: pre;
+}
+
+div.hdlist {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+div.hdlist tr {
+  padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+  font-weight: bold;
+}
+td.hdlist1 {
+  vertical-align: top;
+  font-style: normal;
+  padding-right: 0.8em;
+  color: navy;
+}
+td.hdlist2 {
+  vertical-align: top;
+}
+div.hdlist.compact tr {
+  margin: 0;
+  padding-bottom: 0;
+}
+
+.comment {
+  background: yellow;
+}
+
+.footnote, .footnoteref {
+  font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+  vertical-align: super;
+}
+
+#footnotes {
+  margin: 20px 0 20px 0;
+  padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+  margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+  border: none;
+  border-top: 1px solid silver;
+  height: 1px;
+  text-align: left;
+  margin-left: 0;
+  width: 20%;
+  min-width: 100px;
+}
+
+div.colist td {
+  padding-right: 0.5em;
+  padding-bottom: 0.3em;
+  vertical-align: top;
+}
+div.colist td img {
+  margin-top: 0.3em;
+}
+
+@media print {
+  #footer-badges { display: none; }
+}
+
+#toc {
+  margin-bottom: 2.5em;
+}
+
+#toctitle {
+  color: #527bbd;
+  font-size: 1.1em;
+  font-weight: bold;
+  margin-top: 1.0em;
+  margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+div.toclevel2 {
+  margin-left: 2em;
+  font-size: 0.9em;
+}
+div.toclevel3 {
+  margin-left: 4em;
+  font-size: 0.9em;
+}
+div.toclevel4 {
+  margin-left: 6em;
+  font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.tableblock > table {
+  border: 3px solid #527bbd;
+}
+thead, p.table.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.table {
+  margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+  border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+  border-left-style: none;
+  border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+  border-top-style: none;
+  border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.tableblock {
+  margin-top: 0;
+}
+table.tableblock {
+  border-width: 3px;
+  border-spacing: 0px;
+  border-style: solid;
+  border-color: #527bbd;
+  border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+  border-width: 1px;
+  padding: 4px;
+  border-style: solid;
+  border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+  border-left-style: hidden;
+  border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+  border-top-style: hidden;
+  border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+  border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+  text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+  text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+  text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+  vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+  vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+  vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+  padding-top: 0.5em;
+  padding-bottom: 0.5em;
+  border-top: 2px solid silver;
+  border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+  border-style: none;
+}
+body.manpage div.sectionbody {
+  margin-left: 3em;
+}
+
+@media print {
+  body.manpage div#toc { display: none; }
+}
+
+
+div.listingblock > div.content {
+  background: rgb(28, 28, 28);
+}
+
+div.listingblock > div > pre > code {
+  color: rgb(187, 187, 187);
+}
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = {  // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+  function getText(el) {
+    var text = "";
+    for (var i = el.firstChild; i != null; i = i.nextSibling) {
+      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+        text += i.data;
+      else if (i.firstChild != null)
+        text += getText(i);
+    }
+    return text;
+  }
+
+  function TocEntry(el, text, toclevel) {
+    this.element = el;
+    this.text = text;
+    this.toclevel = toclevel;
+  }
+
+  function tocEntries(el, toclevels) {
+    var result = new Array;
+    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+    // Function that scans the DOM tree for header elements (the DOM2
+    // nodeIterator API would be a better technique but not supported by all
+    // browsers).
+    var iterate = function (el) {
+      for (var i = el.firstChild; i != null; i = i.nextSibling) {
+        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+          var mo = re.exec(i.tagName);
+          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+          }
+          iterate(i);
+        }
+      }
+    }
+    iterate(el);
+    return result;
+  }
+
+  var toc = document.getElementById("toc");
+  if (!toc) {
+    return;
+  }
+
+  // Delete existing TOC entries in case we're reloading the TOC.
+  var tocEntriesToRemove = [];
+  var i;
+  for (i = 0; i < toc.childNodes.length; i++) {
+    var entry = toc.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div'
+     && entry.getAttribute("class")
+     && entry.getAttribute("class").match(/^toclevel/))
+      tocEntriesToRemove.push(entry);
+  }
+  for (i = 0; i < tocEntriesToRemove.length; i++) {
+    toc.removeChild(tocEntriesToRemove[i]);
+  }
+
+  // Rebuild TOC entries.
+  var entries = tocEntries(document.getElementById("content"), toclevels);
+  for (var i = 0; i < entries.length; ++i) {
+    var entry = entries[i];
+    if (entry.element.id == "")
+      entry.element.id = "_toc_" + i;
+    var a = document.createElement("a");
+    a.href = "#" + entry.element.id;
+    a.appendChild(document.createTextNode(entry.text));
+    var div = document.createElement("div");
+    div.appendChild(a);
+    div.className = "toclevel" + entry.toclevel;
+    toc.appendChild(div);
+  }
+  if (entries.length == 0)
+    toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+  // Delete existing footnote entries in case we're reloading the footnodes.
+  var i;
+  var noteholder = document.getElementById("footnotes");
+  if (!noteholder) {
+    return;
+  }
+  var entriesToRemove = [];
+  for (i = 0; i < noteholder.childNodes.length; i++) {
+    var entry = noteholder.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+      entriesToRemove.push(entry);
+  }
+  for (i = 0; i < entriesToRemove.length; i++) {
+    noteholder.removeChild(entriesToRemove[i]);
+  }
+
+  // Rebuild footnote entries.
+  var cont = document.getElementById("content");
+  var spans = cont.getElementsByTagName("span");
+  var refs = {};
+  var n = 0;
+  for (i=0; i<spans.length; i++) {
+    if (spans[i].className == "footnote") {
+      n++;
+      var note = spans[i].getAttribute("data-note");
+      if (!note) {
+        // Use [\s\S] in place of . so multi-line matches work.
+        // Because JavaScript has no s (dotall) regex flag.
+        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+        spans[i].innerHTML =
+          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+        spans[i].setAttribute("data-note", note);
+      }
+      noteholder.innerHTML +=
+        "<div class='footnote' id='_footnote_" + n + "'>" +
+        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+        n + "</a>. " + note + "</div>";
+      var id =spans[i].getAttribute("id");
+      if (id != null) refs["#"+id] = n;
+    }
+  }
+  if (n == 0)
+    noteholder.parentNode.removeChild(noteholder);
+  else {
+    // Process footnoterefs.
+    for (i=0; i<spans.length; i++) {
+      if (spans[i].className == "footnoteref") {
+        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+        href = href.match(/#.*/)[0];  // Because IE return full URL.
+        n = refs[href];
+        spans[i].innerHTML =
+          "[<a href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+      }
+    }
+  }
+},
+
+install: function(toclevels) {
+  var timerId;
+
+  function reinstall() {
+    asciidoc.footnotes();
+    if (toclevels) {
+      asciidoc.toc(toclevels);
+    }
+  }
+
+  function reinstallAndRemoveTimer() {
+    clearInterval(timerId);
+    reinstall();
+  }
+
+  timerId = setInterval(reinstall, 500);
+  if (document.addEventListener)
+    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+  else
+    window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+git-new-branch(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>git-new-branch -
+   Create a new branch with correct tracking information.
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>git new-branch</em> &lt;branch_name&gt;
+<em>git new-branch</em> --upstream_current &lt;branch_name&gt;
+<em>git new-branch</em> --upstream &lt;REF&gt; &lt;branch_name&gt;
+<em>git new-branch</em> --lkgr &lt;branch_name&gt;</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Creates a new branch. By default the new branch will track the configured
+upstream for the repo (defaults to <em>origin/master</em>). If one of the other options
+is specified, it will track that other ref instead.</p></div>
+<div class="paragraph"><p>Conceptually, each branch in your repo represents one <em>Change List (CL)</em>. If you
+have many independent CLs (i.e. the changes in one do not interact with/depend
+on the changes in another), then you should create them as new branches tracking
+the default upstream (i.e. <code>git new-branch &lt;branch_name&gt;</code>). If you have features
+which depend on each other, you should create stacked branches using <code>git
+new-branch --upstream_current &lt;branch_name&gt;</code>.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+--upstream_current
+</dt>
+<dd>
+<p>
+  Set the tracking (upstream) branch to the currently-checked-out branch.
+</p>
+</dd>
+<dt class="hdlist1">
+--uptstream &lt;REF&gt;
+</dt>
+<dd>
+<p>
+  Set the tracking (upstream) branch to &lt;REF&gt;. &lt;REF&gt; may be a local branch,
+  remote branch, or a tag.
+</p>
+</dd>
+<dt class="hdlist1">
+--lkgr
+</dt>
+<dd>
+<p>
+  Alias for <code>--upstream lkgr</code>.
+</p>
+</dd>
+<dt class="hdlist1">
+&lt;branch_name&gt;
+</dt>
+<dd>
+<p>
+  The name for the new branch.
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_configuration_variables">CONFIGURATION VARIABLES</h2>
+<div class="sectionbody">
+<div class="sect2">
+<h3 id="_depot_tools_upstream">depot-tools.upstream</h3>
+<div class="paragraph"><p>This configures the default <em>upstream</em> for all new branches. If it is unset, it
+defaults to <em>origin/master</em>.  This is considered to be the <em>root</em> branch.</p></div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_example">EXAMPLE</h2>
+<div class="sectionbody">
+<div class="listingblock">
+<div class="content">
+<pre><code><strong><span class="white">$ git map-branches</span></strong>
+<span class="red">origin/master</span>
+  <span class="green">cool_feature</span>
+    <span class="green">subfeature</span>
+  <span class="aqua">frozen_changes *</span>
+<strong><span class="white">$ git new-branch independent_cl</span></strong>
+<strong><span class="white">$ git map-branches</span></strong>
+<span class="red">origin/master</span>
+  <span class="green">cool_feature</span>
+    <span class="green">subfeature</span>
+  <span class="green">frozen_changes</span>
+  <span class="aqua">independent_cl *</span>
+<strong><span class="white">$ git new-branch --upstream subfeature nested_cl</span></strong>
+<strong><span class="white">$ git map-branches</span></strong>
+<span class="red">origin/master</span>
+  <span class="green">cool_feature</span>
+    <span class="aqua">subfeature</span>  <b>&lt;1&gt;</b>
+      <span class="aqua">nested_cl *</span>
+  <span class="green">frozen_changes</span>
+  <span class="green">independent_cl</span>
+<strong><span class="white">$ git checkout cool_feature</span></strong>
+<strong><span class="white">$ git new-branch --upstream_current cl_depends_on_cool_feature</span></strong>
+<strong><span class="white">$ git map-branches</span></strong>
+<span class="red">origin/master</span>
+  <span class="aqua">cool_feature</span>
+    <span class="aqua">cl_depends_on_cool_feature *</span>
+    <span class="green">subfeature</span>
+      <span class="green">nested_cl</span>
+  <span class="green">frozen_changes</span>
+  <span class="green">independent_cl</span></code></pre>
+</div></div>
+<div class="colist arabic"><ol>
+<li>
+<p>
+Note that both branches are cyan because they are currently the same
+<em>commit</em> object. See <a href=":git-map-branches.html">:git-map-branches(1)</a> for more detail.
+</p>
+</li>
+</ol></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_suggested_aliases">SUGGESTED ALIASES</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Some common short-hand aliases. Feel free to add these to your <em>~/.gitconfig</em>
+file.</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>[alias]
+  git nb = new-branch
+  git tb = new-branch --upstream_current  <b>&lt;1&gt;</b></code></pre>
+</div></div>
+<div class="colist arabic"><ol>
+<li>
+<p>
+mnemonic: tb &#8594; "track branch"
+</p>
+</li>
+</ol></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_see_also">SEE ALSO</h2>
+<div class="sectionbody">
+<div class="paragraph"><p><a href="git-rebase-update.html">git-rebase-update(1)</a>, <a href="git-reparent-branch.html">git-reparent-branch(1)</a>,
+<a href="git-rename-branch.html">git-rename-branch(1)</a>, <a href="git-upstream-diff.html">git-upstream-diff(1)</a></p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_chromium_depot_tools">CHROMIUM DEPOT_TOOLS</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the chromium <a href="depot_tools.html">depot_tools(1)</a> suite. These tools are meant to
+assist with the development of chromium and related projects. Download the tools
+from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">here</a>.</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2014-03-25 15:09:11 PDT
+</div>
+</div>
+</body>
+</html>

+ 937 - 0
docs/html/git-rebase-update.html

@@ -0,0 +1,937 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.9" />
+<title>git-rebase-update(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+  font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+  font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+  margin: 1em 5% 1em 5%;
+}
+
+a {
+  color: blue;
+  text-decoration: underline;
+}
+a:visited {
+  color: fuchsia;
+}
+
+em {
+  font-style: italic;
+  color: navy;
+}
+
+strong {
+  font-weight: bold;
+  color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  color: #527bbd;
+  margin-top: 1.2em;
+  margin-bottom: 0.5em;
+  line-height: 1.3;
+}
+
+h1, h2, h3 {
+  border-bottom: 2px solid silver;
+}
+h2 {
+  padding-top: 0.5em;
+}
+h3 {
+  float: left;
+}
+h3 + * {
+  clear: left;
+}
+h5 {
+  font-size: 1.0em;
+}
+
+div.sectionbody {
+  margin-left: 0;
+}
+
+hr {
+  border: 1px solid silver;
+}
+
+p {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+  margin-top: 0;
+}
+ul > li     { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+  font-family: "Courier New", Courier, monospace;
+  font-size: inherit;
+  color: navy;
+  padding: 0;
+  margin: 0;
+}
+pre {
+  white-space: pre-wrap;
+}
+
+#author {
+  color: #527bbd;
+  font-weight: bold;
+  font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+  font-size: small;
+  border-top: 2px solid silver;
+  padding-top: 0.5em;
+  margin-top: 4.0em;
+}
+#footer-text {
+  float: left;
+  padding-bottom: 0.5em;
+}
+#footer-badges {
+  float: right;
+  padding-bottom: 0.5em;
+}
+
+#preamble {
+  margin-top: 1.5em;
+  margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.admonitionblock {
+  margin-top: 2.0em;
+  margin-bottom: 2.0em;
+  margin-right: 10%;
+  color: #606060;
+}
+
+div.content { /* Block element content. */
+  padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+  color: #527bbd;
+  font-weight: bold;
+  text-align: left;
+  margin-top: 1.0em;
+  margin-bottom: 0.5em;
+}
+div.title + * {
+  margin-top: 0;
+}
+
+td div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content + div.title {
+  margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+  background: #ffffee;
+  border: 1px solid #dddddd;
+  border-left: 4px solid #f0f0f0;
+  padding: 0.5em;
+}
+
+div.listingblock > div.content {
+  border: 1px solid #dddddd;
+  border-left: 5px solid #f0f0f0;
+  background: #f8f8f8;
+  padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+  padding-left: 1.0em;
+  margin-left: 1.0em;
+  margin-right: 10%;
+  border-left: 5px solid #f0f0f0;
+  color: #888;
+}
+
+div.quoteblock > div.attribution {
+  padding-top: 0.5em;
+  text-align: right;
+}
+
+div.verseblock > pre.content {
+  font-family: inherit;
+  font-size: inherit;
+}
+div.verseblock > div.attribution {
+  padding-top: 0.75em;
+  text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+  text-align: left;
+}
+
+div.admonitionblock .icon {
+  vertical-align: top;
+  font-size: 1.1em;
+  font-weight: bold;
+  text-decoration: underline;
+  color: #527bbd;
+  padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+  padding-left: 0.5em;
+  border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+  border-left: 3px solid #dddddd;
+  padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+dt {
+  margin-top: 0.5em;
+  margin-bottom: 0;
+  font-style: normal;
+  color: navy;
+}
+dd > *:first-child {
+  margin-top: 0.1em;
+}
+
+ul, ol {
+    list-style-position: outside;
+}
+ol.arabic {
+  list-style-type: decimal;
+}
+ol.loweralpha {
+  list-style-type: lower-alpha;
+}
+ol.upperalpha {
+  list-style-type: upper-alpha;
+}
+ol.lowerroman {
+  list-style-type: lower-roman;
+}
+ol.upperroman {
+  list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+  margin-top: 0.1em;
+  margin-bottom: 0.1em;
+}
+
+tfoot {
+  font-weight: bold;
+}
+td > div.verse {
+  white-space: pre;
+}
+
+div.hdlist {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+div.hdlist tr {
+  padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+  font-weight: bold;
+}
+td.hdlist1 {
+  vertical-align: top;
+  font-style: normal;
+  padding-right: 0.8em;
+  color: navy;
+}
+td.hdlist2 {
+  vertical-align: top;
+}
+div.hdlist.compact tr {
+  margin: 0;
+  padding-bottom: 0;
+}
+
+.comment {
+  background: yellow;
+}
+
+.footnote, .footnoteref {
+  font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+  vertical-align: super;
+}
+
+#footnotes {
+  margin: 20px 0 20px 0;
+  padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+  margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+  border: none;
+  border-top: 1px solid silver;
+  height: 1px;
+  text-align: left;
+  margin-left: 0;
+  width: 20%;
+  min-width: 100px;
+}
+
+div.colist td {
+  padding-right: 0.5em;
+  padding-bottom: 0.3em;
+  vertical-align: top;
+}
+div.colist td img {
+  margin-top: 0.3em;
+}
+
+@media print {
+  #footer-badges { display: none; }
+}
+
+#toc {
+  margin-bottom: 2.5em;
+}
+
+#toctitle {
+  color: #527bbd;
+  font-size: 1.1em;
+  font-weight: bold;
+  margin-top: 1.0em;
+  margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+div.toclevel2 {
+  margin-left: 2em;
+  font-size: 0.9em;
+}
+div.toclevel3 {
+  margin-left: 4em;
+  font-size: 0.9em;
+}
+div.toclevel4 {
+  margin-left: 6em;
+  font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.tableblock > table {
+  border: 3px solid #527bbd;
+}
+thead, p.table.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.table {
+  margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+  border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+  border-left-style: none;
+  border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+  border-top-style: none;
+  border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.tableblock {
+  margin-top: 0;
+}
+table.tableblock {
+  border-width: 3px;
+  border-spacing: 0px;
+  border-style: solid;
+  border-color: #527bbd;
+  border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+  border-width: 1px;
+  padding: 4px;
+  border-style: solid;
+  border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+  border-left-style: hidden;
+  border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+  border-top-style: hidden;
+  border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+  border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+  text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+  text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+  text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+  vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+  vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+  vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+  padding-top: 0.5em;
+  padding-bottom: 0.5em;
+  border-top: 2px solid silver;
+  border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+  border-style: none;
+}
+body.manpage div.sectionbody {
+  margin-left: 3em;
+}
+
+@media print {
+  body.manpage div#toc { display: none; }
+}
+
+
+div.listingblock > div.content {
+  background: rgb(28, 28, 28);
+}
+
+div.listingblock > div > pre > code {
+  color: rgb(187, 187, 187);
+}
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = {  // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+  function getText(el) {
+    var text = "";
+    for (var i = el.firstChild; i != null; i = i.nextSibling) {
+      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+        text += i.data;
+      else if (i.firstChild != null)
+        text += getText(i);
+    }
+    return text;
+  }
+
+  function TocEntry(el, text, toclevel) {
+    this.element = el;
+    this.text = text;
+    this.toclevel = toclevel;
+  }
+
+  function tocEntries(el, toclevels) {
+    var result = new Array;
+    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+    // Function that scans the DOM tree for header elements (the DOM2
+    // nodeIterator API would be a better technique but not supported by all
+    // browsers).
+    var iterate = function (el) {
+      for (var i = el.firstChild; i != null; i = i.nextSibling) {
+        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+          var mo = re.exec(i.tagName);
+          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+          }
+          iterate(i);
+        }
+      }
+    }
+    iterate(el);
+    return result;
+  }
+
+  var toc = document.getElementById("toc");
+  if (!toc) {
+    return;
+  }
+
+  // Delete existing TOC entries in case we're reloading the TOC.
+  var tocEntriesToRemove = [];
+  var i;
+  for (i = 0; i < toc.childNodes.length; i++) {
+    var entry = toc.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div'
+     && entry.getAttribute("class")
+     && entry.getAttribute("class").match(/^toclevel/))
+      tocEntriesToRemove.push(entry);
+  }
+  for (i = 0; i < tocEntriesToRemove.length; i++) {
+    toc.removeChild(tocEntriesToRemove[i]);
+  }
+
+  // Rebuild TOC entries.
+  var entries = tocEntries(document.getElementById("content"), toclevels);
+  for (var i = 0; i < entries.length; ++i) {
+    var entry = entries[i];
+    if (entry.element.id == "")
+      entry.element.id = "_toc_" + i;
+    var a = document.createElement("a");
+    a.href = "#" + entry.element.id;
+    a.appendChild(document.createTextNode(entry.text));
+    var div = document.createElement("div");
+    div.appendChild(a);
+    div.className = "toclevel" + entry.toclevel;
+    toc.appendChild(div);
+  }
+  if (entries.length == 0)
+    toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+  // Delete existing footnote entries in case we're reloading the footnodes.
+  var i;
+  var noteholder = document.getElementById("footnotes");
+  if (!noteholder) {
+    return;
+  }
+  var entriesToRemove = [];
+  for (i = 0; i < noteholder.childNodes.length; i++) {
+    var entry = noteholder.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+      entriesToRemove.push(entry);
+  }
+  for (i = 0; i < entriesToRemove.length; i++) {
+    noteholder.removeChild(entriesToRemove[i]);
+  }
+
+  // Rebuild footnote entries.
+  var cont = document.getElementById("content");
+  var spans = cont.getElementsByTagName("span");
+  var refs = {};
+  var n = 0;
+  for (i=0; i<spans.length; i++) {
+    if (spans[i].className == "footnote") {
+      n++;
+      var note = spans[i].getAttribute("data-note");
+      if (!note) {
+        // Use [\s\S] in place of . so multi-line matches work.
+        // Because JavaScript has no s (dotall) regex flag.
+        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+        spans[i].innerHTML =
+          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+        spans[i].setAttribute("data-note", note);
+      }
+      noteholder.innerHTML +=
+        "<div class='footnote' id='_footnote_" + n + "'>" +
+        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+        n + "</a>. " + note + "</div>";
+      var id =spans[i].getAttribute("id");
+      if (id != null) refs["#"+id] = n;
+    }
+  }
+  if (n == 0)
+    noteholder.parentNode.removeChild(noteholder);
+  else {
+    // Process footnoterefs.
+    for (i=0; i<spans.length; i++) {
+      if (spans[i].className == "footnoteref") {
+        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+        href = href.match(/#.*/)[0];  // Because IE return full URL.
+        n = refs[href];
+        spans[i].innerHTML =
+          "[<a href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+      }
+    }
+  }
+},
+
+install: function(toclevels) {
+  var timerId;
+
+  function reinstall() {
+    asciidoc.footnotes();
+    if (toclevels) {
+      asciidoc.toc(toclevels);
+    }
+  }
+
+  function reinstallAndRemoveTimer() {
+    clearInterval(timerId);
+    reinstall();
+  }
+
+  timerId = setInterval(reinstall, 500);
+  if (document.addEventListener)
+    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+  else
+    window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+git-rebase-update(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>git-rebase-update -
+   Updates all branches to have the latest changes from their upstreams.
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>git rebase-update</em> [-v | --verbose] [-n | --no_fetch]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Brings all branches up-to-date with their tracking branches. This involves
+several phases:</p></div>
+<div class="dlist"><dl>
+<dt class="hdlist1">
+Preparation
+</dt>
+<dd>
+<p>
+  If you currently have a branch checked out, any changes on that branch are
+  <em>frozen</em> (See <a href="git-freeze.html">git-freeze(1)</a> for more detail). Additionally, the current
+  branch is recorded for the <em>Restoration</em> phase later (see <em>CONFIGURATION
+  VARIABLES</em> for details on <code>depot-tools.rebase-update.starting-branch</code>).
+</p>
+</dd>
+<dt class="hdlist1">
+Fetching
+</dt>
+<dd>
+<p>
+  All branches are examined to find their upstream references. The correct set
+  of git remotes is determined, and fetched accordingly. Note that if any
+  branches have a tag as their upstream, we are forced to pull all remotes.
+</p>
+<div class="paragraph"><p>Pass <code>--no_fetch</code> to skip this phase.</p></div>
+</dd>
+<dt class="hdlist1">
+Rebasing
+</dt>
+<dd>
+<p>
+  All branches are rebased in topological order from roots (upstreams) to
+  leaves.  Each branch is rebased from its marked merge-base (see <em>CONFIGURATION
+  VARIABLES</em>) to the branch tip on top of its parent branch. If the parent
+  branch is <em>frozen</em> (see <a href="git-freeze.html">git-freeze(1)</a>), the branch will be rebased
+  onto the last non-freeze commit on the parent branch.
+</p>
+<div class="paragraph"><p>Things get interesting when there are merge conflicts on rebase. The <strong>most
+common</strong> cause for conflicts is when your branch has been committed to the
+upstream in squashed form, ala <a href="git-squash-branch.html">git-squash-branch(1)</a>, which is what
+<a href="git-cl.html">git-cl(1)</a> and the <em>Commit Queue</em> will do. Because of that, <code>git
+rebase-update</code> will attempt to squash your conflicted branch to see if the
+squashed version applies cleanly to its upstream.</p></div>
+<div class="paragraph"><p>If it does not apply cleanly, then your original (non-squashed) branch will be
+left in mid-rebase and <code>git rebase-update</code> will exit. You can deal with this
+like any other conflicted rebase. When you&#8217;re done, just <code>git rebase-update</code>
+again to pick up where you left off.</p></div>
+</dd>
+<dt class="hdlist1">
+Cleanup
+</dt>
+<dd>
+<p>
+  Once all the branches have been rebased, any empty branches (i.e. branches
+  with no commits on them) are removed. If a branch is removed in this fashion,
+  any branches which depend on it are reparented to the parent of the removed
+  branch (see <a href="git-reparent-branch.html">git-reparent-branch(1)</a>).
+</p>
+</dd>
+<dt class="hdlist1">
+Restoration
+</dt>
+<dd>
+<p>
+  <code>git rebase-update</code> checks out the branch that you started on, and <em>thaws</em> it,
+  if necessary (see <a href="git-thaw.html">git-thaw(1)</a>). If the branch you started on got
+  cleaned up, <code>git rebase-update</code> will checkout the <em>root</em> ref (defaults to
+  <em>origin/master</em>, as configured by <code>depot-tools.upstream</code>, see
+  <a href="git-new-branch.html">git-new-branch(1)</a>).
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+-n
+</dt>
+<dt class="hdlist1">
+--no_fetch
+</dt>
+<dd>
+<p>
+  Skip the <code>git fetch</code> phase of rebase-update.
+</p>
+</dd>
+<dt class="hdlist1">
+-v
+</dt>
+<dt class="hdlist1">
+--verbose
+</dt>
+<dd>
+<p>
+  More text than your terminal can handle.
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_configuration_variables">CONFIGURATION VARIABLES</h2>
+<div class="sectionbody">
+<div class="sect2">
+<h3 id="_depot_tools_rebase_update_starting_branch">depot-tools.rebase-update.starting-branch</h3>
+<div class="paragraph"><p>When <code>git rebase-update</code> first runs, it will record the current branch here so
+that when it completes successfully, it will return back to the same branch you
+started on, even if <code>git rebase-update</code> is interrupted due to rebase conflicts.
+When <code>git rebase-update</code> completes successfully, this configuration variable is
+removed.</p></div>
+</div>
+<div class="sect2">
+<h3 id="_branch_lt_name_gt_dormant">branch.&lt;name&gt;.dormant</h3>
+<div class="paragraph"><p>If <code>true</code>, will cause rebase-update to skip all processing on the branch.
+Useful for old/high-conflict branches which you want to keep for posterity, but
+don&#8217;t want to deal with when running <code>git rebase-update</code></p></div>
+</div>
+<div class="sect2">
+<h3 id="_branch_lt_name_gt_base">branch.&lt;name&gt;.base</h3>
+<div class="paragraph"><p>Holds the <em>base</em> reference for this branch. By default this is equivalent to
+<code>git merge-base &lt;name&gt; &lt;name&gt;@{upstream}</code>. However, it can diverge if
+<code>&lt;name&gt;@{upstream}</code> is manually rebased. In this case, it correctly preserves
+the value it had before, where <code>git merge-base</code> would now report the wrong
+value.</p></div>
+<div class="paragraph"><p>All of the tools in the <a href="depot_tools.html">depot_tools(1)</a> suite collude to keep this value
+as up-to-date as possible, including <a href="git-reparent-branch.html">git-reparent-branch(1)</a>, and
+<a href="git-new-branch.html">git-new-branch(1)</a>. <a href="git-map.html">git-map(1)</a> also shows the location of these
+marker values in <strong><span class="black-background white">white</span></strong>.</p></div>
+<div class="paragraph"><p><a href="git-mark-merge-base.html">git-mark-merge-base(1)</a> allows easy manual interaction for this value,
+in the unlikely event that it gets out of sync.</p></div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_suggested_aliases">SUGGESTED ALIASES</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Some common short-hand aliases. Feel free to add these to your <em>~/.gitconfig</em>
+file.</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>[alias]
+  git reup = rebase-update</code></pre>
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_see_also">SEE ALSO</h2>
+<div class="sectionbody">
+<div class="paragraph"><p><a href="git-new-branch.html">git-new-branch(1)</a>, <a href="git-reparent-branch.html">git-reparent-branch(1)</a>,
+<a href="git-rename-branch.html">git-rename-branch(1)</a>, <a href="git-upstream-diff.html">git-upstream-diff(1)</a>,
+<a href="git-freeze.html">git-freeze(1)</a>, <a href="git-mark-merge-base.html">git-mark-merge-base(1)</a></p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_chromium_depot_tools">CHROMIUM DEPOT_TOOLS</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the chromium <a href="depot_tools.html">depot_tools(1)</a> suite. These tools are meant to
+assist with the development of chromium and related projects. Download the tools
+from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">here</a>.</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2014-03-25 15:09:11 PDT
+</div>
+</div>
+</body>
+</html>

+ 794 - 0
docs/html/git-rename-branch.html

@@ -0,0 +1,794 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.9" />
+<title>git-rename-branch(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+  font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+  font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+  margin: 1em 5% 1em 5%;
+}
+
+a {
+  color: blue;
+  text-decoration: underline;
+}
+a:visited {
+  color: fuchsia;
+}
+
+em {
+  font-style: italic;
+  color: navy;
+}
+
+strong {
+  font-weight: bold;
+  color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  color: #527bbd;
+  margin-top: 1.2em;
+  margin-bottom: 0.5em;
+  line-height: 1.3;
+}
+
+h1, h2, h3 {
+  border-bottom: 2px solid silver;
+}
+h2 {
+  padding-top: 0.5em;
+}
+h3 {
+  float: left;
+}
+h3 + * {
+  clear: left;
+}
+h5 {
+  font-size: 1.0em;
+}
+
+div.sectionbody {
+  margin-left: 0;
+}
+
+hr {
+  border: 1px solid silver;
+}
+
+p {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+  margin-top: 0;
+}
+ul > li     { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+  font-family: "Courier New", Courier, monospace;
+  font-size: inherit;
+  color: navy;
+  padding: 0;
+  margin: 0;
+}
+pre {
+  white-space: pre-wrap;
+}
+
+#author {
+  color: #527bbd;
+  font-weight: bold;
+  font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+  font-size: small;
+  border-top: 2px solid silver;
+  padding-top: 0.5em;
+  margin-top: 4.0em;
+}
+#footer-text {
+  float: left;
+  padding-bottom: 0.5em;
+}
+#footer-badges {
+  float: right;
+  padding-bottom: 0.5em;
+}
+
+#preamble {
+  margin-top: 1.5em;
+  margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.admonitionblock {
+  margin-top: 2.0em;
+  margin-bottom: 2.0em;
+  margin-right: 10%;
+  color: #606060;
+}
+
+div.content { /* Block element content. */
+  padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+  color: #527bbd;
+  font-weight: bold;
+  text-align: left;
+  margin-top: 1.0em;
+  margin-bottom: 0.5em;
+}
+div.title + * {
+  margin-top: 0;
+}
+
+td div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content + div.title {
+  margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+  background: #ffffee;
+  border: 1px solid #dddddd;
+  border-left: 4px solid #f0f0f0;
+  padding: 0.5em;
+}
+
+div.listingblock > div.content {
+  border: 1px solid #dddddd;
+  border-left: 5px solid #f0f0f0;
+  background: #f8f8f8;
+  padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+  padding-left: 1.0em;
+  margin-left: 1.0em;
+  margin-right: 10%;
+  border-left: 5px solid #f0f0f0;
+  color: #888;
+}
+
+div.quoteblock > div.attribution {
+  padding-top: 0.5em;
+  text-align: right;
+}
+
+div.verseblock > pre.content {
+  font-family: inherit;
+  font-size: inherit;
+}
+div.verseblock > div.attribution {
+  padding-top: 0.75em;
+  text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+  text-align: left;
+}
+
+div.admonitionblock .icon {
+  vertical-align: top;
+  font-size: 1.1em;
+  font-weight: bold;
+  text-decoration: underline;
+  color: #527bbd;
+  padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+  padding-left: 0.5em;
+  border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+  border-left: 3px solid #dddddd;
+  padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+dt {
+  margin-top: 0.5em;
+  margin-bottom: 0;
+  font-style: normal;
+  color: navy;
+}
+dd > *:first-child {
+  margin-top: 0.1em;
+}
+
+ul, ol {
+    list-style-position: outside;
+}
+ol.arabic {
+  list-style-type: decimal;
+}
+ol.loweralpha {
+  list-style-type: lower-alpha;
+}
+ol.upperalpha {
+  list-style-type: upper-alpha;
+}
+ol.lowerroman {
+  list-style-type: lower-roman;
+}
+ol.upperroman {
+  list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+  margin-top: 0.1em;
+  margin-bottom: 0.1em;
+}
+
+tfoot {
+  font-weight: bold;
+}
+td > div.verse {
+  white-space: pre;
+}
+
+div.hdlist {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+div.hdlist tr {
+  padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+  font-weight: bold;
+}
+td.hdlist1 {
+  vertical-align: top;
+  font-style: normal;
+  padding-right: 0.8em;
+  color: navy;
+}
+td.hdlist2 {
+  vertical-align: top;
+}
+div.hdlist.compact tr {
+  margin: 0;
+  padding-bottom: 0;
+}
+
+.comment {
+  background: yellow;
+}
+
+.footnote, .footnoteref {
+  font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+  vertical-align: super;
+}
+
+#footnotes {
+  margin: 20px 0 20px 0;
+  padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+  margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+  border: none;
+  border-top: 1px solid silver;
+  height: 1px;
+  text-align: left;
+  margin-left: 0;
+  width: 20%;
+  min-width: 100px;
+}
+
+div.colist td {
+  padding-right: 0.5em;
+  padding-bottom: 0.3em;
+  vertical-align: top;
+}
+div.colist td img {
+  margin-top: 0.3em;
+}
+
+@media print {
+  #footer-badges { display: none; }
+}
+
+#toc {
+  margin-bottom: 2.5em;
+}
+
+#toctitle {
+  color: #527bbd;
+  font-size: 1.1em;
+  font-weight: bold;
+  margin-top: 1.0em;
+  margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+div.toclevel2 {
+  margin-left: 2em;
+  font-size: 0.9em;
+}
+div.toclevel3 {
+  margin-left: 4em;
+  font-size: 0.9em;
+}
+div.toclevel4 {
+  margin-left: 6em;
+  font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.tableblock > table {
+  border: 3px solid #527bbd;
+}
+thead, p.table.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.table {
+  margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+  border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+  border-left-style: none;
+  border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+  border-top-style: none;
+  border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.tableblock {
+  margin-top: 0;
+}
+table.tableblock {
+  border-width: 3px;
+  border-spacing: 0px;
+  border-style: solid;
+  border-color: #527bbd;
+  border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+  border-width: 1px;
+  padding: 4px;
+  border-style: solid;
+  border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+  border-left-style: hidden;
+  border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+  border-top-style: hidden;
+  border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+  border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+  text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+  text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+  text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+  vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+  vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+  vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+  padding-top: 0.5em;
+  padding-bottom: 0.5em;
+  border-top: 2px solid silver;
+  border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+  border-style: none;
+}
+body.manpage div.sectionbody {
+  margin-left: 3em;
+}
+
+@media print {
+  body.manpage div#toc { display: none; }
+}
+
+
+div.listingblock > div.content {
+  background: rgb(28, 28, 28);
+}
+
+div.listingblock > div > pre > code {
+  color: rgb(187, 187, 187);
+}
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = {  // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+  function getText(el) {
+    var text = "";
+    for (var i = el.firstChild; i != null; i = i.nextSibling) {
+      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+        text += i.data;
+      else if (i.firstChild != null)
+        text += getText(i);
+    }
+    return text;
+  }
+
+  function TocEntry(el, text, toclevel) {
+    this.element = el;
+    this.text = text;
+    this.toclevel = toclevel;
+  }
+
+  function tocEntries(el, toclevels) {
+    var result = new Array;
+    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+    // Function that scans the DOM tree for header elements (the DOM2
+    // nodeIterator API would be a better technique but not supported by all
+    // browsers).
+    var iterate = function (el) {
+      for (var i = el.firstChild; i != null; i = i.nextSibling) {
+        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+          var mo = re.exec(i.tagName);
+          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+          }
+          iterate(i);
+        }
+      }
+    }
+    iterate(el);
+    return result;
+  }
+
+  var toc = document.getElementById("toc");
+  if (!toc) {
+    return;
+  }
+
+  // Delete existing TOC entries in case we're reloading the TOC.
+  var tocEntriesToRemove = [];
+  var i;
+  for (i = 0; i < toc.childNodes.length; i++) {
+    var entry = toc.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div'
+     && entry.getAttribute("class")
+     && entry.getAttribute("class").match(/^toclevel/))
+      tocEntriesToRemove.push(entry);
+  }
+  for (i = 0; i < tocEntriesToRemove.length; i++) {
+    toc.removeChild(tocEntriesToRemove[i]);
+  }
+
+  // Rebuild TOC entries.
+  var entries = tocEntries(document.getElementById("content"), toclevels);
+  for (var i = 0; i < entries.length; ++i) {
+    var entry = entries[i];
+    if (entry.element.id == "")
+      entry.element.id = "_toc_" + i;
+    var a = document.createElement("a");
+    a.href = "#" + entry.element.id;
+    a.appendChild(document.createTextNode(entry.text));
+    var div = document.createElement("div");
+    div.appendChild(a);
+    div.className = "toclevel" + entry.toclevel;
+    toc.appendChild(div);
+  }
+  if (entries.length == 0)
+    toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+  // Delete existing footnote entries in case we're reloading the footnodes.
+  var i;
+  var noteholder = document.getElementById("footnotes");
+  if (!noteholder) {
+    return;
+  }
+  var entriesToRemove = [];
+  for (i = 0; i < noteholder.childNodes.length; i++) {
+    var entry = noteholder.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+      entriesToRemove.push(entry);
+  }
+  for (i = 0; i < entriesToRemove.length; i++) {
+    noteholder.removeChild(entriesToRemove[i]);
+  }
+
+  // Rebuild footnote entries.
+  var cont = document.getElementById("content");
+  var spans = cont.getElementsByTagName("span");
+  var refs = {};
+  var n = 0;
+  for (i=0; i<spans.length; i++) {
+    if (spans[i].className == "footnote") {
+      n++;
+      var note = spans[i].getAttribute("data-note");
+      if (!note) {
+        // Use [\s\S] in place of . so multi-line matches work.
+        // Because JavaScript has no s (dotall) regex flag.
+        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+        spans[i].innerHTML =
+          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+        spans[i].setAttribute("data-note", note);
+      }
+      noteholder.innerHTML +=
+        "<div class='footnote' id='_footnote_" + n + "'>" +
+        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+        n + "</a>. " + note + "</div>";
+      var id =spans[i].getAttribute("id");
+      if (id != null) refs["#"+id] = n;
+    }
+  }
+  if (n == 0)
+    noteholder.parentNode.removeChild(noteholder);
+  else {
+    // Process footnoterefs.
+    for (i=0; i<spans.length; i++) {
+      if (spans[i].className == "footnoteref") {
+        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+        href = href.match(/#.*/)[0];  // Because IE return full URL.
+        n = refs[href];
+        spans[i].innerHTML =
+          "[<a href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+      }
+    }
+  }
+},
+
+install: function(toclevels) {
+  var timerId;
+
+  function reinstall() {
+    asciidoc.footnotes();
+    if (toclevels) {
+      asciidoc.toc(toclevels);
+    }
+  }
+
+  function reinstallAndRemoveTimer() {
+    clearInterval(timerId);
+    reinstall();
+  }
+
+  timerId = setInterval(reinstall, 500);
+  if (document.addEventListener)
+    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+  else
+    window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+git-rename-branch(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>git-rename-branch -
+   Rename a branch and correctly preserve all downstream relationships.
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>git rename-branch</em> &lt;new_name&gt;
+<em>git rename-branch</em> &lt;old_name&gt; &lt;new_name&gt;</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Rename the current (or specified) branch, then update all dowstream branches'
+tracking information to preserve inter-branch dependencies.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_see_also">SEE ALSO</h2>
+<div class="sectionbody">
+<div class="paragraph"><p><a href="git-rebase-update.html">git-rebase-update(1)</a>, <a href="git-reparent-branch.html">git-reparent-branch(1)</a>,
+<a href="git-new-branch.html">git-new-branch(1)</a>, <a href="git-upstream-diff.html">git-upstream-diff(1)</a></p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_chromium_depot_tools">CHROMIUM DEPOT_TOOLS</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the chromium <a href="depot_tools.html">depot_tools(1)</a> suite. These tools are meant to
+assist with the development of chromium and related projects. Download the tools
+from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">here</a>.</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2014-03-25 15:09:11 PDT
+</div>
+</div>
+</body>
+</html>

+ 847 - 0
docs/html/git-reparent-branch.html

@@ -0,0 +1,847 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.9" />
+<title>git-reparent-branch(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+  font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+  font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+  margin: 1em 5% 1em 5%;
+}
+
+a {
+  color: blue;
+  text-decoration: underline;
+}
+a:visited {
+  color: fuchsia;
+}
+
+em {
+  font-style: italic;
+  color: navy;
+}
+
+strong {
+  font-weight: bold;
+  color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  color: #527bbd;
+  margin-top: 1.2em;
+  margin-bottom: 0.5em;
+  line-height: 1.3;
+}
+
+h1, h2, h3 {
+  border-bottom: 2px solid silver;
+}
+h2 {
+  padding-top: 0.5em;
+}
+h3 {
+  float: left;
+}
+h3 + * {
+  clear: left;
+}
+h5 {
+  font-size: 1.0em;
+}
+
+div.sectionbody {
+  margin-left: 0;
+}
+
+hr {
+  border: 1px solid silver;
+}
+
+p {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+  margin-top: 0;
+}
+ul > li     { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+  font-family: "Courier New", Courier, monospace;
+  font-size: inherit;
+  color: navy;
+  padding: 0;
+  margin: 0;
+}
+pre {
+  white-space: pre-wrap;
+}
+
+#author {
+  color: #527bbd;
+  font-weight: bold;
+  font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+  font-size: small;
+  border-top: 2px solid silver;
+  padding-top: 0.5em;
+  margin-top: 4.0em;
+}
+#footer-text {
+  float: left;
+  padding-bottom: 0.5em;
+}
+#footer-badges {
+  float: right;
+  padding-bottom: 0.5em;
+}
+
+#preamble {
+  margin-top: 1.5em;
+  margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.admonitionblock {
+  margin-top: 2.0em;
+  margin-bottom: 2.0em;
+  margin-right: 10%;
+  color: #606060;
+}
+
+div.content { /* Block element content. */
+  padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+  color: #527bbd;
+  font-weight: bold;
+  text-align: left;
+  margin-top: 1.0em;
+  margin-bottom: 0.5em;
+}
+div.title + * {
+  margin-top: 0;
+}
+
+td div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content + div.title {
+  margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+  background: #ffffee;
+  border: 1px solid #dddddd;
+  border-left: 4px solid #f0f0f0;
+  padding: 0.5em;
+}
+
+div.listingblock > div.content {
+  border: 1px solid #dddddd;
+  border-left: 5px solid #f0f0f0;
+  background: #f8f8f8;
+  padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+  padding-left: 1.0em;
+  margin-left: 1.0em;
+  margin-right: 10%;
+  border-left: 5px solid #f0f0f0;
+  color: #888;
+}
+
+div.quoteblock > div.attribution {
+  padding-top: 0.5em;
+  text-align: right;
+}
+
+div.verseblock > pre.content {
+  font-family: inherit;
+  font-size: inherit;
+}
+div.verseblock > div.attribution {
+  padding-top: 0.75em;
+  text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+  text-align: left;
+}
+
+div.admonitionblock .icon {
+  vertical-align: top;
+  font-size: 1.1em;
+  font-weight: bold;
+  text-decoration: underline;
+  color: #527bbd;
+  padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+  padding-left: 0.5em;
+  border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+  border-left: 3px solid #dddddd;
+  padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+dt {
+  margin-top: 0.5em;
+  margin-bottom: 0;
+  font-style: normal;
+  color: navy;
+}
+dd > *:first-child {
+  margin-top: 0.1em;
+}
+
+ul, ol {
+    list-style-position: outside;
+}
+ol.arabic {
+  list-style-type: decimal;
+}
+ol.loweralpha {
+  list-style-type: lower-alpha;
+}
+ol.upperalpha {
+  list-style-type: upper-alpha;
+}
+ol.lowerroman {
+  list-style-type: lower-roman;
+}
+ol.upperroman {
+  list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+  margin-top: 0.1em;
+  margin-bottom: 0.1em;
+}
+
+tfoot {
+  font-weight: bold;
+}
+td > div.verse {
+  white-space: pre;
+}
+
+div.hdlist {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+div.hdlist tr {
+  padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+  font-weight: bold;
+}
+td.hdlist1 {
+  vertical-align: top;
+  font-style: normal;
+  padding-right: 0.8em;
+  color: navy;
+}
+td.hdlist2 {
+  vertical-align: top;
+}
+div.hdlist.compact tr {
+  margin: 0;
+  padding-bottom: 0;
+}
+
+.comment {
+  background: yellow;
+}
+
+.footnote, .footnoteref {
+  font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+  vertical-align: super;
+}
+
+#footnotes {
+  margin: 20px 0 20px 0;
+  padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+  margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+  border: none;
+  border-top: 1px solid silver;
+  height: 1px;
+  text-align: left;
+  margin-left: 0;
+  width: 20%;
+  min-width: 100px;
+}
+
+div.colist td {
+  padding-right: 0.5em;
+  padding-bottom: 0.3em;
+  vertical-align: top;
+}
+div.colist td img {
+  margin-top: 0.3em;
+}
+
+@media print {
+  #footer-badges { display: none; }
+}
+
+#toc {
+  margin-bottom: 2.5em;
+}
+
+#toctitle {
+  color: #527bbd;
+  font-size: 1.1em;
+  font-weight: bold;
+  margin-top: 1.0em;
+  margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+div.toclevel2 {
+  margin-left: 2em;
+  font-size: 0.9em;
+}
+div.toclevel3 {
+  margin-left: 4em;
+  font-size: 0.9em;
+}
+div.toclevel4 {
+  margin-left: 6em;
+  font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.tableblock > table {
+  border: 3px solid #527bbd;
+}
+thead, p.table.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.table {
+  margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+  border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+  border-left-style: none;
+  border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+  border-top-style: none;
+  border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.tableblock {
+  margin-top: 0;
+}
+table.tableblock {
+  border-width: 3px;
+  border-spacing: 0px;
+  border-style: solid;
+  border-color: #527bbd;
+  border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+  border-width: 1px;
+  padding: 4px;
+  border-style: solid;
+  border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+  border-left-style: hidden;
+  border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+  border-top-style: hidden;
+  border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+  border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+  text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+  text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+  text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+  vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+  vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+  vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+  padding-top: 0.5em;
+  padding-bottom: 0.5em;
+  border-top: 2px solid silver;
+  border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+  border-style: none;
+}
+body.manpage div.sectionbody {
+  margin-left: 3em;
+}
+
+@media print {
+  body.manpage div#toc { display: none; }
+}
+
+
+div.listingblock > div.content {
+  background: rgb(28, 28, 28);
+}
+
+div.listingblock > div > pre > code {
+  color: rgb(187, 187, 187);
+}
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = {  // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+  function getText(el) {
+    var text = "";
+    for (var i = el.firstChild; i != null; i = i.nextSibling) {
+      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+        text += i.data;
+      else if (i.firstChild != null)
+        text += getText(i);
+    }
+    return text;
+  }
+
+  function TocEntry(el, text, toclevel) {
+    this.element = el;
+    this.text = text;
+    this.toclevel = toclevel;
+  }
+
+  function tocEntries(el, toclevels) {
+    var result = new Array;
+    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+    // Function that scans the DOM tree for header elements (the DOM2
+    // nodeIterator API would be a better technique but not supported by all
+    // browsers).
+    var iterate = function (el) {
+      for (var i = el.firstChild; i != null; i = i.nextSibling) {
+        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+          var mo = re.exec(i.tagName);
+          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+          }
+          iterate(i);
+        }
+      }
+    }
+    iterate(el);
+    return result;
+  }
+
+  var toc = document.getElementById("toc");
+  if (!toc) {
+    return;
+  }
+
+  // Delete existing TOC entries in case we're reloading the TOC.
+  var tocEntriesToRemove = [];
+  var i;
+  for (i = 0; i < toc.childNodes.length; i++) {
+    var entry = toc.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div'
+     && entry.getAttribute("class")
+     && entry.getAttribute("class").match(/^toclevel/))
+      tocEntriesToRemove.push(entry);
+  }
+  for (i = 0; i < tocEntriesToRemove.length; i++) {
+    toc.removeChild(tocEntriesToRemove[i]);
+  }
+
+  // Rebuild TOC entries.
+  var entries = tocEntries(document.getElementById("content"), toclevels);
+  for (var i = 0; i < entries.length; ++i) {
+    var entry = entries[i];
+    if (entry.element.id == "")
+      entry.element.id = "_toc_" + i;
+    var a = document.createElement("a");
+    a.href = "#" + entry.element.id;
+    a.appendChild(document.createTextNode(entry.text));
+    var div = document.createElement("div");
+    div.appendChild(a);
+    div.className = "toclevel" + entry.toclevel;
+    toc.appendChild(div);
+  }
+  if (entries.length == 0)
+    toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+  // Delete existing footnote entries in case we're reloading the footnodes.
+  var i;
+  var noteholder = document.getElementById("footnotes");
+  if (!noteholder) {
+    return;
+  }
+  var entriesToRemove = [];
+  for (i = 0; i < noteholder.childNodes.length; i++) {
+    var entry = noteholder.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+      entriesToRemove.push(entry);
+  }
+  for (i = 0; i < entriesToRemove.length; i++) {
+    noteholder.removeChild(entriesToRemove[i]);
+  }
+
+  // Rebuild footnote entries.
+  var cont = document.getElementById("content");
+  var spans = cont.getElementsByTagName("span");
+  var refs = {};
+  var n = 0;
+  for (i=0; i<spans.length; i++) {
+    if (spans[i].className == "footnote") {
+      n++;
+      var note = spans[i].getAttribute("data-note");
+      if (!note) {
+        // Use [\s\S] in place of . so multi-line matches work.
+        // Because JavaScript has no s (dotall) regex flag.
+        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+        spans[i].innerHTML =
+          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+        spans[i].setAttribute("data-note", note);
+      }
+      noteholder.innerHTML +=
+        "<div class='footnote' id='_footnote_" + n + "'>" +
+        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+        n + "</a>. " + note + "</div>";
+      var id =spans[i].getAttribute("id");
+      if (id != null) refs["#"+id] = n;
+    }
+  }
+  if (n == 0)
+    noteholder.parentNode.removeChild(noteholder);
+  else {
+    // Process footnoterefs.
+    for (i=0; i<spans.length; i++) {
+      if (spans[i].className == "footnoteref") {
+        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+        href = href.match(/#.*/)[0];  // Because IE return full URL.
+        n = refs[href];
+        spans[i].innerHTML =
+          "[<a href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+      }
+    }
+  }
+},
+
+install: function(toclevels) {
+  var timerId;
+
+  function reinstall() {
+    asciidoc.footnotes();
+    if (toclevels) {
+      asciidoc.toc(toclevels);
+    }
+  }
+
+  function reinstallAndRemoveTimer() {
+    clearInterval(timerId);
+    reinstall();
+  }
+
+  timerId = setInterval(reinstall, 500);
+  if (document.addEventListener)
+    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+  else
+    window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+git-reparent-branch(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>git-reparent-branch -
+   Alter the parentage (upstream) for the current branch.
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>git reparent-branch</em> &lt;new_parent&gt;
+<em>git reparent-branch</em> --lkgr
+<em>git reparent-branch</em> --root</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Change the <em>upstream</em> of the current branch, and then run
+<a href="git-rebase-update.html">git-rebase-update(1)</a> to move the commits in the current branch, as well
+as the commits in all descendant branches, onto the new parent.</p></div>
+<div class="paragraph"><p><code>&lt;new_parent&gt;</code> may be either a local branch, remote branch, OR a tag (such as
+<code>lkgr</code>).</p></div>
+<div class="paragraph"><p>This is particularly useful to reparent an independent CL to become dependent on
+another CL, or vice versa. This could happen if you started both on the
+assumption that they were independent, but later realized that this was not the
+case.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+&lt;new_parent&gt;
+</dt>
+<dd>
+<p>
+  The new parent to set as the upstream for this branch. May be a branch ref or
+  a tag.
+</p>
+</dd>
+<dt class="hdlist1">
+--lkgr
+</dt>
+<dd>
+<p>
+  Reparent to track lkgr.
+</p>
+</dd>
+<dt class="hdlist1">
+--root
+</dt>
+<dd>
+<p>
+  Reparent to track the <em>root</em> branch. Defaults to <em>origin/master</em>. See
+  <a href="git-new-branch.html">git-new-branch(1)</a>'s CONFIGURATION VARIABLES section..
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_suggested_aliases">SUGGESTED ALIASES</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Some common short-hand aliases. Feel free to add these to your <em>~/.gitconfig</em>
+file.</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>[alias]
+  git rp = reparent-branch</code></pre>
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_see_also">SEE ALSO</h2>
+<div class="sectionbody">
+<div class="paragraph"><p><a href="git-rebase-update.html">git-rebase-update(1)</a>, <a href="git-rename-branch.html">git-rename-branch(1)</a>,
+<a href="git-new-branch.html">git-new-branch(1)</a>, <a href="git-upstream-diff.html">git-upstream-diff(1)</a></p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_chromium_depot_tools">CHROMIUM DEPOT_TOOLS</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the chromium <a href="depot_tools.html">depot_tools(1)</a> suite. These tools are meant to
+assist with the development of chromium and related projects. Download the tools
+from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">here</a>.</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2014-03-25 15:09:11 PDT
+</div>
+</div>
+</body>
+</html>

+ 873 - 0
docs/html/git-squash-branch.html

@@ -0,0 +1,873 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.9" />
+<title>git-squash-branch(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+  font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+  font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+  margin: 1em 5% 1em 5%;
+}
+
+a {
+  color: blue;
+  text-decoration: underline;
+}
+a:visited {
+  color: fuchsia;
+}
+
+em {
+  font-style: italic;
+  color: navy;
+}
+
+strong {
+  font-weight: bold;
+  color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  color: #527bbd;
+  margin-top: 1.2em;
+  margin-bottom: 0.5em;
+  line-height: 1.3;
+}
+
+h1, h2, h3 {
+  border-bottom: 2px solid silver;
+}
+h2 {
+  padding-top: 0.5em;
+}
+h3 {
+  float: left;
+}
+h3 + * {
+  clear: left;
+}
+h5 {
+  font-size: 1.0em;
+}
+
+div.sectionbody {
+  margin-left: 0;
+}
+
+hr {
+  border: 1px solid silver;
+}
+
+p {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+  margin-top: 0;
+}
+ul > li     { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+  font-family: "Courier New", Courier, monospace;
+  font-size: inherit;
+  color: navy;
+  padding: 0;
+  margin: 0;
+}
+pre {
+  white-space: pre-wrap;
+}
+
+#author {
+  color: #527bbd;
+  font-weight: bold;
+  font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+  font-size: small;
+  border-top: 2px solid silver;
+  padding-top: 0.5em;
+  margin-top: 4.0em;
+}
+#footer-text {
+  float: left;
+  padding-bottom: 0.5em;
+}
+#footer-badges {
+  float: right;
+  padding-bottom: 0.5em;
+}
+
+#preamble {
+  margin-top: 1.5em;
+  margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.admonitionblock {
+  margin-top: 2.0em;
+  margin-bottom: 2.0em;
+  margin-right: 10%;
+  color: #606060;
+}
+
+div.content { /* Block element content. */
+  padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+  color: #527bbd;
+  font-weight: bold;
+  text-align: left;
+  margin-top: 1.0em;
+  margin-bottom: 0.5em;
+}
+div.title + * {
+  margin-top: 0;
+}
+
+td div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content + div.title {
+  margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+  background: #ffffee;
+  border: 1px solid #dddddd;
+  border-left: 4px solid #f0f0f0;
+  padding: 0.5em;
+}
+
+div.listingblock > div.content {
+  border: 1px solid #dddddd;
+  border-left: 5px solid #f0f0f0;
+  background: #f8f8f8;
+  padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+  padding-left: 1.0em;
+  margin-left: 1.0em;
+  margin-right: 10%;
+  border-left: 5px solid #f0f0f0;
+  color: #888;
+}
+
+div.quoteblock > div.attribution {
+  padding-top: 0.5em;
+  text-align: right;
+}
+
+div.verseblock > pre.content {
+  font-family: inherit;
+  font-size: inherit;
+}
+div.verseblock > div.attribution {
+  padding-top: 0.75em;
+  text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+  text-align: left;
+}
+
+div.admonitionblock .icon {
+  vertical-align: top;
+  font-size: 1.1em;
+  font-weight: bold;
+  text-decoration: underline;
+  color: #527bbd;
+  padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+  padding-left: 0.5em;
+  border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+  border-left: 3px solid #dddddd;
+  padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+dt {
+  margin-top: 0.5em;
+  margin-bottom: 0;
+  font-style: normal;
+  color: navy;
+}
+dd > *:first-child {
+  margin-top: 0.1em;
+}
+
+ul, ol {
+    list-style-position: outside;
+}
+ol.arabic {
+  list-style-type: decimal;
+}
+ol.loweralpha {
+  list-style-type: lower-alpha;
+}
+ol.upperalpha {
+  list-style-type: upper-alpha;
+}
+ol.lowerroman {
+  list-style-type: lower-roman;
+}
+ol.upperroman {
+  list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+  margin-top: 0.1em;
+  margin-bottom: 0.1em;
+}
+
+tfoot {
+  font-weight: bold;
+}
+td > div.verse {
+  white-space: pre;
+}
+
+div.hdlist {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+div.hdlist tr {
+  padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+  font-weight: bold;
+}
+td.hdlist1 {
+  vertical-align: top;
+  font-style: normal;
+  padding-right: 0.8em;
+  color: navy;
+}
+td.hdlist2 {
+  vertical-align: top;
+}
+div.hdlist.compact tr {
+  margin: 0;
+  padding-bottom: 0;
+}
+
+.comment {
+  background: yellow;
+}
+
+.footnote, .footnoteref {
+  font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+  vertical-align: super;
+}
+
+#footnotes {
+  margin: 20px 0 20px 0;
+  padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+  margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+  border: none;
+  border-top: 1px solid silver;
+  height: 1px;
+  text-align: left;
+  margin-left: 0;
+  width: 20%;
+  min-width: 100px;
+}
+
+div.colist td {
+  padding-right: 0.5em;
+  padding-bottom: 0.3em;
+  vertical-align: top;
+}
+div.colist td img {
+  margin-top: 0.3em;
+}
+
+@media print {
+  #footer-badges { display: none; }
+}
+
+#toc {
+  margin-bottom: 2.5em;
+}
+
+#toctitle {
+  color: #527bbd;
+  font-size: 1.1em;
+  font-weight: bold;
+  margin-top: 1.0em;
+  margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+div.toclevel2 {
+  margin-left: 2em;
+  font-size: 0.9em;
+}
+div.toclevel3 {
+  margin-left: 4em;
+  font-size: 0.9em;
+}
+div.toclevel4 {
+  margin-left: 6em;
+  font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.tableblock > table {
+  border: 3px solid #527bbd;
+}
+thead, p.table.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.table {
+  margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+  border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+  border-left-style: none;
+  border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+  border-top-style: none;
+  border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.tableblock {
+  margin-top: 0;
+}
+table.tableblock {
+  border-width: 3px;
+  border-spacing: 0px;
+  border-style: solid;
+  border-color: #527bbd;
+  border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+  border-width: 1px;
+  padding: 4px;
+  border-style: solid;
+  border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+  border-left-style: hidden;
+  border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+  border-top-style: hidden;
+  border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+  border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+  text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+  text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+  text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+  vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+  vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+  vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+  padding-top: 0.5em;
+  padding-bottom: 0.5em;
+  border-top: 2px solid silver;
+  border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+  border-style: none;
+}
+body.manpage div.sectionbody {
+  margin-left: 3em;
+}
+
+@media print {
+  body.manpage div#toc { display: none; }
+}
+
+
+div.listingblock > div.content {
+  background: rgb(28, 28, 28);
+}
+
+div.listingblock > div > pre > code {
+  color: rgb(187, 187, 187);
+}
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = {  // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+  function getText(el) {
+    var text = "";
+    for (var i = el.firstChild; i != null; i = i.nextSibling) {
+      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+        text += i.data;
+      else if (i.firstChild != null)
+        text += getText(i);
+    }
+    return text;
+  }
+
+  function TocEntry(el, text, toclevel) {
+    this.element = el;
+    this.text = text;
+    this.toclevel = toclevel;
+  }
+
+  function tocEntries(el, toclevels) {
+    var result = new Array;
+    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+    // Function that scans the DOM tree for header elements (the DOM2
+    // nodeIterator API would be a better technique but not supported by all
+    // browsers).
+    var iterate = function (el) {
+      for (var i = el.firstChild; i != null; i = i.nextSibling) {
+        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+          var mo = re.exec(i.tagName);
+          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+          }
+          iterate(i);
+        }
+      }
+    }
+    iterate(el);
+    return result;
+  }
+
+  var toc = document.getElementById("toc");
+  if (!toc) {
+    return;
+  }
+
+  // Delete existing TOC entries in case we're reloading the TOC.
+  var tocEntriesToRemove = [];
+  var i;
+  for (i = 0; i < toc.childNodes.length; i++) {
+    var entry = toc.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div'
+     && entry.getAttribute("class")
+     && entry.getAttribute("class").match(/^toclevel/))
+      tocEntriesToRemove.push(entry);
+  }
+  for (i = 0; i < tocEntriesToRemove.length; i++) {
+    toc.removeChild(tocEntriesToRemove[i]);
+  }
+
+  // Rebuild TOC entries.
+  var entries = tocEntries(document.getElementById("content"), toclevels);
+  for (var i = 0; i < entries.length; ++i) {
+    var entry = entries[i];
+    if (entry.element.id == "")
+      entry.element.id = "_toc_" + i;
+    var a = document.createElement("a");
+    a.href = "#" + entry.element.id;
+    a.appendChild(document.createTextNode(entry.text));
+    var div = document.createElement("div");
+    div.appendChild(a);
+    div.className = "toclevel" + entry.toclevel;
+    toc.appendChild(div);
+  }
+  if (entries.length == 0)
+    toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+  // Delete existing footnote entries in case we're reloading the footnodes.
+  var i;
+  var noteholder = document.getElementById("footnotes");
+  if (!noteholder) {
+    return;
+  }
+  var entriesToRemove = [];
+  for (i = 0; i < noteholder.childNodes.length; i++) {
+    var entry = noteholder.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+      entriesToRemove.push(entry);
+  }
+  for (i = 0; i < entriesToRemove.length; i++) {
+    noteholder.removeChild(entriesToRemove[i]);
+  }
+
+  // Rebuild footnote entries.
+  var cont = document.getElementById("content");
+  var spans = cont.getElementsByTagName("span");
+  var refs = {};
+  var n = 0;
+  for (i=0; i<spans.length; i++) {
+    if (spans[i].className == "footnote") {
+      n++;
+      var note = spans[i].getAttribute("data-note");
+      if (!note) {
+        // Use [\s\S] in place of . so multi-line matches work.
+        // Because JavaScript has no s (dotall) regex flag.
+        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+        spans[i].innerHTML =
+          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+        spans[i].setAttribute("data-note", note);
+      }
+      noteholder.innerHTML +=
+        "<div class='footnote' id='_footnote_" + n + "'>" +
+        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+        n + "</a>. " + note + "</div>";
+      var id =spans[i].getAttribute("id");
+      if (id != null) refs["#"+id] = n;
+    }
+  }
+  if (n == 0)
+    noteholder.parentNode.removeChild(noteholder);
+  else {
+    // Process footnoterefs.
+    for (i=0; i<spans.length; i++) {
+      if (spans[i].className == "footnoteref") {
+        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+        href = href.match(/#.*/)[0];  // Because IE return full URL.
+        n = refs[href];
+        spans[i].innerHTML =
+          "[<a href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+      }
+    }
+  }
+},
+
+install: function(toclevels) {
+  var timerId;
+
+  function reinstall() {
+    asciidoc.footnotes();
+    if (toclevels) {
+      asciidoc.toc(toclevels);
+    }
+  }
+
+  function reinstallAndRemoveTimer() {
+    clearInterval(timerId);
+    reinstall();
+  }
+
+  timerId = setInterval(reinstall, 500);
+  if (document.addEventListener)
+    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+  else
+    window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+git-squash-branch(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>git-squash-branch -
+   Takes all commits in a single branch and replaces them with a single commit.
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>git squash-branch</em> [-m &lt;message&gt;]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p><code>git squash-branch</code> is a simple helper command. It takes all the commits on the
+current branch from the <em>merge_base</em> to HEAD, and reduces them to a single
+commit. The new commit will contain a summary of all the commits which were
+squashed, preceeded by a header message indicating that it&#8217;s the result of a
+squash (or the message you pass on the command line.).</p></div>
+<div class="paragraph"><p>Squashing branches is useful when trying to rebase-update over branches which
+were pushed to their upsteram (or committed by the <em>Commit Queue</em>), and then
+conflicting changes landed in upstream on top of the push/commit. If you know
+that your branch was committed but <a href="git-rebase-update.html">git-rebase-update(1)</a> isn&#8217;t able to
+automatically clean it, you can squash the troublesome branch before <code>git
+rebase-update</code>, and then when <code>git rebase-update</code> presents the conflict, you can
+verify that the conflict diff is what you expected (and then skip it with
+<code>git rebase --skip</code>).</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+-m &lt;message&gt;
+</dt>
+<dt class="hdlist1">
+--message=&lt;message&gt;
+</dt>
+<dd>
+<p>
+  Optional message to use for the first line of the squashed commit. If omitted,
+  it defaults to "git squash commit.".
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_example">EXAMPLE</h2>
+<div class="sectionbody">
+<div class="listingblock">
+<div class="content">
+<pre><code><strong><span class="white">$ git map</span></strong>
+<span class="white blue-background">*</span>&#8203;<strong><span class="blue-background red"> 7dcfe47       </span></strong> <span class="green">(</span>&#8203;<strong><span class="aqua">frozen_changes</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-12</span> ~ FREEZE.unindexed
+* <strong><span class="red">4b0c180</span></strong>        <span class="yellow">2014-03-12</span> ~ modfile
+* <strong><span class="red">59a7cca</span></strong>        <span class="yellow">2014-03-12</span> ~ a deleted file
+* <strong><span class="red">6bec695</span></strong>        <span class="green">(</span>&#8203;<span class="red">origin/master</span>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Add neat feature    <strong><span class="white">&lt;(frozen_changes)</span></strong>
+* <strong><span class="red">d15a38a</span></strong>        <span class="yellow">2014-03-11</span> ~ Epic README update
+* <strong><span class="red">d559894</span></strong>        <span class="green">(</span>&#8203;<strong><span class="lime">master</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Important upstream change
+<span class="red">|</span> * <strong><span class="red">9c311fd</span></strong>      <span class="green">(</span>&#8203;<strong><span class="lime">cool_feature</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Respond to CL comments
+<span class="red">|</span> <span class="green">|</span> * <strong><span class="red">2a1eeb2</span></strong>    <span class="green">(</span>&#8203;<strong><span class="lime">subfeature</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ integrate with CoolService
+<span class="red">|</span> <span class="green">|</span> * <strong><span class="red">d777af6</span></strong>    <span class="yellow">2014-03-11</span> ~ slick commenting action
+<span class="red">|</span> <span class="green">|/</span>
+<span class="red">|</span> * <strong><span class="red">265803a</span></strong>      <span class="yellow">2014-03-11</span> ~ another improvement    <strong><span class="white">&lt;(subfeature)</span></strong>
+<span class="red">|</span> * <strong><span class="red">6d831ac</span></strong>      <span class="green">(</span>&#8203;<strong><span class="fuchsia">spleen_tag</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Refactor spleen
+<span class="red">|</span> * <strong><span class="red">82e74ab</span></strong>      <span class="yellow">2014-03-11</span> ~ Add widget
+<span class="red">|/</span>
+* <strong><span class="red">d08c5b3</span></strong>        <span class="green">(</span>&#8203;<strong><span class="lime">bogus_noparent</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Wonderful beginnings    <strong><span class="white">&lt;(cool_feature)</span></strong>
+<strong><span class="white">$ git squash-branch "cool squash demo"</span></strong>
+<strong><span class="white">$ git map</span></strong>
+<span class="white blue-background">*</span>&#8203;<strong><span class="blue-background red"> 2c81508       </span></strong> <span class="green">(</span>&#8203;<strong><span class="aqua">frozen_changes</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-22</span> ~ cool squash demo
+* <strong><span class="red">6bec695</span></strong>        <span class="green">(</span>&#8203;<span class="red">origin/master</span>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Add neat feature    <strong><span class="white">&lt;(frozen_changes)</span></strong>
+* <strong><span class="red">d15a38a</span></strong>        <span class="yellow">2014-03-11</span> ~ Epic README update
+* <strong><span class="red">d559894</span></strong>        <span class="green">(</span>&#8203;<strong><span class="lime">master</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Important upstream change
+<span class="red">|</span> * <strong><span class="red">9c311fd</span></strong>      <span class="green">(</span>&#8203;<strong><span class="lime">cool_feature</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Respond to CL comments
+<span class="red">|</span> <span class="green">|</span> * <strong><span class="red">2a1eeb2</span></strong>    <span class="green">(</span>&#8203;<strong><span class="lime">subfeature</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ integrate with CoolService
+<span class="red">|</span> <span class="green">|</span> * <strong><span class="red">d777af6</span></strong>    <span class="yellow">2014-03-11</span> ~ slick commenting action
+<span class="red">|</span> <span class="green">|/</span>
+<span class="red">|</span> * <strong><span class="red">265803a</span></strong>      <span class="yellow">2014-03-11</span> ~ another improvement    <strong><span class="white">&lt;(subfeature)</span></strong>
+<span class="red">|</span> * <strong><span class="red">6d831ac</span></strong>      <span class="green">(</span>&#8203;<strong><span class="fuchsia">spleen_tag</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Refactor spleen
+<span class="red">|</span> * <strong><span class="red">82e74ab</span></strong>      <span class="yellow">2014-03-11</span> ~ Add widget
+<span class="red">|/</span>
+* <strong><span class="red">d08c5b3</span></strong>        <span class="green">(</span>&#8203;<strong><span class="lime">bogus_noparent</span></strong>&#8203;<span class="green">)</span> <span class="yellow">2014-03-11</span> ~ Wonderful beginnings    <strong><span class="white">&lt;(cool_feature)</span></strong></code></pre>
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_suggested_aliases">SUGGESTED ALIASES</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Some common short-hand aliases. Feel free to add these to your <em>~/.gitconfig</em>
+file.</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>[alias]
+  git squash = squash-branch</code></pre>
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_see_also">SEE ALSO</h2>
+<div class="sectionbody">
+<div class="paragraph"><p><a href="git-rebase-update.html">git-rebase-update(1)</a></p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_chromium_depot_tools">CHROMIUM DEPOT_TOOLS</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the chromium <a href="depot_tools.html">depot_tools(1)</a> suite. These tools are meant to
+assist with the development of chromium and related projects. Download the tools
+from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">here</a>.</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2014-03-25 15:09:11 PDT
+</div>
+</div>
+</body>
+</html>

+ 1 - 1
docs/html/git-thaw.html

@@ -787,7 +787,7 @@ from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">
 <div id="footnotes"><hr /></div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2014-03-14 13:12:40 PDT
+Last updated 2014-03-25 15:09:11 PDT
 </div>
 </div>
 </body>

+ 887 - 0
docs/html/git-upstream-diff.html

@@ -0,0 +1,887 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.9" />
+<title>git-upstream-diff(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+  font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+  font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+  margin: 1em 5% 1em 5%;
+}
+
+a {
+  color: blue;
+  text-decoration: underline;
+}
+a:visited {
+  color: fuchsia;
+}
+
+em {
+  font-style: italic;
+  color: navy;
+}
+
+strong {
+  font-weight: bold;
+  color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  color: #527bbd;
+  margin-top: 1.2em;
+  margin-bottom: 0.5em;
+  line-height: 1.3;
+}
+
+h1, h2, h3 {
+  border-bottom: 2px solid silver;
+}
+h2 {
+  padding-top: 0.5em;
+}
+h3 {
+  float: left;
+}
+h3 + * {
+  clear: left;
+}
+h5 {
+  font-size: 1.0em;
+}
+
+div.sectionbody {
+  margin-left: 0;
+}
+
+hr {
+  border: 1px solid silver;
+}
+
+p {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+  margin-top: 0;
+}
+ul > li     { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+  font-family: "Courier New", Courier, monospace;
+  font-size: inherit;
+  color: navy;
+  padding: 0;
+  margin: 0;
+}
+pre {
+  white-space: pre-wrap;
+}
+
+#author {
+  color: #527bbd;
+  font-weight: bold;
+  font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+  font-size: small;
+  border-top: 2px solid silver;
+  padding-top: 0.5em;
+  margin-top: 4.0em;
+}
+#footer-text {
+  float: left;
+  padding-bottom: 0.5em;
+}
+#footer-badges {
+  float: right;
+  padding-bottom: 0.5em;
+}
+
+#preamble {
+  margin-top: 1.5em;
+  margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.admonitionblock {
+  margin-top: 2.0em;
+  margin-bottom: 2.0em;
+  margin-right: 10%;
+  color: #606060;
+}
+
+div.content { /* Block element content. */
+  padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+  color: #527bbd;
+  font-weight: bold;
+  text-align: left;
+  margin-top: 1.0em;
+  margin-bottom: 0.5em;
+}
+div.title + * {
+  margin-top: 0;
+}
+
+td div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content + div.title {
+  margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+  background: #ffffee;
+  border: 1px solid #dddddd;
+  border-left: 4px solid #f0f0f0;
+  padding: 0.5em;
+}
+
+div.listingblock > div.content {
+  border: 1px solid #dddddd;
+  border-left: 5px solid #f0f0f0;
+  background: #f8f8f8;
+  padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+  padding-left: 1.0em;
+  margin-left: 1.0em;
+  margin-right: 10%;
+  border-left: 5px solid #f0f0f0;
+  color: #888;
+}
+
+div.quoteblock > div.attribution {
+  padding-top: 0.5em;
+  text-align: right;
+}
+
+div.verseblock > pre.content {
+  font-family: inherit;
+  font-size: inherit;
+}
+div.verseblock > div.attribution {
+  padding-top: 0.75em;
+  text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+  text-align: left;
+}
+
+div.admonitionblock .icon {
+  vertical-align: top;
+  font-size: 1.1em;
+  font-weight: bold;
+  text-decoration: underline;
+  color: #527bbd;
+  padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+  padding-left: 0.5em;
+  border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+  border-left: 3px solid #dddddd;
+  padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+dt {
+  margin-top: 0.5em;
+  margin-bottom: 0;
+  font-style: normal;
+  color: navy;
+}
+dd > *:first-child {
+  margin-top: 0.1em;
+}
+
+ul, ol {
+    list-style-position: outside;
+}
+ol.arabic {
+  list-style-type: decimal;
+}
+ol.loweralpha {
+  list-style-type: lower-alpha;
+}
+ol.upperalpha {
+  list-style-type: upper-alpha;
+}
+ol.lowerroman {
+  list-style-type: lower-roman;
+}
+ol.upperroman {
+  list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+  margin-top: 0.1em;
+  margin-bottom: 0.1em;
+}
+
+tfoot {
+  font-weight: bold;
+}
+td > div.verse {
+  white-space: pre;
+}
+
+div.hdlist {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+div.hdlist tr {
+  padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+  font-weight: bold;
+}
+td.hdlist1 {
+  vertical-align: top;
+  font-style: normal;
+  padding-right: 0.8em;
+  color: navy;
+}
+td.hdlist2 {
+  vertical-align: top;
+}
+div.hdlist.compact tr {
+  margin: 0;
+  padding-bottom: 0;
+}
+
+.comment {
+  background: yellow;
+}
+
+.footnote, .footnoteref {
+  font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+  vertical-align: super;
+}
+
+#footnotes {
+  margin: 20px 0 20px 0;
+  padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+  margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+  border: none;
+  border-top: 1px solid silver;
+  height: 1px;
+  text-align: left;
+  margin-left: 0;
+  width: 20%;
+  min-width: 100px;
+}
+
+div.colist td {
+  padding-right: 0.5em;
+  padding-bottom: 0.3em;
+  vertical-align: top;
+}
+div.colist td img {
+  margin-top: 0.3em;
+}
+
+@media print {
+  #footer-badges { display: none; }
+}
+
+#toc {
+  margin-bottom: 2.5em;
+}
+
+#toctitle {
+  color: #527bbd;
+  font-size: 1.1em;
+  font-weight: bold;
+  margin-top: 1.0em;
+  margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+div.toclevel2 {
+  margin-left: 2em;
+  font-size: 0.9em;
+}
+div.toclevel3 {
+  margin-left: 4em;
+  font-size: 0.9em;
+}
+div.toclevel4 {
+  margin-left: 6em;
+  font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.tableblock > table {
+  border: 3px solid #527bbd;
+}
+thead, p.table.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.table {
+  margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+  border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+  border-left-style: none;
+  border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+  border-top-style: none;
+  border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.tableblock {
+  margin-top: 0;
+}
+table.tableblock {
+  border-width: 3px;
+  border-spacing: 0px;
+  border-style: solid;
+  border-color: #527bbd;
+  border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+  border-width: 1px;
+  padding: 4px;
+  border-style: solid;
+  border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+  border-left-style: hidden;
+  border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+  border-top-style: hidden;
+  border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+  border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+  text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+  text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+  text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+  vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+  vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+  vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+  padding-top: 0.5em;
+  padding-bottom: 0.5em;
+  border-top: 2px solid silver;
+  border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+  border-style: none;
+}
+body.manpage div.sectionbody {
+  margin-left: 3em;
+}
+
+@media print {
+  body.manpage div#toc { display: none; }
+}
+
+
+div.listingblock > div.content {
+  background: rgb(28, 28, 28);
+}
+
+div.listingblock > div > pre > code {
+  color: rgb(187, 187, 187);
+}
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = {  // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+  function getText(el) {
+    var text = "";
+    for (var i = el.firstChild; i != null; i = i.nextSibling) {
+      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+        text += i.data;
+      else if (i.firstChild != null)
+        text += getText(i);
+    }
+    return text;
+  }
+
+  function TocEntry(el, text, toclevel) {
+    this.element = el;
+    this.text = text;
+    this.toclevel = toclevel;
+  }
+
+  function tocEntries(el, toclevels) {
+    var result = new Array;
+    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+    // Function that scans the DOM tree for header elements (the DOM2
+    // nodeIterator API would be a better technique but not supported by all
+    // browsers).
+    var iterate = function (el) {
+      for (var i = el.firstChild; i != null; i = i.nextSibling) {
+        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+          var mo = re.exec(i.tagName);
+          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+          }
+          iterate(i);
+        }
+      }
+    }
+    iterate(el);
+    return result;
+  }
+
+  var toc = document.getElementById("toc");
+  if (!toc) {
+    return;
+  }
+
+  // Delete existing TOC entries in case we're reloading the TOC.
+  var tocEntriesToRemove = [];
+  var i;
+  for (i = 0; i < toc.childNodes.length; i++) {
+    var entry = toc.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div'
+     && entry.getAttribute("class")
+     && entry.getAttribute("class").match(/^toclevel/))
+      tocEntriesToRemove.push(entry);
+  }
+  for (i = 0; i < tocEntriesToRemove.length; i++) {
+    toc.removeChild(tocEntriesToRemove[i]);
+  }
+
+  // Rebuild TOC entries.
+  var entries = tocEntries(document.getElementById("content"), toclevels);
+  for (var i = 0; i < entries.length; ++i) {
+    var entry = entries[i];
+    if (entry.element.id == "")
+      entry.element.id = "_toc_" + i;
+    var a = document.createElement("a");
+    a.href = "#" + entry.element.id;
+    a.appendChild(document.createTextNode(entry.text));
+    var div = document.createElement("div");
+    div.appendChild(a);
+    div.className = "toclevel" + entry.toclevel;
+    toc.appendChild(div);
+  }
+  if (entries.length == 0)
+    toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+  // Delete existing footnote entries in case we're reloading the footnodes.
+  var i;
+  var noteholder = document.getElementById("footnotes");
+  if (!noteholder) {
+    return;
+  }
+  var entriesToRemove = [];
+  for (i = 0; i < noteholder.childNodes.length; i++) {
+    var entry = noteholder.childNodes[i];
+    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+      entriesToRemove.push(entry);
+  }
+  for (i = 0; i < entriesToRemove.length; i++) {
+    noteholder.removeChild(entriesToRemove[i]);
+  }
+
+  // Rebuild footnote entries.
+  var cont = document.getElementById("content");
+  var spans = cont.getElementsByTagName("span");
+  var refs = {};
+  var n = 0;
+  for (i=0; i<spans.length; i++) {
+    if (spans[i].className == "footnote") {
+      n++;
+      var note = spans[i].getAttribute("data-note");
+      if (!note) {
+        // Use [\s\S] in place of . so multi-line matches work.
+        // Because JavaScript has no s (dotall) regex flag.
+        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+        spans[i].innerHTML =
+          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+        spans[i].setAttribute("data-note", note);
+      }
+      noteholder.innerHTML +=
+        "<div class='footnote' id='_footnote_" + n + "'>" +
+        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+        n + "</a>. " + note + "</div>";
+      var id =spans[i].getAttribute("id");
+      if (id != null) refs["#"+id] = n;
+    }
+  }
+  if (n == 0)
+    noteholder.parentNode.removeChild(noteholder);
+  else {
+    // Process footnoterefs.
+    for (i=0; i<spans.length; i++) {
+      if (spans[i].className == "footnoteref") {
+        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+        href = href.match(/#.*/)[0];  // Because IE return full URL.
+        n = refs[href];
+        spans[i].innerHTML =
+          "[<a href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+      }
+    }
+  }
+},
+
+install: function(toclevels) {
+  var timerId;
+
+  function reinstall() {
+    asciidoc.footnotes();
+    if (toclevels) {
+      asciidoc.toc(toclevels);
+    }
+  }
+
+  function reinstallAndRemoveTimer() {
+    clearInterval(timerId);
+    reinstall();
+  }
+
+  timerId = setInterval(reinstall, 500);
+  if (document.addEventListener)
+    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+  else
+    window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+git-upstream-diff(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>git-upstream-diff -
+   Print a diff of the current branch, compared to its upstream.
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>git upstream-diff</em> [--wordwise] [&lt;extra args for git-diff&gt;*]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Shows a diff beween your current branch and it&#8217;s upstream. This is <em>roughly</em> the
+same as:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>git diff --patience -C -C HEAD@{upstream}  <b>&lt;1&gt;</b> <b>&lt;2&gt;</b></code></pre>
+</div></div>
+<div class="colist arabic"><ol>
+<li>
+<p>
+<code>-C -C</code> detects file copies/renames
+</p>
+</li>
+<li>
+<p>
+<code>--patience</code> uses the patience-diff algorithm, which tends to produce nicer
+  diffs in many cases.
+</p>
+</li>
+</ol></div>
+<div class="paragraph"><p>The difference is that <code>HEAD@{upstream}</code> is actually the tagged merge base of
+your branch (See <a href="git-rebase-update.html">git-rebase-update(1)</a>). This means that if your upstream
+branch was rebased, but you haven&#8217;t yet rebased the current branch on top of it,
+you&#8217;ll still see an accurate diff compared to just diffing against
+<code>@{upstream}</code>.</p></div>
+<div class="paragraph"><p>The <code>--wordwise</code> option also allows <code>git-diff</code> to do word-by-word comparison
+in a semi-intelligent way. However, sometimes it can produce surprising results,
+so it is disabled by default.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+--wordwise
+</dt>
+<dd>
+<p>
+  Print a colorized word-wise diff instead of a line-wise diff.
+</p>
+</dd>
+<dt class="hdlist1">
+&lt;extra args for git-diff&gt;
+</dt>
+<dd>
+<p>
+  Extra arguments are included in the invocation of <a href="git-diff.html">git-diff(1)</a>. These
+  can be anything that <code>git-diff</code> normally takes.
+</p>
+<div class="openblock">
+<div class="content">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+<code>--stat</code>
+</dt>
+<dd>
+<p>
+  This is particularly useful to show <em>which</em> files have been changed in
+  comparison to the upstream branch.
+</p>
+</dd>
+<dt class="hdlist1">
+<code>-- &lt;filename patterns&gt;*</code>
+</dt>
+<dd>
+<p>
+  Restrict the diff to only show the diff for given files compared to the
+  upstream.
+</p>
+</dd>
+</dl></div>
+</div></div>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_configuration_variables">CONFIGURATION VARIABLES</h2>
+<div class="sectionbody">
+<div class="sect2">
+<h3 id="_depot_tools_upstream_diff_default_args">depot-tools.upstream-diff.default-args</h3>
+<div class="paragraph"><p>A list-configuration variable. Each instance of this config variable will be
+prepended to all invocations of <code>git upstream-diff</code>, as if you had passed them
+on the command line.</p></div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_suggested_aliases">SUGGESTED ALIASES</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Some common short-hand aliases. Feel free to add these to your <em>~/.gitconfig</em>
+file.</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>[alias]
+  git udiff = upstream-diff</code></pre>
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_see_also">SEE ALSO</h2>
+<div class="sectionbody">
+<div class="paragraph"><p><a href="git-rebase-update.html">git-rebase-update(1)</a></p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_chromium_depot_tools">CHROMIUM DEPOT_TOOLS</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the chromium <a href="depot_tools.html">depot_tools(1)</a> suite. These tools are meant to
+assist with the development of chromium and related projects. Download the tools
+from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">here</a>.</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2014-03-25 15:03:05 PDT
+</div>
+</div>
+</body>
+</html>

+ 38 - 3
docs/man1/depot_tools.1

@@ -2,12 +2,12 @@
 .\"     Title: depot_tools
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 03/14/2014
+.\"      Date: 03/25/2014
 .\"    Manual: Chromium depot_tools Manual
-.\"    Source: depot_tools a57ed8f
+.\"    Source: depot_tools 207bff1
 .\"  Language: English
 .\"
-.TH "DEPOT_TOOLS" "1" "03/14/2014" "depot_tools a57ed8f" "Chromium depot_tools Manual"
+.TH "DEPOT_TOOLS" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -55,6 +55,11 @@ Helper script to display all local git branches with \(oqupstream\(cq hierarchy
 Display history of all branches in a colorized terminal format\&.
 .RE
 .PP
+\fBgit-mark-merge-base\fR(1)
+.RS 4
+Manually interact with depot_tools\*(Aq merge\-base markers\&.
+.RE
+.PP
 \fBgit-nav-downstream\fR(1)
 .RS 4
 Checkout a downstream branch of the currently checked out branch\&.
@@ -65,10 +70,40 @@ Checkout a downstream branch of the currently checked out branch\&.
 Checkout the upstream branch of the currently checked out branch\&.
 .RE
 .PP
+\fBgit-new-branch\fR(1)
+.RS 4
+Create a new branch with correct tracking information\&.
+.RE
+.PP
+\fBgit-rebase-update\fR(1)
+.RS 4
+Updates all branches to have the latest changes from their upstreams\&.
+.RE
+.PP
+\fBgit-rename-branch\fR(1)
+.RS 4
+Rename a branch and correctly preserve all downstream relationships\&.
+.RE
+.PP
+\fBgit-reparent-branch\fR(1)
+.RS 4
+Alter the parentage (upstream) for the current branch\&.
+.RE
+.PP
+\fBgit-squash-branch\fR(1)
+.RS 4
+Takes all commits in a single branch and replaces them with a single commit\&.
+.RE
+.PP
 \fBgit-thaw\fR(1)
 .RS 4
 Un\-freeze all changes on a frozen branch\&.
 .RE
+.PP
+\fBgit-upstream-diff\fR(1)
+.RS 4
+Print a diff of the current branch, compared to its upstream\&.
+.RE
 .SH "NOTES"
 .IP " 1." 4
 here

+ 3 - 3
docs/man1/git-freeze.1

@@ -2,12 +2,12 @@
 .\"     Title: git-freeze
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 03/14/2014
+.\"      Date: 03/25/2014
 .\"    Manual: Chromium depot_tools Manual
-.\"    Source: depot_tools a57ed8f
+.\"    Source: depot_tools 207bff1
 .\"  Language: English
 .\"
-.TH "GIT\-FREEZE" "1" "03/14/2014" "depot_tools a57ed8f" "Chromium depot_tools Manual"
+.TH "GIT\-FREEZE" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------

+ 18 - 3
docs/man1/git-map-branches.1

@@ -2,12 +2,12 @@
 .\"     Title: git-map-branches
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 03/14/2014
+.\"      Date: 03/25/2014
 .\"    Manual: Chromium depot_tools Manual
-.\"    Source: depot_tools a57ed8f
+.\"    Source: depot_tools 207bff1
 .\"  Language: English
 .\"
-.TH "GIT\-MAP\-BRANCHES" "1" "03/14/2014" "depot_tools a57ed8f" "Chromium depot_tools Manual"
+.TH "GIT\-MAP\-BRANCHES" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -148,6 +148,21 @@ origin/master
 .RE
 .\}
 .sp
+.SH "SUGGESTED ALIASES"
+.sp
+Some common short\-hand aliases\&. Feel free to add these to your \fI~/\&.gitconfig\fR file\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+[alias]
+  git bmap = map\-branches
+.fi
+.if n \{\
+.RE
+.\}
+.sp
 .SH "SEE ALSO"
 .sp
 \fBgit-map\fR(1)

+ 21 - 9
docs/man1/git-map.1

@@ -2,12 +2,12 @@
 .\"     Title: git-map
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 03/14/2014
+.\"      Date: 03/25/2014
 .\"    Manual: Chromium depot_tools Manual
-.\"    Source: depot_tools a57ed8f
+.\"    Source: depot_tools 207bff1
 .\"  Language: English
 .\"
-.TH "GIT\-MAP" "1" "03/14/2014" "depot_tools a57ed8f" "Chromium depot_tools Manual"
+.TH "GIT\-MAP" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -95,6 +95,18 @@ magenta\&.
 .sp -1
 .IP \(bu 2.3
 .\}
+Merge Base markers are
+white\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
 The currently checked out commit is highlighted with a
 blue background\&.
 .RE
@@ -110,13 +122,13 @@ invocation\&. This can be used to restrict what refs
 \fIgit map\fR
 operates on, etc\&.
 .sp
-If you run git map with a series of fixed arguments frequently, you can use the depot_tools\&.map_extra configuration variable to pre\-set arguments (See
+If you run git map with a series of fixed arguments frequently, you can use the depot\-tools\&.map\-extra configuration variable to pre\-set arguments (See
 CONFIGURATION VARIABLES)
 .RE
 .SH "CONFIGURATION VARIABLES"
-.SS "depot_tools\&.map_extra"
+.SS "depot\-tools\&.map\-extra"
 .sp
-Each value of the \fIdepot_tools\&.map_extra\fR config variable is applied as an additional argument to git log during the execution of git map\&. If you wish to configure this, use git config \-\-add depot_tools\&.map_extra <value> to do so\&.
+Each value of the \fIdepot\-tools\&.map\-extra\fR config variable is applied as an additional argument to git log during the execution of git map\&. If you wish to configure this, use git config \-\-add depot\-tools\&.map\-extra <value> to do so\&.
 .SH "EXAMPLE"
 .sp
 Running \fIgit map\fR would result in an output something like:
@@ -129,18 +141,18 @@ Running \fIgit map\fR would result in an output something like:
 *\:\fB 7dcfe47       \fR (\:\fBfrozen_changes\fR\:) 2014\-03\-12 ~ FREEZE\&.unindexed
 * \fB4b0c180\fR        2014\-03\-12 ~ modfile
 * \fB59a7cca\fR        2014\-03\-12 ~ a deleted file
-* \fB6bec695\fR        (\:origin/master\:) 2014\-03\-11 ~ Add neat feature
+* \fB6bec695\fR        (\:origin/master\:) 2014\-03\-11 ~ Add neat feature    \fB<(frozen_changes)\fR
 * \fBd15a38a\fR        2014\-03\-11 ~ Epic README update
 * \fBd559894\fR        (\:\fBmaster\fR\:) 2014\-03\-11 ~ Important upstream change
 | * \fB9c311fd\fR      (\:\fBcool_feature\fR\:) 2014\-03\-11 ~ Respond to CL comments
 | | * \fB2a1eeb2\fR    (\:\fBsubfeature\fR\:) 2014\-03\-11 ~ integrate with CoolService
 | | * \fBd777af6\fR    2014\-03\-11 ~ slick commenting action
 | |/
-| * \fB265803a\fR      2014\-03\-11 ~ another improvement
+| * \fB265803a\fR      2014\-03\-11 ~ another improvement    \fB<(subfeature)\fR
 | * \fB6d831ac\fR      (\:\fBspleen_tag\fR\:) 2014\-03\-11 ~ Refactor spleen
 | * \fB82e74ab\fR      2014\-03\-11 ~ Add widget
 |/
-* \fBd08c5b3\fR        (\:\fBbogus_noparent\fR\:) 2014\-03\-11 ~ Wonderful beginnings
+* \fBd08c5b3\fR        (\:\fBbogus_noparent\fR\:) 2014\-03\-11 ~ Wonderful beginnings    \fB<(cool_feature)\fR
 .fi
 .if n \{\
 .RE

+ 69 - 0
docs/man1/git-mark-merge-base.1

@@ -0,0 +1,69 @@
+'\" t
+.\"     Title: git-mark-merge-base
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\"      Date: 03/25/2014
+.\"    Manual: Chromium depot_tools Manual
+.\"    Source: depot_tools 207bff1
+.\"  Language: English
+.\"
+.TH "GIT\-MARK\-MERGE\-BA" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+git-mark-merge-base \- Manually interact with depot_tools\*(Aq merge\-base markers\&.
+.SH "SYNOPSIS"
+.sp
+.nf
+\fIgit mark\-merge\-base\fR
+\fIgit mark\-merge\-base\fR <commit hash>
+\fIgit mark\-merge\-base\fR [\-d | \-\-delete]
+.fi
+.sp
+.SH "DESCRIPTION"
+.sp
+Inspect, set or delete the current merge\-base marker for the current branch\&. This should not be needed, but is useful if things get into a snarled state\&. Pass no arguments to view the current value\&. If you provide <commit hash>, then git mark\-merge\-base will attempt to set that as the merge\-base value\&.
+.sp
+It is invalid to pick a commit which is not an ancestor of the current branch\&.
+.sp
+See \fBgit-rebase-update\fR(1)\*(Aqs description of the branch\&.<name>\&.base configuration variable for more info on what the merge base markers are for\&.
+.SH "OPTIONS"
+.PP
+\-d, \-\-delete
+.RS 4
+Delete the merge\-base marker for the current branch\&.
+.RE
+.PP
+<commit hash>
+.RS 4
+The new value to set for the current branch\(cqs merge\-base marker\&.
+.RE
+.SH "SEE ALSO"
+.sp
+\fBgit-rebase-update\fR(1), \fBgit-reparent-branch\fR(1), \fBgit-rename-branch\fR(1), \fBgit-upstream-diff\fR(1)
+.SH "CHROMIUM DEPOT_TOOLS"
+.sp
+Part of the chromium \fBdepot_tools\fR(1) suite\&. These tools are meant to assist with the development of chromium and related projects\&. Download the tools from \m[blue]\fBhere\fR\m[]\&\s-2\u[1]\d\s+2\&.
+.SH "NOTES"
+.IP " 1." 4
+here
+.RS 4
+\%https://chromium.googlesource.com/chromium/tools/depot_tools.git
+.RE

+ 18 - 3
docs/man1/git-nav-downstream.1

@@ -2,12 +2,12 @@
 .\"     Title: git-nav-downstream
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 03/14/2014
+.\"      Date: 03/25/2014
 .\"    Manual: Chromium depot_tools Manual
-.\"    Source: depot_tools a57ed8f
+.\"    Source: depot_tools 207bff1
 .\"  Language: English
 .\"
-.TH "GIT\-NAV\-DOWNSTREAM" "1" "03/14/2014" "depot_tools a57ed8f" "Chromium depot_tools Manual"
+.TH "GIT\-NAV\-DOWNSTREAM" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -72,6 +72,21 @@ origin/master
 .RE
 .\}
 .sp
+.SH "SUGGESTED ALIASES"
+.sp
+Some common short\-hand aliases\&. Feel free to add these to your \fI~/\&.gitconfig\fR file\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+[alias]
+  git down = nav\-downstream
+.fi
+.if n \{\
+.RE
+.\}
+.sp
 .SH "SEE ALSO"
 .sp
 \fBgit-map-branches\fR(1), \fBgit-nav-upstream\fR(1)

+ 18 - 3
docs/man1/git-nav-upstream.1

@@ -2,12 +2,12 @@
 .\"     Title: git-nav-upstream
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 03/14/2014
+.\"      Date: 03/25/2014
 .\"    Manual: Chromium depot_tools Manual
-.\"    Source: depot_tools a57ed8f
+.\"    Source: depot_tools 207bff1
 .\"  Language: English
 .\"
-.TH "GIT\-NAV\-UPSTREAM" "1" "03/14/2014" "depot_tools a57ed8f" "Chromium depot_tools Manual"
+.TH "GIT\-NAV\-UPSTREAM" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -66,6 +66,21 @@ origin/master
 .RE
 .\}
 .sp
+.SH "SUGGESTED ALIASES"
+.sp
+Some common short\-hand aliases\&. Feel free to add these to your \fI~/\&.gitconfig\fR file\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+[alias]
+  git up = nav\-upstream
+.fi
+.if n \{\
+.RE
+.\}
+.sp
 .SH "SEE ALSO"
 .sp
 \fBgit-map-branches\fR(1), \fBgit-nav-downstream\fR(1)

+ 150 - 0
docs/man1/git-new-branch.1

@@ -0,0 +1,150 @@
+'\" t
+.\"     Title: git-new-branch
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\"      Date: 03/25/2014
+.\"    Manual: Chromium depot_tools Manual
+.\"    Source: depot_tools 207bff1
+.\"  Language: English
+.\"
+.TH "GIT\-NEW\-BRANCH" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+git-new-branch \- Create a new branch with correct tracking information\&.
+.SH "SYNOPSIS"
+.sp
+.nf
+\fIgit new\-branch\fR <branch_name>
+\fIgit new\-branch\fR \-\-upstream_current <branch_name>
+\fIgit new\-branch\fR \-\-upstream <REF> <branch_name>
+\fIgit new\-branch\fR \-\-lkgr <branch_name>
+.fi
+.sp
+.SH "DESCRIPTION"
+.sp
+Creates a new branch\&. By default the new branch will track the configured upstream for the repo (defaults to \fIorigin/master\fR)\&. If one of the other options is specified, it will track that other ref instead\&.
+.sp
+Conceptually, each branch in your repo represents one \fIChange List (CL)\fR\&. If you have many independent CLs (i\&.e\&. the changes in one do not interact with/depend on the changes in another), then you should create them as new branches tracking the default upstream (i\&.e\&. git new\-branch <branch_name>)\&. If you have features which depend on each other, you should create stacked branches using git new\-branch \-\-upstream_current <branch_name>\&.
+.SH "OPTIONS"
+.PP
+\-\-upstream_current
+.RS 4
+Set the tracking (upstream) branch to the currently\-checked\-out branch\&.
+.RE
+.PP
+\-\-uptstream <REF>
+.RS 4
+Set the tracking (upstream) branch to <REF>\&. <REF> may be a local branch, remote branch, or a tag\&.
+.RE
+.PP
+\-\-lkgr
+.RS 4
+Alias for
+\-\-upstream lkgr\&.
+.RE
+.PP
+<branch_name>
+.RS 4
+The name for the new branch\&.
+.RE
+.SH "CONFIGURATION VARIABLES"
+.SS "depot\-tools\&.upstream"
+.sp
+This configures the default \fIupstream\fR for all new branches\&. If it is unset, it defaults to \fIorigin/master\fR\&. This is considered to be the \fIroot\fR branch\&.
+.SH "EXAMPLE"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fB$ git map\-branches\fR
+origin/master
+  cool_feature
+    subfeature
+  frozen_changes *
+\fB$ git new\-branch independent_cl\fR
+\fB$ git map\-branches\fR
+origin/master
+  cool_feature
+    subfeature
+  frozen_changes
+  independent_cl *
+\fB$ git new\-branch \-\-upstream subfeature nested_cl\fR
+\fB$ git map\-branches\fR
+origin/master
+  cool_feature
+    subfeature  \fB(1)\fR
+      nested_cl *
+  frozen_changes
+  independent_cl
+\fB$ git checkout cool_feature\fR
+\fB$ git new\-branch \-\-upstream_current cl_depends_on_cool_feature\fR
+\fB$ git map\-branches\fR
+origin/master
+  cool_feature
+    cl_depends_on_cool_feature *
+    subfeature
+      nested_cl
+  frozen_changes
+  independent_cl
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.sp
+\fB1. \fRNote that both branches are cyan because they are currently the same
+\fIcommit\fR
+object\&. See
+\fB:git-map-branches\fR(1)
+for more detail\&.
+.br
+.SH "SUGGESTED ALIASES"
+.sp
+Some common short\-hand aliases\&. Feel free to add these to your \fI~/\&.gitconfig\fR file\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+[alias]
+  git nb = new\-branch
+  git tb = new\-branch \-\-upstream_current  \fB(1)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.sp
+\fB1. \fRmnemonic: tb \(-> "track branch"
+.br
+.SH "SEE ALSO"
+.sp
+\fBgit-rebase-update\fR(1), \fBgit-reparent-branch\fR(1), \fBgit-rename-branch\fR(1), \fBgit-upstream-diff\fR(1)
+.SH "CHROMIUM DEPOT_TOOLS"
+.sp
+Part of the chromium \fBdepot_tools\fR(1) suite\&. These tools are meant to assist with the development of chromium and related projects\&. Download the tools from \m[blue]\fBhere\fR\m[]\&\s-2\u[1]\d\s+2\&.
+.SH "NOTES"
+.IP " 1." 4
+here
+.RS 4
+\%https://chromium.googlesource.com/chromium/tools/depot_tools.git
+.RE

+ 165 - 0
docs/man1/git-rebase-update.1

@@ -0,0 +1,165 @@
+'\" t
+.\"     Title: git-rebase-update
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\"      Date: 03/25/2014
+.\"    Manual: Chromium depot_tools Manual
+.\"    Source: depot_tools 207bff1
+.\"  Language: English
+.\"
+.TH "GIT\-REBASE\-UPDATE" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+git-rebase-update \- Updates all branches to have the latest changes from their upstreams\&.
+.SH "SYNOPSIS"
+.sp
+.nf
+\fIgit rebase\-update\fR [\-v | \-\-verbose] [\-n | \-\-no_fetch]
+.fi
+.sp
+.SH "DESCRIPTION"
+.sp
+Brings all branches up\-to\-date with their tracking branches\&. This involves several phases:
+.PP
+Preparation
+.RS 4
+If you currently have a branch checked out, any changes on that branch are
+\fIfrozen\fR
+(See
+\fBgit-freeze\fR(1)
+for more detail)\&. Additionally, the current branch is recorded for the
+\fIRestoration\fR
+phase later (see
+\fICONFIGURATION VARIABLES\fR
+for details on
+depot\-tools\&.rebase\-update\&.starting\-branch)\&.
+.RE
+.PP
+Fetching
+.RS 4
+All branches are examined to find their upstream references\&. The correct set of git remotes is determined, and fetched accordingly\&. Note that if any branches have a tag as their upstream, we are forced to pull all remotes\&.
+.sp
+Pass
+\-\-no_fetch
+to skip this phase\&.
+.RE
+.PP
+Rebasing
+.RS 4
+All branches are rebased in topological order from roots (upstreams) to leaves\&. Each branch is rebased from its marked merge\-base (see
+\fICONFIGURATION VARIABLES\fR) to the branch tip on top of its parent branch\&. If the parent branch is
+\fIfrozen\fR
+(see
+\fBgit-freeze\fR(1)), the branch will be rebased onto the last non\-freeze commit on the parent branch\&.
+.sp
+Things get interesting when there are merge conflicts on rebase\&. The
+\fBmost common\fR
+cause for conflicts is when your branch has been committed to the upstream in squashed form, ala
+\fBgit-squash-branch\fR(1), which is what
+\fBgit-cl\fR(1)
+and the
+\fICommit Queue\fR
+will do\&. Because of that,
+git rebase\-update
+will attempt to squash your conflicted branch to see if the squashed version applies cleanly to its upstream\&.
+.sp
+If it does not apply cleanly, then your original (non\-squashed) branch will be left in mid\-rebase and
+git rebase\-update
+will exit\&. You can deal with this like any other conflicted rebase\&. When you\(cqre done, just
+git rebase\-update
+again to pick up where you left off\&.
+.RE
+.PP
+Cleanup
+.RS 4
+Once all the branches have been rebased, any empty branches (i\&.e\&. branches with no commits on them) are removed\&. If a branch is removed in this fashion, any branches which depend on it are reparented to the parent of the removed branch (see
+\fBgit-reparent-branch\fR(1))\&.
+.RE
+.PP
+Restoration
+.RS 4
+git rebase\-update
+checks out the branch that you started on, and
+\fIthaws\fR
+it, if necessary (see
+\fBgit-thaw\fR(1))\&. If the branch you started on got cleaned up,
+git rebase\-update
+will checkout the
+\fIroot\fR
+ref (defaults to
+\fIorigin/master\fR, as configured by
+depot\-tools\&.upstream, see
+\fBgit-new-branch\fR(1))\&.
+.RE
+.SH "OPTIONS"
+.PP
+\-n, \-\-no_fetch
+.RS 4
+Skip the
+git fetch
+phase of rebase\-update\&.
+.RE
+.PP
+\-v, \-\-verbose
+.RS 4
+More text than your terminal can handle\&.
+.RE
+.SH "CONFIGURATION VARIABLES"
+.SS "depot\-tools\&.rebase\-update\&.starting\-branch"
+.sp
+When git rebase\-update first runs, it will record the current branch here so that when it completes successfully, it will return back to the same branch you started on, even if git rebase\-update is interrupted due to rebase conflicts\&. When git rebase\-update completes successfully, this configuration variable is removed\&.
+.SS "branch\&.<name>\&.dormant"
+.sp
+If true, will cause rebase\-update to skip all processing on the branch\&. Useful for old/high\-conflict branches which you want to keep for posterity, but don\(cqt want to deal with when running git rebase\-update
+.SS "branch\&.<name>\&.base"
+.sp
+Holds the \fIbase\fR reference for this branch\&. By default this is equivalent to git merge\-base <name> <name>@{upstream}\&. However, it can diverge if <name>@{upstream} is manually rebased\&. In this case, it correctly preserves the value it had before, where git merge\-base would now report the wrong value\&.
+.sp
+All of the tools in the \fBdepot_tools\fR(1) suite collude to keep this value as up\-to\-date as possible, including \fBgit-reparent-branch\fR(1), and \fBgit-new-branch\fR(1)\&. \fBgit-map\fR(1) also shows the location of these marker values in \fBwhite\fR\&.
+.sp
+\fBgit-mark-merge-base\fR(1) allows easy manual interaction for this value, in the unlikely event that it gets out of sync\&.
+.SH "SUGGESTED ALIASES"
+.sp
+Some common short\-hand aliases\&. Feel free to add these to your \fI~/\&.gitconfig\fR file\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+[alias]
+  git reup = rebase\-update
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.sp
+\fBgit-new-branch\fR(1), \fBgit-reparent-branch\fR(1), \fBgit-rename-branch\fR(1), \fBgit-upstream-diff\fR(1), \fBgit-freeze\fR(1), \fBgit-mark-merge-base\fR(1)
+.SH "CHROMIUM DEPOT_TOOLS"
+.sp
+Part of the chromium \fBdepot_tools\fR(1) suite\&. These tools are meant to assist with the development of chromium and related projects\&. Download the tools from \m[blue]\fBhere\fR\m[]\&\s-2\u[1]\d\s+2\&.
+.SH "NOTES"
+.IP " 1." 4
+here
+.RS 4
+\%https://chromium.googlesource.com/chromium/tools/depot_tools.git
+.RE

+ 53 - 0
docs/man1/git-rename-branch.1

@@ -0,0 +1,53 @@
+'\" t
+.\"     Title: git-rename-branch
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\"      Date: 03/25/2014
+.\"    Manual: Chromium depot_tools Manual
+.\"    Source: depot_tools 207bff1
+.\"  Language: English
+.\"
+.TH "GIT\-RENAME\-BRANCH" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+git-rename-branch \- Rename a branch and correctly preserve all downstream relationships\&.
+.SH "SYNOPSIS"
+.sp
+.nf
+\fIgit rename\-branch\fR <new_name>
+\fIgit rename\-branch\fR <old_name> <new_name>
+.fi
+.sp
+.SH "DESCRIPTION"
+.sp
+Rename the current (or specified) branch, then update all dowstream branches\*(Aq tracking information to preserve inter\-branch dependencies\&.
+.SH "SEE ALSO"
+.sp
+\fBgit-rebase-update\fR(1), \fBgit-reparent-branch\fR(1), \fBgit-new-branch\fR(1), \fBgit-upstream-diff\fR(1)
+.SH "CHROMIUM DEPOT_TOOLS"
+.sp
+Part of the chromium \fBdepot_tools\fR(1) suite\&. These tools are meant to assist with the development of chromium and related projects\&. Download the tools from \m[blue]\fBhere\fR\m[]\&\s-2\u[1]\d\s+2\&.
+.SH "NOTES"
+.IP " 1." 4
+here
+.RS 4
+\%https://chromium.googlesource.com/chromium/tools/depot_tools.git
+.RE

+ 93 - 0
docs/man1/git-reparent-branch.1

@@ -0,0 +1,93 @@
+'\" t
+.\"     Title: git-reparent-branch
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\"      Date: 03/25/2014
+.\"    Manual: Chromium depot_tools Manual
+.\"    Source: depot_tools 207bff1
+.\"  Language: English
+.\"
+.TH "GIT\-REPARENT\-BRANC" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+git-reparent-branch \- Alter the parentage (upstream) for the current branch\&.
+.SH "SYNOPSIS"
+.sp
+.nf
+\fIgit reparent\-branch\fR <new_parent>
+\fIgit reparent\-branch\fR \-\-lkgr
+\fIgit reparent\-branch\fR \-\-root
+.fi
+.sp
+.SH "DESCRIPTION"
+.sp
+Change the \fIupstream\fR of the current branch, and then run \fBgit-rebase-update\fR(1) to move the commits in the current branch, as well as the commits in all descendant branches, onto the new parent\&.
+.sp
+<new_parent> may be either a local branch, remote branch, OR a tag (such as lkgr)\&.
+.sp
+This is particularly useful to reparent an independent CL to become dependent on another CL, or vice versa\&. This could happen if you started both on the assumption that they were independent, but later realized that this was not the case\&.
+.SH "OPTIONS"
+.PP
+<new_parent>
+.RS 4
+The new parent to set as the upstream for this branch\&. May be a branch ref or a tag\&.
+.RE
+.PP
+\-\-lkgr
+.RS 4
+Reparent to track lkgr\&.
+.RE
+.PP
+\-\-root
+.RS 4
+Reparent to track the
+\fIroot\fR
+branch\&. Defaults to
+\fIorigin/master\fR\&. See
+\fBgit-new-branch\fR(1)\*(Aqs CONFIGURATION VARIABLES section\&.\&.
+.RE
+.SH "SUGGESTED ALIASES"
+.sp
+Some common short\-hand aliases\&. Feel free to add these to your \fI~/\&.gitconfig\fR file\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+[alias]
+  git rp = reparent\-branch
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.sp
+\fBgit-rebase-update\fR(1), \fBgit-rename-branch\fR(1), \fBgit-new-branch\fR(1), \fBgit-upstream-diff\fR(1)
+.SH "CHROMIUM DEPOT_TOOLS"
+.sp
+Part of the chromium \fBdepot_tools\fR(1) suite\&. These tools are meant to assist with the development of chromium and related projects\&. Download the tools from \m[blue]\fBhere\fR\m[]\&\s-2\u[1]\d\s+2\&.
+.SH "NOTES"
+.IP " 1." 4
+here
+.RS 4
+\%https://chromium.googlesource.com/chromium/tools/depot_tools.git
+.RE

+ 117 - 0
docs/man1/git-squash-branch.1

@@ -0,0 +1,117 @@
+'\" t
+.\"     Title: git-squash-branch
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\"      Date: 03/25/2014
+.\"    Manual: Chromium depot_tools Manual
+.\"    Source: depot_tools 207bff1
+.\"  Language: English
+.\"
+.TH "GIT\-SQUASH\-BRANCH" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+git-squash-branch \- Takes all commits in a single branch and replaces them with a single commit\&.
+.SH "SYNOPSIS"
+.sp
+.nf
+\fIgit squash\-branch\fR [\-m <message>]
+.fi
+.sp
+.SH "DESCRIPTION"
+.sp
+git squash\-branch is a simple helper command\&. It takes all the commits on the current branch from the \fImerge_base\fR to HEAD, and reduces them to a single commit\&. The new commit will contain a summary of all the commits which were squashed, preceeded by a header message indicating that it\(cqs the result of a squash (or the message you pass on the command line\&.)\&.
+.sp
+Squashing branches is useful when trying to rebase\-update over branches which were pushed to their upsteram (or committed by the \fICommit Queue\fR), and then conflicting changes landed in upstream on top of the push/commit\&. If you know that your branch was committed but \fBgit-rebase-update\fR(1) isn\(cqt able to automatically clean it, you can squash the troublesome branch before git rebase\-update, and then when git rebase\-update presents the conflict, you can verify that the conflict diff is what you expected (and then skip it with git rebase \-\-skip)\&.
+.SH "OPTIONS"
+.PP
+\-m <message>, \-\-message=<message>
+.RS 4
+Optional message to use for the first line of the squashed commit\&. If omitted, it defaults to "git squash commit\&."\&.
+.RE
+.SH "EXAMPLE"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fB$ git map\fR
+*\:\fB 7dcfe47       \fR (\:\fBfrozen_changes\fR\:) 2014\-03\-12 ~ FREEZE\&.unindexed
+* \fB4b0c180\fR        2014\-03\-12 ~ modfile
+* \fB59a7cca\fR        2014\-03\-12 ~ a deleted file
+* \fB6bec695\fR        (\:origin/master\:) 2014\-03\-11 ~ Add neat feature    \fB<(frozen_changes)\fR
+* \fBd15a38a\fR        2014\-03\-11 ~ Epic README update
+* \fBd559894\fR        (\:\fBmaster\fR\:) 2014\-03\-11 ~ Important upstream change
+| * \fB9c311fd\fR      (\:\fBcool_feature\fR\:) 2014\-03\-11 ~ Respond to CL comments
+| | * \fB2a1eeb2\fR    (\:\fBsubfeature\fR\:) 2014\-03\-11 ~ integrate with CoolService
+| | * \fBd777af6\fR    2014\-03\-11 ~ slick commenting action
+| |/
+| * \fB265803a\fR      2014\-03\-11 ~ another improvement    \fB<(subfeature)\fR
+| * \fB6d831ac\fR      (\:\fBspleen_tag\fR\:) 2014\-03\-11 ~ Refactor spleen
+| * \fB82e74ab\fR      2014\-03\-11 ~ Add widget
+|/
+* \fBd08c5b3\fR        (\:\fBbogus_noparent\fR\:) 2014\-03\-11 ~ Wonderful beginnings    \fB<(cool_feature)\fR
+\fB$ git squash\-branch "cool squash demo"\fR
+\fB$ git map\fR
+*\:\fB 2c81508       \fR (\:\fBfrozen_changes\fR\:) 2014\-03\-22 ~ cool squash demo
+* \fB6bec695\fR        (\:origin/master\:) 2014\-03\-11 ~ Add neat feature    \fB<(frozen_changes)\fR
+* \fBd15a38a\fR        2014\-03\-11 ~ Epic README update
+* \fBd559894\fR        (\:\fBmaster\fR\:) 2014\-03\-11 ~ Important upstream change
+| * \fB9c311fd\fR      (\:\fBcool_feature\fR\:) 2014\-03\-11 ~ Respond to CL comments
+| | * \fB2a1eeb2\fR    (\:\fBsubfeature\fR\:) 2014\-03\-11 ~ integrate with CoolService
+| | * \fBd777af6\fR    2014\-03\-11 ~ slick commenting action
+| |/
+| * \fB265803a\fR      2014\-03\-11 ~ another improvement    \fB<(subfeature)\fR
+| * \fB6d831ac\fR      (\:\fBspleen_tag\fR\:) 2014\-03\-11 ~ Refactor spleen
+| * \fB82e74ab\fR      2014\-03\-11 ~ Add widget
+|/
+* \fBd08c5b3\fR        (\:\fBbogus_noparent\fR\:) 2014\-03\-11 ~ Wonderful beginnings    \fB<(cool_feature)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SUGGESTED ALIASES"
+.sp
+Some common short\-hand aliases\&. Feel free to add these to your \fI~/\&.gitconfig\fR file\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+[alias]
+  git squash = squash\-branch
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.sp
+\fBgit-rebase-update\fR(1)
+.SH "CHROMIUM DEPOT_TOOLS"
+.sp
+Part of the chromium \fBdepot_tools\fR(1) suite\&. These tools are meant to assist with the development of chromium and related projects\&. Download the tools from \m[blue]\fBhere\fR\m[]\&\s-2\u[1]\d\s+2\&.
+.SH "NOTES"
+.IP " 1." 4
+here
+.RS 4
+\%https://chromium.googlesource.com/chromium/tools/depot_tools.git
+.RE

+ 3 - 3
docs/man1/git-thaw.1

@@ -2,12 +2,12 @@
 .\"     Title: git-thaw
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 03/14/2014
+.\"      Date: 03/25/2014
 .\"    Manual: Chromium depot_tools Manual
-.\"    Source: depot_tools a57ed8f
+.\"    Source: depot_tools 207bff1
 .\"  Language: English
 .\"
-.TH "GIT\-THAW" "1" "03/14/2014" "depot_tools a57ed8f" "Chromium depot_tools Manual"
+.TH "GIT\-THAW" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------

+ 119 - 0
docs/man1/git-upstream-diff.1

@@ -0,0 +1,119 @@
+'\" t
+.\"     Title: git-upstream-diff
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\"      Date: 03/25/2014
+.\"    Manual: Chromium depot_tools Manual
+.\"    Source: depot_tools 207bff1
+.\"  Language: English
+.\"
+.TH "GIT\-UPSTREAM\-DIFF" "1" "03/25/2014" "depot_tools 207bff1" "Chromium depot_tools Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+git-upstream-diff \- Print a diff of the current branch, compared to its upstream\&.
+.SH "SYNOPSIS"
+.sp
+.nf
+\fIgit upstream\-diff\fR [\-\-wordwise] [<extra args for git\-diff>*]
+.fi
+.sp
+.SH "DESCRIPTION"
+.sp
+Shows a diff beween your current branch and it\(cqs upstream\&. This is \fIroughly\fR the same as:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+git diff \-\-patience \-C \-C HEAD@{upstream}  \fB(1)\fR \fB(2)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.sp
+\fB1. \fR\-C \-C
+detects file copies/renames
+.br
+\fB2. \fR\-\-patience
+uses the patience\-diff algorithm, which tends to produce nicer diffs in many cases\&.
+.br
+.sp
+The difference is that HEAD@{upstream} is actually the tagged merge base of your branch (See \fBgit-rebase-update\fR(1))\&. This means that if your upstream branch was rebased, but you haven\(cqt yet rebased the current branch on top of it, you\(cqll still see an accurate diff compared to just diffing against @{upstream}\&.
+.sp
+The \-\-wordwise option also allows git\-diff to do word\-by\-word comparison in a semi\-intelligent way\&. However, sometimes it can produce surprising results, so it is disabled by default\&.
+.SH "OPTIONS"
+.PP
+\-\-wordwise
+.RS 4
+Print a colorized word\-wise diff instead of a line\-wise diff\&.
+.RE
+.PP
+<extra args for git\-diff>
+.RS 4
+Extra arguments are included in the invocation of
+\fBgit-diff\fR(1)\&. These can be anything that
+git\-diff
+normally takes\&.
+.PP
+\-\-stat
+.RS 4
+This is particularly useful to show
+\fIwhich\fR
+files have been changed in comparison to the upstream branch\&.
+.RE
+.PP
+\-\- <filename patterns>*
+.RS 4
+Restrict the diff to only show the diff for given files compared to the upstream\&.
+.RE
+.RE
+.SH "CONFIGURATION VARIABLES"
+.SS "depot\-tools\&.upstream\-diff\&.default\-args"
+.sp
+A list\-configuration variable\&. Each instance of this config variable will be prepended to all invocations of git upstream\-diff, as if you had passed them on the command line\&.
+.SH "SUGGESTED ALIASES"
+.sp
+Some common short\-hand aliases\&. Feel free to add these to your \fI~/\&.gitconfig\fR file\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+[alias]
+  git udiff = upstream\-diff
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.sp
+\fBgit-rebase-update\fR(1)
+.SH "CHROMIUM DEPOT_TOOLS"
+.sp
+Part of the chromium \fBdepot_tools\fR(1) suite\&. These tools are meant to assist with the development of chromium and related projects\&. Download the tools from \m[blue]\fBhere\fR\m[]\&\s-2\u[1]\d\s+2\&.
+.SH "NOTES"
+.IP " 1." 4
+here
+.RS 4
+\%https://chromium.googlesource.com/chromium/tools/depot_tools.git
+.RE

+ 5 - 0
docs/src/_aliases.txt

@@ -0,0 +1,5 @@
+SUGGESTED ALIASES
+-----------------
+
+Some common short-hand aliases. Feel free to add these to your '~/.gitconfig'
+file.

+ 1 - 1
docs/src/_footer.txt

@@ -5,4 +5,4 @@ Part of the chromium linkgit:depot_tools[1] suite. These tools are meant to
 assist with the development of chromium and related projects. Download the tools
 from link:{sys3:git config remote.origin.url}[here].
 
-// vim: ft=asciidoc noexpandtab:
+// vim: ft=asciidoc:

+ 1 - 1
docs/src/_git-map-branches_desc.helper.txt

@@ -1,4 +1,4 @@
 Helper script to display all local git branches with ‘upstream’ hierarchy in
 colorized terminal format.
 
-// vim: ft=asciidoc noexpandtab:
+// vim: ft=asciidoc:

+ 1 - 1
docs/src/_git-map_desc.helper.txt

@@ -1,3 +1,3 @@
 Display history of all branches in a colorized terminal format.
 
-// vim: ft=asciidoc noexpandtab:
+// vim: ft=asciidoc:

+ 1 - 0
docs/src/_git-mark-merge-base_desc.helper.txt

@@ -0,0 +1 @@
+Manually interact with depot_tools' merge-base markers.

+ 1 - 0
docs/src/_git-new-branch_desc.helper.txt

@@ -0,0 +1 @@
+Create a new branch with correct tracking information.

+ 1 - 0
docs/src/_git-rebase-update_desc.helper.txt

@@ -0,0 +1 @@
+Updates all branches to have the latest changes from their upstreams.

+ 1 - 0
docs/src/_git-rename-branch_desc.helper.txt

@@ -0,0 +1 @@
+Rename a branch and correctly preserve all downstream relationships.

+ 1 - 0
docs/src/_git-reparent-branch_desc.helper.txt

@@ -0,0 +1 @@
+Alter the parentage (upstream) for the current branch.

+ 1 - 0
docs/src/_git-squash-branch_desc.helper.txt

@@ -0,0 +1 @@
+Takes all commits in a single branch and replaces them with a single commit.

+ 1 - 0
docs/src/_git-upstream-diff_desc.helper.txt

@@ -0,0 +1 @@
+Print a diff of the current branch, compared to its upstream.

+ 1 - 1
docs/src/depot_tools.txt

@@ -25,4 +25,4 @@ include::__essential.txt[maxdepth=1]
 
 include::__helper.txt[maxdepth=1]
 
-// vim: ft=asciidoc noexpandtab:
+// vim: ft=asciidoc:

+ 1 - 1
docs/src/git-freeze.txt

@@ -79,4 +79,4 @@ linkgit:git-thaw[1]
 
 include::_footer.txt[]
 
-// vim: ft=asciidoc noexpandtab:
+// vim: ft=asciidoc:

+ 11 - 4
docs/src/git-map-branches.txt

@@ -18,13 +18,13 @@ Git map-branches displays all local branches such that:
 
 * Current branch is [aqua]#cyan#.
 ** The branch which will be modified with git-commit is denoted with an asterisk
-	 (`*`) after the name.
+   (`*`) after the name.
 * Local branches are [green]#green#.
 * Remote branches are [red]#red# (usually, the root of all other branches).
 * `{NO UPSTREAM}` is a special placeholder in [fuchsia]#magenta#.
 ** Branches which have this as their parent are usually misconfigured, and
-	 should be assigned a parent by checking out the branch and running git branch
-	 --set-upstream-to=<correct parent branch>.
+   should be assigned a parent by checking out the branch and running git branch
+   --set-upstream-to=<correct parent branch>.
 
 NOTE: If multiple branches are on the same commit, they will all be cyan.
 
@@ -48,10 +48,17 @@ assuming that the `frozen_changes` branch was currently checked out, running
   [aqua]#duplicate_cool_feature_no_upstream#
 ----
 
+include::_aliases.txt[]
+
+----
+[alias]
+  git bmap = map-branches
+----
+
 SEE ALSO
 --------
 linkgit:git-map[1]
 
 include::_footer.txt[]
 
-// vim: ft=asciidoc noexpandtab:
+// vim: ft=asciidoc:

+ 12 - 11
docs/src/git-map.txt

@@ -20,6 +20,7 @@ Git map formats the output of `git log --graph` from all refs such that:
 * Local branches are [green]#green#.
 * Remote branches are [red]#red#.
 * Tags are [fuchsia]#magenta#.
+* Merge Base markers are [black-background white]#white#.
 * The currently checked out commit is highlighted with a [yellow blue-background]#blue background#.
 
 The output is automatically piped through the `less` pager command, even on
@@ -28,47 +29,47 @@ windows.
 OPTIONS
 -------
 <extra_args>...::
-	Extra parameters to pass to the internal linkgit:git-log[1] invocation. This
-	can be used to restrict what refs 'git map' operates on, etc.
+  Extra parameters to pass to the internal linkgit:git-log[1] invocation. This
+  can be used to restrict what refs 'git map' operates on, etc.
 +
 If you run git map with a series of fixed arguments frequently, you can use
-the depot_tools.map_extra configuration variable to pre-set arguments (See
+the depot-tools.map-extra configuration variable to pre-set arguments (See
 `CONFIGURATION VARIABLES`)
 
 
 CONFIGURATION VARIABLES
 -----------------------
 
-depot_tools.map_extra
+depot-tools.map-extra
 ~~~~~~~~~~~~~~~~~~~~~
 
-Each value of the 'depot_tools.map_extra' config variable is applied as an
+Each value of the 'depot-tools.map-extra' config variable is applied as an
 additional argument to `git log` during the execution of git map. If you wish to
-configure this, use git `config --add depot_tools.map_extra <value>` to do so.
+configure this, use git `config --add depot-tools.map-extra <value>` to do so.
 
 EXAMPLE
 -------
 
 Running 'git map' would result in an output something like:
 
-[subs="quotes,attributes"]
+[subs="specialcharacters,quotes,attributes"]
 ----
 [white]**$ git map**
 [white blue-background]##*##{zwsp}[blue-background red]** 7dcfe47       ** [green]##(##{zwsp}[aqua]**frozen_changes**{zwsp}[green]##)## [yellow]##2014-03-12## \~ FREEZE.unindexed
 * [red]**4b0c180**        [yellow]##2014-03-12## \~ modfile
 * [red]**59a7cca**        [yellow]##2014-03-12## \~ a deleted file
-* [red]**6bec695**        [green]##(##{zwsp}[red]##origin/master##{zwsp}[green]##)## [yellow]##2014-03-11## \~ Add neat feature
+* [red]**6bec695**        [green]##(##{zwsp}[red]##origin/master##{zwsp}[green]##)## [yellow]##2014-03-11## \~ Add neat feature    [white]**<(frozen_changes)**
 * [red]**d15a38a**        [yellow]##2014-03-11## \~ Epic README update
 * [red]**d559894**        [green]##(##{zwsp}[lime]**master**{zwsp}[green]##)## [yellow]##2014-03-11## \~ Important upstream change
 [red]##|## * [red]**9c311fd**      [green]##(##{zwsp}[lime]**cool_feature**{zwsp}[green]##)## [yellow]##2014-03-11## \~ Respond to CL comments
 [red]##|## [green]##|## * [red]**2a1eeb2**    [green]##(##{zwsp}[lime]**subfeature**{zwsp}[green]##)## [yellow]##2014-03-11## \~ integrate with CoolService
 [red]##|## [green]##|## * [red]**d777af6**    [yellow]##2014-03-11## \~ slick commenting action
 [red]##|## [green]##|/##
-[red]##|## * [red]**265803a**      [yellow]##2014-03-11## \~ another improvement
+[red]##|## * [red]**265803a**      [yellow]##2014-03-11## \~ another improvement    [white]**<(subfeature)**
 [red]##|## * [red]**6d831ac**      [green]##(##{zwsp}[fuchsia]**spleen_tag**{zwsp}[green]##)## [yellow]##2014-03-11## \~ Refactor spleen
 [red]##|## * [red]**82e74ab**      [yellow]##2014-03-11## \~ Add widget
 [red]##|/##
-* [red]**d08c5b3**        [green]##(##{zwsp}[lime]**bogus_noparent**{zwsp}[green]##)## [yellow]##2014-03-11## ~ Wonderful beginnings
+* [red]**d08c5b3**        [green]##(##{zwsp}[lime]**bogus_noparent**{zwsp}[green]##)## [yellow]##2014-03-11## ~ Wonderful beginnings    [white]**<(cool_feature)**
 ----
 
 As you can see, the structure of the commit history is visible, particularly
@@ -82,4 +83,4 @@ linkgit:git-map-branches[1]
 
 include::_footer.txt[]
 
-// vim: ft=asciidoc noexpandtab:
+// vim: ft=asciidoc:

+ 46 - 0
docs/src/git-mark-merge-base.txt

@@ -0,0 +1,46 @@
+git-mark-merge-base(1)
+======================
+
+NAME
+----
+git-mark-merge-base -
+include::_git-mark-merge-base_desc.helper.txt[]
+
+SYNOPSIS
+--------
+[verse]
+'git mark-merge-base'
+'git mark-merge-base' <commit hash>
+'git mark-merge-base' [-d | --delete]
+
+DESCRIPTION
+-----------
+
+Inspect, set or delete the current merge-base marker for the current branch.
+This should not be needed, but is useful if things get into a snarled state.
+Pass no arguments to view the current value. If you provide <commit hash>, then
+`git mark-merge-base` will attempt to set that as the merge-base value.
+
+It is invalid to pick a commit which is not an ancestor of the current branch.
+
+See linkgit:git-rebase-update[1]'s description of the `branch.<name>.base`
+configuration variable for more info on what the merge base markers are for.
+
+OPTIONS
+-------
+
+-d::
+--delete::
+  Delete the merge-base marker for the current branch.
+
+<commit hash>::
+  The new value to set for the current branch's merge-base marker.
+
+SEE ALSO
+--------
+linkgit:git-rebase-update[1], linkgit:git-reparent-branch[1],
+linkgit:git-rename-branch[1], linkgit:git-upstream-diff[1]
+
+include::_footer.txt[]
+
+// vim: ft=asciidoc:

+ 9 - 1
docs/src/git-nav-downstream.txt

@@ -49,10 +49,18 @@ Selection (0-2)[0]: 0
   [green]#bogus_noparent#
 ----
 
+include::_aliases.txt[]
+
+----
+[alias]
+  git down = nav-downstream
+----
+
+
 SEE ALSO
 --------
 linkgit:git-map-branches[1], linkgit:git-nav-upstream[1]
 
 include::_footer.txt[]
 
-// vim: ft=asciidoc noexpandtab:
+// vim: ft=asciidoc:

+ 8 - 1
docs/src/git-nav-upstream.txt

@@ -41,10 +41,17 @@ EXAMPLE
   [green]#bogus_noparent#
 ----
 
+include::_aliases.txt[]
+
+----
+[alias]
+  git up = nav-upstream
+----
+
 SEE ALSO
 --------
 linkgit:git-map-branches[1], linkgit:git-nav-downstream[1]
 
 include::_footer.txt[]
 
-// vim: ft=asciidoc noexpandtab:
+// vim: ft=asciidoc:

+ 113 - 0
docs/src/git-new-branch.txt

@@ -0,0 +1,113 @@
+git-new-branch(1)
+=================
+
+NAME
+----
+git-new-branch -
+include::_git-new-branch_desc.helper.txt[]
+
+SYNOPSIS
+--------
+[verse]
+'git new-branch' <branch_name>
+'git new-branch' --upstream_current <branch_name>
+'git new-branch' --upstream <REF> <branch_name>
+'git new-branch' --lkgr <branch_name>
+
+DESCRIPTION
+-----------
+
+Creates a new branch. By default the new branch will track the configured
+upstream for the repo (defaults to 'origin/master'). If one of the other options
+is specified, it will track that other ref instead.
+
+Conceptually, each branch in your repo represents one 'Change List (CL)'. If you
+have many independent CLs (i.e. the changes in one do not interact with/depend
+on the changes in another), then you should create them as new branches tracking
+the default upstream (i.e. `git new-branch <branch_name>`). If you have features
+which depend on each other, you should create stacked branches using `git
+new-branch --upstream_current <branch_name>`.
+
+OPTIONS
+-------
+
+--upstream_current::
+  Set the tracking (upstream) branch to the currently-checked-out branch.
+
+--uptstream <REF>::
+  Set the tracking (upstream) branch to <REF>. <REF> may be a local branch,
+  remote branch, or a tag.
+
+--lkgr::
+  Alias for `--upstream lkgr`.
+
+<branch_name>::
+  The name for the new branch.
+
+
+CONFIGURATION VARIABLES
+-----------------------
+
+depot-tools.upstream
+~~~~~~~~~~~~~~~~~~~~
+
+This configures the default 'upstream' for all new branches. If it is unset, it
+defaults to 'origin/master'.  This is considered to be the 'root' branch.
+
+EXAMPLE
+-------
+
+[subs="specialcharacters,quotes,attributes,callouts"]
+----
+[white]**$ git map-branches**
+[red]#origin/master#
+  [green]#cool_feature#
+    [green]#subfeature#
+  [aqua]#frozen_changes *#
+[white]**$ git new-branch independent_cl**
+[white]**$ git map-branches**
+[red]#origin/master#
+  [green]#cool_feature#
+    [green]#subfeature#
+  [green]#frozen_changes#
+  [aqua]#independent_cl *#
+[white]**$ git new-branch --upstream subfeature nested_cl**
+[white]**$ git map-branches**
+[red]#origin/master#
+  [green]#cool_feature#
+    [aqua]#subfeature#  <1>
+      [aqua]#nested_cl *#
+  [green]#frozen_changes#
+  [green]#independent_cl#
+[white]**$ git checkout cool_feature**
+[white]**$ git new-branch --upstream_current cl_depends_on_cool_feature**
+[white]**$ git map-branches**
+[red]#origin/master#
+  [aqua]#cool_feature#
+    [aqua]#cl_depends_on_cool_feature *#
+    [green]#subfeature#
+      [green]#nested_cl#
+  [green]#frozen_changes#
+  [green]#independent_cl#
+----
+<1> Note that both branches are cyan because they are currently the same
+'commit' object. See linkgit::git-map-branches[1] for more detail.
+
+include::_aliases.txt[]
+
+----
+[alias]
+  git nb = new-branch
+  git tb = new-branch --upstream_current  <1>
+----
+<1> mnemonic: tb -> "track branch"
+
+
+SEE ALSO
+--------
+linkgit:git-rebase-update[1], linkgit:git-reparent-branch[1],
+linkgit:git-rename-branch[1], linkgit:git-upstream-diff[1]
+
+include::_footer.txt[]
+
+// vim: ft=asciidoc:

+ 130 - 0
docs/src/git-rebase-update.txt

@@ -0,0 +1,130 @@
+git-rebase-update(1)
+====================
+
+NAME
+----
+git-rebase-update -
+include::_git-rebase-update_desc.helper.txt[]
+
+SYNOPSIS
+--------
+[verse]
+'git rebase-update' [-v | --verbose] [-n | --no_fetch]
+
+DESCRIPTION
+-----------
+
+Brings all branches up-to-date with their tracking branches. This involves
+several phases:
+
+Preparation::
+  If you currently have a branch checked out, any changes on that branch are
+  'frozen' (See linkgit:git-freeze[1] for more detail). Additionally, the current
+  branch is recorded for the 'Restoration' phase later (see 'CONFIGURATION
+  VARIABLES' for details on `depot-tools.rebase-update.starting-branch`).
+
+Fetching::
+  All branches are examined to find their upstream references. The correct set
+  of git remotes is determined, and fetched accordingly. Note that if any
+  branches have a tag as their upstream, we are forced to pull all remotes.
++
+Pass `--no_fetch` to skip this phase.
+
+Rebasing::
+  All branches are rebased in topological order from roots (upstreams) to
+  leaves.  Each branch is rebased from its marked merge-base (see 'CONFIGURATION
+  VARIABLES') to the branch tip on top of its parent branch. If the parent
+  branch is 'frozen' (see linkgit:git-freeze[1]), the branch will be rebased
+  onto the last non-freeze commit on the parent branch.
++
+Things get interesting when there are merge conflicts on rebase. The *most
+common* cause for conflicts is when your branch has been committed to the
+upstream in squashed form, ala linkgit:git-squash-branch[1], which is what
+linkgit:git-cl[1] and the 'Commit Queue' will do. Because of that, `git
+rebase-update` will attempt to squash your conflicted branch to see if the
+squashed version applies cleanly to its upstream.
++
+If it does not apply cleanly, then your original (non-squashed) branch will be
+left in mid-rebase and `git rebase-update` will exit. You can deal with this
+like any other conflicted rebase. When you're done, just `git rebase-update`
+again to pick up where you left off.
+
+Cleanup::
+  Once all the branches have been rebased, any empty branches (i.e. branches
+  with no commits on them) are removed. If a branch is removed in this fashion,
+  any branches which depend on it are reparented to the parent of the removed
+  branch (see linkgit:git-reparent-branch[1]).
+
+Restoration::
+  `git rebase-update` checks out the branch that you started on, and 'thaws' it,
+  if necessary (see linkgit:git-thaw[1]). If the branch you started on got
+  cleaned up, `git rebase-update` will checkout the 'root' ref (defaults to
+  'origin/master', as configured by `depot-tools.upstream`, see
+  linkgit:git-new-branch[1]).
+
+
+OPTIONS
+-------
+
+-n::
+--no_fetch::
+  Skip the `git fetch` phase of rebase-update.
+
+-v::
+--verbose::
+  More text than your terminal can handle.
+
+
+CONFIGURATION VARIABLES
+-----------------------
+
+depot-tools.rebase-update.starting-branch
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When `git rebase-update` first runs, it will record the current branch here so
+that when it completes successfully, it will return back to the same branch you
+started on, even if `git rebase-update` is interrupted due to rebase conflicts.
+When `git rebase-update` completes successfully, this configuration variable is
+removed.
+
+branch.<name>.dormant
+~~~~~~~~~~~~~~~~~~~~~
+
+If `true`, will cause rebase-update to skip all processing on the branch.
+Useful for old/high-conflict branches which you want to keep for posterity, but
+don't want to deal with when running `git rebase-update`
+
+branch.<name>.base
+~~~~~~~~~~~~~~~~~~
+
+Holds the 'base' reference for this branch. By default this is equivalent to
+`git merge-base <name> <name>@{upstream}`. However, it can diverge if
+`<name>@{upstream}` is manually rebased. In this case, it correctly preserves
+the value it had before, where `git merge-base` would now report the wrong
+value.
+
+All of the tools in the linkgit:depot_tools[1] suite collude to keep this value
+as up-to-date as possible, including linkgit:git-reparent-branch[1], and
+linkgit:git-new-branch[1]. linkgit:git-map[1] also shows the location of these
+marker values in [black-background white]**white**.
+
+linkgit:git-mark-merge-base[1] allows easy manual interaction for this value,
+in the unlikely event that it gets out of sync.
+
+include::_aliases.txt[]
+
+----
+[alias]
+  git reup = rebase-update
+----
+
+
+SEE ALSO
+--------
+linkgit:git-new-branch[1], linkgit:git-reparent-branch[1],
+linkgit:git-rename-branch[1], linkgit:git-upstream-diff[1],
+linkgit:git-freeze[1], linkgit:git-mark-merge-base[1]
+
+include::_footer.txt[]
+
+// vim: ft=asciidoc:

+ 28 - 0
docs/src/git-rename-branch.txt

@@ -0,0 +1,28 @@
+git-rename-branch(1)
+====================
+
+NAME
+----
+git-rename-branch -
+include::_git-rename-branch_desc.helper.txt[]
+
+SYNOPSIS
+--------
+[verse]
+'git rename-branch' <new_name>
+'git rename-branch' <old_name> <new_name>
+
+DESCRIPTION
+-----------
+
+Rename the current (or specified) branch, then update all dowstream branches'
+tracking information to preserve inter-branch dependencies.
+
+SEE ALSO
+--------
+linkgit:git-rebase-update[1], linkgit:git-reparent-branch[1],
+linkgit:git-new-branch[1], linkgit:git-upstream-diff[1]
+
+include::_footer.txt[]
+
+// vim: ft=asciidoc:

+ 61 - 0
docs/src/git-reparent-branch.txt

@@ -0,0 +1,61 @@
+git-reparent-branch(1)
+=====================
+
+NAME
+----
+git-reparent-branch -
+include::_git-reparent-branch_desc.helper.txt[]
+
+SYNOPSIS
+--------
+[verse]
+'git reparent-branch' <new_parent>
+'git reparent-branch' --lkgr
+'git reparent-branch' --root
+
+DESCRIPTION
+-----------
+
+Change the 'upstream' of the current branch, and then run
+linkgit:git-rebase-update[1] to move the commits in the current branch, as well
+as the commits in all descendant branches, onto the new parent.
+
+`<new_parent>` may be either a local branch, remote branch, OR a tag (such as
+`lkgr`).
+
+This is particularly useful to reparent an independent CL to become dependent on
+another CL, or vice versa. This could happen if you started both on the
+assumption that they were independent, but later realized that this was not the
+case.
+
+
+OPTIONS
+-------
+
+<new_parent>::
+  The new parent to set as the upstream for this branch. May be a branch ref or
+  a tag.
+
+--lkgr::
+  Reparent to track lkgr.
+
+--root::
+  Reparent to track the 'root' branch. Defaults to 'origin/master'. See
+  linkgit:git-new-branch[1]'s CONFIGURATION VARIABLES section..
+
+
+include::_aliases.txt[]
+
+----
+[alias]
+  git rp = reparent-branch
+----
+
+SEE ALSO
+--------
+linkgit:git-rebase-update[1], linkgit:git-rename-branch[1],
+linkgit:git-new-branch[1], linkgit:git-upstream-diff[1]
+
+include::_footer.txt[]
+
+// vim: ft=asciidoc:

+ 92 - 0
docs/src/git-squash-branch.txt

@@ -0,0 +1,92 @@
+git-squash-branch(1)
+====================
+
+NAME
+----
+git-squash-branch -
+include::_git-squash-branch_desc.helper.txt[]
+
+SYNOPSIS
+--------
+[verse]
+'git squash-branch' [-m <message>]
+
+DESCRIPTION
+-----------
+
+`git squash-branch` is a simple helper command. It takes all the commits on the
+current branch from the 'merge_base' to HEAD, and reduces them to a single
+commit. The new commit will contain a summary of all the commits which were
+squashed, preceeded by a header message indicating that it's the result of a
+squash (or the message you pass on the command line.).
+
+Squashing branches is useful when trying to rebase-update over branches which
+were pushed to their upsteram (or committed by the 'Commit Queue'), and then
+conflicting changes landed in upstream on top of the push/commit. If you know
+that your branch was committed but linkgit:git-rebase-update[1] isn't able to
+automatically clean it, you can squash the troublesome branch before `git
+rebase-update`, and then when `git rebase-update` presents the conflict, you can
+verify that the conflict diff is what you expected (and then skip it with
+`git rebase --skip`).
+
+OPTIONS
+-------
+
+-m <message>::
+--message=<message>::
+  Optional message to use for the first line of the squashed commit. If omitted,
+  it defaults to "git squash commit.".
+
+EXAMPLE
+-------
+
+[subs="specialcharacters,quotes,attributes"]
+----
+[white]**$ git map**
+[white blue-background]##\*##{zwsp}[blue-background red]** 7dcfe47       ** [green]##(##{zwsp}[aqua]**frozen_changes**{zwsp}[green]##)## [yellow]##2014-03-12## \~ FREEZE.unindexed
+* [red]**4b0c180**        [yellow]##2014-03-12## \~ modfile
+* [red]**59a7cca**        [yellow]##2014-03-12## \~ a deleted file
+* [red]**6bec695**        [green]##(##{zwsp}[red]##origin/master##{zwsp}[green]##)## [yellow]##2014-03-11## \~ Add neat feature    [white]**<(frozen_changes)**
+* [red]**d15a38a**        [yellow]##2014-03-11## \~ Epic README update
+* [red]**d559894**        [green]##(##{zwsp}[lime]**master**{zwsp}[green]##)## [yellow]##2014-03-11## \~ Important upstream change
+[red]##|## * [red]**9c311fd**      [green]##(##{zwsp}[lime]**cool_feature**{zwsp}[green]##)## [yellow]##2014-03-11## \~ Respond to CL comments
+[red]##|## [green]##|## * [red]**2a1eeb2**    [green]##(##{zwsp}[lime]**subfeature**{zwsp}[green]##)## [yellow]##2014-03-11## \~ integrate with CoolService
+[red]##|## [green]##|## * [red]**d777af6**    [yellow]##2014-03-11## \~ slick commenting action
+[red]##|## [green]##|/##
+[red]##|## * [red]**265803a**      [yellow]##2014-03-11## \~ another improvement    [white]**<(subfeature)**
+[red]##|## * [red]**6d831ac**      [green]##(##{zwsp}[fuchsia]**spleen_tag**{zwsp}[green]##)## [yellow]##2014-03-11## \~ Refactor spleen
+[red]##|## * [red]**82e74ab**      [yellow]##2014-03-11## \~ Add widget
+[red]##|/##
+* [red]**d08c5b3**        [green]##(##{zwsp}[lime]**bogus_noparent**{zwsp}[green]##)## [yellow]##2014-03-11## \~ Wonderful beginnings    [white]**<(cool_feature)**
+[white]**$ git squash-branch "cool squash demo"**
+[white]**$ git map**
+[white blue-background]##*##{zwsp}[blue-background red]** 2c81508       ** [green]##(##{zwsp}[aqua]**frozen_changes**{zwsp}[green]##)## [yellow]##2014-03-22## \~ cool squash demo
+* [red]**6bec695**        [green]##(##{zwsp}[red]##origin/master##{zwsp}[green]##)## [yellow]##2014-03-11## \~ Add neat feature    [white]**<(frozen_changes)**
+* [red]**d15a38a**        [yellow]##2014-03-11## \~ Epic README update
+* [red]**d559894**        [green]##(##{zwsp}[lime]**master**{zwsp}[green]##)## [yellow]##2014-03-11## \~ Important upstream change
+[red]##|## * [red]**9c311fd**      [green]##(##{zwsp}[lime]**cool_feature**{zwsp}[green]##)## [yellow]##2014-03-11## \~ Respond to CL comments
+[red]##|## [green]##|## * [red]**2a1eeb2**    [green]##(##{zwsp}[lime]**subfeature**{zwsp}[green]##)## [yellow]##2014-03-11## \~ integrate with CoolService
+[red]##|## [green]##|## * [red]**d777af6**    [yellow]##2014-03-11## \~ slick commenting action
+[red]##|## [green]##|/##
+[red]##|## * [red]**265803a**      [yellow]##2014-03-11## \~ another improvement    [white]**<(subfeature)**
+[red]##|## * [red]**6d831ac**      [green]##(##{zwsp}[fuchsia]**spleen_tag**{zwsp}[green]##)## [yellow]##2014-03-11## \~ Refactor spleen
+[red]##|## * [red]**82e74ab**      [yellow]##2014-03-11## \~ Add widget
+[red]##|/##
+* [red]**d08c5b3**        [green]##(##{zwsp}[lime]**bogus_noparent**{zwsp}[green]##)## [yellow]##2014-03-11## ~ Wonderful beginnings    [white]**<(cool_feature)**
+----
+
+include::_aliases.txt[]
+
+----
+[alias]
+  git squash = squash-branch
+----
+
+
+SEE ALSO
+--------
+linkgit:git-rebase-update[1]
+
+include::_footer.txt[]
+
+// vim: ft=asciidoc:

+ 1 - 1
docs/src/git-thaw.txt

@@ -26,4 +26,4 @@ linkgit:git-freeze[1]
 
 include::_footer.txt[]
 
-// vim: ft=asciidoc noexpandtab:
+// vim: ft=asciidoc:

+ 81 - 0
docs/src/git-upstream-diff.txt

@@ -0,0 +1,81 @@
+git-upstream-diff(1)
+====================
+
+NAME
+----
+git-upstream-diff -
+include::_git-upstream-diff_desc.helper.txt[]
+
+SYNOPSIS
+--------
+[verse]
+'git upstream-diff' [--wordwise] [<extra args for git-diff>*]
+
+DESCRIPTION
+-----------
+
+Shows a diff beween your current branch and it's upstream. This is 'roughly' the
+same as:
+
+----
+git diff --patience -C -C HEAD@{upstream}  <1> <2>
+----
+<1> `-C -C` detects file copies/renames
+<2> `--patience` uses the patience-diff algorithm, which tends to produce nicer
+  diffs in many cases.
+
+The difference is that `HEAD@{upstream}` is actually the tagged merge base of
+your branch (See linkgit:git-rebase-update[1]). This means that if your upstream
+branch was rebased, but you haven't yet rebased the current branch on top of it,
+you'll still see an accurate diff compared to just diffing against
+`@{upstream}`.
+
+The `--wordwise` option also allows `git-diff` to do word-by-word comparison
+in a semi-intelligent way. However, sometimes it can produce surprising results,
+so it is disabled by default.
+
+
+OPTIONS
+-------
+
+--wordwise::
+  Print a colorized word-wise diff instead of a line-wise diff.
+
+<extra args for git-diff>::
+  Extra arguments are included in the invocation of linkgit:git-diff[1]. These
+  can be anything that `git-diff` normally takes.
++
+--
+`--stat`;;
+  This is particularly useful to show 'which' files have been changed in
+  comparison to the upstream branch.
+`-- <filename patterns>*`;;
+  Restrict the diff to only show the diff for given files compared to the
+  upstream.
+--
+
+
+CONFIGURATION VARIABLES
+-----------------------
+
+depot-tools.upstream-diff.default-args
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A list-configuration variable. Each instance of this config variable will be
+prepended to all invocations of `git upstream-diff`, as if you had passed them
+on the command line.
+
+include::_aliases.txt[]
+
+----
+[alias]
+  git udiff = upstream-diff
+----
+
+SEE ALSO
+--------
+linkgit:git-rebase-update[1]
+
+include::_footer.txt[]
+
+// vim: ft=asciidoc:

+ 8 - 0
git-mark-merge-base

@@ -0,0 +1,8 @@
+#!/bin/bash
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# git_mark_merge_base.py -- Manually set the merge base for the current branch.
+
+. $(type -P python_git_runner.sh)

+ 9 - 0
git-new-branch

@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# git_new_branch.py -- Create a new branch which tracks the default upstream
+# (origin/master).
+
+. $(type -P python_git_runner.sh)

+ 9 - 0
git-rebase-update

@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# git_rebase_update.py -- Update remote sources, and use rebase to update all
+# branches in this repo.
+
+. $(type -P python_git_runner.sh)

+ 9 - 0
git-rename-branch

@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# git_rename_branch.py -- Rename the current branch, correctly updating the
+# upstream branch of all the downstream branches.
+
+. $(type -P python_git_runner.sh)

+ 10 - 0
git-reparent-branch

@@ -0,0 +1,10 @@
+#!/bin/bash
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# git_reparent_branch.py -- Change the parent (upstream) branch of the current
+# branch. Afterwards, run a `git rebase-update` cycle to ensure that all
+# branches correctly reflect their parentage.
+
+. $(type -P python_git_runner.sh)

+ 8 - 0
git-squash-branch

@@ -0,0 +1,8 @@
+#!/bin/bash
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# git_squash_branch.py -- Collapses the current branch to a single commit.
+
+. $(type -P python_git_runner.sh)

+ 9 - 0
git-upstream-diff

@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# git_upstream_diff.py -- Provide the diff between the current branch and its
+# upstream.
+
+. $(type -P python_git_runner.sh)

+ 316 - 51
git_common.py

@@ -1,4 +1,4 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
+# Copyright 2014 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
@@ -16,10 +16,12 @@ IMapIterator.__next__ = IMapIterator.next
 
 
 import binascii
+import collections
 import contextlib
 import functools
 import logging
 import os
+import re
 import signal
 import sys
 import tempfile
@@ -29,6 +31,14 @@ import subprocess2
 
 
 GIT_EXE = 'git.bat' if sys.platform.startswith('win') else 'git'
+TEST_MODE = False
+
+FREEZE = 'FREEZE'
+FREEZE_SECTIONS = {
+  'indexed': 'soft',
+  'unindexed': 'mixed'
+}
+FREEZE_MATCHER = re.compile(r'%s.(%s)' % (FREEZE, '|'.join(FREEZE_SECTIONS)))
 
 
 class BadCommitRefException(Exception):
@@ -200,14 +210,48 @@ class ProgressPrinter(object):
     del self._thread
 
 
+def once(function):
+  """@Decorates |function| so that it only performs its action once, no matter
+  how many times the decorated |function| is called."""
+  def _inner_gen():
+    yield function()
+    while True:
+      yield
+  return _inner_gen().next
+
+
+## Git functions
+
+
+def branch_config(branch, option, default=None):
+  return config('branch.%s.%s' % (branch, option), default=default)
+
+
+def branch_config_map(option):
+  """Return {branch: <|option| value>} for all branches."""
+  try:
+    reg = re.compile(r'^branch\.(.*)\.%s$' % option)
+    lines = run('config', '--get-regexp', reg.pattern).splitlines()
+    return {reg.match(k).group(1): v for k, v in (l.split() for l in lines)}
+  except subprocess2.CalledProcessError:
+    return {}
+
+
 def branches(*args):
-  NO_BRANCH = ('* (no branch)', '* (detached from ')
+  NO_BRANCH = ('* (no branch', '* (detached from ')
   for line in run('branch', *args).splitlines():
     if line.startswith(NO_BRANCH):
       continue
     yield line.split()[-1]
 
 
+def config(option, default=None):
+  try:
+    return run('config', '--get', option) or default
+  except subprocess2.CalledProcessError:
+    return default
+
+
 def config_list(option):
   try:
     return run('config', '--get-all', option).split()
@@ -216,7 +260,134 @@ def config_list(option):
 
 
 def current_branch():
-  return run('rev-parse', '--abbrev-ref', 'HEAD')
+  try:
+    return run('rev-parse', '--abbrev-ref', 'HEAD')
+  except subprocess2.CalledProcessError:
+    return None
+
+
+def del_branch_config(branch, option, scope='local'):
+  del_config('branch.%s.%s' % (branch, option), scope=scope)
+
+
+def del_config(option, scope='local'):
+  try:
+    run('config', '--' + scope, '--unset', option)
+  except subprocess2.CalledProcessError:
+    pass
+
+
+def freeze():
+  took_action = False
+
+  try:
+    run('commit', '-m', FREEZE + '.indexed')
+    took_action = True
+  except subprocess2.CalledProcessError:
+    pass
+
+  try:
+    run('add', '-A')
+    run('commit', '-m', FREEZE + '.unindexed')
+    took_action = True
+  except subprocess2.CalledProcessError:
+    pass
+
+  if not took_action:
+    return 'Nothing to freeze.'
+
+
+def get_branch_tree():
+  """Get the dictionary of {branch: parent}, compatible with topo_iter.
+
+  Returns a tuple of (skipped, <branch_tree dict>) where skipped is a set of
+  branches without upstream branches defined.
+  """
+  skipped = set()
+  branch_tree = {}
+
+  for branch in branches():
+    parent = upstream(branch)
+    if not parent:
+      skipped.add(branch)
+      continue
+    branch_tree[branch] = parent
+
+  return skipped, branch_tree
+
+
+def get_or_create_merge_base(branch, parent=None):
+  """Finds the configured merge base for branch.
+
+  If parent is supplied, it's used instead of calling upstream(branch).
+  """
+  base = branch_config(branch, 'base')
+  if base:
+    try:
+      run('merge-base', '--is-ancestor', base, branch)
+      logging.debug('Found pre-set merge-base for %s: %s', branch, base)
+    except subprocess2.CalledProcessError:
+      logging.debug('Found WRONG pre-set merge-base for %s: %s', branch, base)
+      base = None
+
+  if not base:
+    base = run('merge-base', parent or upstream(branch), branch)
+    manual_merge_base(branch, base)
+
+  return base
+
+
+def hash_multi(*reflike):
+  return run('rev-parse', *reflike).splitlines()
+
+
+def hash_one(reflike):
+  return run('rev-parse', reflike)
+
+
+def in_rebase():
+  git_dir = run('rev-parse', '--git-dir')
+  return (
+    os.path.exists(os.path.join(git_dir, 'rebase-merge')) or
+    os.path.exists(os.path.join(git_dir, 'rebase-apply')))
+
+
+def intern_f(f, kind='blob'):
+  """Interns a file object into the git object store.
+
+  Args:
+    f (file-like object) - The file-like object to intern
+    kind (git object type) - One of 'blob', 'commit', 'tree', 'tag'.
+
+  Returns the git hash of the interned object (hex encoded).
+  """
+  ret = run('hash-object', '-t', kind, '-w', '--stdin', stdin=f)
+  f.close()
+  return ret
+
+
+def is_dormant(branch):
+  # TODO(iannucci): Do an oldness check?
+  return branch_config(branch, 'dormant', 'false') != 'false'
+
+
+def manual_merge_base(branch, base):
+  set_branch_config(branch, 'base', base)
+
+
+def mktree(treedict):
+  """Makes a git tree object and returns its hash.
+
+  See |tree()| for the values of mode, type, and ref.
+
+  Args:
+    treedict - { name: (mode, type, ref) }
+  """
+  with tempfile.TemporaryFile() as f:
+    for name, (mode, typ, ref) in treedict.iteritems():
+      f.write('%s %s %s\t%s\0' % (mode, typ, ref, name))
+    f.seek(0)
+    return run('mktree', '-z', stdin=f)
 
 
 def parse_commitrefs(*commitrefs):
@@ -233,67 +404,176 @@ def parse_commitrefs(*commitrefs):
     raise BadCommitRefException(commitrefs)
 
 
+RebaseRet = collections.namedtuple('RebaseRet', 'success message')
+
+
+def rebase(parent, start, branch, abort=False):
+  """Rebases |start|..|branch| onto the branch |parent|.
+
+  Args:
+    parent - The new parent ref for the rebased commits.
+    start  - The commit to start from
+    branch - The branch to rebase
+    abort  - If True, will call git-rebase --abort in the event that the rebase
+             doesn't complete successfully.
+
+  Returns a namedtuple with fields:
+    success - a boolean indicating that the rebase command completed
+              successfully.
+    message - if the rebase failed, this contains the stdout of the failed
+              rebase.
+  """
+  try:
+    args = ['--onto', parent, start, branch]
+    if TEST_MODE:
+      args.insert(0, '--committer-date-is-author-date')
+    run('rebase', *args)
+    return RebaseRet(True, '')
+  except subprocess2.CalledProcessError as cpe:
+    if abort:
+      run('rebase', '--abort')
+    return RebaseRet(False, cpe.output)
+
+
+def remove_merge_base(branch):
+  del_branch_config(branch, 'base')
+
+
+def root():
+  return config('depot-tools.upstream', 'origin/master')
+
+
 def run(*cmd, **kwargs):
-  """Runs a git command. Returns stdout as a string.
+  """The same as run_with_stderr, except it only returns stdout."""
+  return run_with_stderr(*cmd, **kwargs)[0]
+
+
+def run_stream(*cmd, **kwargs):
+  """Runs a git command. Returns stdout as a PIPE (file-like object).
 
-  If logging is DEBUG, we'll print the command before we run it.
+  stderr is dropped to avoid races if the process outputs to both stdout and
+  stderr.
+  """
+  kwargs.setdefault('stderr', subprocess2.VOID)
+  kwargs.setdefault('stdout', subprocess2.PIPE)
+  cmd = (GIT_EXE,) + cmd
+  proc = subprocess2.Popen(cmd, **kwargs)
+  return proc.stdout
+
+
+def run_with_stderr(*cmd, **kwargs):
+  """Runs a git command.
+
+  Returns (stdout, stderr) as a pair of strings.
 
   kwargs
     autostrip (bool) - Strip the output. Defaults to True.
+    indata (str) - Specifies stdin data for the process.
   """
+  kwargs.setdefault('stdin', subprocess2.PIPE)
+  kwargs.setdefault('stdout', subprocess2.PIPE)
+  kwargs.setdefault('stderr', subprocess2.PIPE)
   autostrip = kwargs.pop('autostrip', True)
+  indata = kwargs.pop('indata', None)
 
-  retstream, proc = stream_proc(*cmd, **kwargs)
-  ret = retstream.read()
+  cmd = (GIT_EXE,) + cmd
+  proc = subprocess2.Popen(cmd, **kwargs)
+  ret, err = proc.communicate(indata)
   retcode = proc.wait()
   if retcode != 0:
-    raise subprocess2.CalledProcessError(retcode, cmd, os.getcwd(), ret, None)
+    raise subprocess2.CalledProcessError(retcode, cmd, os.getcwd(), ret, err)
 
   if autostrip:
     ret = (ret or '').strip()
-  return ret
+    err = (err or '').strip()
 
+  return ret, err
 
-def stream_proc(*cmd, **kwargs):
-  """Runs a git command. Returns stdout as a file.
 
-  If logging is DEBUG, we'll print the command before we run it.
-  """
-  cmd = (GIT_EXE,) + cmd
-  logging.debug('Running %s', ' '.join(repr(tok) for tok in cmd))
-  proc = subprocess2.Popen(cmd, stderr=subprocess2.VOID,
-                           stdout=subprocess2.PIPE, **kwargs)
-  return proc.stdout, proc
+def set_branch_config(branch, option, value, scope='local'):
+  set_config('branch.%s.%s' % (branch, option), value, scope=scope)
 
 
-def stream(*cmd, **kwargs):
-  return stream_proc(*cmd, **kwargs)[0]
+def set_config(option, value, scope='local'):
+  run('config', '--' + scope, option, value)
 
+def squash_current_branch(header=None, merge_base=None):
+  header = header or 'git squash commit.'
+  merge_base = merge_base or get_or_create_merge_base(current_branch())
+  log_msg = header + '\n'
+  if log_msg:
+    log_msg += '\n'
+  log_msg += run('log', '--reverse', '--format=%H%n%B', '%s..HEAD' % merge_base)
+  run('reset', '--soft', merge_base)
+  run('commit', '-a', '-F', '-', indata=log_msg)
 
-def hash_one(reflike):
-  return run('rev-parse', reflike)
 
+def tags(*args):
+  return run('tag', *args).splitlines()
 
-def hash_multi(*reflike):
-  return run('rev-parse', *reflike).splitlines()
 
+def thaw():
+  took_action = False
+  for sha in (s.strip() for s in run_stream('rev-list', 'HEAD').xreadlines()):
+    msg = run('show', '--format=%f%b', '-s', 'HEAD')
+    match = FREEZE_MATCHER.match(msg)
+    if not match:
+      if not took_action:
+        return 'Nothing to thaw.'
+      break
 
-def intern_f(f, kind='blob'):
-  """Interns a file object into the git object store.
+    run('reset', '--' + FREEZE_SECTIONS[match.group(1)], sha)
+    took_action = True
 
-  Args:
-    f (file-like object) - The file-like object to intern
-    kind (git object type) - One of 'blob', 'commit', 'tree', 'tag'.
 
-  Returns the git hash of the interned object (hex encoded).
-  """
-  ret = run('hash-object', '-t', kind, '-w', '--stdin', stdin=f)
-  f.close()
-  return ret
+def topo_iter(branch_tree, top_down=True):
+  """Generates (branch, parent) in topographical order for a branch tree.
 
+  Given a tree:
 
-def tags(*args):
-  return run('tag', *args).splitlines()
+            A1
+        B1      B2
+      C1  C2    C3
+                D1
+
+  branch_tree would look like: {
+    'D1': 'C3',
+    'C3': 'B2',
+    'B2': 'A1',
+    'C1': 'B1',
+    'C2': 'B1',
+    'B1': 'A1',
+  }
+
+  It is OK to have multiple 'root' nodes in your graph.
+
+  if top_down is True, items are yielded from A->D. Otherwise they're yielded
+  from D->A. Within a layer the branches will be yielded in sorted order.
+  """
+  branch_tree = branch_tree.copy()
+
+  # TODO(iannucci): There is probably a more efficient way to do these.
+  if top_down:
+    while branch_tree:
+      this_pass = [(b, p) for b, p in branch_tree.iteritems()
+                   if p not in branch_tree]
+      assert this_pass, "Branch tree has cycles: %r" % branch_tree
+      for branch, parent in sorted(this_pass):
+        yield branch, parent
+        del branch_tree[branch]
+  else:
+    parent_to_branches = collections.defaultdict(set)
+    for branch, parent in branch_tree.iteritems():
+      parent_to_branches[parent].add(branch)
+
+    while branch_tree:
+      this_pass = [(b, p) for b, p in branch_tree.iteritems()
+                   if not parent_to_branches[b]]
+      assert this_pass, "Branch tree has cycles: %r" % branch_tree
+      for branch, parent in sorted(this_pass):
+        yield branch, parent
+        parent_to_branches[parent].discard(branch)
+        del branch_tree[branch]
 
 
 def tree(treeref, recurse=False):
@@ -339,18 +619,3 @@ def upstream(branch):
                branch+'@{upstream}')
   except subprocess2.CalledProcessError:
     return None
-
-
-def mktree(treedict):
-  """Makes a git tree object and returns its hash.
-
-  See |tree()| for the values of mode, type, and ref.
-
-  Args:
-    treedict - { name: (mode, type, ref) }
-  """
-  with tempfile.TemporaryFile() as f:
-    for name, (mode, typ, ref) in treedict.iteritems():
-      f.write('%s %s %s\t%s\0' % (mode, typ, ref, name))
-    f.seek(0)
-    return run('mktree', '-z', stdin=f)

+ 10 - 50
git_freezer.py

@@ -1,73 +1,33 @@
 #!/usr/local/bin/python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
 import sys
-import re
 import optparse
 
 import subcommand
-import subprocess2
-
-from git_common import run, stream
-
-FREEZE = 'FREEZE'
-SECTIONS = {
-  'indexed': 'soft',
-  'unindexed': 'mixed'
-}
-MATCHER = re.compile(r'%s.(%s)' % (FREEZE, '|'.join(SECTIONS)))
-
-
-def freeze():
-  took_action = False
-
-  try:
-    run('commit', '-m', FREEZE + '.indexed')
-    took_action = True
-  except subprocess2.CalledProcessError:
-    pass
-
-  try:
-    run('add', '-A')
-    run('commit', '-m', FREEZE + '.unindexed')
-    took_action = True
-  except subprocess2.CalledProcessError:
-    pass
-
-  if not took_action:
-    return 'Nothing to freeze.'
-
-
-def thaw():
-  took_action = False
-  for sha in (s.strip() for s in stream('rev-list', 'HEAD').xreadlines()):
-    msg = run('show', '--format=%f%b', '-s', 'HEAD')
-    match = MATCHER.match(msg)
-    if not match:
-      if not took_action:
-        return 'Nothing to thaw.'
-      break
-
-    run('reset', '--' + SECTIONS[match.group(1)], sha)
-    took_action = True
 
+from git_common import freeze, thaw
 
-def CMDfreeze(parser, args):  # pragma: no cover
+def CMDfreeze(parser, args):
   """Freeze a branch's changes."""
   parser.parse_args(args)
   return freeze()
 
 
-def CMDthaw(parser, args):  # pragma: no cover
+def CMDthaw(parser, args):
   """Returns a frozen branch to the state before it was frozen."""
   parser.parse_args(args)
   return thaw()
 
 
-def main():  # pragma: no cover
+def main():
   dispatcher = subcommand.CommandDispatcher(__name__)
   ret = dispatcher.execute(optparse.OptionParser(), sys.argv[1:])
   if ret:
     print ret
 
 
-if __name__ == '__main__':  # pragma: no cover
-  main()
+if __name__ == '__main__':
+  main()

+ 23 - 0
git_map.py

@@ -10,13 +10,16 @@ commits with branches + tags that point to them. Items are colorized as follows:
   * Green   - Local branch
   * Red     - Remote branches
   * Magenta - Tags
+  * White   - Merge Base Markers
   * Blue background - The currently checked out commit
 """
+
 import sys
 
 import subprocess2
 
 from git_common import current_branch, branches, tags, config_list, GIT_EXE
+from git_common import branch_config_map
 
 from third_party import colorama
 
@@ -24,12 +27,16 @@ CYAN = colorama.Fore.CYAN
 GREEN = colorama.Fore.GREEN
 MAGENTA = colorama.Fore.MAGENTA
 RED = colorama.Fore.RED
+WHITE = colorama.Fore.WHITE
 
 BLUEBAK = colorama.Back.BLUE
 
 BRIGHT = colorama.Style.BRIGHT
 RESET = colorama.Fore.RESET + colorama.Back.RESET + colorama.Style.RESET_ALL
 
+# Git emits combined color
+BRIGHT_RED = '\x1b[1;31m'
+
 def main():
   map_extra = config_list('depot_tools.map_extra')
   fmt = '%C(red bold)%h%x09%Creset%C(green)%d%Creset %C(yellow)%ad%Creset ~ %s'
@@ -40,6 +47,7 @@ def main():
     stdout=subprocess2.PIPE,
     shell=False)
 
+  merge_base_map = branch_config_map('base')
   current = current_branch()
   all_branches = set(branches())
   if current in all_branches:
@@ -47,6 +55,21 @@ def main():
   all_tags = set(tags())
   try:
     for line in log_proc.stdout.xreadlines():
+      if merge_base_map:
+        commit = line[line.find(BRIGHT_RED)+len(BRIGHT_RED):line.find('\t')]
+        base_for_branches = set()
+        for branch, sha in merge_base_map.iteritems():
+          if sha.startswith(commit):
+            base_for_branches.add(branch)
+        if base_for_branches:
+          newline = '\r\n' if line.endswith('\r\n') else '\n'
+          line = line.rstrip(newline)
+          line += ''.join(
+              (BRIGHT, WHITE, '    <(%s)' % (', '.join(base_for_branches)),
+               newline))
+          for b in base_for_branches:
+            del merge_base_map[b]
+
       start = line.find(GREEN+' (')
       end   = line.find(')', start)
       if start != -1 and end != -1:

+ 19 - 8
git_map_branches.py

@@ -19,9 +19,11 @@ Branches are colorized as follows:
     * Note that multiple branches may be Cyan, if they are all on the same
       commit, and you have that commit checked out.
   * Green - a local branch
-  * Magenta - a placeholder for the '{NO UPSTREAM}' "branch". If you have
-    local branches which do not track any upstream, then you will see this.
+  * Magenta - a tag
+  * Magenta '{NO UPSTREAM}' - If you have local branches which do not track any
+    upstream, then you will see this.
 """
+
 import collections
 import sys
 
@@ -29,15 +31,14 @@ from third_party import colorama
 from third_party.colorama import Fore, Style
 
 from git_common import current_branch, branches, upstream, hash_one, hash_multi
+from git_common import tags
 
 NO_UPSTREAM = '{NO UPSTREAM}'
 
-def print_branch(cur, cur_hash, branch, branch_hashes, par_map, branch_map,
-                 depth=0):
-  branch_hash = branch_hashes[branch]
+def color_for_branch(branch, branch_hash, cur_hash, tag_set):
   if branch.startswith('origin'):
     color = Fore.RED
-  elif branch == NO_UPSTREAM:
+  elif branch == NO_UPSTREAM or branch in tag_set:
     color = Fore.MAGENTA
   elif branch_hash == cur_hash:
     color = Fore.CYAN
@@ -49,6 +50,15 @@ def print_branch(cur, cur_hash, branch, branch_hashes, par_map, branch_map,
   else:
     color += Style.NORMAL
 
+  return color
+
+
+def print_branch(cur, cur_hash, branch, branch_hashes, par_map, branch_map,
+                 tag_set, depth=0):
+  branch_hash = branch_hashes[branch]
+
+  color = color_for_branch(branch, branch_hash, cur_hash, tag_set)
+
   suffix = ''
   if cur == 'HEAD':
     if branch_hash == cur_hash:
@@ -59,7 +69,7 @@ def print_branch(cur, cur_hash, branch, branch_hashes, par_map, branch_map,
   print color + "  "*depth + branch + suffix
   for child in par_map.pop(branch, ()):
     print_branch(cur, cur_hash, child, branch_hashes, par_map, branch_map,
-                 depth=depth+1)
+                 tag_set, depth=depth+1)
 
 
 def main(argv):
@@ -77,13 +87,14 @@ def main(argv):
   current_hash = hashes[0]
   par_hashes = {k: hashes[i+1] for i, k in enumerate(branch_map.iterkeys())}
   par_hashes[NO_UPSTREAM] = 0
+  tag_set = tags()
   while par_map:
     for parent in par_map:
       if parent not in branch_map:
         if parent not in par_hashes:
           par_hashes[parent] = hash_one(parent)
         print_branch(current, current_hash, parent, par_hashes, par_map,
-                     branch_map)
+                     branch_map, tag_set)
         break
 
 

+ 68 - 0
git_mark_merge_base.py

@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Explicitly set/remove/print the merge-base for the current branch.
+
+This manually set merge base will be a stand-in for `git merge-base` for the
+purposes of the chromium depot_tools git extensions. Passing no arguments will
+just print the effective merge base for the current branch.
+"""
+
+import argparse
+import sys
+
+from subprocess2 import CalledProcessError
+
+from git_common import remove_merge_base, manual_merge_base, current_branch
+from git_common import get_or_create_merge_base, hash_one
+
+
+def main(argv):
+  parser = argparse.ArgumentParser(
+    description=__doc__.strip().splitlines()[0],
+    epilog=' '.join(__doc__.strip().splitlines()[1:]))
+  g = parser.add_mutually_exclusive_group()
+  g.add_argument(
+    'merge_base', nargs='?',
+    help='The new hash to use as the merge base for the current branch'
+  )
+  g.add_argument('--delete', '-d', action='store_true',
+                 help='Remove the set mark.')
+  opts = parser.parse_args(argv)
+
+  cur = current_branch()
+
+  if opts.delete:
+    try:
+      remove_merge_base(cur)
+    except CalledProcessError:
+      print "No merge base currently exists for %s." % cur
+    return 0
+
+  if opts.merge_base:
+    try:
+      opts.merge_base = hash_one(opts.merge_base)
+    except CalledProcessError:
+      print >> sys.stderr, (
+          'fatal: could not resolve %s as a commit' % (opts.merge_base)
+      )
+      return 1
+
+    manual_merge_base(cur, opts.merge_base)
+
+  ret = 0
+  actual = get_or_create_merge_base(cur)
+  if opts.merge_base and opts.merge_base != actual:
+    ret = 1
+    print "Invalid merge_base %s" % opts.merge_base
+
+  print "merge_base(%s): %s" % (cur, actual)
+
+  return ret
+
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv[1:]))

+ 1 - 0
git_nav_downstream.py

@@ -8,6 +8,7 @@ Checks out a downstream branch from the currently checked out branch. If there
 is more than one downstream branch, then this script will prompt you to select
 which branch.
 """
+
 import sys
 
 from git_common import current_branch, branches, upstream, run, hash_one

+ 53 - 0
git_new_branch.py

@@ -0,0 +1,53 @@
+#!/usr/local/bin/python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import sys
+
+import subprocess2
+
+from git_common import run, root, set_config, get_or_create_merge_base, tags
+from git_common import hash_one
+
+
+def main(args):
+  parser = argparse.ArgumentParser(
+    formatter_class=argparse.ArgumentDefaultsHelpFormatter
+  )
+  parser.add_argument('branch_name')
+  g = parser.add_mutually_exclusive_group()
+  g.add_argument('--upstream_current', action='store_true',
+                 help='set upstream branch to current branch.')
+  g.add_argument('--upstream', metavar='REF', default=root(),
+                 help='upstream branch (or tag) to track.')
+  g.add_argument('--lkgr', action='store_const', const='lkgr', dest='upstream',
+                 help='set basis ref for new branch to lkgr.')
+
+  opts = parser.parse_args(args)
+
+  try:
+    if opts.upstream_current:
+      run('checkout', '--track', '-b', opts.branch_name)
+    else:
+      if opts.upstream in tags():
+        # TODO(iannucci): ensure that basis_ref is an ancestor of HEAD?
+        run('checkout', '--no-track', '-b', opts.branch_name,
+            hash_one(opts.upstream))
+        set_config('branch.%s.remote' % opts.branch_name, '.')
+        set_config('branch.%s.merge' % opts.branch_name, opts.upstream)
+      else:
+        # TODO(iannucci): Detect unclean workdir then stash+pop if we need to
+        # teleport to a conflicting portion of history?
+        run('checkout', '--track', opts.upstream, '-b', opts.branch_name)
+
+    get_or_create_merge_base(opts.branch_name)
+  except subprocess2.CalledProcessError as cpe:
+    sys.stdout.write(cpe.stdout)
+    sys.stderr.write(cpe.stderr)
+    return 1
+
+
+if __name__ == '__main__':  # pragma: no cover
+  sys.exit(main(sys.argv[1:]))

+ 245 - 0
git_rebase_update.py

@@ -0,0 +1,245 @@
+#!/usr/bin/python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Tool to update all branches to have the latest changes from their upstreams.
+"""
+
+import argparse
+import collections
+import logging
+import sys
+import textwrap
+
+from pprint import pformat
+
+import git_common as git
+
+
+STARTING_BRANCH_KEY = 'depot-tools.rebase-update.starting-branch'
+
+
+def find_return_branch():
+  """Finds the branch which we should return to after rebase-update completes.
+
+  This value may persist across multiple invocations of rebase-update, if
+  rebase-update runs into a conflict mid-way.
+  """
+  return_branch = git.config(STARTING_BRANCH_KEY)
+  if return_branch is None:
+    return_branch = git.current_branch()
+    if return_branch != 'HEAD':
+      git.set_config(STARTING_BRANCH_KEY, return_branch)
+
+  return return_branch
+
+
+def fetch_remotes(branch_tree):
+  """Fetches all remotes which are needed to update |branch_tree|."""
+  fetch_tags = False
+  remotes = set()
+  tag_set = git.tags()
+  for parent in branch_tree.itervalues():
+    if parent in tag_set:
+      fetch_tags = True
+    else:
+      full_ref = git.run('rev-parse', '--symbolic-full-name', parent)
+      if full_ref.startswith('refs/remotes'):
+        parts = full_ref.split('/')
+        remote_name = parts[2]
+        remotes.add(remote_name)
+
+  fetch_args = []
+  if fetch_tags:
+    # Need to fetch all because we don't know what remote the tag comes from :(
+    # TODO(iannucci): assert that the tags are in the remote fetch refspec
+    fetch_args = ['--all']
+  else:
+    fetch_args.append('--multiple')
+    fetch_args.extend(remotes)
+  # TODO(iannucci): Should we fetch git-svn?
+
+  if not fetch_args:  # pragma: no cover
+    print 'Nothing to fetch.'
+  else:
+    out, err = git.run_with_stderr('fetch', *fetch_args)
+    for data, stream in zip((out, err), (sys.stdout, sys.stderr)):
+      if data:
+        print >> stream, data
+
+
+def remove_empty_branches(branch_tree):
+  tag_set = git.tags()
+  ensure_root_checkout = git.once(lambda: git.run('checkout', git.root()))
+
+  downstreams = collections.defaultdict(list)
+  for branch, parent in git.topo_iter(branch_tree, top_down=False):
+    downstreams[parent].append(branch)
+
+    if git.hash_one(branch) == git.hash_one(parent):
+      ensure_root_checkout()
+
+      logging.debug('branch %s merged to %s', branch, parent)
+
+      for down in downstreams[branch]:
+        if parent in tag_set:
+          git.set_branch_config(down, 'remote', '.')
+          git.set_branch_config(down, 'merge', 'refs/tags/%s' % parent)
+          print ('Reparented %s to track %s [tag] (was tracking %s)'
+                 % (down, parent, branch))
+        else:
+          git.run('branch', '--set-upstream-to', parent, down)
+          print ('Reparented %s to track %s (was tracking %s)'
+                 % (down, parent, branch))
+
+      print git.run('branch', '-d', branch)
+
+
+def rebase_branch(branch, parent, start_hash):
+  logging.debug('considering %s(%s) -> %s(%s) : %s',
+                branch, git.hash_one(branch), parent, git.hash_one(parent),
+                start_hash)
+
+  # If parent has FROZEN commits, don't base branch on top of them. Instead,
+  # base branch on top of whatever commit is before them.
+  back_ups = 0
+  orig_parent = parent
+  while git.run('log', '-n1', '--format=%s',
+                parent, '--').startswith(git.FREEZE):
+    back_ups += 1
+    parent = git.run('rev-parse', parent+'~')
+
+  if back_ups:
+    logging.debug('Backed parent up by %d from %s to %s',
+                  back_ups, orig_parent, parent)
+
+  if git.hash_one(parent) != start_hash:
+    # Try a plain rebase first
+    print 'Rebasing:', branch
+    if not git.rebase(parent, start_hash, branch, abort=True).success:
+      # TODO(iannucci): Find collapsible branches in a smarter way?
+      print "Failed! Attempting to squash", branch, "...",
+      squash_branch = branch+"_squash_attempt"
+      git.run('checkout', '-b', squash_branch)
+      git.squash_current_branch(merge_base=start_hash)
+
+      # Try to rebase the branch_squash_attempt branch to see if it's empty.
+      squash_ret = git.rebase(parent, start_hash, squash_branch, abort=True)
+      empty_rebase = git.hash_one(squash_branch) == git.hash_one(parent)
+      git.run('checkout', branch)
+      git.run('branch', '-D', squash_branch)
+      if squash_ret.success and empty_rebase:
+        print 'Success!'
+        git.squash_current_branch(merge_base=start_hash)
+        git.rebase(parent, start_hash, branch)
+      else:
+        # rebase and leave in mid-rebase state.
+        git.rebase(parent, start_hash, branch)
+        print squash_ret.message
+        print
+        print textwrap.dedent(
+        """
+        Squashing failed. You probably have a real merge conflict.
+
+        Your working copy is in mid-rebase. Either:
+         * completely resolve like a normal git-rebase; OR
+         * abort the rebase and mark this branch as dormant:
+               git config branch.%s.dormant true
+
+        And then run `git rebase-update` again to resume.
+        """ % branch)
+        return False
+  else:
+    print '%s up-to-date' % branch
+
+  git.remove_merge_base(branch)
+  git.get_or_create_merge_base(branch)
+
+  return True
+
+
+def main(args=()):
+  parser = argparse.ArgumentParser()
+  parser.add_argument('--verbose', '-v', action='store_true')
+  parser.add_argument('--no_fetch', '-n', action='store_true',
+                      help='Skip fetching remotes.')
+  opts = parser.parse_args(args)
+
+  if opts.verbose:  # pragma: no cover
+    logging.getLogger().setLevel(logging.DEBUG)
+
+  # TODO(iannucci): snapshot all branches somehow, so we can implement
+  #                 `git rebase-update --undo`.
+  #   * Perhaps just copy packed-refs + refs/ + logs/ to the side?
+  #     * commit them to a secret ref?
+  #       * Then we could view a summary of each run as a
+  #         `diff --stat` on that secret ref.
+
+  if git.in_rebase():
+    # TODO(iannucci): Be able to resume rebase with flags like --continue,
+    # etc.
+    print (
+      'Rebase in progress. Please complete the rebase before running '
+      '`git rebase-update`.'
+    )
+    return 1
+
+  return_branch = find_return_branch()
+
+  if git.current_branch() == 'HEAD':
+    if git.run('status', '--porcelain'):
+      print 'Cannot rebase-update with detached head + uncommitted changes.'
+      return 1
+  else:
+    git.freeze()  # just in case there are any local changes.
+
+  skipped, branch_tree = git.get_branch_tree()
+  for branch in skipped:
+    print 'Skipping %s: No upstream specified' % branch
+
+  if not opts.no_fetch:
+    fetch_remotes(branch_tree)
+
+  merge_base = {}
+  for branch, parent in branch_tree.iteritems():
+    merge_base[branch] = git.get_or_create_merge_base(branch, parent)
+
+  logging.debug('branch_tree: %s' % pformat(branch_tree))
+  logging.debug('merge_base: %s' % pformat(merge_base))
+
+  retcode = 0
+  # Rebase each branch starting with the root-most branches and working
+  # towards the leaves.
+  for branch, parent in git.topo_iter(branch_tree):
+    if git.is_dormant(branch):
+      print 'Skipping dormant branch', branch
+    else:
+      ret = rebase_branch(branch, parent, merge_base[branch])
+      if not ret:
+        retcode = 1
+        break
+
+  if not retcode:
+    remove_empty_branches(branch_tree)
+
+    # return_branch may not be there any more.
+    if return_branch in git.branches():
+      git.run('checkout', return_branch)
+      git.thaw()
+    else:
+      root_branch = git.root()
+      if return_branch != 'HEAD':
+        print (
+          "%r was merged with its parent, checking out %r instead."
+          % (return_branch, root_branch)
+        )
+      git.run('checkout', root_branch)
+    git.del_config(STARTING_BRANCH_KEY)
+
+  return retcode
+
+
+if __name__ == '__main__':  # pragma: no cover
+  sys.exit(main(sys.argv[1:]))

+ 50 - 0
git_rename_branch.py

@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Rename the current branch while maintaining correct dependencies."""
+
+import argparse
+import sys
+
+import subprocess2
+
+from git_common import current_branch, run, set_branch_config, branch_config
+from git_common import branch_config_map
+
+def main(args):
+  current = current_branch()
+  if current == 'HEAD':
+    current = None
+  old_name_help = 'The old branch to rename.'
+  if current:
+    old_name_help += ' (default %(default)r)'
+
+  parser = argparse.ArgumentParser()
+  parser.add_argument('old_name', nargs=('?' if current else 1),
+                      help=old_name_help, default=current)
+  parser.add_argument('new_name', help='The new branch name.')
+
+  opts = parser.parse_args(args)
+
+  # when nargs=1, we get a list :(
+  if isinstance(opts.old_name, list):
+    opts.old_name = opts.old_name[0]
+
+  try:
+    run('branch', '-m', opts.old_name, opts.new_name)
+
+    # update the downstreams
+    for branch, merge in branch_config_map('merge').iteritems():
+      if merge == 'refs/heads/' + opts.old_name:
+        # Only care about local branches
+        if branch_config(branch, 'remote') == '.':
+          set_branch_config(branch, 'merge', 'refs/heads/' + opts.new_name)
+  except subprocess2.CalledProcessError as cpe:
+    sys.stderr.write(cpe.stderr)
+    return 1
+
+
+if __name__ == '__main__':  # pragma: no cover
+  sys.exit(main(sys.argv[1:]))

+ 74 - 0
git_reparent_branch.py

@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Change the upstream of the current branch."""
+
+import argparse
+import sys
+
+import subprocess2
+
+from git_common import upstream, current_branch, run, tags, set_branch_config
+from git_common import get_or_create_merge_base, root
+
+import git_rebase_update
+
+def main(args):
+  root_ref = root()
+
+  parser = argparse.ArgumentParser()
+  g = parser.add_mutually_exclusive_group()
+  g.add_argument('new_parent', nargs='?',
+                 help='New parent branch (or tag) to reparent to.')
+  g.add_argument('--root', action='store_true',
+                 help='Reparent to the configured root branch (%s).' % root_ref)
+  g.add_argument('--lkgr', action='store_true',
+                 help='Reparent to the lkgr tag.')
+  opts = parser.parse_args(args)
+
+  # TODO(iannucci): Allow specification of the branch-to-reparent
+
+  branch = current_branch()
+  if opts.root:
+    new_parent = root_ref
+  elif opts.lkgr:
+    new_parent = 'lkgr'
+  else:
+    new_parent = opts.new_parent
+  cur_parent = upstream(branch)
+
+  if branch == 'HEAD' or not branch:
+    parser.error('Must be on the branch you want to reparent')
+  if new_parent == cur_parent:
+    parser.error('Cannot reparent a branch to its existing parent')
+
+  get_or_create_merge_base(branch, cur_parent)
+
+  all_tags = tags()
+  if cur_parent in all_tags:
+    cur_parent += ' [tag]'
+
+  try:
+    run('show-ref', new_parent)
+  except subprocess2.CalledProcessError:
+    print >> sys.stderr, 'fatal: invalid reference: %s' % new_parent
+    return 1
+
+  if new_parent in all_tags:
+    print ("Reparenting %s to track %s [tag] (was %s)"
+           % (branch, new_parent, cur_parent))
+    set_branch_config(branch, 'remote', '.')
+    set_branch_config(branch, 'merge', new_parent)
+  else:
+    print ("Reparenting %s to track %s (was %s)"
+           % (branch, new_parent, cur_parent))
+    run('branch', '--set-upstream-to', new_parent, branch)
+
+  # TODO(iannucci): ONLY rebase-update the branch which moved (and dependants)
+  return git_rebase_update.main(['--no_fetch'])
+
+
+if __name__ == '__main__':  # pragma: no cover
+  sys.exit(main(sys.argv[1:]))

+ 20 - 0
git_squash_branch.py

@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import sys
+
+from git_common import squash_current_branch
+
+def main(args):
+  parser = argparse.ArgumentParser()
+  parser.add_argument(
+      '-m', '--message', metavar='<msg>', default='git squash commit.',
+      help='Use the given <msg> as the first line of the commit message.')
+  opts = parser.parse_args(args)
+  squash_current_branch(opts.message)
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))

+ 36 - 0
git_upstream_diff.py

@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import sys
+
+import subprocess2
+
+from git_common import current_branch, get_or_create_merge_base, config_list
+from git_common import GIT_EXE
+
+def main(args):
+  default_args = config_list('depot-tools.upstream-diff.default-args')
+  args = default_args + args
+
+  parser = argparse.ArgumentParser()
+  parser.add_argument('--wordwise', action='store_true', default=False,
+                      help=(
+                        'Print a colorized wordwise diff '
+                        'instead of line-wise diff'))
+  opts, extra_args = parser.parse_known_args(args)
+
+  cmd = [GIT_EXE, 'diff', '--patience', '-C', '-C']
+  if opts.wordwise:
+    cmd += ['--word-diff=color', r'--word-diff-regex=(\w+|[^[:space:]])']
+  cmd += [get_or_create_merge_base(current_branch())]
+
+  cmd += extra_args
+
+  subprocess2.check_call(cmd)
+
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv[1:]))

+ 112 - 29
testing_support/git_test_utils.py

@@ -10,9 +10,12 @@ import hashlib
 import os
 import shutil
 import subprocess
+import sys
 import tempfile
 import unittest
 
+from cStringIO import StringIO
+
 
 def git_hash_data(data, typ='blob'):
   """Calculate the git-style SHA1 for some data.
@@ -159,6 +162,12 @@ class GitRepoSchema(object):
         v.difference_update(empty_keys)
       is_root = False
 
+  def add_partial(self, commit, parent=None):
+    if commit not in self.par_map:
+      self.par_map[commit] = OrderedSet()
+    if parent is not None:
+      self.par_map[commit].add(parent)
+
   def add_commits(self, schema):
     """Adds more commits from a schema into the existing Schema.
 
@@ -170,10 +179,7 @@ class GitRepoSchema(object):
     for commits in (l.split() for l in schema.splitlines() if l.strip()):
       parent = None
       for commit in commits:
-        if commit not in self.par_map:
-          self.par_map[commit] = OrderedSet()
-        if parent is not None:
-          self.par_map[commit].add(parent)
+        self.add_partial(commit, parent)
         parent = commit
       if parent and not self.master:
         self.master = parent
@@ -195,6 +201,18 @@ class GitRepoSchema(object):
       self.data_cache[commit] = self.content_fn(commit)
     return self.data_cache[commit]
 
+  def simple_graph(self):
+    """Returns a dictionary of {commit_subject: {parent commit_subjects}}
+
+    This allows you to get a very simple connection graph over the whole repo
+    for comparison purposes. Only commit subjects (not ids, not content/data)
+    are considered
+    """
+    ret = {}
+    for commit in self.walk():
+      ret.setdefault(commit.name, set()).update(commit.parents)
+    return ret
+
 
 class GitRepo(object):
   """Creates a real git repo for a GitRepoSchema.
@@ -253,12 +271,16 @@ class GitRepo(object):
     self.commit_map = {}
     self._date = datetime.datetime(1970, 1, 1)
 
+    self.to_schema_refs = ['--branches']
+
     self.git('init')
+    self.git('config', 'user.name', 'testcase')
+    self.git('config', 'user.email', 'testcase@example.com')
     for commit in schema.walk():
       self._add_schema_commit(commit, schema.data_for(commit.name))
       self.last_commit = self[commit.name]
     if schema.master:
-      self.git('update-ref', 'master', self[schema.master])
+      self.git('update-ref', 'refs/heads/master', self[schema.master])
 
   def __getitem__(self, commit_name):
     """Gets the hash of a commit by its schema name.
@@ -269,8 +291,8 @@ class GitRepo(object):
     """
     return self.commit_map[commit_name]
 
-  def _add_schema_commit(self, commit, data):
-    data = data or {}
+  def _add_schema_commit(self, commit, commit_data):
+    commit_data = commit_data or {}
 
     if commit.parents:
       parents = list(commit.parents)
@@ -281,22 +303,9 @@ class GitRepo(object):
       self.git('checkout', '--orphan', 'root_%s' % commit.name)
       self.git('rm', '-rf', '.')
 
-    env = {}
-    for prefix in ('AUTHOR', 'COMMITTER'):
-      for suffix in ('NAME', 'EMAIL', 'DATE'):
-        singleton = '%s_%s' % (prefix, suffix)
-        key = getattr(self, singleton)
-        if key in data:
-          val = data[key]
-        else:
-          if suffix == 'DATE':
-            val = self._date
-            self._date += datetime.timedelta(days=1)
-          else:
-            val = getattr(self, 'DEFAULT_%s' % singleton)
-        env['GIT_%s' % singleton] = str(val)
+    env = self.get_git_commit_env(commit_data)
 
-    for fname, file_data in data.iteritems():
+    for fname, file_data in commit_data.iteritems():
       deleted = False
       if 'data' in file_data:
         data = file_data.get('data')
@@ -324,6 +333,25 @@ class GitRepo(object):
     if commit.is_branch:
       self.git('branch', '-f', 'branch_%s' % commit.name, self[commit.name])
 
+  def get_git_commit_env(self, commit_data=None):
+    commit_data = commit_data or {}
+    env = {}
+    for prefix in ('AUTHOR', 'COMMITTER'):
+      for suffix in ('NAME', 'EMAIL', 'DATE'):
+        singleton = '%s_%s' % (prefix, suffix)
+        key = getattr(self, singleton)
+        if key in commit_data:
+          val = commit_data[key]
+        else:
+          if suffix == 'DATE':
+            val = self._date
+            self._date += datetime.timedelta(days=1)
+          else:
+            val = getattr(self, 'DEFAULT_%s' % singleton)
+        env['GIT_%s' % singleton] = str(val)
+    return env
+
+
   def git(self, *args, **kwargs):
     """Runs a git command specified by |args| in this repo."""
     assert self.repo_path is not None
@@ -335,6 +363,9 @@ class GitRepo(object):
     except subprocess.CalledProcessError as e:
       return self.COMMAND_OUTPUT(e.returncode, e.output)
 
+  def git_commit(self, message):
+    return self.git('commit', '-am', message, env=self.get_git_commit_env())
+
   def nuke(self):
     """Obliterates the git repo on disk.
 
@@ -354,11 +385,59 @@ class GitRepo(object):
     finally:
       os.chdir(curdir)
 
+  def capture_stdio(self, fn, *args, **kwargs):
+    """Run a python function with the given args and kwargs with the cwd set to
+    the git repo.
+
+    Returns the (stdout, stderr) of whatever ran, instead of the what |fn|
+    returned.
+    """
+    stdout = sys.stdout
+    stderr = sys.stderr
+    try:
+      sys.stdout = StringIO()
+      sys.stderr = StringIO()
+      try:
+        self.run(fn, *args, **kwargs)
+      except SystemExit:
+        pass
+      return sys.stdout.getvalue(), sys.stderr.getvalue()
+    finally:
+      sys.stdout = stdout
+      sys.stderr = stderr
+
+  def open(self, path, mode='rb'):
+    return open(os.path.join(self.repo_path, path), mode)
+
+  def to_schema(self):
+    lines = self.git('rev-list', '--parents', '--reverse', '--topo-order',
+                     '--format=%s', *self.to_schema_refs).stdout.splitlines()
+    hash_to_msg = {}
+    ret = GitRepoSchema()
+    current = None
+    parents = []
+    for line in lines:
+      if line.startswith('commit'):
+        assert current is None
+        tokens = line.split()
+        current, parents = tokens[1], tokens[2:]
+        assert all(p in hash_to_msg for p in parents)
+      else:
+        assert current is not None
+        hash_to_msg[current] = line
+        ret.add_partial(line)
+        for parent in parents:
+          ret.add_partial(line, hash_to_msg[parent])
+        current = None
+        parents = []
+    assert current is None
+    return ret
+
 
 class GitRepoSchemaTestBase(unittest.TestCase):
   """A TestCase with a built-in GitRepoSchema.
 
-  Expects a class variable REPO to be a GitRepoSchema string in the form
+  Expects a class variable REPO_SCHEMA to be a GitRepoSchema string in the form
   described by that class.
 
   You may also set class variables in the form COMMIT_%(commit_name)s, which
@@ -367,7 +446,7 @@ class GitRepoSchemaTestBase(unittest.TestCase):
   You probably will end up using either GitRepoReadOnlyTestBase or
   GitRepoReadWriteTestBase for real tests.
   """
-  REPO = None
+  REPO_SCHEMA = None
 
   @classmethod
   def getRepoContent(cls, commit):
@@ -376,8 +455,8 @@ class GitRepoSchemaTestBase(unittest.TestCase):
   @classmethod
   def setUpClass(cls):
     super(GitRepoSchemaTestBase, cls).setUpClass()
-    assert cls.REPO is not None
-    cls.r_schema = GitRepoSchema(cls.REPO, cls.getRepoContent)
+    assert cls.REPO_SCHEMA is not None
+    cls.r_schema = GitRepoSchema(cls.REPO_SCHEMA, cls.getRepoContent)
 
 
 class GitRepoReadOnlyTestBase(GitRepoSchemaTestBase):
@@ -387,12 +466,12 @@ class GitRepoReadOnlyTestBase(GitRepoSchemaTestBase):
   This GitRepo will appear as self.repo, and will be deleted and recreated once
   for the duration of all the tests in the subclass.
   """
-  REPO = None
+  REPO_SCHEMA = None
 
   @classmethod
   def setUpClass(cls):
     super(GitRepoReadOnlyTestBase, cls).setUpClass()
-    assert cls.REPO is not None
+    assert cls.REPO_SCHEMA is not None
     cls.repo = cls.r_schema.reify()
 
   def setUp(self):
@@ -411,7 +490,7 @@ class GitRepoReadWriteTestBase(GitRepoSchemaTestBase):
   This GitRepo will appear as self.repo, and will be deleted and recreated for
   each test function in the subclass.
   """
-  REPO = None
+  REPO_SCHEMA = None
 
   def setUp(self):
     super(GitRepoReadWriteTestBase, self).setUp()
@@ -420,3 +499,7 @@ class GitRepoReadWriteTestBase(GitRepoSchemaTestBase):
   def tearDown(self):
     self.repo.nuke()
     super(GitRepoReadWriteTestBase, self).tearDown()
+
+  def assertSchema(self, schema_string):
+    self.assertEqual(GitRepoSchema(schema_string).simple_graph(),
+                     self.repo.to_schema().simple_graph())

+ 296 - 9
tests/git_common_test.py

@@ -27,6 +27,7 @@ class GitCommonTestBase(unittest.TestCase):
     super(GitCommonTestBase, cls).setUpClass()
     import git_common
     cls.gc = git_common
+    cls.gc.TEST_MODE = True
 
 
 class Support(GitCommonTestBase):
@@ -63,6 +64,23 @@ class Support(GitCommonTestBase):
   def testMemoizeOneThreadsafe(self):
     self._testMemoizeOneBody(threadsafe=True)
 
+  def testOnce(self):
+    testlist = []
+
+    # This works around a bug in pylint
+    once = self.gc.once
+
+    @once
+    def add_to_list():
+      testlist.append('dog')
+
+    add_to_list()
+    add_to_list()
+    add_to_list()
+    add_to_list()
+
+    self.assertEquals(testlist, ['dog'])
+
 
 def slow_square(i):
   """Helper for ScopedPoolTest.
@@ -134,15 +152,15 @@ class ProgressPrinterTest(GitCommonTestBase):
         time.sleep(0.02)
         inc()
 
-    filtered = set(x.strip() for x in stream.data)
-    rslt = set(fmt % {'count': i} for i in xrange(11))
+    filtered = {x.strip() for x in stream.data}
+    rslt = {fmt % {'count': i} for i in xrange(11)}
     self.assertSetEqual(filtered, rslt)
     self.assertGreaterEqual(stream.count, 10)
 
 
 class GitReadOnlyFunctionsTest(git_test_utils.GitRepoReadOnlyTestBase,
                                GitCommonTestBase):
-  REPO = """
+  REPO_SCHEMA = """
   A B C D
     B E D
   """
@@ -194,7 +212,7 @@ class GitReadOnlyFunctionsTest(git_test_utils.GitRepoReadOnlyTestBase,
     items = set(self.repo.commit_map.itervalues())
 
     def testfn():
-      for line in self.gc.stream('log', '--format=%H').xreadlines():
+      for line in self.gc.run_stream('log', '--format=%H').xreadlines():
         line = line.strip()
         self.assertIn(line, items)
         items.remove(line)
@@ -202,16 +220,22 @@ class GitReadOnlyFunctionsTest(git_test_utils.GitRepoReadOnlyTestBase,
     self.repo.run(testfn)
 
   def testCurrentBranch(self):
+    def cur_branch_out_of_git():
+      os.chdir('..')
+      return self.gc.current_branch()
+    self.assertIsNone(self.repo.run(cur_branch_out_of_git))
+
     self.repo.git('checkout', 'branch_D')
     self.assertEqual(self.repo.run(self.gc.current_branch), 'branch_D')
 
   def testBranches(self):
     self.assertEqual(self.repo.run(set, self.gc.branches()),
-                     set(('branch_D', 'root_A')))
+                     {'master', 'branch_D', 'root_A'})
 
-  def testTags(self):
-    self.assertEqual(set(self.repo.run(self.gc.tags)),
-                     {'tag_'+l for l in 'ABCDE'})
+  def testDormant(self):
+    self.assertFalse(self.repo.run(self.gc.is_dormant, 'master'))
+    self.repo.git('config', 'branch.master.dormant', 'true')
+    self.assertTrue(self.repo.run(self.gc.is_dormant, 'master'))
 
   def testParseCommitrefs(self):
     ret = self.repo.run(
@@ -234,6 +258,10 @@ class GitReadOnlyFunctionsTest(git_test_utils.GitRepoReadOnlyTestBase,
     with self.assertRaisesRegexp(Exception, r"one of \('master', 'bananas'\)"):
       self.repo.run(self.gc.parse_commitrefs, 'master', 'bananas')
 
+  def testTags(self):
+    self.assertEqual(set(self.repo.run(self.gc.tags)),
+                     {'tag_'+l for l in 'ABCDE'})
+
   def testTree(self):
     tree = self.repo.run(self.gc.tree, 'master:some/files')
     file1 = self.COMMIT_A['some/files/file1']['data']
@@ -279,7 +307,7 @@ class GitReadOnlyFunctionsTest(git_test_utils.GitRepoReadOnlyTestBase,
 
 class GitMutableFunctionsTest(git_test_utils.GitRepoReadWriteTestBase,
                               GitCommonTestBase):
-  REPO = ''
+  REPO_SCHEMA = ''
 
   def _intern_data(self, data):
     with tempfile.TemporaryFile() as f:
@@ -311,6 +339,25 @@ class GitMutableFunctionsTest(git_test_utils.GitRepoReadWriteTestBase,
     self.assertEquals(self.repo.run(self.gc.config_list, 'happy.derpies'),
                       ['food', 'cat'])
 
+    self.assertEquals('cat', self.repo.run(self.gc.config, 'dude.bob', 'cat'))
+
+    self.repo.run(self.gc.set_config, 'dude.bob', 'dog')
+
+    self.assertEquals('dog', self.repo.run(self.gc.config, 'dude.bob', 'cat'))
+
+    self.repo.run(self.gc.del_config, 'dude.bob')
+
+    # This should work without raising an exception
+    self.repo.run(self.gc.del_config, 'dude.bob')
+
+    self.assertEquals('cat', self.repo.run(self.gc.config, 'dude.bob', 'cat'))
+
+    self.assertEquals('origin/master', self.repo.run(self.gc.root))
+
+    self.repo.git('config', 'depot-tools.upstream', 'catfood')
+
+    self.assertEquals('catfood', self.repo.run(self.gc.root))
+
   def testUpstream(self):
     self.repo.git('commit', '--allow-empty', '-am', 'foooooo')
     self.assertEquals(self.repo.run(self.gc.upstream, 'bobly'), None)
@@ -320,6 +367,246 @@ class GitMutableFunctionsTest(git_test_utils.GitRepoReadWriteTestBase,
                       'master')
 
 
+class GitMutableStructuredTest(git_test_utils.GitRepoReadWriteTestBase,
+                               GitCommonTestBase):
+  REPO_SCHEMA = """
+  A B C D E F G
+    B H I J K
+          J L
+
+  X Y Z
+  """
+
+  COMMIT_B = {'file': {'data': 'B'}}
+  COMMIT_H = {'file': {'data': 'H'}}
+  COMMIT_I = {'file': {'data': 'I'}}
+  COMMIT_J = {'file': {'data': 'J'}}
+  COMMIT_K = {'file': {'data': 'K'}}
+  COMMIT_L = {'file': {'data': 'L'}}
+
+  def setUp(self):
+    super(GitMutableStructuredTest, self).setUp()
+    self.repo.git('branch', '--set-upstream-to', 'root_X', 'branch_Z')
+    self.repo.git('branch', '--set-upstream-to', 'branch_G', 'branch_K')
+    self.repo.git('branch', '--set-upstream-to', 'branch_K', 'branch_L')
+    self.repo.git('branch', '--set-upstream-to', 'root_A', 'branch_G')
+    self.repo.git('branch', '--set-upstream-to', 'root_X', 'root_A')
+
+  def testMergeBase(self):
+    self.repo.git('checkout', 'branch_K')
+
+    self.assertEqual(
+      self.repo['B'],
+      self.repo.run(self.gc.get_or_create_merge_base, 'branch_K', 'branch_G')
+    )
+
+    self.assertEqual(
+      self.repo['J'],
+      self.repo.run(self.gc.get_or_create_merge_base, 'branch_L', 'branch_K')
+    )
+
+    self.assertEqual(
+      self.repo['B'], self.repo.run(self.gc.config, 'branch.branch_K.base')
+    )
+
+    # deadbeef is a bad hash, so this will result in repo['B']
+    self.repo.run(self.gc.manual_merge_base, 'branch_K', 'deadbeef')
+
+    self.assertEqual(
+      self.repo['B'],
+      self.repo.run(self.gc.get_or_create_merge_base, 'branch_K', 'branch_G')
+    )
+
+    # but if we pick a real ancestor, then it'll work
+    self.repo.run(self.gc.manual_merge_base, 'branch_K', self.repo['I'])
+
+    self.assertEqual(
+      self.repo['I'],
+      self.repo.run(self.gc.get_or_create_merge_base, 'branch_K', 'branch_G')
+    )
+
+    self.assertEqual({'branch_K': self.repo['I'], 'branch_L': self.repo['J']},
+                     self.repo.run(self.gc.branch_config_map, 'base'))
+
+    self.repo.run(self.gc.remove_merge_base, 'branch_K')
+    self.repo.run(self.gc.remove_merge_base, 'branch_L')
+
+    self.assertEqual(None,
+                     self.repo.run(self.gc.config, 'branch.branch_K.base'))
+
+    self.assertEqual({}, self.repo.run(self.gc.branch_config_map, 'base'))
+
+  def testGetBranchTree(self):
+    skipped, tree = self.repo.run(self.gc.get_branch_tree)
+    self.assertEqual(skipped, {'master', 'root_X'})
+    self.assertEqual(tree, {
+      'branch_G': 'root_A',
+      'root_A': 'root_X',
+      'branch_K': 'branch_G',
+      'branch_L': 'branch_K',
+      'branch_Z': 'root_X'
+    })
+
+    topdown = list(self.gc.topo_iter(tree))
+    bottomup = list(self.gc.topo_iter(tree, top_down=False))
+
+    self.assertEqual(topdown, [
+      ('branch_Z', 'root_X'),
+      ('root_A', 'root_X'),
+      ('branch_G', 'root_A'),
+      ('branch_K', 'branch_G'),
+      ('branch_L', 'branch_K'),
+    ])
+
+    self.assertEqual(bottomup, [
+      ('branch_L', 'branch_K'),
+      ('branch_Z', 'root_X'),
+      ('branch_K', 'branch_G'),
+      ('branch_G', 'root_A'),
+      ('root_A', 'root_X'),
+    ])
+
+  def testSquashBranch(self):
+    self.repo.git('checkout', 'branch_K')
+
+    self.repo.run(self.gc.squash_current_branch, 'cool message')
+
+    lines = ['cool message', '']
+    for l in 'HIJK':
+      lines.extend((self.repo[l], l, ''))
+    lines.pop()
+    msg = '\n'.join(lines)
+
+    self.assertEquals(self.repo.run(self.gc.run, 'log', '-n1', '--format=%B'),
+                      msg)
+
+    self.assertEquals(
+      self.repo.git('cat-file', 'blob', 'branch_K:file').stdout,
+      'K'
+    )
+
+  def testRebase(self):
+    self.assertSchema("""
+    A B C D E F G
+      B H I J K
+            J L
+
+    X Y Z
+    """)
+
+    rslt = self.repo.run(
+      self.gc.rebase, 'branch_G', 'branch_K~4', 'branch_K')
+    self.assertTrue(rslt.success)
+
+    self.assertSchema("""
+    A B C D E F G H I J K
+      B H I J L
+
+    X Y Z
+    """)
+
+    rslt = self.repo.run(
+      self.gc.rebase, 'branch_K', 'branch_L~1', 'branch_L', abort=True)
+    self.assertFalse(rslt.success)
+
+    self.assertFalse(self.repo.run(self.gc.in_rebase))
+
+    rslt = self.repo.run(
+      self.gc.rebase, 'branch_K', 'branch_L~1', 'branch_L', abort=False)
+    self.assertFalse(rslt.success)
+
+    self.assertTrue(self.repo.run(self.gc.in_rebase))
+
+    self.assertEqual(self.repo.git('status', '--porcelain').stdout, 'UU file\n')
+    self.repo.git('checkout', '--theirs', 'file')
+    self.repo.git('add', 'file')
+    self.repo.git('rebase', '--continue')
+
+    self.assertSchema("""
+    A B C D E F G H I J K L
+
+    X Y Z
+    """)
+
+
+class GitFreezeThaw(git_test_utils.GitRepoReadWriteTestBase):
+  @classmethod
+  def setUpClass(cls):
+    super(GitFreezeThaw, cls).setUpClass()
+    import git_common
+    cls.gc = git_common
+    cls.gc.TEST_MODE = True
+
+  REPO_SCHEMA = """
+  A B C D
+    B E D
+  """
+
+  COMMIT_A = {
+    'some/files/file1': {'data': 'file1'},
+    'some/files/file2': {'data': 'file2'},
+    'some/files/file3': {'data': 'file3'},
+    'some/other/file':  {'data': 'otherfile'},
+  }
+
+  COMMIT_C = {
+    'some/files/file2': {
+      'mode': 0755,
+      'data': 'file2 - vanilla'},
+  }
+
+  COMMIT_E = {
+    'some/files/file2': {'data': 'file2 - merged'},
+  }
+
+  COMMIT_D = {
+    'some/files/file2': {'data': 'file2 - vanilla\nfile2 - merged'},
+  }
+
+  def testNothing(self):
+    self.assertIsNotNone(self.repo.run(self.gc.thaw))  # 'Nothing to thaw'
+    self.assertIsNotNone(self.repo.run(self.gc.freeze))  # 'Nothing to freeze'
+
+  def testAll(self):
+    def inner():
+      with open('some/files/file2', 'a') as f2:
+        print >> f2, 'cool appended line'
+      os.mkdir('some/other_files')
+      with open('some/other_files/subdir_file', 'w') as f3:
+        print >> f3, 'new file!'
+      with open('some/files/file5', 'w') as f5:
+        print >> f5, 'New file!1!one!'
+
+      STATUS_1 = '\n'.join((
+        ' M some/files/file2',
+        'A  some/files/file5',
+        '?? some/other_files/'
+      )) + '\n'
+
+      self.repo.git('add', 'some/files/file5')
+
+      # Freeze group 1
+      self.assertEquals(self.repo.git('status', '--porcelain').stdout, STATUS_1)
+      self.assertIsNone(self.gc.freeze())
+      self.assertEquals(self.repo.git('status', '--porcelain').stdout, '')
+
+      # Freeze group 2
+      with open('some/files/file2', 'a') as f2:
+        print >> f2, 'new! appended line!'
+      self.assertEquals(self.repo.git('status', '--porcelain').stdout,
+                        ' M some/files/file2\n')
+      self.assertIsNone(self.gc.freeze())
+      self.assertEquals(self.repo.git('status', '--porcelain').stdout, '')
+
+      # Thaw it out!
+      self.assertIsNone(self.gc.thaw())
+      self.assertIsNotNone(self.gc.thaw())  # One thaw should thaw everything
+
+      self.assertEquals(self.repo.git('status', '--porcelain').stdout, STATUS_1)
+
+    self.repo.run(inner)
+
+
 if __name__ == '__main__':
   sys.exit(coverage_utils.covered_main(
     os.path.join(DEPOT_TOOLS_ROOT, 'git_common.py')

+ 0 - 99
tests/git_freezer_test.py

@@ -1,99 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Unit tests for git_freezer.py"""
-
-import os
-import sys
-
-DEPOT_TOOLS_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-sys.path.insert(0, DEPOT_TOOLS_ROOT)
-
-from testing_support import coverage_utils
-from testing_support import git_test_utils
-
-
-class GitFreezeThaw(git_test_utils.GitRepoReadWriteTestBase):
-  @classmethod
-  def setUpClass(cls):
-    super(GitFreezeThaw, cls).setUpClass()
-    import git_freezer
-    cls.gf = git_freezer
-
-  REPO = """
-  A B C D
-    B E D
-  """
-
-  COMMIT_A = {
-    'some/files/file1': {'data': 'file1'},
-    'some/files/file2': {'data': 'file2'},
-    'some/files/file3': {'data': 'file3'},
-    'some/other/file':  {'data': 'otherfile'},
-  }
-
-  COMMIT_C = {
-    'some/files/file2': {
-      'mode': 0755,
-      'data': 'file2 - vanilla'},
-  }
-
-  COMMIT_E = {
-    'some/files/file2': {'data': 'file2 - merged'},
-  }
-
-  COMMIT_D = {
-    'some/files/file2': {'data': 'file2 - vanilla\nfile2 - merged'},
-  }
-
-  def testNothing(self):
-    self.assertIsNotNone(self.repo.run(self.gf.thaw))  # 'Nothing to thaw'
-    self.assertIsNotNone(self.repo.run(self.gf.freeze))  # 'Nothing to freeze'
-
-  def testAll(self):
-    def inner():
-      with open('some/files/file2', 'a') as f2:
-        print >> f2, 'cool appended line'
-      os.mkdir('some/other_files')
-      with open('some/other_files/subdir_file', 'w') as f3:
-        print >> f3, 'new file!'
-      with open('some/files/file5', 'w') as f5:
-        print >> f5, 'New file!1!one!'
-
-      STATUS_1 = '\n'.join((
-        ' M some/files/file2',
-        'A  some/files/file5',
-        '?? some/other_files/'
-      )) + '\n'
-
-      self.repo.git('add', 'some/files/file5')
-
-      # Freeze group 1
-      self.assertEquals(self.repo.git('status', '--porcelain').stdout, STATUS_1)
-      self.assertIsNone(self.gf.freeze())
-      self.assertEquals(self.repo.git('status', '--porcelain').stdout, '')
-
-      # Freeze group 2
-      with open('some/files/file2', 'a') as f2:
-        print >> f2, 'new! appended line!'
-      self.assertEquals(self.repo.git('status', '--porcelain').stdout,
-                        ' M some/files/file2\n')
-      self.assertIsNone(self.gf.freeze())
-      self.assertEquals(self.repo.git('status', '--porcelain').stdout, '')
-
-      # Thaw it out!
-      self.assertIsNone(self.gf.thaw())
-      self.assertIsNotNone(self.gf.thaw())  # One thaw should thaw everything
-
-      self.assertEquals(self.repo.git('status', '--porcelain').stdout, STATUS_1)
-
-    self.repo.run(inner)
-
-
-
-if __name__ == '__main__':
-  sys.exit(coverage_utils.covered_main(
-    os.path.join(DEPOT_TOOLS_ROOT, 'git_freezer.py')
-  ))

+ 1 - 1
tests/git_number_test.py

@@ -17,7 +17,7 @@ from testing_support import coverage_utils
 
 
 class Basic(git_test_utils.GitRepoReadWriteTestBase):
-  REPO = """
+  REPO_SCHEMA = """
   A B C D E
     B   F E
   X Y     E

+ 337 - 0
tests/git_rebase_update_test.py

@@ -0,0 +1,337 @@
+#!/usr/bin/env python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Unit tests for git_rebase_update.py"""
+
+import os
+import sys
+
+DEPOT_TOOLS_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+sys.path.insert(0, DEPOT_TOOLS_ROOT)
+
+from testing_support import coverage_utils
+from testing_support import git_test_utils
+
+class GitRebaseUpdateTest(git_test_utils.GitRepoReadWriteTestBase):
+  REPO_SCHEMA = """
+  A B C D E F G
+    B H I J K
+          J L
+  """
+
+  @classmethod
+  def getRepoContent(cls, commit):
+    # Every commit X gets a file X with the content X
+    return {commit: {'data': commit}}
+
+  @classmethod
+  def setUpClass(cls):
+    super(GitRebaseUpdateTest, cls).setUpClass()
+    import git_rebase_update, git_new_branch, git_reparent_branch, git_common
+    import git_rename_branch
+    cls.reup = git_rebase_update
+    cls.rp = git_reparent_branch
+    cls.nb = git_new_branch
+    cls.mv = git_rename_branch
+    cls.gc = git_common
+    cls.gc.TEST_MODE = True
+
+  def setUp(self):
+    super(GitRebaseUpdateTest, self).setUp()
+    # Include branch_K, branch_L to make sure that ABCDEFG all get the
+    # same commit hashes as self.repo. Otherwise they get committed with the
+    # wrong timestamps, due to commit ordering.
+    # TODO(iannucci): Make commit timestamps deterministic in left to right, top
+    #                 to bottom order, not in lexi-topographical order.
+    origin_schema = git_test_utils.GitRepoSchema("""
+    A B C D E F G M N O
+      B H I J K
+            J L
+    """, self.getRepoContent)
+    self.origin = origin_schema.reify()
+    self.origin.git('checkout', 'master')
+    self.origin.git('branch', '-d', *['branch_'+l for l in 'KLG'])
+
+    self.repo.git('remote', 'add', 'origin', self.origin.repo_path)
+    self.repo.git('config', '--add', 'remote.origin.fetch',
+                  '+refs/tags/*:refs/tags/*')
+    self.repo.git('update-ref', 'refs/remotes/origin/master', 'tag_E')
+    self.repo.git('branch', '--set-upstream-to', 'branch_G', 'branch_K')
+    self.repo.git('branch', '--set-upstream-to', 'branch_K', 'branch_L')
+    self.repo.git('branch', '--set-upstream-to', 'origin/master', 'branch_G')
+
+    self.repo.to_schema_refs += ['origin/master']
+
+  def tearDown(self):
+    self.origin.nuke()
+    super(GitRebaseUpdateTest, self).tearDown()
+
+  def testRebaseUpdate(self):
+    self.repo.git('checkout', 'branch_K')
+
+    self.repo.run(self.nb.main, ['foobar'])
+    self.assertEqual(self.repo.git('rev-parse', 'HEAD').stdout,
+                     self.repo.git('rev-parse', 'origin/master').stdout)
+
+    with self.repo.open('foobar', 'w') as f:
+      f.write('this is the foobar file')
+    self.repo.git('add', 'foobar')
+    self.repo.git_commit('foobar1')
+
+    with self.repo.open('foobar', 'w') as f:
+      f.write('totes the Foobar file')
+    self.repo.git_commit('foobar2')
+
+    self.repo.git('checkout', 'branch_K')
+    self.repo.run(self.nb.main, ['--upstream_current', 'sub_K'])
+    with self.repo.open('K', 'w') as f:
+      f.write('This depends on K')
+    self.repo.git_commit('sub_K')
+
+    self.repo.run(self.nb.main, ['old_branch'])
+    self.repo.git('reset', '--hard', self.repo['A'])
+    with self.repo.open('old_file', 'w') as f:
+      f.write('old_files we want to keep around')
+    self.repo.git('add', 'old_file')
+    self.repo.git_commit('old_file')
+    self.repo.git('config', 'branch.old_branch.dormant', 'true')
+
+    self.repo.git('checkout', 'origin/master')
+
+    self.assertSchema("""
+    A B H I J K sub_K
+            J L
+      B C D E foobar1 foobar2
+            E F G
+    A old_file
+    """)
+    self.assertEquals(self.repo['A'], self.origin['A'])
+    self.assertEquals(self.repo['E'], self.origin['E'])
+
+    with self.repo.open('bob', 'wb') as f:
+      f.write('testing auto-freeze/thaw')
+
+    output, _ = self.repo.capture_stdio(self.reup.main)
+    self.assertIn('Cannot rebase-update', output)
+
+    self.repo.git('checkout', 'branch_K')
+
+    output, _ = self.repo.capture_stdio(self.reup.main)
+
+    self.assertIn('Rebasing: branch_G', output)
+    self.assertIn('Rebasing: branch_K', output)
+    self.assertIn('Rebasing: branch_L', output)
+    self.assertIn('Rebasing: foobar', output)
+    self.assertIn('Rebasing: sub_K', output)
+    self.assertIn('Deleted branch branch_G', output)
+    self.assertIn('Reparented branch_K to track origin/master', output)
+
+    self.assertSchema("""
+    A B C D E F G M N O H I J K sub_K
+                              K L
+                      O foobar1 foobar2
+    A old_file
+    """)
+
+    output, _ = self.repo.capture_stdio(self.reup.main)
+    self.assertIn('branch_K up-to-date', output)
+    self.assertIn('branch_L up-to-date', output)
+    self.assertIn('foobar up-to-date', output)
+    self.assertIn('sub_K up-to-date', output)
+
+    with self.repo.open('bob') as f:
+      self.assertEquals('testing auto-freeze/thaw', f.read())
+
+    self.assertEqual(self.repo.git('status', '--porcelain').stdout, '?? bob\n')
+
+    self.repo.git('checkout', 'origin/master')
+    _, err = self.repo.capture_stdio(self.rp.main, ['foobar'])
+    self.assertIn('Must be on the branch', err)
+
+    self.repo.git('checkout', 'branch_K')
+    _, err = self.repo.capture_stdio(self.rp.main, ['origin/master'])
+    self.assertIn('Cannot reparent a branch to its existing parent', err)
+    output, _ = self.repo.capture_stdio(self.rp.main, ['foobar'])
+    self.assertIn('Rebasing: branch_K', output)
+    self.assertIn('Rebasing: sub_K', output)
+    self.assertIn('Rebasing: branch_L', output)
+
+    self.assertSchema("""
+    A B C D E F G M N O foobar1 foobar2 H I J K L
+                                              K sub_K
+    A old_file
+    """)
+
+    self.repo.git('checkout', 'sub_K')
+    output, _ = self.repo.capture_stdio(self.rp.main, ['foobar'])
+    self.assertIn('Squashing failed', output)
+
+    self.assertTrue(self.repo.run(self.gc.in_rebase))
+
+    self.repo.git('rebase', '--abort')
+    self.assertIsNone(self.repo.run(self.gc.thaw))
+
+    self.assertSchema("""
+    A B C D E F G M N O foobar1 foobar2 H I J K L
+    A old_file
+                                              K sub_K
+    """)
+
+    self.assertEqual(self.repo.git('status', '--porcelain').stdout, '?? bob\n')
+
+    branches = self.repo.run(set, self.gc.branches())
+    self.assertEqual(branches, {'branch_K', 'master', 'sub_K', 'root_A',
+                                'branch_L', 'old_branch', 'foobar'})
+
+    self.repo.git('checkout', 'branch_K')
+    self.repo.run(self.mv.main, ['special_K'])
+
+    branches = self.repo.run(set, self.gc.branches())
+    self.assertEqual(branches, {'special_K', 'master', 'sub_K', 'root_A',
+                                'branch_L', 'old_branch', 'foobar'})
+
+    self.repo.git('checkout', 'origin/master')
+    _, err = self.repo.capture_stdio(self.mv.main, ['special_K', 'cool branch'])
+    self.assertIn('fatal: \'cool branch\' is not a valid branch name.', err)
+
+    self.repo.run(self.mv.main, ['special_K', 'cool_branch'])
+    branches = self.repo.run(set, self.gc.branches())
+    self.assertEqual(branches, {'cool_branch', 'master', 'sub_K', 'root_A',
+                                'branch_L', 'old_branch', 'foobar'})
+
+    _, branch_tree = self.repo.run(self.gc.get_branch_tree)
+    self.assertEqual(branch_tree['sub_K'], 'foobar')
+
+
+  def testRebaseConflicts(self):
+    # Pretend that branch_L landed
+    self.origin.git('checkout', 'master')
+    with self.origin.open('L', 'w') as f:
+      f.write('L')
+    self.origin.git('add', 'L')
+    self.origin.git_commit('L')
+
+    # Add a commit to branch_K so that things fail
+    self.repo.git('checkout', 'branch_K')
+    with self.repo.open('M', 'w') as f:
+      f.write('NOPE')
+    self.repo.git('add', 'M')
+    self.repo.git_commit('K NOPE')
+
+    # Add a commits to branch_L which will work when squashed
+    self.repo.git('checkout', 'branch_L')
+    self.repo.git('reset', 'branch_L~')
+    with self.repo.open('L', 'w') as f:
+      f.write('NOPE')
+    self.repo.git('add', 'L')
+    self.repo.git_commit('L NOPE')
+    with self.repo.open('L', 'w') as f:
+      f.write('L')
+    self.repo.git('add', 'L')
+    self.repo.git_commit('L YUP')
+
+    # start on a branch which will be deleted
+    self.repo.git('checkout', 'branch_G')
+
+    output, _ = self.repo.capture_stdio(self.reup.main)
+    self.assertIn('branch.branch_K.dormant true', output)
+
+    output, _ = self.repo.capture_stdio(self.reup.main)
+    self.assertIn('Rebase in progress', output)
+
+    self.repo.git('checkout', '--theirs', 'M')
+    self.repo.git('rebase', '--skip')
+
+    output, _ = self.repo.capture_stdio(self.reup.main)
+    self.assertIn('Failed! Attempting to squash', output)
+    self.assertIn('Deleted branch branch_G', output)
+    self.assertIn('Deleted branch branch_L', output)
+    self.assertIn('\'branch_G\' was merged', output)
+    self.assertIn('checking out \'origin/master\'', output)
+
+
+  def testTrackTag(self):
+    self.origin.git('tag', 'lkgr', self.origin['M'])
+    self.repo.git('tag', 'lkgr', self.repo['D'])
+
+    self.repo.git('config', 'branch.branch_G.remote', '.')
+    self.repo.git('config', 'branch.branch_G.merge', 'refs/tags/lkgr')
+
+    self.assertIn(
+        'fatal: \'foo bar\' is not a valid branch name',
+        self.repo.capture_stdio(self.nb.main, ['--lkgr', 'foo bar'])[1])
+
+    self.repo.run(self.nb.main, ['--lkgr', 'foobar'])
+
+    with self.repo.open('foobar', 'w') as f:
+      f.write('this is the foobar file')
+    self.repo.git('add', 'foobar')
+    self.repo.git_commit('foobar1')
+
+    with self.repo.open('foobar', 'w') as f:
+      f.write('totes the Foobar file')
+    self.repo.git_commit('foobar2')
+
+    self.assertSchema("""
+    A B H I J K
+            J L
+      B C D E F G
+          D foobar1 foobar2
+    """)
+    self.assertEquals(self.repo['A'], self.origin['A'])
+    self.assertEquals(self.repo['G'], self.origin['G'])
+
+    output, _ = self.repo.capture_stdio(self.reup.main)
+    self.assertIn('Fetching', output)
+    self.assertIn('Rebasing: branch_G', output)
+    self.assertIn('Rebasing: branch_K', output)
+    self.assertIn('Rebasing: branch_L', output)
+    self.assertIn('Rebasing: foobar', output)
+    self.assertEquals(self.repo.git('rev-parse', 'lkgr').stdout.strip(),
+                      self.origin['M'])
+
+    self.assertSchema("""
+    A B C D E F G M N O
+                  M H I J K L
+                  M foobar1 foobar2
+    """)
+
+    _, err = self.repo.capture_stdio(self.rp.main, ['tag F'])
+    self.assertIn('fatal: invalid reference', err)
+
+    output, _ = self.repo.capture_stdio(self.rp.main, ['tag_F'])
+    self.assertIn('to track tag_F [tag] (was lkgr [tag])', output)
+
+    self.assertSchema("""
+    A B C D E F G M N O
+                  M H I J K L
+              F foobar1 foobar2
+    """)
+
+    output, _ = self.repo.capture_stdio(self.rp.main, ['--lkgr'])
+    self.assertIn('to track lkgr [tag] (was tag_F [tag])', output)
+
+    self.assertSchema("""
+    A B C D E F G M N O
+                  M H I J K L
+                  M foobar1 foobar2
+    """)
+
+    output, _ = self.repo.capture_stdio(self.rp.main, ['--root'])
+    self.assertIn('to track origin/master (was lkgr [tag])', output)
+
+    self.assertSchema("""
+    A B C D E F G M N O foobar1 foobar2
+                  M H I J K L
+    """)
+
+
+if __name__ == '__main__':
+  sys.exit(coverage_utils.covered_main((
+    os.path.join(DEPOT_TOOLS_ROOT, 'git_rebase_update.py'),
+    os.path.join(DEPOT_TOOLS_ROOT, 'git_new_branch.py'),
+    os.path.join(DEPOT_TOOLS_ROOT, 'git_reparent_branch.py'),
+    os.path.join(DEPOT_TOOLS_ROOT, 'git_rename_branch.py')
+  )))