Commit c050a5b2 authored by iannucci@chromium.org's avatar iannucci@chromium.org

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
parent a5d9502e
......@@ -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>
......
......@@ -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>
......
......@@ -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>
......
......@@ -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>
......
<!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>
......@@ -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>
......
......@@ -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>
......
<!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>
<!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>
<!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>
<!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>
<!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>
......@@ -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>
......
<!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>
......@@ -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
......
......@@ -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
.\" -----------------------------------------------------------------
......
......@@ -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)
......
......@@ -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
......
'\" 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
......@@ -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)
......
......@@ -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)
......
'\" 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
'\" 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
'\" 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
'\" 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
'\" 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
......@@ -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
.\" -----------------------------------------------------------------
......
'\" 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
SUGGESTED ALIASES
-----------------
Some common short-hand aliases. Feel free to add these to your '~/.gitconfig'
file.
......@@ -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:
Helper script to display all local git branches with ‘upstream’ hierarchy in
colorized terminal format.
// vim: ft=asciidoc noexpandtab:
// vim: ft=asciidoc:
Display history of all branches in a colorized terminal format.
// vim: ft=asciidoc noexpandtab:
// vim: ft=asciidoc:
Manually interact with depot_tools' merge-base markers.
Create a new branch with correct tracking information.
Updates all branches to have the latest changes from their upstreams.
Rename a branch and correctly preserve all downstream relationships.
Alter the parentage (upstream) for the current branch.
Takes all commits in a single branch and replaces them with a single commit.
Print a diff of the current branch, compared to its upstream.
......@@ -25,4 +25,4 @@ include::__essential.txt[maxdepth=1]
include::__helper.txt[maxdepth=1]
// vim: ft=asciidoc noexpandtab:
// vim: ft=asciidoc:
......@@ -79,4 +79,4 @@ linkgit:git-thaw[1]
include::_footer.txt[]
// vim: ft=asciidoc noexpandtab:
// vim: ft=asciidoc:
......@@ -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:
\ No newline at end of file
// vim: ft=asciidoc:
\ No newline at end of file
......@@ -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:
\ No newline at end of file
// vim: ft=asciidoc:
\ No newline at end of file
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:
......@@ -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:
......@@ -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:
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:
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:
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:
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:
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:
......@@ -26,4 +26,4 @@ linkgit:git-freeze[1]
include::_footer.txt[]
// vim: ft=asciidoc noexpandtab:
// vim: ft=asciidoc:
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:
#!/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)
#!/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)
#!/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)
\ No newline at end of file
#!/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)
#!/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)
\ No newline at end of file
#!/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)
\ No newline at end of file
#!/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)
# 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)
#!/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()
\ No newline at end of file
if __name__ == '__main__':
main()
......@@ -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,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
......
#!/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:]))
......@@ -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
......
#!/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:]))
#!/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:]))
#!/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:]))
#!/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:]))
#!/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))
#!/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:]))
......@@ -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())
......@@ -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')
......
#!/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')
))
......@@ -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
......
#!/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')
)))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment