Autogenerated HTML docs for v2.45.0-31-gd4cc1
[git-htmldocs.git] / gitdiffcore.html
blob1d303137ddd762a8401963de7a6a411403f539a4
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
5 <head>
6 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
7 <meta name="generator" content="AsciiDoc 10.2.0" />
8 <title>gitdiffcore(7)</title>
9 <style type="text/css">
10 /* Shared CSS for AsciiDoc xhtml11 and html5 backends */
12 /* Default font. */
13 body {
14 font-family: Georgia,serif;
17 /* Title font. */
18 h1, h2, h3, h4, h5, h6,
19 div.title, caption.title,
20 thead, p.table.header,
21 #toctitle,
22 #author, #revnumber, #revdate, #revremark,
23 #footer {
24 font-family: Arial,Helvetica,sans-serif;
27 body {
28 margin: 1em 5% 1em 5%;
31 a {
32 color: blue;
33 text-decoration: underline;
35 a:visited {
36 color: fuchsia;
39 em {
40 font-style: italic;
41 color: navy;
44 strong {
45 font-weight: bold;
46 color: #083194;
49 h1, h2, h3, h4, h5, h6 {
50 color: #527bbd;
51 margin-top: 1.2em;
52 margin-bottom: 0.5em;
53 line-height: 1.3;
56 h1, h2, h3 {
57 border-bottom: 2px solid silver;
59 h2 {
60 padding-top: 0.5em;
62 h3 {
63 float: left;
65 h3 + * {
66 clear: left;
68 h5 {
69 font-size: 1.0em;
72 div.sectionbody {
73 margin-left: 0;
76 hr {
77 border: 1px solid silver;
80 p {
81 margin-top: 0.5em;
82 margin-bottom: 0.5em;
85 ul, ol, li > p {
86 margin-top: 0;
88 ul > li { color: #aaa; }
89 ul > li > * { color: black; }
91 .monospaced, code, pre {
92 font-family: "Courier New", Courier, monospace;
93 font-size: inherit;
94 color: navy;
95 padding: 0;
96 margin: 0;
98 pre {
99 white-space: pre-wrap;
102 #author {
103 color: #527bbd;
104 font-weight: bold;
105 font-size: 1.1em;
107 #email {
109 #revnumber, #revdate, #revremark {
112 #footer {
113 font-size: small;
114 border-top: 2px solid silver;
115 padding-top: 0.5em;
116 margin-top: 4.0em;
118 #footer-text {
119 float: left;
120 padding-bottom: 0.5em;
122 #footer-badges {
123 float: right;
124 padding-bottom: 0.5em;
127 #preamble {
128 margin-top: 1.5em;
129 margin-bottom: 1.5em;
131 div.imageblock, div.exampleblock, div.verseblock,
132 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
133 div.admonitionblock {
134 margin-top: 1.0em;
135 margin-bottom: 1.5em;
137 div.admonitionblock {
138 margin-top: 2.0em;
139 margin-bottom: 2.0em;
140 margin-right: 10%;
141 color: #606060;
144 div.content { /* Block element content. */
145 padding: 0;
148 /* Block element titles. */
149 div.title, caption.title {
150 color: #527bbd;
151 font-weight: bold;
152 text-align: left;
153 margin-top: 1.0em;
154 margin-bottom: 0.5em;
156 div.title + * {
157 margin-top: 0;
160 td div.title:first-child {
161 margin-top: 0.0em;
163 div.content div.title:first-child {
164 margin-top: 0.0em;
166 div.content + div.title {
167 margin-top: 0.0em;
170 div.sidebarblock > div.content {
171 background: #ffffee;
172 border: 1px solid #dddddd;
173 border-left: 4px solid #f0f0f0;
174 padding: 0.5em;
177 div.listingblock > div.content {
178 border: 1px solid #dddddd;
179 border-left: 5px solid #f0f0f0;
180 background: #f8f8f8;
181 padding: 0.5em;
184 div.quoteblock, div.verseblock {
185 padding-left: 1.0em;
186 margin-left: 1.0em;
187 margin-right: 10%;
188 border-left: 5px solid #f0f0f0;
189 color: #888;
192 div.quoteblock > div.attribution {
193 padding-top: 0.5em;
194 text-align: right;
197 div.verseblock > pre.content {
198 font-family: inherit;
199 font-size: inherit;
201 div.verseblock > div.attribution {
202 padding-top: 0.75em;
203 text-align: left;
205 /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
206 div.verseblock + div.attribution {
207 text-align: left;
210 div.admonitionblock .icon {
211 vertical-align: top;
212 font-size: 1.1em;
213 font-weight: bold;
214 text-decoration: underline;
215 color: #527bbd;
216 padding-right: 0.5em;
218 div.admonitionblock td.content {
219 padding-left: 0.5em;
220 border-left: 3px solid #dddddd;
223 div.exampleblock > div.content {
224 border-left: 3px solid #dddddd;
225 padding-left: 0.5em;
228 div.imageblock div.content { padding-left: 0; }
229 span.image img { border-style: none; vertical-align: text-bottom; }
230 a.image:visited { color: white; }
232 dl {
233 margin-top: 0.8em;
234 margin-bottom: 0.8em;
236 dt {
237 margin-top: 0.5em;
238 margin-bottom: 0;
239 font-style: normal;
240 color: navy;
242 dd > *:first-child {
243 margin-top: 0.1em;
246 ul, ol {
247 list-style-position: outside;
249 ol.arabic {
250 list-style-type: decimal;
252 ol.loweralpha {
253 list-style-type: lower-alpha;
255 ol.upperalpha {
256 list-style-type: upper-alpha;
258 ol.lowerroman {
259 list-style-type: lower-roman;
261 ol.upperroman {
262 list-style-type: upper-roman;
265 div.compact ul, div.compact ol,
266 div.compact p, div.compact p,
267 div.compact div, div.compact div {
268 margin-top: 0.1em;
269 margin-bottom: 0.1em;
272 tfoot {
273 font-weight: bold;
275 td > div.verse {
276 white-space: pre;
279 div.hdlist {
280 margin-top: 0.8em;
281 margin-bottom: 0.8em;
283 div.hdlist tr {
284 padding-bottom: 15px;
286 dt.hdlist1.strong, td.hdlist1.strong {
287 font-weight: bold;
289 td.hdlist1 {
290 vertical-align: top;
291 font-style: normal;
292 padding-right: 0.8em;
293 color: navy;
295 td.hdlist2 {
296 vertical-align: top;
298 div.hdlist.compact tr {
299 margin: 0;
300 padding-bottom: 0;
303 .comment {
304 background: yellow;
307 .footnote, .footnoteref {
308 font-size: 0.8em;
311 span.footnote, span.footnoteref {
312 vertical-align: super;
315 #footnotes {
316 margin: 20px 0 20px 0;
317 padding: 7px 0 0 0;
320 #footnotes div.footnote {
321 margin: 0 0 5px 0;
324 #footnotes hr {
325 border: none;
326 border-top: 1px solid silver;
327 height: 1px;
328 text-align: left;
329 margin-left: 0;
330 width: 20%;
331 min-width: 100px;
334 div.colist td {
335 padding-right: 0.5em;
336 padding-bottom: 0.3em;
337 vertical-align: top;
339 div.colist td img {
340 margin-top: 0.3em;
343 @media print {
344 #footer-badges { display: none; }
347 #toc {
348 margin-bottom: 2.5em;
351 #toctitle {
352 color: #527bbd;
353 font-size: 1.1em;
354 font-weight: bold;
355 margin-top: 1.0em;
356 margin-bottom: 0.1em;
359 div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
360 margin-top: 0;
361 margin-bottom: 0;
363 div.toclevel2 {
364 margin-left: 2em;
365 font-size: 0.9em;
367 div.toclevel3 {
368 margin-left: 4em;
369 font-size: 0.9em;
371 div.toclevel4 {
372 margin-left: 6em;
373 font-size: 0.9em;
376 span.aqua { color: aqua; }
377 span.black { color: black; }
378 span.blue { color: blue; }
379 span.fuchsia { color: fuchsia; }
380 span.gray { color: gray; }
381 span.green { color: green; }
382 span.lime { color: lime; }
383 span.maroon { color: maroon; }
384 span.navy { color: navy; }
385 span.olive { color: olive; }
386 span.purple { color: purple; }
387 span.red { color: red; }
388 span.silver { color: silver; }
389 span.teal { color: teal; }
390 span.white { color: white; }
391 span.yellow { color: yellow; }
393 span.aqua-background { background: aqua; }
394 span.black-background { background: black; }
395 span.blue-background { background: blue; }
396 span.fuchsia-background { background: fuchsia; }
397 span.gray-background { background: gray; }
398 span.green-background { background: green; }
399 span.lime-background { background: lime; }
400 span.maroon-background { background: maroon; }
401 span.navy-background { background: navy; }
402 span.olive-background { background: olive; }
403 span.purple-background { background: purple; }
404 span.red-background { background: red; }
405 span.silver-background { background: silver; }
406 span.teal-background { background: teal; }
407 span.white-background { background: white; }
408 span.yellow-background { background: yellow; }
410 span.big { font-size: 2em; }
411 span.small { font-size: 0.6em; }
413 span.underline { text-decoration: underline; }
414 span.overline { text-decoration: overline; }
415 span.line-through { text-decoration: line-through; }
417 div.unbreakable { page-break-inside: avoid; }
421 * xhtml11 specific
423 * */
425 div.tableblock {
426 margin-top: 1.0em;
427 margin-bottom: 1.5em;
429 div.tableblock > table {
430 border: 3px solid #527bbd;
432 thead, p.table.header {
433 font-weight: bold;
434 color: #527bbd;
436 p.table {
437 margin-top: 0;
439 /* Because the table frame attribute is overridden by CSS in most browsers. */
440 div.tableblock > table[frame="void"] {
441 border-style: none;
443 div.tableblock > table[frame="hsides"] {
444 border-left-style: none;
445 border-right-style: none;
447 div.tableblock > table[frame="vsides"] {
448 border-top-style: none;
449 border-bottom-style: none;
454 * html5 specific
456 * */
458 table.tableblock {
459 margin-top: 1.0em;
460 margin-bottom: 1.5em;
462 thead, p.tableblock.header {
463 font-weight: bold;
464 color: #527bbd;
466 p.tableblock {
467 margin-top: 0;
469 table.tableblock {
470 border-width: 3px;
471 border-spacing: 0px;
472 border-style: solid;
473 border-color: #527bbd;
474 border-collapse: collapse;
476 th.tableblock, td.tableblock {
477 border-width: 1px;
478 padding: 4px;
479 border-style: solid;
480 border-color: #527bbd;
483 table.tableblock.frame-topbot {
484 border-left-style: hidden;
485 border-right-style: hidden;
487 table.tableblock.frame-sides {
488 border-top-style: hidden;
489 border-bottom-style: hidden;
491 table.tableblock.frame-none {
492 border-style: hidden;
495 th.tableblock.halign-left, td.tableblock.halign-left {
496 text-align: left;
498 th.tableblock.halign-center, td.tableblock.halign-center {
499 text-align: center;
501 th.tableblock.halign-right, td.tableblock.halign-right {
502 text-align: right;
505 th.tableblock.valign-top, td.tableblock.valign-top {
506 vertical-align: top;
508 th.tableblock.valign-middle, td.tableblock.valign-middle {
509 vertical-align: middle;
511 th.tableblock.valign-bottom, td.tableblock.valign-bottom {
512 vertical-align: bottom;
517 * manpage specific
519 * */
521 body.manpage h1 {
522 padding-top: 0.5em;
523 padding-bottom: 0.5em;
524 border-top: 2px solid silver;
525 border-bottom: 2px solid silver;
527 body.manpage h2 {
528 border-style: none;
530 body.manpage div.sectionbody {
531 margin-left: 3em;
534 @media print {
535 body.manpage div#toc { display: none; }
539 </style>
540 <script type="text/javascript">
541 /*<![CDATA[*/
542 var asciidoc = { // Namespace.
544 /////////////////////////////////////////////////////////////////////
545 // Table Of Contents generator
546 /////////////////////////////////////////////////////////////////////
548 /* Author: Mihai Bazon, September 2002
549 * http://students.infoiasi.ro/~mishoo
551 * Table Of Content generator
552 * Version: 0.4
554 * Feel free to use this script under the terms of the GNU General Public
555 * License, as long as you do not remove or alter this notice.
558 /* modified by Troy D. Hanson, September 2006. License: GPL */
559 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
561 // toclevels = 1..4.
562 toc: function (toclevels) {
564 function getText(el) {
565 var text = "";
566 for (var i = el.firstChild; i != null; i = i.nextSibling) {
567 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
568 text += i.data;
569 else if (i.firstChild != null)
570 text += getText(i);
572 return text;
575 function TocEntry(el, text, toclevel) {
576 this.element = el;
577 this.text = text;
578 this.toclevel = toclevel;
581 function tocEntries(el, toclevels) {
582 var result = new Array;
583 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
584 // Function that scans the DOM tree for header elements (the DOM2
585 // nodeIterator API would be a better technique but not supported by all
586 // browsers).
587 var iterate = function (el) {
588 for (var i = el.firstChild; i != null; i = i.nextSibling) {
589 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
590 var mo = re.exec(i.tagName);
591 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
592 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
594 iterate(i);
598 iterate(el);
599 return result;
602 var toc = document.getElementById("toc");
603 if (!toc) {
604 return;
607 // Delete existing TOC entries in case we're reloading the TOC.
608 var tocEntriesToRemove = [];
609 var i;
610 for (i = 0; i < toc.childNodes.length; i++) {
611 var entry = toc.childNodes[i];
612 if (entry.nodeName.toLowerCase() == 'div'
613 && entry.getAttribute("class")
614 && entry.getAttribute("class").match(/^toclevel/))
615 tocEntriesToRemove.push(entry);
617 for (i = 0; i < tocEntriesToRemove.length; i++) {
618 toc.removeChild(tocEntriesToRemove[i]);
621 // Rebuild TOC entries.
622 var entries = tocEntries(document.getElementById("content"), toclevels);
623 for (var i = 0; i < entries.length; ++i) {
624 var entry = entries[i];
625 if (entry.element.id == "")
626 entry.element.id = "_toc_" + i;
627 var a = document.createElement("a");
628 a.href = "#" + entry.element.id;
629 a.appendChild(document.createTextNode(entry.text));
630 var div = document.createElement("div");
631 div.appendChild(a);
632 div.className = "toclevel" + entry.toclevel;
633 toc.appendChild(div);
635 if (entries.length == 0)
636 toc.parentNode.removeChild(toc);
640 /////////////////////////////////////////////////////////////////////
641 // Footnotes generator
642 /////////////////////////////////////////////////////////////////////
644 /* Based on footnote generation code from:
645 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
648 footnotes: function () {
649 // Delete existing footnote entries in case we're reloading the footnodes.
650 var i;
651 var noteholder = document.getElementById("footnotes");
652 if (!noteholder) {
653 return;
655 var entriesToRemove = [];
656 for (i = 0; i < noteholder.childNodes.length; i++) {
657 var entry = noteholder.childNodes[i];
658 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
659 entriesToRemove.push(entry);
661 for (i = 0; i < entriesToRemove.length; i++) {
662 noteholder.removeChild(entriesToRemove[i]);
665 // Rebuild footnote entries.
666 var cont = document.getElementById("content");
667 var spans = cont.getElementsByTagName("span");
668 var refs = {};
669 var n = 0;
670 for (i=0; i<spans.length; i++) {
671 if (spans[i].className == "footnote") {
672 n++;
673 var note = spans[i].getAttribute("data-note");
674 if (!note) {
675 // Use [\s\S] in place of . so multi-line matches work.
676 // Because JavaScript has no s (dotall) regex flag.
677 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
678 spans[i].innerHTML =
679 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
680 "' title='View footnote' class='footnote'>" + n + "</a>]";
681 spans[i].setAttribute("data-note", note);
683 noteholder.innerHTML +=
684 "<div class='footnote' id='_footnote_" + n + "'>" +
685 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
686 n + "</a>. " + note + "</div>";
687 var id =spans[i].getAttribute("id");
688 if (id != null) refs["#"+id] = n;
691 if (n == 0)
692 noteholder.parentNode.removeChild(noteholder);
693 else {
694 // Process footnoterefs.
695 for (i=0; i<spans.length; i++) {
696 if (spans[i].className == "footnoteref") {
697 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
698 href = href.match(/#.*/)[0]; // Because IE return full URL.
699 n = refs[href];
700 spans[i].innerHTML =
701 "[<a href='#_footnote_" + n +
702 "' title='View footnote' class='footnote'>" + n + "</a>]";
708 install: function(toclevels) {
709 var timerId;
711 function reinstall() {
712 asciidoc.footnotes();
713 if (toclevels) {
714 asciidoc.toc(toclevels);
718 function reinstallAndRemoveTimer() {
719 clearInterval(timerId);
720 reinstall();
723 timerId = setInterval(reinstall, 500);
724 if (document.addEventListener)
725 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
726 else
727 window.onload = reinstallAndRemoveTimer;
731 asciidoc.install();
732 /*]]>*/
733 </script>
734 </head>
735 <body class="manpage">
736 <div id="header">
737 <h1>
738 gitdiffcore(7) Manual Page
739 </h1>
740 <h2>NAME</h2>
741 <div class="sectionbody">
742 <p>gitdiffcore -
743 Tweaking diff output
744 </p>
745 </div>
746 </div>
747 <div id="content">
748 <div class="sect1">
749 <h2 id="_synopsis">SYNOPSIS</h2>
750 <div class="sectionbody">
751 <div class="verseblock">
752 <pre class="content"><em>git diff</em> *</pre>
753 <div class="attribution">
754 </div></div>
755 </div>
756 </div>
757 <div class="sect1">
758 <h2 id="_description">DESCRIPTION</h2>
759 <div class="sectionbody">
760 <div class="paragraph"><p>The diff commands <em>git diff-index</em>, <em>git diff-files</em>, and <em>git diff-tree</em>
761 can be told to manipulate differences they find in
762 unconventional ways before showing <em>diff</em> output. The manipulation
763 is collectively called "diffcore transformation". This short note
764 describes what they are and how to use them to produce <em>diff</em> output
765 that is easier to understand than the conventional kind.</p></div>
766 </div>
767 </div>
768 <div class="sect1">
769 <h2 id="_the_chain_of_operation">The chain of operation</h2>
770 <div class="sectionbody">
771 <div class="paragraph"><p>The <em>git diff-&#42;</em> family works by first comparing two sets of
772 files:</p></div>
773 <div class="ulist"><ul>
774 <li>
776 <em>git diff-index</em> compares contents of a "tree" object and the
777 working directory (when <code>--cached</code> flag is not used) or a
778 "tree" object and the index file (when <code>--cached</code> flag is
779 used);
780 </p>
781 </li>
782 <li>
784 <em>git diff-files</em> compares contents of the index file and the
785 working directory;
786 </p>
787 </li>
788 <li>
790 <em>git diff-tree</em> compares contents of two "tree" objects;
791 </p>
792 </li>
793 </ul></div>
794 <div class="paragraph"><p>In all of these cases, the commands themselves first optionally limit
795 the two sets of files by any pathspecs given on their command-lines,
796 and compare corresponding paths in the two resulting sets of files.</p></div>
797 <div class="paragraph"><p>The pathspecs are used to limit the world diff operates in. They remove
798 the filepairs outside the specified sets of pathnames. E.g. If the
799 input set of filepairs included:</p></div>
800 <div class="listingblock">
801 <div class="content">
802 <pre><code>:100644 100644 bcd1234... 0123456... M junkfile</code></pre>
803 </div></div>
804 <div class="paragraph"><p>but the command invocation was <code>git diff-files myfile</code>, then the
805 junkfile entry would be removed from the list because only "myfile"
806 is under consideration.</p></div>
807 <div class="paragraph"><p>The result of comparison is passed from these commands to what is
808 internally called "diffcore", in a format similar to what is output
809 when the -p option is not used. E.g.</p></div>
810 <div class="listingblock">
811 <div class="content">
812 <pre><code>in-place edit :100644 100644 bcd1234... 0123456... M file0
813 create :000000 100644 0000000... 1234567... A file4
814 delete :100644 000000 1234567... 0000000... D file5
815 unmerged :000000 000000 0000000... 0000000... U file6</code></pre>
816 </div></div>
817 <div class="paragraph"><p>The diffcore mechanism is fed a list of such comparison results
818 (each of which is called "filepair", although at this point each
819 of them talks about a single file), and transforms such a list
820 into another list. There are currently 5 such transformations:</p></div>
821 <div class="ulist"><ul>
822 <li>
824 diffcore-break
825 </p>
826 </li>
827 <li>
829 diffcore-rename
830 </p>
831 </li>
832 <li>
834 diffcore-merge-broken
835 </p>
836 </li>
837 <li>
839 diffcore-pickaxe
840 </p>
841 </li>
842 <li>
844 diffcore-order
845 </p>
846 </li>
847 <li>
849 diffcore-rotate
850 </p>
851 </li>
852 </ul></div>
853 <div class="paragraph"><p>These are applied in sequence. The set of filepairs <em>git diff-&#42;</em>
854 commands find are used as the input to diffcore-break, and
855 the output from diffcore-break is used as the input to the
856 next transformation. The final result is then passed to the
857 output routine and generates either diff-raw format (see Output
858 format sections of the manual for <em>git diff-&#42;</em> commands) or
859 diff-patch format.</p></div>
860 </div>
861 </div>
862 <div class="sect1">
863 <h2 id="_diffcore_break_for_splitting_up_complete_rewrites">diffcore-break: For Splitting Up Complete Rewrites</h2>
864 <div class="sectionbody">
865 <div class="paragraph"><p>The second transformation in the chain is diffcore-break, and is
866 controlled by the -B option to the <em>git diff-&#42;</em> commands. This is
867 used to detect a filepair that represents "complete rewrite" and
868 break such filepair into two filepairs that represent delete and
869 create. E.g. If the input contained this filepair:</p></div>
870 <div class="listingblock">
871 <div class="content">
872 <pre><code>:100644 100644 bcd1234... 0123456... M file0</code></pre>
873 </div></div>
874 <div class="paragraph"><p>and if it detects that the file "file0" is completely rewritten,
875 it changes it to:</p></div>
876 <div class="listingblock">
877 <div class="content">
878 <pre><code>:100644 000000 bcd1234... 0000000... D file0
879 :000000 100644 0000000... 0123456... A file0</code></pre>
880 </div></div>
881 <div class="paragraph"><p>For the purpose of breaking a filepair, diffcore-break examines
882 the extent of changes between the contents of the files before
883 and after modification (i.e. the contents that have "bcd1234&#8230;"
884 and "0123456&#8230;" as their SHA-1 content ID, in the above
885 example). The amount of deletion of original contents and
886 insertion of new material are added together, and if it exceeds
887 the "break score", the filepair is broken into two. The break
888 score defaults to 50% of the size of the smaller of the original
889 and the result (i.e. if the edit shrinks the file, the size of
890 the result is used; if the edit lengthens the file, the size of
891 the original is used), and can be customized by giving a number
892 after "-B" option (e.g. "-B75" to tell it to use 75%).</p></div>
893 </div>
894 </div>
895 <div class="sect1">
896 <h2 id="_diffcore_rename_for_detecting_renames_and_copies">diffcore-rename: For Detecting Renames and Copies</h2>
897 <div class="sectionbody">
898 <div class="paragraph"><p>This transformation is used to detect renames and copies, and is
899 controlled by the -M option (to detect renames) and the -C option
900 (to detect copies as well) to the <em>git diff-&#42;</em> commands. If the
901 input contained these filepairs:</p></div>
902 <div class="listingblock">
903 <div class="content">
904 <pre><code>:100644 000000 0123456... 0000000... D fileX
905 :000000 100644 0000000... 0123456... A file0</code></pre>
906 </div></div>
907 <div class="paragraph"><p>and the contents of the deleted file fileX is similar enough to
908 the contents of the created file file0, then rename detection
909 merges these filepairs and creates:</p></div>
910 <div class="listingblock">
911 <div class="content">
912 <pre><code>:100644 100644 0123456... 0123456... R100 fileX file0</code></pre>
913 </div></div>
914 <div class="paragraph"><p>When the "-C" option is used, the original contents of modified files,
915 and deleted files (and also unmodified files, if the
916 "--find-copies-harder" option is used) are considered as candidates
917 of the source files in rename/copy operation. If the input were like
918 these filepairs, that talk about a modified file fileY and a newly
919 created file file0:</p></div>
920 <div class="listingblock">
921 <div class="content">
922 <pre><code>:100644 100644 0123456... 1234567... M fileY
923 :000000 100644 0000000... bcd3456... A file0</code></pre>
924 </div></div>
925 <div class="paragraph"><p>the original contents of fileY and the resulting contents of
926 file0 are compared, and if they are similar enough, they are
927 changed to:</p></div>
928 <div class="listingblock">
929 <div class="content">
930 <pre><code>:100644 100644 0123456... 1234567... M fileY
931 :100644 100644 0123456... bcd3456... C100 fileY file0</code></pre>
932 </div></div>
933 <div class="paragraph"><p>In both rename and copy detection, the same "extent of changes"
934 algorithm used in diffcore-break is used to determine if two
935 files are "similar enough", and can be customized to use
936 a similarity score different from the default of 50% by giving a
937 number after the "-M" or "-C" option (e.g. "-M8" to tell it to use
938 8/10 = 80%).</p></div>
939 <div class="paragraph"><p>Note that when rename detection is on but both copy and break
940 detection are off, rename detection adds a preliminary step that first
941 checks if files are moved across directories while keeping their
942 filename the same. If there is a file added to a directory whose
943 contents are sufficiently similar to a file with the same name that got
944 deleted from a different directory, it will mark them as renames and
945 exclude them from the later quadratic step (the one that pairwise
946 compares all unmatched files to find the "best" matches, determined by
947 the highest content similarity). So, for example, if a deleted
948 docs/ext.txt and an added docs/config/ext.txt are similar enough, they
949 will be marked as a rename and prevent an added docs/ext.md that may
950 be even more similar to the deleted docs/ext.txt from being considered
951 as the rename destination in the later step. For this reason, the
952 preliminary "match same filename" step uses a bit higher threshold to
953 mark a file pair as a rename and stop considering other candidates for
954 better matches. At most, one comparison is done per file in this
955 preliminary pass; so if there are several remaining ext.txt files
956 throughout the directory hierarchy after exact rename detection, this
957 preliminary step may be skipped for those files.</p></div>
958 <div class="paragraph"><p>Note. When the "-C" option is used with <code>--find-copies-harder</code>
959 option, <em>git diff-&#42;</em> commands feed unmodified filepairs to
960 diffcore mechanism as well as modified ones. This lets the copy
961 detector consider unmodified files as copy source candidates at
962 the expense of making it slower. Without <code>--find-copies-harder</code>,
963 <em>git diff-&#42;</em> commands can detect copies only if the file that was
964 copied happened to have been modified in the same changeset.</p></div>
965 </div>
966 </div>
967 <div class="sect1">
968 <h2 id="_diffcore_merge_broken_for_putting_complete_rewrites_back_together">diffcore-merge-broken: For Putting Complete Rewrites Back Together</h2>
969 <div class="sectionbody">
970 <div class="paragraph"><p>This transformation is used to merge filepairs broken by
971 diffcore-break, and not transformed into rename/copy by
972 diffcore-rename, back into a single modification. This always
973 runs when diffcore-break is used.</p></div>
974 <div class="paragraph"><p>For the purpose of merging broken filepairs back, it uses a
975 different "extent of changes" computation from the ones used by
976 diffcore-break and diffcore-rename. It counts only the deletion
977 from the original, and does not count insertion. If you removed
978 only 10 lines from a 100-line document, even if you added 910
979 new lines to make a new 1000-line document, you did not do a
980 complete rewrite. diffcore-break breaks such a case in order to
981 help diffcore-rename to consider such filepairs as a candidate of
982 rename/copy detection, but if filepairs broken that way were not
983 matched with other filepairs to create rename/copy, then this
984 transformation merges them back into the original
985 "modification".</p></div>
986 <div class="paragraph"><p>The "extent of changes" parameter can be tweaked from the
987 default 80% (that is, unless more than 80% of the original
988 material is deleted, the broken pairs are merged back into a
989 single modification) by giving a second number to -B option,
990 like these:</p></div>
991 <div class="ulist"><ul>
992 <li>
994 -B50/60 (give 50% "break score" to diffcore-break, use 60%
995 for diffcore-merge-broken).
996 </p>
997 </li>
998 <li>
1000 -B/60 (the same as above, since diffcore-break defaults to 50%).
1001 </p>
1002 </li>
1003 </ul></div>
1004 <div class="paragraph"><p>Note that earlier implementation left a broken pair as separate
1005 creation and deletion patches. This was an unnecessary hack, and
1006 the latest implementation always merges all the broken pairs
1007 back into modifications, but the resulting patch output is
1008 formatted differently for easier review in case of such
1009 a complete rewrite by showing the entire contents of the old version
1010 prefixed with <em>-</em>, followed by the entire contents of the new
1011 version prefixed with <em>+</em>.</p></div>
1012 </div>
1013 </div>
1014 <div class="sect1">
1015 <h2 id="_diffcore_pickaxe_for_detecting_addition_deletion_of_specified_string">diffcore-pickaxe: For Detecting Addition/Deletion of Specified String</h2>
1016 <div class="sectionbody">
1017 <div class="paragraph"><p>This transformation limits the set of filepairs to those that change
1018 specified strings between the preimage and the postimage in a certain
1019 way. -S&lt;block-of-text&gt; and -G&lt;regular-expression&gt; options are used to
1020 specify different ways these strings are sought.</p></div>
1021 <div class="paragraph"><p>"-S&lt;block-of-text&gt;" detects filepairs whose preimage and postimage
1022 have different number of occurrences of the specified block of text.
1023 By definition, it will not detect in-file moves. Also, when a
1024 changeset moves a file wholesale without affecting the interesting
1025 string, diffcore-rename kicks in as usual, and <code>-S</code> omits the filepair
1026 (since the number of occurrences of that string didn&#8217;t change in that
1027 rename-detected filepair). When used with <code>--pickaxe-regex</code>, treat
1028 the &lt;block-of-text&gt; as an extended POSIX regular expression to match,
1029 instead of a literal string.</p></div>
1030 <div class="paragraph"><p>"-G&lt;regular-expression&gt;" (mnemonic: grep) detects filepairs whose
1031 textual diff has an added or a deleted line that matches the given
1032 regular expression. This means that it will detect in-file (or what
1033 rename-detection considers the same file) moves, which is noise. The
1034 implementation runs diff twice and greps, and this can be quite
1035 expensive. To speed things up, binary files without textconv filters
1036 will be ignored.</p></div>
1037 <div class="paragraph"><p>When <code>-S</code> or <code>-G</code> are used without <code>--pickaxe-all</code>, only filepairs
1038 that match their respective criterion are kept in the output. When
1039 <code>--pickaxe-all</code> is used, if even one filepair matches their respective
1040 criterion in a changeset, the entire changeset is kept. This behavior
1041 is designed to make reviewing changes in the context of the whole
1042 changeset easier.</p></div>
1043 </div>
1044 </div>
1045 <div class="sect1">
1046 <h2 id="_diffcore_order_for_sorting_the_output_based_on_filenames">diffcore-order: For Sorting the Output Based on Filenames</h2>
1047 <div class="sectionbody">
1048 <div class="paragraph"><p>This is used to reorder the filepairs according to the user&#8217;s
1049 (or project&#8217;s) taste, and is controlled by the -O option to the
1050 <em>git diff-&#42;</em> commands.</p></div>
1051 <div class="paragraph"><p>This takes a text file each of whose lines is a shell glob
1052 pattern. Filepairs that match a glob pattern on an earlier line
1053 in the file are output before ones that match a later line, and
1054 filepairs that do not match any glob pattern are output last.</p></div>
1055 <div class="paragraph"><p>As an example, a typical orderfile for the core Git probably
1056 would look like this:</p></div>
1057 <div class="listingblock">
1058 <div class="content">
1059 <pre><code>README
1060 Makefile
1061 Documentation
1064 t</code></pre>
1065 </div></div>
1066 </div>
1067 </div>
1068 <div class="sect1">
1069 <h2 id="_diffcore_rotate_for_changing_at_which_path_output_starts">diffcore-rotate: For Changing At Which Path Output Starts</h2>
1070 <div class="sectionbody">
1071 <div class="paragraph"><p>This transformation takes one pathname, and rotates the set of
1072 filepairs so that the filepair for the given pathname comes first,
1073 optionally discarding the paths that come before it. This is used
1074 to implement the <code>--skip-to</code> and the <code>--rotate-to</code> options. It is
1075 an error when the specified pathname is not in the set of filepairs,
1076 but it is not useful to error out when used with "git log" family of
1077 commands, because it is unreasonable to expect that a given path
1078 would be modified by each and every commit shown by the "git log"
1079 command. For this reason, when used with "git log", the filepair
1080 that sorts the same as, or the first one that sorts after, the given
1081 pathname is where the output starts.</p></div>
1082 <div class="paragraph"><p>Use of this transformation combined with diffcore-order will produce
1083 unexpected results, as the input to this transformation is likely
1084 not sorted when diffcore-order is in effect.</p></div>
1085 </div>
1086 </div>
1087 <div class="sect1">
1088 <h2 id="_see_also">SEE ALSO</h2>
1089 <div class="sectionbody">
1090 <div class="paragraph"><p><a href="git-diff.html">git-diff(1)</a>,
1091 <a href="git-diff-files.html">git-diff-files(1)</a>,
1092 <a href="git-diff-index.html">git-diff-index(1)</a>,
1093 <a href="git-diff-tree.html">git-diff-tree(1)</a>,
1094 <a href="git-format-patch.html">git-format-patch(1)</a>,
1095 <a href="git-log.html">git-log(1)</a>,
1096 <a href="gitglossary.html">gitglossary(7)</a>,
1097 <a href="user-manual.html">The Git User&#8217;s Manual</a></p></div>
1098 </div>
1099 </div>
1100 <div class="sect1">
1101 <h2 id="_git">GIT</h2>
1102 <div class="sectionbody">
1103 <div class="paragraph"><p>Part of the <a href="git.html">git(1)</a> suite</p></div>
1104 </div>
1105 </div>
1106 </div>
1107 <div id="footnotes"><hr /></div>
1108 <div id="footer">
1109 <div id="footer-text">
1110 Last updated
1111 2024-02-08 15:45:59 PST
1112 </div>
1113 </div>
1114 </body>
1115 </html>