€•@Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ-/translations/zh_CN/maintainer/messy-diffstat”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/zh_TW/maintainer/messy-diffstat”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/it_IT/maintainer/messy-diffstat”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/ja_JP/maintainer/messy-diffstat”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/ko_KR/maintainer/messy-diffstat”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/sp_SP/maintainer/messy-diffstat”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)”}”(hŒ SPDX-License-Identifier: GPL-2.0”h]”hŒ SPDX-License-Identifier: GPL-2.0”…””}”hh£sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1h¡hhhžhhŸŒG/var/lib/git/docbuild/linux/Documentation/maintainer/messy-diffstat.rst”h KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒ%Handling messy pull-request diffstats”h]”hŒ%Handling messy pull-request diffstats”…””}”(hh»hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hh¶hžhhŸh³h KubhŒ paragraph”“”)”}”(hXeSubsystem maintainers routinely use ``git request-pull`` as part of the process of sending work upstream. Normally, the result includes a nice diffstat that shows which files will be touched and how much of each will be changed. Occasionally, though, a repository with a relatively complicated development history will yield a massive diffstat containing a great deal of unrelated work. The result looks ugly and obscures what the pull request is actually doing. This document describes what is happening and how to fix things up; it is derived from The Wisdom of Linus Torvalds, found in Linus1_ and Linus2_.”h]”(hŒ$Subsystem maintainers routinely use ”…””}”(hhËhžhhŸNh NubhŒliteral”“”)”}”(hŒ``git request-pull``”h]”hŒgit request-pull”…””}”(hhÕhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhhËubhX as part of the process of sending work upstream. Normally, the result includes a nice diffstat that shows which files will be touched and how much of each will be changed. Occasionally, though, a repository with a relatively complicated development history will yield a massive diffstat containing a great deal of unrelated work. The result looks ugly and obscures what the pull request is actually doing. This document describes what is happening and how to fix things up; it is derived from The Wisdom of Linus Torvalds, found in ”…””}”(hhËhžhhŸNh NubhŒ reference”“”)”}”(hŒLinus1_”h]”hŒLinus1”…””}”(hhéhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒLinus1”Œrefuri”Œ`https://lore.kernel.org/lkml/CAHk-=wg3wXH2JNxkQi+eLZkpuxqV+wPiHhw_Jf7ViH33Sw7PHA@mail.gmail.com/”uh1hçhhËŒresolved”KubhŒ and ”…””}”(hhËhžhhŸNh Nubhè)”}”(hŒLinus2_”h]”hŒLinus2”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒLinus2”hùŒ`https://lore.kernel.org/lkml/CAHk-=wgXbSa8yq8Dht8at+gxb_idnJ7X5qWZQWRBN4_CUPr=eQ@mail.gmail.com/”uh1hçhhËhûKubhŒ.”…””}”(hhËhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h Khh¶hžhubhŒtarget”“”)”}”(hŒl.. _Linus1: https://lore.kernel.org/lkml/CAHk-=wg3wXH2JNxkQi+eLZkpuxqV+wPiHhw_Jf7ViH33Sw7PHA@mail.gmail.com/”h]”h}”(h]”Œlinus1”ah ]”h"]”Œlinus1”ah$]”h&]”hùhúuh1jh Khh¶hžhhŸh³Œ referenced”Kubj)”}”(hŒl.. _Linus2: https://lore.kernel.org/lkml/CAHk-=wgXbSa8yq8Dht8at+gxb_idnJ7X5qWZQWRBN4_CUPr=eQ@mail.gmail.com/”h]”h}”(h]”Œlinus2”ah ]”h"]”Œlinus2”ah$]”h&]”hùjuh1jh Khh¶hžhhŸh³j)KubhÊ)”}”(hŒA Git development history proceeds as a series of commits. In a simplified manner, mainline kernel development looks like this::”h]”hŒ€A Git development history proceeds as a series of commits. In a simplified manner, mainline kernel development looks like this:”…””}”(hj6hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h Khh¶hžhubhŒ literal_block”“”)”}”(hŒA... vM --- vN-rc1 --- vN-rc2 --- vN-rc3 --- ... --- vN-rc7 --- vN”h]”hŒA... vM --- vN-rc1 --- vN-rc2 --- vN-rc3 --- ... --- vN-rc7 --- vN”…””}”hjFsbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1jDhŸh³h Khh¶hžhubhÊ)”}”(hŒ^If one wants to see what has changed between two points, a command like this will do the job::”h]”hŒ]If one wants to see what has changed between two points, a command like this will do the job:”…””}”(hjThžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h Khh¶hžhubjE)”}”(hŒ*$ git diff --stat --summary vN-rc2..vN-rc3”h]”hŒ*$ git diff --stat --summary vN-rc2..vN-rc3”…””}”hjbsbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1jDhŸh³h Khh¶hžhubhÊ)”}”(hŒåHere, there are two clear points in the history; Git will essentially "subtract" the beginning point from the end point and display the resulting differences. The requested operation is unambiguous and easy enough to understand.”h]”hŒéHere, there are two clear points in the history; Git will essentially “subtract†the beginning point from the end point and display the resulting differences. The requested operation is unambiguous and easy enough to understand.”…””}”(hjphžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h Khh¶hžhubhÊ)”}”(hŒ†When a subsystem maintainer creates a branch and commits changes to it, the result in the simplest case is a history that looks like::”h]”hŒ…When a subsystem maintainer creates a branch and commits changes to it, the result in the simplest case is a history that looks like:”…””}”(hj~hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K#hh¶hžhubjE)”}”(hŒ... vM --- vN-rc1 --- vN-rc2 --- vN-rc3 --- ... --- vN-rc7 --- vN | +-- c1 --- c2 --- ... --- cN”h]”hŒ... vM --- vN-rc1 --- vN-rc2 --- vN-rc3 --- ... --- vN-rc7 --- vN | +-- c1 --- c2 --- ... --- cN”…””}”hjŒsbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1jDhŸh³h K&hh¶hžhubhÊ)”}”(hXQIf that maintainer now uses ``git diff`` to see what has changed between the mainline branch (let's call it "linus") and cN, there are still two clear endpoints, and the result is as expected. So a pull request generated with ``git request-pull`` will also be as expected. But now consider a slightly more complex development history::”h]”(hŒIf that maintainer now uses ”…””}”(hjšhžhhŸNh NubhÔ)”}”(hŒ ``git diff``”h]”hŒgit diff”…””}”(hj¢hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjšubhŒÁ to see what has changed between the mainline branch (let’s call it “linusâ€) and cN, there are still two clear endpoints, and the result is as expected. So a pull request generated with ”…””}”(hjšhžhhŸNh NubhÔ)”}”(hŒ``git request-pull``”h]”hŒgit request-pull”…””}”(hj´hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjšubhŒY will also be as expected. But now consider a slightly more complex development history:”…””}”(hjšhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K*hh¶hžhubjE)”}”(hŒ×... vM --- vN-rc1 --- vN-rc2 --- vN-rc3 --- ... --- vN-rc7 --- vN | | | +-- c1 --- c2 --- ... --- cN | / +-- x1 --- x2 --- x3”h]”hŒ×... vM --- vN-rc1 --- vN-rc2 --- vN-rc3 --- ... --- vN-rc7 --- vN | | | +-- c1 --- c2 --- ... --- cN | / +-- x1 --- x2 --- x3”…””}”hjÌsbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1jDhŸh³h K0hh¶hžhubhÊ)”}”(hŒäOur maintainer has created one branch at vN-rc1 and another at vN-rc2; the two were then subsequently merged into c2. Now a pull request generated for cN may end up being messy indeed, and developers often end up wondering why.”h]”hŒäOur maintainer has created one branch at vN-rc1 and another at vN-rc2; the two were then subsequently merged into c2. Now a pull request generated for cN may end up being messy indeed, and developers often end up wondering why.”…””}”(hjÚhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K6hh¶hžhubhÊ)”}”(hXSWhat is happening here is that there are no longer two clear end points for the ``git diff`` operation to use. The development culminating in cN started in two different places; to generate the diffstat, ``git diff`` ends up having pick one of them and hoping for the best. If the diffstat starts at vN-rc1, it may end up including all of the changes between there and the second origin end point (vN-rc2), which is certainly not what our maintainer had in mind. With all of that extra junk in the diffstat, it may be impossible to tell what actually happened in the changes leading up to cN.”h]”(hŒPWhat is happening here is that there are no longer two clear end points for the ”…””}”(hjèhžhhŸNh NubhÔ)”}”(hŒ ``git diff``”h]”hŒgit diff”…””}”(hjðhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjèubhŒq operation to use. The development culminating in cN started in two different places; to generate the diffstat, ”…””}”(hjèhžhhŸNh NubhÔ)”}”(hŒ ``git diff``”h]”hŒgit diff”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjèubhXz ends up having pick one of them and hoping for the best. If the diffstat starts at vN-rc1, it may end up including all of the changes between there and the second origin end point (vN-rc2), which is certainly not what our maintainer had in mind. With all of that extra junk in the diffstat, it may be impossible to tell what actually happened in the changes leading up to cN.”…””}”(hjèhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K;hh¶hžhubhÊ)”}”(hX]Maintainers often try to resolve this problem by, for example, rebasing the branch or performing another merge with the linus branch, then recreating the pull request. This approach tends not to lead to joy at the receiving end of that pull request; rebasing and/or merging just before pushing upstream is a well-known way to get a grumpy response.”h]”hX]Maintainers often try to resolve this problem by, for example, rebasing the branch or performing another merge with the linus branch, then recreating the pull request. This approach tends not to lead to joy at the receiving end of that pull request; rebasing and/or merging just before pushing upstream is a well-known way to get a grumpy response.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KEhh¶hžhubhÊ)”}”(hXSo what is to be done? The best response when confronted with this situation is to indeed to do a merge with the branch you intend your work to be pulled into, but to do it privately, as if it were the source of shame. Create a new, throwaway branch and do the merge there::”h]”hXSo what is to be done? The best response when confronted with this situation is to indeed to do a merge with the branch you intend your work to be pulled into, but to do it privately, as if it were the source of shame. Create a new, throwaway branch and do the merge there:”…””}”(hj(hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KKhh¶hžhubjE)”}”(hXL... vM --- vN-rc1 --- vN-rc2 --- vN-rc3 --- ... --- vN-rc7 --- vN | | | | +-- c1 --- c2 --- ... --- cN | | / | | +-- x1 --- x2 --- x3 +------------+-- TEMP”h]”hXL... vM --- vN-rc1 --- vN-rc2 --- vN-rc3 --- ... --- vN-rc7 --- vN | | | | +-- c1 --- c2 --- ... --- cN | | / | | +-- x1 --- x2 --- x3 +------------+-- TEMP”…””}”hj6sbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1jDhŸh³h KPhh¶hžhubhÊ)”}”(hX The merge operation resolves all of the complications resulting from the multiple beginning points, yielding a coherent result that contains only the differences from the mainline branch. Now it will be possible to generate a diffstat with the desired information::”h]”hX The merge operation resolves all of the complications resulting from the multiple beginning points, yielding a coherent result that contains only the differences from the mainline branch. Now it will be possible to generate a diffstat with the desired information:”…””}”(hjDhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KVhh¶hžhubjE)”}”(hŒ*$ git diff -C --stat --summary linus..TEMP”h]”hŒ*$ git diff -C --stat --summary linus..TEMP”…””}”hjRsbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1jDhŸh³h K[hh¶hžhubhÊ)”}”(hX Save the output from this command, then simply delete the TEMP branch; definitely do not expose it to the outside world. Take the saved diffstat output and edit it into the messy pull request, yielding a result that shows what is really going on. That request can then be sent upstream.”h]”hX Save the output from this command, then simply delete the TEMP branch; definitely do not expose it to the outside world. Take the saved diffstat output and edit it into the messy pull request, yielding a result that shows what is really going on. That request can then be sent upstream.”…””}”(hj`hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K]hh¶hžhubeh}”(h]”Œ%handling-messy-pull-request-diffstats”ah ]”h"]”Œ%handling messy pull-request diffstats”ah$]”h&]”uh1h´hhhžhhŸh³h Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”h³uh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(h¹NŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j™Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”h³Œ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”(Œlinus1”]”héaŒlinus2”]”jauŒrefids”}”Œnameids”}”(jsjpj&j#j3j0uŒ nametypes”}”(js‰j&ˆj3ˆuh}”(jph¶j#jj0j*uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nhžhub.