Merge & Cherrypick

Repository.merge_base(oid1: Oid, oid2: Oid) Oid

Find as good common ancestors as possible for a merge. Returns None if there is no merge base between the commits

Repository.merge(id: Oid)

Merges the given id into HEAD.

Merges the given commit(s) into HEAD, writing the results into the working directory. Any changes are staged for commit and any conflicts are written to the index. Callers should inspect the repository’s index after this completes, resolve any conflicts and prepare a commit.

Repository.merge_analysis(their_head: Oid, our_ref: str = 'HEAD') tuple[int, int]

Analyzes the given branch and determines the opportunities for merging it into a reference (defaults to HEAD).

Parameters:

our_ref

The reference name (String) to perform the analysis from

their_head

Head (commit Oid) to merge into

The first returned value is a mixture of the GIT_MERGE_ANALYSIS_NONE, _NORMAL, _UP_TO_DATE, _FASTFORWARD and _UNBORN flags. The second value is the user’s preference from ‘merge.ff’

The merge method

The method does a merge over the current working copy. It gets an Oid object as a parameter.

As its name says, it only does the merge, does not commit nor update the branch reference in the case of a fastforward.

For the moment, the merge does not support options, it will perform the merge with the default ones defined in GIT_MERGE_OPTS_INIT libgit2 constant.

Example:

>>> other_branch_tip = '5ebeeebb320790caf276b9fc8b24546d63316533'
>>> repo.merge(other_branch_tip)

You can now inspect the index file for conflicts and get back to the user to resolve if there are. Once there are no conflicts left, you can create a commit with these two parents.

>>> user = repo.default_signature
>>> tree = repo.index.write_tree()
>>> message = "Merging branches"
>>> new_commit = repo.create_commit('HEAD', user, user, message, tree,
                                    [repo.head.target, other_branch_tip])

Cherrypick

Repository.cherrypick(id: Oid)

Cherry-pick the given oid, producing changes in the index and working directory.

Merges the given commit into HEAD as a cherrypick, writing the results into the working directory. Any changes are staged for commit and any conflicts are written to the index. Callers should inspect the repository’s index after this completes, resolve any conflicts and prepare a commit.

Note that after a successful cherrypick you have to run Repository.state_cleanup() in order to get the repository out of cherrypicking mode.

Lower-level methods

These methods allow more direct control over how to perform the merging. They do not modify the working directory and return an in-memory Index representing the result of the merge.

Repository.merge_commits(ours, theirs, favor='normal', flags={}, file_flags={})

Merge two arbitrary commits.

Returns: an index with the result of the merge.

Parameters:

ours

The commit to take as “ours” or base.

theirs

The commit which will be merged into “ours”

favor

How to deal with file-level conflicts. Can be one of

  • normal (default). Conflicts will be preserved.

  • ours. The “ours” side of the conflict region is used.

  • theirs. The “theirs” side of the conflict region is used.

  • union. Unique lines from each side will be used.

For all but NORMAL, the index will not record a conflict.

flags

A dict of str: bool to turn on or off functionality while merging. If a key is not present, the default will be used. The keys are:

  • find_renames. Detect file renames. Defaults to True.

  • fail_on_conflict. If a conflict occurs, exit immediately instead of attempting to continue resolving conflicts.

  • skip_reuc. Do not write the REUC extension on the generated index.

  • no_recursive. If the commits being merged have multiple merge bases, do not build a recursive merge base (by merging the multiple merge bases), instead simply use the first base.

file_flags

A dict of str: bool to turn on or off functionality while merging. If a key is not present, the default will be used. The keys are:

  • standard_style. Create standard conflicted merge files.

  • diff3_style. Create diff3-style file.

  • simplify_alnum. Condense non-alphanumeric regions for simplified diff file.

  • ignore_whitespace. Ignore all whitespace.

  • ignore_whitespace_change. Ignore changes in amount of whitespace.

  • ignore_whitespace_eol. Ignore whitespace at end of line.

  • patience. Use the “patience diff” algorithm

  • minimal. Take extra time to find minimal diff

Both “ours” and “theirs” can be any object which peels to a commit or the id (string or Oid) of an object which peels to a commit.

Repository.merge_trees(ancestor, ours, theirs, favor='normal', flags={}, file_flags={})

Merge two trees.

Returns: an Index that reflects the result of the merge.

Parameters:

ancestor

The tree which is the common ancestor between ‘ours’ and ‘theirs’.

ours

The commit to take as “ours” or base.

theirs

The commit which will be merged into “ours”.

favor

How to deal with file-level conflicts. Can be one of:

  • normal (default). Conflicts will be preserved.

  • ours. The “ours” side of the conflict region is used.

  • theirs. The “theirs” side of the conflict region is used.

  • union. Unique lines from each side will be used.

For all but NORMAL, the index will not record a conflict.

flags

A dict of str: bool to turn on or off functionality while merging. If a key is not present, the default will be used. The keys are:

  • find_renames. Detect file renames. Defaults to True.

  • fail_on_conflict. If a conflict occurs, exit immediately instead of attempting to continue resolving conflicts.

  • skip_reuc. Do not write the REUC extension on the generated index.

  • no_recursive. If the commits being merged have multiple merge bases, do not build a recursive merge base (by merging the multiple merge bases), instead simply use the first base.

file_flags

A dict of str: bool to turn on or off functionality while merging. If a key is not present, the default will be used. The keys are:

  • standard_style. Create standard conflicted merge files.

  • diff3_style. Create diff3-style file.

  • simplify_alnum. Condense non-alphanumeric regions for simplified diff file.

  • ignore_whitespace. Ignore all whitespace.

  • ignore_whitespace_change. Ignore changes in amount of whitespace.

  • ignore_whitespace_eol. Ignore whitespace at end of line.

  • patience. Use the “patience diff” algorithm

  • minimal. Take extra time to find minimal diff

N-way merges

The following methods perform the calculation for a base to an n-way merge.

Repository.merge_base_many(oids: list[Oid]) Oid

Find as good common ancestors as possible for an n-way merge. Returns None if there is no merge base between the commits

Repository.merge_base_octopus(oids: list[Oid]) Oid

Find as good common ancestors as possible for an n-way octopus merge. Returns None if there is no merge base between the commits

With this base at hand one can do repeated invokations of Repository.merge_commits() and Repository.merge_trees() to perform the actual merge into one tree (and deal with conflicts along the way).