All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Gunthorpe <jgg@nvidia.com>
To: Mark Brown <broonie@kernel.org>
Cc: Leon Romanovsky <leonro@nvidia.com>,
	linux-kernel@vger.kernel.org, linux-next@vger.kernel.org
Subject: Re: Missing signoff in the rdma tree
Date: Mon, 6 Apr 2026 14:30:18 -0300	[thread overview]
Message-ID: <20260406173018.GO310919@nvidia.com> (raw)
In-Reply-To: <df6f8a58-5c8d-437e-aad6-fee85a89f5e6@sirena.org.uk>

On Mon, Apr 06, 2026 at 05:38:14PM +0100, Mark Brown wrote:

> > are missing a Signed-off-by from their committers
> 
> This issue is still present today.

When Leon fixed the previous mistake with rebase it caused all of
this. filter-repo isn't good about not changing commits it doesn't
have to change, so it isn't so useful when merges are present.
rebase -r will reset the commiter for other commits.

Couldn't find a built in alternative and got tired of this, so I ended
up using AI to build a script based on an commit editor I already had
to fix it. I've included it below incase anyone else finds it useful
someday.

$ python3 edit_committer.py refs/heads/k.o/for-next \
        "Jason Gunthorpe" "jgg@nvidia.com" \
        v7.0-rc1 \
        eb15cffa15201b 485a21c14b4133 9ed273bbe66370 \
        0edac801a2693e 4e99362444a2f6 f0579e330b7736 \
        9db6a217ba5ddf ce150a8376e1ee d59f007207b394 \
        ac4bb15208d1f0 12c73bee531336 ac593f5b66c9d1 \
        6df3a6414d7364 42d2a291ef4748 f1cac281b42456 \
        4ac738c6a7b906 715eccd4798ec7 ea08d8cb8b5203 \
        8e886928a19d70

 Processing 2536 commits from v7.0-rc1 to 69db255d5faf
       8e886928a19d -> 38a6e5579d0d (target)
       ea08d8cb8b52 -> b51caeb24aad (target)
       715eccd4798e -> 1de9287ece44 (target)
       4ac738c6a7b9 -> dbf6491bb98d (target)
       f1cac281b424 -> 14badc323ed7 (target)
       42d2a291ef47 -> 4c379ba04c11 (target)
       6df3a6414d73 -> 5ebe8832ef90 (target)
       ac593f5b66c9 -> b33d860a13b4 (target)
       12c73bee5313 -> 3f6b103c4bf2 (target)
       ac4bb15208d1 -> 0cee3acab27a (target)
       d59f007207b3 -> bc30311e492e (target)
       ce150a8376e1 -> bed686d8dcd4 (target)
       9db6a217ba5d -> 613713f251c8 (target)
       f0579e330b77 -> eee6268421a2 (target)
       4e99362444a2 -> 13f9a813eee5 (target)
       0edac801a269 -> 1234a9d8aebb (target)
       9ed273bbe663 -> 3d4a42360c33 (target)
       485a21c14b41 -> cec5157b6c73 (target)
       eb15cffa1520 -> a06165a705ee (target)
       8db7b7d9ba17 -> 1dc469f669fe (parent changed)
       33960c206db2 -> 553dfa8cbd0c (parent changed)
       e86b2bf1c311 -> 797291a66ce3 (parent changed)
       932f1eef09ec -> ff85a2ebacbd (parent changed)
       f39003e8fa8c -> 3a0b171302ee (parent changed)
       5c3f6de46d6a -> 4707bf5f6c86 (parent changed)
       353b3bbdb2c4 -> 2afa8b9f5ff8 (parent changed)
       76ae14db9058 -> 1b50f42049d8 (parent changed)
       120ad1fd5914 -> 56521f587704 (parent changed)
       ba8c700185d6 -> 786ee8ddf47a (parent changed)
       e2849b392974 -> 679eb25de4ee (parent changed)
       2ad64eeaefd2 -> 0fed679e0862 (parent changed)
       1487bad4ea51 -> 6be4ca0ab3a2 (parent changed)
       5122be2a19aa -> 5aeb6e039972 (parent changed)
       4ae130ccec08 -> 9d6ba4ced734 (parent changed)
       dfd4d5a38e65 -> f3cf74933c9c (parent changed)
       a8f6ced534c0 -> 2bb02691df65 (parent changed)
       cdb802af06d6 -> 5aa437c93d90 (parent changed)
       ffdf34ca1a47 -> a60e3f3d6fba (parent changed)
       c8cc77c8418f -> 13f2a53c2a71 (parent changed)
       e5ef99e3401c -> f1327abd6abe (parent changed)
       a7a49104859d -> e01027cab38a (parent changed)
       a2347bc64b89 -> 6c45efd8f9bb (parent changed)
       ada307fd98db -> ce68351be075 (parent changed)
       b8934c5c3f83 -> dc76086a2d94 (parent changed)
       f0c62197416b -> b247ed6f60bd (parent changed)
       c291b1133360 -> 2b2f078236a4 (parent changed)
       d8d84ea1abcc -> 345f842771ff (parent changed)
       933153ef70b8 -> e69609c5d469 (parent changed)
       f9616c93912e -> 2f49e1590344 (parent changed)
       09220f0b8388 -> adc09d7fbbb9 (parent changed)
       b5bc2b6ef6fe -> e6fd24917897 (parent changed)
       997f21ed1e93 -> 179b32095854 (parent changed)
       578cb2be0db2 -> 911e5ca3e169 (parent changed)
       f968d01f47d0 -> dbeb256e8dd8 (parent changed)
       74e2711bb2af -> cef2842c922c (parent changed)
       7a8b545a8012 -> ae638288b202 (parent changed)
       e81275b67f59 -> 8d7573b19402 (parent changed)
       092585a85a19 -> e910d98dc440 (parent changed)
       7fde9cc10f60 -> 54b3bce97211 (parent changed)
       56f6ff43f486 -> 3268330fa84f (parent changed)
       4698e4c4a163 -> c8f9a7a96e9a (parent changed)
       d21477adfa80 -> 530b251b0f7a (parent changed)
       9b4e46b8cce6 -> f899787095cd (parent changed)
       fda720ddb439 -> 0453bf09a68b (parent changed)
       ab214eefaac1 -> d5c8f2f39907 (parent changed)
       03f4c8090204 -> 604caebc7f06 (parent changed)
       7186189cfa22 -> 676b570707be (parent changed)
       16d0d9d4e2e9 -> 67820de31679 (parent changed)
       5af7526eeb73 -> 69309e17293c (parent changed)
       a9cd442a5347 -> 8e3e07cca004 (parent changed)
       69db255d5faf -> fdcbddcd3aa1 (parent changed)

     71 commits rewritten
     Updating refs/heads/k.o/for-next from 69db255d5faf to fdcbddcd3aa1

#!/usr/bin/env python3
"""Change the committer on specific commits without altering unmodified commits.
"""
import re
import subprocess
import sys
import tempfile

IDRE = re.compile(rb"^[0-9a-fA-F]{40}$")


def git_output(args, mode=None):
    o = subprocess.check_output(["git"] + args)
    if mode == "lines":
        return o.splitlines()
    return o.strip()


def git_read_commit(commit_id):
    """Read a commit object and return (raw_keys, desc_lines)"""
    lines = git_output(["cat-file", "commit", commit_id], mode="lines")

    keys = []
    itr = iter(lines)
    for line in itr:
        stripped = line.rstrip()
        if not stripped:
            break
        # Indented lines (e.g. gpgsig continuation) belong to previous key
        if line.startswith(b" "):
            keys[-1] = (keys[-1][0], keys[-1][1] + b"\n" + line)
            continue
        kv = stripped.partition(b" ")
        keys.append((kv[0], kv[2]))

    desc = list(itr)
    return keys, desc


def rebuild_commit(keys, desc):
    """Rebuild a commit object and return its new hash"""
    with tempfile.NamedTemporaryFile() as f:
        for k, v in keys:
            f.write(k + b" " + v + b"\n")
        f.write(b"\n")
        for line in desc:
            f.write(line + b"\n")
        f.flush()

        return git_output(["hash-object", "-t", "commit", "-w", f.name]).decode()


def get_commit_list(ancestor, newest):
    """Return commit IDs from newest to ancestor (exclusive), topological order"""
    ids = git_output(["rev-list", "--topo-order", newest, "^" + ancestor],
                     mode="lines")
    return [i.decode() for i in ids]


def main():
    ref = sys.argv[1]
    new_committer_name = sys.argv[2]
    new_committer_email = sys.argv[3]
    ancestor = sys.argv[4]
    target_prefixes = sys.argv[5:]

    if not target_prefixes:
        print("Usage: edit_committer.py <ref> <name> <email> <ancestor> <commit-prefix>...")
        sys.exit(1)

    newest = git_output(["rev-parse", ref]).decode()
    commit_ids = get_commit_list(ancestor, newest)

    print(f"Processing {len(commit_ids)} commits from {ancestor[:12]} to {newest[:12]}")

    # Process oldest first
    commit_ids.reverse()

    commit_map = {}
    changed = 0

    for cid in commit_ids:
        keys, desc = git_read_commit(cid)

        # Check if this commit is a target for committer rewrite
        is_target = any(cid.startswith(prefix) for prefix in target_prefixes)

        # Update parent pointers if any parents were rewritten
        new_keys = []
        parents_changed = False
        for k, v in keys:
            if k == b"parent":
                old_parent = v.decode()
                new_parent = commit_map.get(old_parent, old_parent)
                if new_parent != old_parent:
                    parents_changed = True
                new_keys.append((k, new_parent.encode()))
            elif is_target and k == b"committer":
                # Rewrite committer, preserving the date portion
                old_val = v.decode()
                # Format: "Name <email> timestamp timezone"
                m = re.match(r".*>(.+)$", old_val)
                date_part = m.group(1) if m else ""
                new_val = f"{new_committer_name} <{new_committer_email}>{date_part}"
                new_keys.append((k, new_val.encode()))
                parents_changed = True  # force rebuild
            else:
                new_keys.append((k, v))

        if not parents_changed and not is_target:
            commit_map[cid] = cid
            continue

        new_id = rebuild_commit(new_keys, desc)
        commit_map[cid] = new_id
        if new_id != cid:
            changed += 1
            label = "(target)" if is_target else "(parent changed)"
            print(f"  {cid[:12]} -> {new_id[:12]} {label}")

    new_head = commit_map.get(newest, newest)
    if new_head == newest:
        print("No changes needed.")
    else:
        # Verify trees match
        diff = git_output(["diff-tree", "-r", newest, new_head])
        assert diff == b"", f"Tree mismatch!\n{diff}"
        print(f"\n{changed} commits rewritten")
        print(f"Updating {ref} from {newest[:12]} to {new_head[:12]}")
        subprocess.check_call(
            ["git", "update-ref", "-m", "edit_committer", ref, new_head, newest])

    return 0


if __name__ == "__main__":
    sys.exit(main())

  reply	other threads:[~2026-04-06 17:30 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-09 11:10 Missing signoff in the rdma tree Mark Brown
2026-03-09 11:40 ` Leon Romanovsky
2026-03-09 11:46   ` Mark Brown
2026-03-09 11:52     ` Leon Romanovsky
2026-03-09 12:43       ` Mark Brown
2026-03-09 12:48         ` Jason Gunthorpe
2026-04-06 16:38 ` Mark Brown
2026-04-06 17:30   ` Jason Gunthorpe [this message]
  -- strict thread matches above, loose matches on Subject: below --
2026-03-23 13:25 Mark Brown
2026-03-30 22:10 ` Mark Brown
2026-03-31  4:59   ` Leon Romanovsky
2026-05-18  8:23 Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260406173018.GO310919@nvidia.com \
    --to=jgg@nvidia.com \
    --cc=broonie@kernel.org \
    --cc=leonro@nvidia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-next@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.