backporting.rst 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. .. SPDX-License-Identifier: GPL-2.0
  2. ===================================
  3. Backporting and conflict resolution
  4. ===================================
  5. :Author: Vegard Nossum <vegard.nossum@oracle.com>
  6. .. contents::
  7. :local:
  8. :depth: 3
  9. :backlinks: none
  10. Introduction
  11. ============
  12. Some developers may never really have to deal with backporting patches,
  13. merging branches, or resolving conflicts in their day-to-day work, so
  14. when a merge conflict does pop up, it can be daunting. Luckily,
  15. resolving conflicts is a skill like any other, and there are many useful
  16. techniques you can use to make the process smoother and increase your
  17. confidence in the result.
  18. This document aims to be a comprehensive, step-by-step guide to
  19. backporting and conflict resolution.
  20. Applying the patch to a tree
  21. ============================
  22. Sometimes the patch you are backporting already exists as a git commit,
  23. in which case you just cherry-pick it directly using
  24. ``git cherry-pick``. However, if the patch comes from an email, as it
  25. often does for the Linux kernel, you will need to apply it to a tree
  26. using ``git am``.
  27. If you've ever used ``git am``, you probably already know that it is
  28. quite picky about the patch applying perfectly to your source tree. In
  29. fact, you've probably had nightmares about ``.rej`` files and trying to
  30. edit the patch to make it apply.
  31. It is strongly recommended to instead find an appropriate base version
  32. where the patch applies cleanly and *then* cherry-pick it over to your
  33. destination tree, as this will make git output conflict markers and let
  34. you resolve conflicts with the help of git and any other conflict
  35. resolution tools you might prefer to use. For example, if you want to
  36. apply a patch that just arrived on LKML to an older stable kernel, you
  37. can apply it to the most recent mainline kernel and then cherry-pick it
  38. to your older stable branch.
  39. It's generally better to use the exact same base as the one the patch
  40. was generated from, but it doesn't really matter that much as long as it
  41. applies cleanly and isn't too far from the original base. The only
  42. problem with applying the patch to the "wrong" base is that it may pull
  43. in more unrelated changes in the context of the diff when cherry-picking
  44. it to the older branch.
  45. A good reason to prefer ``git cherry-pick`` over ``git am`` is that git
  46. knows the precise history of an existing commit, so it will know when
  47. code has moved around and changed the line numbers; this in turn makes
  48. it less likely to apply the patch to the wrong place (which can result
  49. in silent mistakes or messy conflicts).
  50. If you are using `b4`_. and you are applying the patch directly from an
  51. email, you can use ``b4 am`` with the options ``-g``/``--guess-base``
  52. and ``-3``/``--prep-3way`` to do some of this automatically (see the
  53. `b4 presentation`_ for more information). However, the rest of this
  54. article will assume that you are doing a plain ``git cherry-pick``.
  55. .. _b4: https://people.kernel.org/monsieuricon/introducing-b4-and-patch-attestation
  56. .. _b4 presentation: https://youtu.be/mF10hgVIx9o?t=2996
  57. Once you have the patch in git, you can go ahead and cherry-pick it into
  58. your source tree. Don't forget to cherry-pick with ``-x`` if you want a
  59. written record of where the patch came from!
  60. Note that if you are submitting a patch for stable, the format is
  61. slightly different; the first line after the subject line needs tobe
  62. either::
  63. commit <upstream commit> upstream
  64. or::
  65. [ Upstream commit <upstream commit> ]
  66. Resolving conflicts
  67. ===================
  68. Uh-oh; the cherry-pick failed with a vaguely threatening message::
  69. CONFLICT (content): Merge conflict
  70. What to do now?
  71. In general, conflicts appear when the context of the patch (i.e., the
  72. lines being changed and/or the lines surrounding the changes) doesn't
  73. match what's in the tree you are trying to apply the patch *to*.
  74. For backports, what likely happened was that the branch you are
  75. backporting from contains patches not in the branch you are backporting
  76. to. However, the reverse is also possible. In any case, the result is a
  77. conflict that needs to be resolved.
  78. If your attempted cherry-pick fails with a conflict, git automatically
  79. edits the files to include so-called conflict markers showing you where
  80. the conflict is and how the two branches have diverged. Resolving the
  81. conflict typically means editing the end result in such a way that it
  82. takes into account these other commits.
  83. Resolving the conflict can be done either by hand in a regular text
  84. editor or using a dedicated conflict resolution tool.
  85. Many people prefer to use their regular text editor and edit the
  86. conflict directly, as it may be easier to understand what you're doing
  87. and to control the final result. There are definitely pros and cons to
  88. each method, and sometimes there's value in using both.
  89. We will not cover using dedicated merge tools here beyond providing some
  90. pointers to various tools that you could use:
  91. - `Emacs Ediff mode <https://www.emacswiki.org/emacs/EdiffMode>`__
  92. - `vimdiff/gvimdiff <https://linux.die.net/man/1/vimdiff>`__
  93. - `KDiff3 <http://kdiff3.sourceforge.net/>`__
  94. - `TortoiseMerge <https://tortoisesvn.net/TortoiseMerge.html>`__
  95. - `Meld <https://meldmerge.org/help/>`__
  96. - `P4Merge <https://www.perforce.com/products/helix-core-apps/merge-diff-tool-p4merge>`__
  97. - `Beyond Compare <https://www.scootersoftware.com/>`__
  98. - `IntelliJ <https://www.jetbrains.com/help/idea/resolve-conflicts.html>`__
  99. - `VSCode <https://code.visualstudio.com/docs/editor/versioncontrol>`__
  100. To configure git to work with these, see ``git mergetool --help`` or
  101. the official `git-mergetool documentation`_.
  102. .. _git-mergetool documentation: https://git-scm.com/docs/git-mergetool
  103. Prerequisite patches
  104. --------------------
  105. Most conflicts happen because the branch you are backporting to is
  106. missing some patches compared to the branch you are backporting *from*.
  107. In the more general case (such as merging two independent branches),
  108. development could have happened on either branch, or the branches have
  109. simply diverged -- perhaps your older branch had some other backports
  110. applied to it that themselves needed conflict resolutions, causing a
  111. divergence.
  112. It's important to always identify the commit or commits that caused the
  113. conflict, as otherwise you cannot be confident in the correctness of
  114. your resolution. As an added bonus, especially if the patch is in an
  115. area you're not that familiar with, the changelogs of these commits will
  116. often give you the context to understand the code and potential problems
  117. or pitfalls with your conflict resolution.
  118. git log
  119. ~~~~~~~
  120. A good first step is to look at ``git log`` for the file that has the
  121. conflict -- this is usually sufficient when there aren't a lot of
  122. patches to the file, but may get confusing if the file is big and
  123. frequently patched. You should run ``git log`` on the range of commits
  124. between your currently checked-out branch (``HEAD``) and the parent of
  125. the patch you are picking (``<commit>``), i.e.::
  126. git log HEAD..<commit>^ -- <path>
  127. Even better, if you want to restrict this output to a single function
  128. (because that's where the conflict appears), you can use the following
  129. syntax::
  130. git log -L:'\<function\>':<path> HEAD..<commit>^
  131. .. note::
  132. The ``\<`` and ``\>`` around the function name ensure that the
  133. matches are anchored on a word boundary. This is important, as this
  134. part is actually a regex and git only follows the first match, so
  135. if you use ``-L:thread_stack:kernel/fork.c`` it may only give you
  136. results for the function ``try_release_thread_stack_to_cache`` even
  137. though there are many other functions in that file containing the
  138. string ``thread_stack`` in their names.
  139. Another useful option for ``git log`` is ``-G``, which allows you to
  140. filter on certain strings appearing in the diffs of the commits you are
  141. listing::
  142. git log -G'regex' HEAD..<commit>^ -- <path>
  143. This can also be a handy way to quickly find when something (e.g. a
  144. function call or a variable) was changed, added, or removed. The search
  145. string is a regular expression, which means you can potentially search
  146. for more specific things like assignments to a specific struct member::
  147. git log -G'\->index\>.*='
  148. git blame
  149. ~~~~~~~~~
  150. Another way to find prerequisite commits (albeit only the most recent
  151. one for a given conflict) is to run ``git blame``. In this case, you
  152. need to run it against the parent commit of the patch you are
  153. cherry-picking and the file where the conflict appeared, i.e.::
  154. git blame <commit>^ -- <path>
  155. This command also accepts the ``-L`` argument (for restricting the
  156. output to a single function), but in this case you specify the filename
  157. at the end of the command as usual::
  158. git blame -L:'\<function\>' <commit>^ -- <path>
  159. Navigate to the place where the conflict occurred. The first column of
  160. the blame output is the commit ID of the patch that added a given line
  161. of code.
  162. It might be a good idea to ``git show`` these commits and see if they
  163. look like they might be the source of the conflict. Sometimes there will
  164. be more than one of these commits, either because multiple commits
  165. changed different lines of the same conflict area *or* because multiple
  166. subsequent patches changed the same line (or lines) multiple times. In
  167. the latter case, you may have to run ``git blame`` again and specify the
  168. older version of the file to look at in order to dig further back in
  169. the history of the file.
  170. Prerequisite vs. incidental patches
  171. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  172. Having found the patch that caused the conflict, you need to determine
  173. whether it is a prerequisite for the patch you are backporting or
  174. whether it is just incidental and can be skipped. An incidental patch
  175. would be one that touches the same code as the patch you are
  176. backporting, but does not change the semantics of the code in any
  177. material way. For example, a whitespace cleanup patch is completely
  178. incidental -- likewise, a patch that simply renames a function or a
  179. variable would be incidental as well. On the other hand, if the function
  180. being changed does not even exist in your current branch then this would
  181. not be incidental at all and you need to carefully consider whether the
  182. patch adding the function should be cherry-picked first.
  183. If you find that there is a necessary prerequisite patch, then you need
  184. to stop and cherry-pick that instead. If you've already resolved some
  185. conflicts in a different file and don't want to do it again, you can
  186. create a temporary copy of that file.
  187. To abort the current cherry-pick, go ahead and run
  188. ``git cherry-pick --abort``, then restart the cherry-picking process
  189. with the commit ID of the prerequisite patch instead.
  190. Understanding conflict markers
  191. ------------------------------
  192. Combined diffs
  193. ~~~~~~~~~~~~~~
  194. Let's say you've decided against picking (or reverting) additional
  195. patches and you just want to resolve the conflict. Git will have
  196. inserted conflict markers into your file. Out of the box, this will look
  197. something like::
  198. <<<<<<< HEAD
  199. this is what's in your current tree before cherry-picking
  200. =======
  201. this is what the patch wants it to be after cherry-picking
  202. >>>>>>> <commit>... title
  203. This is what you would see if you opened the file in your editor.
  204. However, if you were to run ``git diff`` without any arguments, the
  205. output would look something like this::
  206. $ git diff
  207. [...]
  208. ++<<<<<<<< HEAD
  209. +this is what's in your current tree before cherry-picking
  210. ++========
  211. + this is what the patch wants it to be after cherry-picking
  212. ++>>>>>>>> <commit>... title
  213. When you are resolving a conflict, the behavior of ``git diff`` differs
  214. from its normal behavior. Notice the two columns of diff markers
  215. instead of the usual one; this is a so-called "`combined diff`_", here
  216. showing the 3-way diff (or diff-of-diffs) between
  217. #. the current branch (before cherry-picking) and the current working
  218. directory, and
  219. #. the current branch (before cherry-picking) and the file as it looks
  220. after the original patch has been applied.
  221. .. _combined diff: https://git-scm.com/docs/diff-format#_combined_diff_format
  222. Better diffs
  223. ~~~~~~~~~~~~
  224. 3-way combined diffs include all the other changes that happened to the
  225. file between your current branch and the branch you are cherry-picking
  226. from. While this is useful for spotting other changes that you need to
  227. take into account, this also makes the output of ``git diff`` somewhat
  228. intimidating and difficult to read. You may instead prefer to run
  229. ``git diff HEAD`` (or ``git diff --ours``) which shows only the diff
  230. between the current branch before cherry-picking and the current working
  231. directory. It looks like this::
  232. $ git diff HEAD
  233. [...]
  234. +<<<<<<<< HEAD
  235. this is what's in your current tree before cherry-picking
  236. +========
  237. +this is what the patch wants it to be after cherry-picking
  238. +>>>>>>>> <commit>... title
  239. As you can see, this reads just like any other diff and makes it clear
  240. which lines are in the current branch and which lines are being added
  241. because they are part of the merge conflict or the patch being
  242. cherry-picked.
  243. Merge styles and diff3
  244. ~~~~~~~~~~~~~~~~~~~~~~
  245. The default conflict marker style shown above is known as the ``merge``
  246. style. There is also another style available, known as the ``diff3``
  247. style, which looks like this::
  248. <<<<<<< HEAD
  249. this is what is in your current tree before cherry-picking
  250. ||||||| parent of <commit> (title)
  251. this is what the patch expected to find there
  252. =======
  253. this is what the patch wants it to be after being applied
  254. >>>>>>> <commit> (title)
  255. As you can see, this has 3 parts instead of 2, and includes what git
  256. expected to find there but didn't. It is *highly recommended* to use
  257. this conflict style as it makes it much clearer what the patch actually
  258. changed; i.e., it allows you to compare the before-and-after versions
  259. of the file for the commit you are cherry-picking. This allows you to
  260. make better decisions about how to resolve the conflict.
  261. To change conflict marker styles, you can use the following command::
  262. git config merge.conflictStyle diff3
  263. There is a third option, ``zdiff3``, introduced in `Git 2.35`_,
  264. which has the same 3 sections as ``diff3``, but where common lines have
  265. been trimmed off, making the conflict area smaller in some cases.
  266. .. _Git 2.35: https://github.blog/2022-01-24-highlights-from-git-2-35/
  267. Iterating on conflict resolutions
  268. ---------------------------------
  269. The first step in any conflict resolution process is to understand the
  270. patch you are backporting. For the Linux kernel this is especially
  271. important, since an incorrect change can lead to the whole system
  272. crashing -- or worse, an undetected security vulnerability.
  273. Understanding the patch can be easy or difficult depending on the patch
  274. itself, the changelog, and your familiarity with the code being changed.
  275. However, a good question for every change (or every hunk of the patch)
  276. might be: "Why is this hunk in the patch?" The answers to these
  277. questions will inform your conflict resolution.
  278. Resolution process
  279. ~~~~~~~~~~~~~~~~~~
  280. Sometimes the easiest thing to do is to just remove all but the first
  281. part of the conflict, leaving the file essentially unchanged, and apply
  282. the changes by hand. Perhaps the patch is changing a function call
  283. argument from ``0`` to ``1`` while a conflicting change added an
  284. entirely new (and insignificant) parameter to the end of the parameter
  285. list; in that case, it's easy enough to change the argument from ``0``
  286. to ``1`` by hand and leave the rest of the arguments alone. This
  287. technique of manually applying changes is mostly useful if the conflict
  288. pulled in a lot of unrelated context that you don't really need to care
  289. about.
  290. For particularly nasty conflicts with many conflict markers, you can use
  291. ``git add`` or ``git add -i`` to selectively stage your resolutions to
  292. get them out of the way; this also lets you use ``git diff HEAD`` to
  293. always see what remains to be resolved or ``git diff --cached`` to see
  294. what your patch looks like so far.
  295. Dealing with file renames
  296. ~~~~~~~~~~~~~~~~~~~~~~~~~
  297. One of the most annoying things that can happen while backporting a
  298. patch is discovering that one of the files being patched has been
  299. renamed, as that typically means git won't even put in conflict markers,
  300. but will just throw up its hands and say (paraphrased): "Unmerged path!
  301. You do the work..."
  302. There are generally a few ways to deal with this. If the patch to the
  303. renamed file is small, like a one-line change, the easiest thing is to
  304. just go ahead and apply the change by hand and be done with it. On the
  305. other hand, if the change is big or complicated, you definitely don't
  306. want to do it by hand.
  307. As a first pass, you can try something like this, which will lower the
  308. rename detection threshold to 30% (by default, git uses 50%, meaning
  309. that two files need to have at least 50% in common for it to consider
  310. an add-delete pair to be a potential rename)::
  311. git cherry-pick -strategy=recursive -Xrename-threshold=30
  312. Sometimes the right thing to do will be to also backport the patch that
  313. did the rename, but that's definitely not the most common case. Instead,
  314. what you can do is to temporarily rename the file in the branch you're
  315. backporting to (using ``git mv`` and committing the result), restart the
  316. attempt to cherry-pick the patch, rename the file back (``git mv`` and
  317. committing again), and finally squash the result using ``git rebase -i``
  318. (see the `rebase tutorial`_) so it appears as a single commit when you
  319. are done.
  320. .. _rebase tutorial: https://medium.com/@slamflipstrom/a-beginners-guide-to-squashing-commits-with-git-rebase-8185cf6e62ec
  321. Gotchas
  322. -------
  323. Function arguments
  324. ~~~~~~~~~~~~~~~~~~
  325. Pay attention to changing function arguments! It's easy to gloss over
  326. details and think that two lines are the same but actually they differ
  327. in some small detail like which variable was passed as an argument
  328. (especially if the two variables are both a single character that look
  329. the same, like i and j).
  330. Error handling
  331. ~~~~~~~~~~~~~~
  332. If you cherry-pick a patch that includes a ``goto`` statement (typically
  333. for error handling), it is absolutely imperative to double check that
  334. the target label is still correct in the branch you are backporting to.
  335. The same goes for added ``return``, ``break``, and ``continue``
  336. statements.
  337. Error handling is typically located at the bottom of the function, so it
  338. may not be part of the conflict even though could have been changed by
  339. other patches.
  340. A good way to ensure that you review the error paths is to always use
  341. ``git diff -W`` and ``git show -W`` (AKA ``--function-context``) when
  342. inspecting your changes. For C code, this will show you the whole
  343. function that's being changed in a patch. One of the things that often
  344. go wrong during backports is that something else in the function changed
  345. on either of the branches that you're backporting from or to. By
  346. including the whole function in the diff you get more context and can
  347. more easily spot problems that might otherwise go unnoticed.
  348. Refactored code
  349. ~~~~~~~~~~~~~~~
  350. Something that happens quite often is that code gets refactored by
  351. "factoring out" a common code sequence or pattern into a helper
  352. function. When backporting patches to an area where such a refactoring
  353. has taken place, you effectively need to do the reverse when
  354. backporting: a patch to a single location may need to be applied to
  355. multiple locations in the backported version. (One giveaway for this
  356. scenario is that a function was renamed -- but that's not always the
  357. case.)
  358. To avoid incomplete backports, it's worth trying to figure out if the
  359. patch fixes a bug that appears in more than one place. One way to do
  360. this would be to use ``git grep``. (This is actually a good idea to do
  361. in general, not just for backports.) If you do find that the same kind
  362. of fix would apply to other places, it's also worth seeing if those
  363. places exist upstream -- if they don't, it's likely the patch may need
  364. to be adjusted. ``git log`` is your friend to figure out what happened
  365. to these areas as ``git blame`` won't show you code that has been
  366. removed.
  367. If you do find other instances of the same pattern in the upstream tree
  368. and you're not sure whether it's also a bug, it may be worth asking the
  369. patch author. It's not uncommon to find new bugs during backporting!
  370. Verifying the result
  371. ====================
  372. colordiff
  373. ---------
  374. Having committed a conflict-free new patch, you can now compare your
  375. patch to the original patch. It is highly recommended that you use a
  376. tool such as `colordiff`_ that can show two files side by side and color
  377. them according to the changes between them::
  378. colordiff -yw -W 200 <(git diff -W <upstream commit>^-) <(git diff -W HEAD^-) | less -SR
  379. .. _colordiff: https://www.colordiff.org/
  380. Here, ``-y`` means to do a side-by-side comparison; ``-w`` ignores
  381. whitespace, and ``-W 200`` sets the width of the output (as otherwise it
  382. will use 130 by default, which is often a bit too little).
  383. The ``rev^-`` syntax is a handy shorthand for ``rev^..rev``, essentially
  384. giving you just the diff for that single commit; also see
  385. the official `git rev-parse documentation`_.
  386. .. _git rev-parse documentation: https://git-scm.com/docs/git-rev-parse#_other_rev_parent_shorthand_notations
  387. Again, note the inclusion of ``-W`` for ``git diff``; this ensures that
  388. you will see the full function for any function that has changed.
  389. One incredibly important thing that colordiff does is to highlight lines
  390. that are different. For example, if an error-handling ``goto`` has
  391. changed labels between the original and backported patch, colordiff will
  392. show these side-by-side but highlighted in a different color. Thus, it
  393. is easy to see that the two ``goto`` statements are jumping to different
  394. labels. Likewise, lines that were not modified by either patch but
  395. differ in the context will also be highlighted and thus stand out during
  396. a manual inspection.
  397. Of course, this is just a visual inspection; the real test is building
  398. and running the patched kernel (or program).
  399. Build testing
  400. -------------
  401. We won't cover runtime testing here, but it can be a good idea to build
  402. just the files touched by the patch as a quick sanity check. For the
  403. Linux kernel you can build single files like this, assuming you have the
  404. ``.config`` and build environment set up correctly::
  405. make path/to/file.o
  406. Note that this won't discover linker errors, so you should still do a
  407. full build after verifying that the single file compiles. By compiling
  408. the single file first you can avoid having to wait for a full build *in
  409. case* there are compiler errors in any of the files you've changed.
  410. Runtime testing
  411. ---------------
  412. Even a successful build or boot test is not necessarily enough to rule
  413. out a missing dependency somewhere. Even though the chances are small,
  414. there could be code changes where two independent changes to the same
  415. file result in no conflicts, no compile-time errors, and runtime errors
  416. only in exceptional cases.
  417. One concrete example of this was a pair of patches to the system call
  418. entry code where the first patch saved/restored a register and a later
  419. patch made use of the same register somewhere in the middle of this
  420. sequence. Since there was no overlap between the changes, one could
  421. cherry-pick the second patch, have no conflicts, and believe that
  422. everything was fine, when in fact the code was now scribbling over an
  423. unsaved register.
  424. Although the vast majority of errors will be caught during compilation
  425. or by superficially exercising the code, the only way to *really* verify
  426. a backport is to review the final patch with the same level of scrutiny
  427. as you would (or should) give to any other patch. Having unit tests and
  428. regression tests or other types of automatic testing can help increase
  429. the confidence in the correctness of a backport.
  430. Submitting backports to stable
  431. ==============================
  432. As the stable maintainers try to cherry-pick mainline fixes onto their
  433. stable kernels, they may send out emails asking for backports when when
  434. encountering conflicts, see e.g.
  435. <https://lore.kernel.org/stable/2023101528-jawed-shelving-071a@gregkh/>.
  436. These emails typically include the exact steps you need to cherry-pick
  437. the patch to the correct tree and submit the patch.
  438. One thing to make sure is that your changelog conforms to the expected
  439. format::
  440. <original patch title>
  441. [ Upstream commit <mainline rev> ]
  442. <rest of the original changelog>
  443. [ <summary of the conflicts and their resolutions> ]
  444. Signed-off-by: <your name and email>
  445. The "Upstream commit" line is sometimes slightly different depending on
  446. the stable version. Older version used this format::
  447. commit <mainline rev> upstream.
  448. It is most common to indicate the kernel version the patch applies to
  449. in the email subject line (using e.g.
  450. ``git send-email --subject-prefix='PATCH 6.1.y'``), but you can also put
  451. it in the Signed-off-by:-area or below the ``---`` line.
  452. The stable maintainers expect separate submissions for each active
  453. stable version, and each submission should also be tested separately.
  454. A few final words of advice
  455. ===========================
  456. 1) Approach the backporting process with humility.
  457. 2) Understand the patch you are backporting; this means reading both
  458. the changelog and the code.
  459. 3) Be honest about your confidence in the result when submitting the
  460. patch.
  461. 4) Ask relevant maintainers for explicit acks.
  462. Examples
  463. ========
  464. The above shows roughly the idealized process of backporting a patch.
  465. For a more concrete example, see this video tutorial where two patches
  466. are backported from mainline to stable:
  467. `Backporting Linux Kernel Patches`_.
  468. .. _Backporting Linux Kernel Patches: https://youtu.be/sBR7R1V2FeA