Search code examples
gitgit-rewrite-historygit-filter-repo

How to modify the list of parents in a git-filter-repo commit callback


How do I write a git-filter-repo commit callback to add a parent to a commit?

eg, something like:

git filter-repo --commit-callback 'if commit.original_id == b"123abc...": commit.parents.append(b"789def...")'

Rationale: Someone copied file contents and made a simple commit as if it were new work. I want to change their commit to a merge commit with two parents: the first being the existing parent, the second being the commit that I have identified by hand where they copied from.

I do not want to edit the commit message or the the tree, or try to perform any kind of real merging.

If this were simpler I could just use commit-tree with multiple -p options, but I want the additional features of git-filter-repo to recreate all my branches etc after the modification.

Bonus point: is there any documentation for the data and methods which are available to be modified when writing a git-filter-repo callback? I found many examples but no reference list.


Solution

  • Ok, so not knowing Python at all I wrote some pseudocode in the question, and @phd has helpfully pointed out in the comments that it actually runs:

    git filter-repo --commit-callback 'if commit.original_id == b"123abc...": commit.parents.append(b"789def...")'

    And the docs are here.

    Edit: However, because git-filter-repo internally treats each commit as a set of changes from its first parent, if you edit the first parent then you will also implicitly edit the tree object.

    In my case appending a parent only edited the first parent in the case of a commit that had no parents to begin with (an initial commit), so I had to use git commit-tree just for that case, and then git-filter-repo for the rest.