fromupstream: Recover the Change-Id encoded in the Message-Id
If you're like the cool kids, you've started encoding a Change-Id into
your Message-Id when posting patches upstream. Maybe you use patman
to post your patches (so you get this automatically) or maybe you've
coded up a git hook like Johannes Berg talks about [1]. Now when you
pick your patches back using the fromupstream script you obviously
want the Change-Id recovered.
Specifically, the flow envisioned is:
1. Write a patch.
2. Post a WIP to gerrit for early review by your friends.
3. Make some changes based on your friends' early reviews.
4. Post v1 of your patch to mailing lists.
5. Pick v1 using fromupstream and upload to gerrit to show all your
friends your progress.
6. Get feedback upstream; make changes.
7. Post v2 of your patch to mailing lists.
8. Pick v2 using fromupstream and upload to gerrit to show all your
friends your progress.
When you upload v1 and v2 to gerrit you want to keep the same
Change-Id so that it replaces older versions of the same change. In
the past you had to manually look up the old Change-Id and then pass
the --changeid argument to set it (or use --replace). Now you can get
it more automatically.
This feature can also be useful if you're not a cool kid but you work
with people who are cool kids. Even if you haven't yet figured out
how to encode your Change-Id into the Message-Id, you might be picking
patches from other people who have, and thus this automatic Change-Id
will still be useful for you. ;-)
NOTE: For now I'm assuming that we can make this behavior the default.
If someone can think of a reason why this shouldn't be default we can
make it default to being off.
This patch not only detects Change-Id from the Message-Id when picking
from patchwork, it also detects the Change-Id if a maintainer was nice
and included a "Link: " tag with a URL including the Change-Id. This
is fairly common practice and becomming more and more common.
For an example patch with the Change-Id, see [2].
[1] https://patchwork.ozlabs.org/patch/1157266/
[2] https://lore.kernel.org/r/20190925125811.v3.1.I31ab239a765022d9402c38f8a12d9f7bae76b770@changeid
BUG=None
TEST=Try picking a patch from patchwork and one FROMGIT w/ a Link:
Change-Id: Iebc34f0c3d73623317aa4c3f12269b405633e6de
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/1825450
Reviewed-by: Tzung-Bi Shih <tzungbi@chromium.org>
Reviewed-by: Alexandru M Stan <amstan@chromium.org>
diff --git a/contrib/fromupstream.py b/contrib/fromupstream.py
index 26eb400..11ebf95 100755
--- a/contrib/fromupstream.py
+++ b/contrib/fromupstream.py
@@ -138,13 +138,18 @@
errprint('Error: No patch content found')
sys.exit(1)
+ message_id = mailbox.Message(patch_contents)['Message-Id']
+ message_id = re.sub('^<|>$', '', message_id.strip())
if args['source_line'] is None:
args['source_line'] = '(am from %s/patch/%d/)' % (url, patch_id)
- message_id = mailbox.Message(patch_contents)['Message-Id']
- message_id = re.sub('^<|>$', '', message_id.strip())
args['source_line'] += (
'\n(also found at https://lkml.kernel.org/r/%s)' % message_id)
+ # Auto-snarf the Change-Id if it was encoded into the Message-Id.
+ mo = re.match(r'.*(I[a-f0-9]{40})@changeid$', message_id)
+ if mo and args['changeid'] is None:
+ args['changeid'] = mo.group(1)
+
if args['replace']:
subprocess.call(['git', 'reset', '--hard', 'HEAD~1'])
@@ -400,6 +405,13 @@
['git', 'show', '-s', '--format=%B', 'HEAD']
).strip('\n')
+ # If we see a "Link: " that seems to point to a Message-Id with an
+ # automatic Change-Id we'll snarf it out.
+ mo = re.search(r'^Link:.*(I[a-f0-9]{40})@changeid', commit_message,
+ re.MULTILINE)
+ if mo and args['changeid'] is None:
+ args['changeid'] = mo.group(1)
+
# replace changeid if needed
if args['changeid'] is not None:
commit_message = re.sub(r'(Change-Id: )(\w+)', r'\1%s' %