{"id":1417,"date":"2021-03-03T18:55:53","date_gmt":"2021-03-03T17:55:53","guid":{"rendered":"http:\/\/blogs.gentoo.org\/mgorny\/?p=1417"},"modified":"2021-03-03T18:55:53","modified_gmt":"2021-03-03T17:55:53","slug":"moving-commits-between-independent-git-histories","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/mgorny\/2021\/03\/03\/moving-commits-between-independent-git-histories\/","title":{"rendered":"Moving commits between independent git histories"},"content":{"rendered":"<p><a rel='external' href='https:\/\/www.pypy.org\/'>PyPy<\/a> is an alternative Python implementation.  While it does replace a large part of the interpreter, a large part of the standard library is shared with <a rel='external' href='https:\/\/python.org'>CPython<\/a>.  As a result, PyPy is frequently affected by the same vulnerabilities as CPython, and we have to backport security fixes to it.<\/p>\n<p>Backporting security fixes inside CPython is relatively easy.  All main Python branches are in a single repository, so it&#8217;s just a matter of cherry-picking the commits.  Normally, you can easily move patches between two <em>related<\/em> git repositories using git-style patches but this isn&#8217;t going to work for two repositories with unrelated histories.<\/p>\n<p>Does this mean manually patching PyPy and rewriting commit messages by hand?  Luckily, there&#8217;s a relatively simple <kbd>git am<\/kbd> trick that can help you avoid that.<br \/>\n<!--more--><\/p>\n<p>Roughly, the idea is to:<\/p>\n<p>1. Create a git-format-patch of the change to backport.<\/p>\n<p>2. Attempt to apply the change via <kbd>git am<\/kbd> \u2014 it will fail and your repository will be left in middle of an am session.<\/p>\n<p>3. Apply the change via <kbd>patch<\/kbd>.<\/p>\n<p>4. <kbd>git add<\/kbd> the changes.<\/p>\n<p>5. Finally, call <kbd>git am --continue<\/kbd> to finish, wrapping your changes in the original commit metadata.<\/p>\n<p>For example, let&#8217;s try backporting <a rel='external' href='https:\/\/github.com\/python\/cpython\/commit\/d0d4d30882fe3ab9b1badbecf5d15d94326fd13e'>CVE-2021-23336 (parameter cloaking) fix<\/a>:<\/p>\n<p>First, grab the relevant patch from the CPython repository:<\/p>\n<pre><code>$ git format-patch -1 d0d4d30882fe3ab9b1badbecf5d15d94326fd13e\r\n0001-3.7-bpo-42967-only-use-as-a-query-string-separator-G.patch<\/code><\/pre>\n<p>Then, inside the local clone of a random PyPy git mirror:<\/p>\n<pre><code>$ git am -3 ~\/git\/cpython\/0001-3.7-bpo-42967-only-use-as-a-query-string-separator-G.patch\r\nApplying: bpo-42967: only use '&amp;' as a query string separator (GH-24297) (GH-24531)\r\nerror: sha1 information is lacking or useless (Doc\/library\/cgi.rst).\r\nerror: could not build fake ancestor\r\nPatch failed at 0001 bpo-42967: only use '&amp;' as a query string separator (GH-24297) (GH-24531)\r\nhint: Use 'git am --show-current-patch=diff' to see the failed patch\r\nWhen you have resolved this problem, run \"git am --continue\".\r\nIf you prefer to skip this patch, run \"git am --skip\" instead.\r\nTo restore the original branch and stop patching, run \"git am --abort\".<\/code><\/pre>\n<p>Now enter the directory that stdlib resides in, and apply the patch manually, skipping any missing files:<\/p>\n<pre><code>$ patch -p2 &lt; ~\/git\/cpython\/0001-3.7-bpo-42967-only-use-as-a-query-string-separator-G.patch\r\ncan&#039;t find file to patch at input line 39\r\nPerhaps you used the wrong -p or --strip option?\r\nThe text leading up to this was:\r\n--------------------------\r\n|From d0d4d30882fe3ab9b1badbecf5d15d94326fd13e Mon Sep 17 00:00:00 2001\r\n|From: Senthil Kumaran \r\n|Date: Mon, 15 Feb 2021 10:34:14 -0800\r\n|Subject: [PATCH] [3.7] bpo-42967: only use '&amp;' as a query string separator\r\n| (GH-24297)  (GH-24531)\r\n|MIME-Version: 1.0\r\n|Content-Type: text\/plain; charset=UTF-8\r\n|Content-Transfer-Encoding: 8bit\r\n|\r\n|bpo-42967: [security] Address a web cache-poisoning issue reported in\r\n|urllib.parse.parse_qsl().\r\n|\r\n|urllib.parse will only us \"&amp;\" as query string separator by default\r\n|instead of both \";\" and \"&amp;\" as allowed in earlier versions. An optional\r\n|argument seperator with default value \"&amp;\" is added to specify the\r\n|separator.\r\n|\r\n|Co-authored-by: \u00c9ric Araujo \r\n|Co-authored-by: Ken Jin \r\n|Co-authored-by: Adam Goldschmidt \r\n|(cherry picked from commit fcbe0cb04d35189401c0c880ebfb4311e952d776)\r\n|---\r\n| Doc\/library\/cgi.rst                           |  9 ++-\r\n| Doc\/library\/urllib.parse.rst                  | 23 ++++++-\r\n| Doc\/whatsnew\/3.6.rst                          | 13 ++++\r\n| Doc\/whatsnew\/3.7.rst                          | 13 ++++\r\n| Lib\/cgi.py                                    | 23 ++++---\r\n| Lib\/test\/test_cgi.py                          | 29 ++++++--\r\n| Lib\/test\/test_urlparse.py                     | 68 +++++++++++++------\r\n| Lib\/urllib\/parse.py                           | 19 ++++--\r\n| ...\/2021-02-14-15-59-16.bpo-42967.YApqDS.rst  |  1 +\r\n| 9 files changed, 152 insertions(+), 46 deletions(-)\r\n| create mode 100644 Misc\/NEWS.d\/next\/Security\/2021-02-14-15-59-16.bpo-42967.YApqDS.rst\r\n|\r\n|diff --git a\/Doc\/library\/cgi.rst b\/Doc\/library\/cgi.rst\r\n|index 0b1aead9dd..f0ec7e8cc6 100644\r\n|--- a\/Doc\/library\/cgi.rst\r\n|+++ b\/Doc\/library\/cgi.rst\r\n--------------------------\r\nFile to patch: \r\nSkip this patch? [y] \r\nSkipping patch.\r\n3 out of 3 hunks ignored\r\n[...]\r\npatching file cgi.py\r\npatching file test\/test_cgi.py\r\npatching file test\/test_urlparse.py\r\npatching file urllib\/parse.py\r\npatching file NEWS.d\/next\/Security\/2021-02-14-15-59-16.bpo-42967.YApqDS.rst<\/code><\/pre>\n<p>Adjust the changes as appropriate:<\/p>\n<pre><code>$ rm -r NEWS.d\/\r\n$ git status\r\nHEAD detached from release-pypy3.7-v7.3.3\r\nYou are in the middle of an am session.\r\n  (fix conflicts and then run \"git am --continue\")\r\n  (use \"git am --skip\" to skip this patch)\r\n  (use \"git am --abort\" to restore the original branch)\r\n\r\nChanges not staged for commit:\r\n  (use \"git add ...\" to update what will be committed)\r\n  (use \"git restore ...\" to discard changes in working directory)\r\n\tmodified:   cgi.py\r\n\tmodified:   test\/test_cgi.py\r\n\tmodified:   test\/test_urlparse.py\r\n\tmodified:   urllib\/parse.py\r\n\r\nno changes added to commit (use \"git add\" and\/or \"git commit -a\")\r\n$ git add cgi.py test\/test_cgi.py test\/test_urlparse.py urllib\/parse.py<\/pre>\n<p><\/code><\/p>\n<p>And finally let <kbd>git am<\/kbd> commit the changes for you:<\/p>\n<pre><code>$ git am --continue\r\nApplying: bpo-42967: only use '&amp;' as a query string separator (GH-24297) (GH-24531)<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>PyPy is an alternative Python implementation. While it does replace a large part of the interpreter, a large part of the standard library is shared with CPython. As a result, PyPy is frequently affected by the same vulnerabilities as CPython, and we have to backport security fixes to it. Backporting security fixes inside CPython is &hellip; <a href=\"https:\/\/blogs.gentoo.org\/mgorny\/2021\/03\/03\/moving-commits-between-independent-git-histories\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Moving commits between independent git histories&#8221;<\/span><\/a><\/p>\n","protected":false},"author":137,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[3],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/1417"}],"collection":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/users\/137"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/comments?post=1417"}],"version-history":[{"count":8,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/1417\/revisions"}],"predecessor-version":[{"id":1425,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/1417\/revisions\/1425"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/media?parent=1417"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/categories?post=1417"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/tags?post=1417"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}