diff mbox series

[b4,v2] b4: Include git notes when generating patches

Message ID 20250407-add-git-notes-v2-1-c0042e938e91@amd.com (mailing list archive)
State New
Headers show
Series [b4,v2] b4: Include git notes when generating patches | expand

Commit Message

Yazen Ghannam April 7, 2025, 2:14 p.m. UTC
By default, 'git show' will include git notes in its output. However,
this is not the case if '--format', or related flags, are given.

Include the '--notes' flag to include git notes in the generated patch.

Also, git-filter-repo does not use git rebase when changing history. So
the default 'notes rewrite' flow will not work. The notes will still be
available, but they will not be associated with the newly created
objects. Fortunately, git-filter-repo records the list of changed objects
after every operation.

Add a callback to copy the notes to the newly created objects. Use the
'--force' flag to avoid benign warnings related to existing notes, etc.
Notes will be copied from an old object to a new object which should not
have any existing notes. Or notes will be copied from an old object to
itself (unchanged), so overwriting its notes is not an issue.

Based on the discussion here:
https://github.com/newren/git-filter-repo/issues/22

This should have no effect on non-users of git notes.

Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
Hi Konstantin,

I know you mentioned leaving this topic for now. But after looking
through the issue link, it seemed that the resolution is fairly simple.
And this does not require any special handling/knowledge from 'b4'
users.

Thanks,
Yazen
---
Changes in v2:
- Address git-filter-repo notes handling issue.
- Link to v1: https://patch.msgid.link/20250130201331.73584-1-yazen.ghannam@amd.com
---

Notes:
    Discussion:
    Why use git-filter-repo?
    
    Is it to rewrite history without user input?
    
    Git 2.44 allows 'rebase --autosquash' for non-interactive rebasing.
    https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/2.44.0.adoc
    
    Maybe this can be used in the future and git-filter-repo can be
    deprecated.

 src/b4/__init__.py |  1 +
 src/b4/ez.py       | 11 +++++++++++
 2 files changed, 12 insertions(+)


---
base-commit: c25d17121045ab14bec8912d490ba764b515b370
change-id: 20250407-add-git-notes-7cdca2caf472
diff mbox series

Patch

diff --git a/src/b4/__init__.py b/src/b4/__init__.py
index 99ece6484d8e..9e070b088413 100644
--- a/src/b4/__init__.py
+++ b/src/b4/__init__.py
@@ -3491,6 +3491,7 @@  def git_range_to_patches(gitdir: Optional[str], start: str, end: str,
             logger.debug('Ignoring commit %s', commit)
             continue
         showargs = [
+            '--notes',
             '--format=email',
             '--binary',
             '--patch-with-stat',
diff --git a/src/b4/ez.py b/src/b4/ez.py
index 156926aae33c..1e3f982f0d08 100644
--- a/src/b4/ez.py
+++ b/src/b4/ez.py
@@ -659,6 +659,7 @@  def store_cover(content: str, tracking: dict, new: bool = False) -> None:
             frf = fr.RepoFilter(args, commit_callback=fred.callback)
             logger.info('Invoking git-filter-repo to update the cover letter.')
             frf.run()
+            fred.update_notes()
 
     if strategy == 'branch-description':
         mybranch = b4.git_get_current_branch(None)
@@ -775,6 +776,15 @@  class FRCommitMessageEditor:
         if commit.original_id in self.edit_map:
             commit.message = self.edit_map[commit.original_id]
 
+    def update_notes(self):
+        fr_map_file = os.path.join('.git', 'filter-repo', 'commit-map')
+        with open(os.path.join(b4.git_get_toplevel(), fr_map_file), 'br') as f:
+            f.readline() # Skip header
+            args = ['notes', 'copy', '--force', '--stdin']
+            ecode, out = b4.git_run_command(None, args, stdin=f.read(), logstderr=True)
+            if ecode > 0:
+                logger.info('FAIL: update_notes: %s', out)
+
 
 def edit_cover() -> None:
     is_prep_branch(mustbe=True)
@@ -1208,6 +1218,7 @@  def update_trailers(cmdargs: argparse.Namespace) -> None:
     frf = fr.RepoFilter(args, commit_callback=fred.callback)
     logger.info('Invoking git-filter-repo to update trailers.')
     frf.run()
+    fred.update_notes()
     logger.info('Trailers updated.')