Jump to content

Rebase a close-to-mainline kernel

From postmarketOS Wiki

Ideally, all patches should be sent to the Linux Kernel Mailing List so that they can be incorporated into upstream Linux. However, there are times when you need to maintain your own kernel fork. This type of fork is often referred to as a close-to-mainline kernel. This guide explains how to rebase your patch stack onto a new upstream kernel version.

Configure git

This step is optional, and you only have to do it once. These configs help git handle large repository size more efficiently.

$ git config --global pack.threads 0
$ git config --global fetch.parallel 16
$ git config --global rerere.enabled true
  • pack.threads 0: use all available CPU cores when compressing data.
  • fetch.parallel 16: allow multiple fetch operations in parallel.
  • rerere.enabled true: enable reuse recorded resolution to remember how merge conflicts were resolved.

Add upstream remotes

The mainline repository contains the development branch managed by Linus Torvalds. Released kernel versions are in the stable repository.

$ git remote add mainline https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ git remote add stable https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

The Linux kernel repository is quite large, and depending on your location, kernel.org may be slow. In such cases you can use a mirror instead.

$ git remote add mainline https://github.com/torvalds/linux.git
$ git remote add stable https://github.com/gregkh/linux.git

Fetch the upstream release

This may take some time depending on your network.

$ git fetch --progress {remote} tag v{version} --no-tags
  • --progress: force show transfer progress.
  • {remote}: mainline or stable.
  • {version}: upstream kernel version you want to rebase onto.
  • --no-tags: avoid downloading all tags.

Verify the tag

After fetching, verify that the tag exists locally.

$ git show v{version}

Create a branch for upstream

Create a branch that points to the upstream release you will rebase onto.

$ git checkout -b upstream-v{version} v{version}

Switch to your kernel branch

Switch to your kernel branch that contains your patches.

$ git checkout {my-kernel-branch}

Rebase onto the new upstream

Rebase your patch stack onto the new upstream base. Git will replay your commits on top of upstream.

$ git rebase upstream-v{version}

Resolve merge conflicts

Most of the time there will be merge conflicts at this stage. You must adapt your patches to upstream changes by editing the affected files manually.

Once the conflict is resolved, mark it as such:

$ git add path/to/conflicting/file

Then continue the rebase:

$ git rebase --continue

Git will move to the next patch. Repeat until the rebase is complete.

Clean up the patch stack

You may have fixups or patches that are no longer necessary. Use an interactive rebase to clean up the history. You can reorder commits, squash related patches, or remove unnecessary ones.

$ git rebase -i upstream-v{version}