Rebase

Repository.rebase_init(branch: Reference | Commit | Oid | None = None, upstream: Reference | Commit | Oid | None = None, onto: Reference | Commit | Oid | None = None, *, inmemory: bool = False, quiet: bool = False, rewrite_notes_ref: str | None = None, favor: MergeFavor = MergeFavor.NORMAL, flags: MergeFlag = <MergeFlag.FIND_RENAMES: 1>, file_flags: MergeFileFlag = <MergeFileFlag.DEFAULT: 0>, checkout_strategy: CheckoutStrategy | None = None, ancestor_label: str | None = None, our_label: str | None = None, their_label: str | None = None) Rebase

Initialize a rebase operation to rebase the changes in branch relative to upstream onto another branch, and return a Rebase object. To begin the rebase process, iterate over it; commit each successful operation with Rebase.commit(), then call Rebase.finish() or Rebase.abort().

Parameters:

branch

The terminal commit to rebase: a Reference, Commit, or commit Oid. None means rebase the current branch.

upstream

The commit to begin rebasing from. None means rebase all reachable commits.

onto

The branch to rebase onto. None means rebase onto the given upstream.

inmemory

Begin an in-memory rebase, which will allow callers to step through the rebase operations and commit the rebased changes, but will not rewind HEAD or update the repository to be in a rebasing state. This will not interfere with the working directory.

quiet

Instruct other clients working on this rebase that you want a quiet rebase experience. This has no effect upon libgit2 directly, but is provided for interoperability between Git tools.

rewrite_notes_ref

Name of the notes reference used to rewrite notes for rebased commits when finishing the rebase. If None, the notes.rewriteRef configuration option is examined.

favor

An enums.MergeFavor constant specifying how to deal with file-level conflicts. For all but NORMAL, the index will not record a conflict.

flags

A combination of enums.MergeFlag constants.

file_flags

A combination of enums.MergeFileFlag constants. For example, MergeFileFlag.STYLE_DIFF3 asks for conflict markers that include the common ancestor content.

checkout_strategy

A CheckoutStrategy value controlling how files are written during Rebase.__next__() and Rebase.abort(), or None for libgit2’s default.

ancestor_label, our_label, their_label

Override the labels used in conflict markers. By default libgit2 labels the “ours” side with the name of the branch being rebased onto, and the “theirs” side with the summary of the commit being replayed.

Repository.rebase_open(*, inmemory: bool = False, quiet: bool = False, rewrite_notes_ref: str | None = None, favor: MergeFavor = MergeFavor.NORMAL, flags: MergeFlag = <MergeFlag.FIND_RENAMES: 1>, file_flags: MergeFileFlag = <MergeFileFlag.DEFAULT: 0>, checkout_strategy: CheckoutStrategy | None = None, ancestor_label: str | None = None, our_label: str | None = None, their_label: str | None = None) Rebase

Open an existing rebase that was previously started by either an invocation of rebase_init() or by another client.

The keyword arguments have the same meaning as in rebase_init().

The Rebase type

class pygit2.Rebase(repo: BaseRepository, crebase: GitRebaseC, refs: list)

An in-progress rebase.

Returned by Repository.rebase_init() and Repository.rebase_open(). Iterating over this object performs the rebase operations one by one; each must be committed with commit(), after resolving any conflicts that were left in the repository’s index. Finalize with finish(), or roll everything back with abort().

__getitem__(index: int) RebaseOperation

The rebase operation at the given index.

__len__() int

The total number of rebase operations.

__next__() RebaseOperation

Perform the next rebase operation and return it.

If the operation is one that applies a patch (which is any operation except RebaseOperationType.EXEC) then the patch will be applied and the index and working directory will be updated with the changes. If there are conflicts, you will need to address those before calling commit().

Raises StopIteration when there are no more operations to perform.

abort() None

Abort the rebase, resetting the repository and working directory to their state before the rebase began.

commit(committer: Signature, author: Signature | None = None, message: str | None = None) Oid | None

Commit the current patch and return the id of the new commit, or None if the current commit has already been applied to the upstream and there is nothing to commit — mirroring how git rebase skips already-applied patches. You must have resolved any conflicts that were introduced during the patch application from the last __next__() invocation.

Raises GitError if there are unmerged changes in the index.

Parameters:

committerSignature

The committer of the rebase.

authorSignature

The author of the updated commit, or None to keep the author from the original commit.

messagestr

The message for this commit, or None to use the message from the original commit.

property current_index: int | None

The index of the rebase operation that is currently being applied, or None if the first operation has not yet been applied (because __next__() has not been called yet).

finish(signature: Signature | None = None) None

Finish the rebase once all patches have been applied.

Parameters:

signatureSignature

The identity that is finishing the rebase (optional).

property inmemory_index: Index

The index produced by the last operation, which is the result of __next__() and which will be committed by the next invocation of commit(). This is useful for resolving conflicts in an in-memory rebase before committing them.

This is only applicable for in-memory rebases; for rebases within a working directory, the changes were applied to the repository’s index.

property onto_id: Oid

The onto id.

property onto_name: str | None

The onto ref name.

property orig_head_id: Oid

The original HEAD id.

property orig_head_name: str | None

The original HEAD ref name.

class pygit2.RebaseOperation(type: RebaseOperationType, id: Oid, exec: str | None)

A single instruction to be performed during a rebase.

exec

The executable the user has requested be run. This will only be populated for operations of type RebaseOperationType.EXEC.

id

The commit ID being cherry-picked. For operations of type RebaseOperationType.EXEC this is the zero OID.

type

The type of rebase operation.

Example

Rebase the current branch onto its upstream:

>>> committer = repo.default_signature
>>> rebase = repo.rebase_init(upstream=repo.branches['origin/master'])
>>> for operation in rebase:
...     # If repo.index.conflicts is not None at this point, the
...     # operation left conflicts in the index and conflict markers
...     # in the working directory.  Resolve them, stage each
...     # resolution with repo.index.add(path), and only then commit.
...     rebase.commit(committer=committer)
>>> rebase.finish(committer)

Use abort() instead of finish() to reset the repository and the working directory to their state before the rebase began.

commit() returns None for a patch that turns out to be already present upstream; like git rebase, simply move on to the next operation.

With inmemory=True the rebase does not touch HEAD, the repository state, or the working directory; each step’s result is available as rebase.inmemory_index and updating the branch reference afterwards is the caller’s responsibility.

Working with rebase operations

Iterating over a Rebase yields a RebaseOperation describing each step. len() and indexing expose the same operations up front, without advancing the rebase, so the plan can be inspected before applying it:

>>> rebase = repo.rebase_init(upstream=repo.branches['origin/master'])
>>> for i in range(len(rebase)):
...     print(rebase[i])
<pygit2.RebaseOperation PICK 4a3fe06...>
<pygit2.RebaseOperation PICK 8ae4a25...>

A rebase started with rebase_init() replays the non-merge commits in upstream..branch; merge commits are skipped, linearizing the history, just like plain git rebase (libgit2 has no equivalent of --rebase-merges). Every operation’s type is therefore RebaseOperationType.PICK, id names the original commit being replayed, and exec is None. The remaining RebaseOperationType values mirror the verbs of git’s interactive rebase, which libgit2 does not implement (as of 1.9): they are declared for completeness but never produced. Looking the original commit up is useful for progress reporting or for reusing its metadata:

>>> from pygit2.enums import RebaseOperationType
>>> committer = repo.default_signature
>>> for operation in rebase:
...     assert operation.type == RebaseOperationType.PICK
...     original = repo[operation.id]
...     step, total = rebase.current_index + 1, len(rebase)
...     print(f'[{step}/{total}] picking {original.short_id}:',
...           original.message.strip())
...     rebase.commit(committer=committer)
[1/2] picking 4a3fe06: Add feature
[2/2] picking 8ae4a25: Fix tests
>>> rebase.finish(committer)