module documentation

Utilities for diffing files and trees.

Class RenameDetector Object for handling rename detection between two trees.
Class TreeChange Named tuple a single change between two trees.
Function tree_changes Find the differences between the contents of two trees.
Function tree_changes_for_merge Get the tree changes for a merge tree relative to all its parents.
Function walk_trees Recursively walk all the entries of two trees.
Constant CHANGE_ADD Undocumented
Constant CHANGE_COPY Undocumented
Constant CHANGE_DELETE Undocumented
Constant CHANGE_MODIFY Undocumented
Constant CHANGE_RENAME Undocumented
Constant CHANGE_UNCHANGED Undocumented
Constant MAX_FILES Undocumented
Constant RENAME_CHANGE_TYPES Undocumented
Constant RENAME_THRESHOLD Undocumented
Constant REWRITE_THRESHOLD Undocumented
Type Variable T Undocumented
Type Variable U Undocumented
Function _all_eq Undocumented
Function _all_same Undocumented
Function _common_bytes Count the number of common bytes in two block count dicts.
Function _count_blocks Count the blocks in an object.
Function _is_tree Undocumented
Function _merge_entries Merge the entries of two trees.
Function _similarity_score Compute a similarity score for two objects.
Function _skip_tree Undocumented
Function _tree_change_key Undocumented
Function _tree_entries Undocumented
Constant _BLOCK_SIZE Undocumented
Constant _MAX_SCORE Undocumented
def tree_changes(store: BaseObjectStore, tree1_id: ObjectID | None, tree2_id: ObjectID | None, want_unchanged: bool = False, rename_detector: RenameDetector | None = None, include_trees: bool = False, change_type_same: bool = False, paths: Sequence[bytes] | None = None) -> Iterator[TreeChange]:

Find the differences between the contents of two trees.

Parameters
store:BaseObjectStoreAn ObjectStore for looking up objects.
tree1_id:ObjectID | NoneThe SHA of the source tree.
tree2_id:ObjectID | NoneThe SHA of the target tree.
want_unchanged:boolIf True, include TreeChanges for unmodified entries as well.
rename_detector:RenameDetector | NoneRenameDetector object for detecting renames.
include_trees:boolWhether to include trees
change_type_same:boolWhether to report change types in the same entry or as delete+add.
paths:Sequence[bytes] | NoneOptional list of paths to filter to (as bytes).
Returns
Iterator[TreeChange]
Iterator over TreeChange instances for each change between the
source and target tree.
def tree_changes_for_merge(store: BaseObjectStore, parent_tree_ids: Sequence[ObjectID], tree_id: ObjectID, rename_detector: RenameDetector | None = None) -> Iterator[list[TreeChange | None]]:

Get the tree changes for a merge tree relative to all its parents.

Parameters
store:BaseObjectStoreAn ObjectStore for looking up objects.
parent_tree_ids:Sequence[ObjectID]An iterable of the SHAs of the parent trees.
tree_id:ObjectIDThe SHA of the merge tree.
rename_detector:RenameDetector | NoneRenameDetector object for detecting renames.
Returns
Iterator[list[TreeChange | None]]

Iterator over lists of TreeChange objects, one per conflicted path in the merge.

Each list contains one element per parent, with the TreeChange for that path relative to that parent. An element may be None if it never existed in one parent and was deleted in two others.

A path is only included in the output if it is a conflict, i.e. its SHA in the merge tree is not found in any of the parents, or in the case of deletes, if not all of the old SHAs match.

def walk_trees(store: BaseObjectStore, tree1_id: ObjectID | None, tree2_id: ObjectID | None, prune_identical: bool = False, paths: Sequence[bytes] | None = None) -> Iterator[tuple[TreeEntry | None, TreeEntry | None]]:

Recursively walk all the entries of two trees.

Iteration is depth-first pre-order, as in e.g. os.walk.

Parameters
store:BaseObjectStoreAn ObjectStore for looking up objects.
tree1_id:ObjectID | NoneThe SHA of the first Tree object to iterate, or None.
tree2_id:ObjectID | NoneThe SHA of the second Tree object to iterate, or None.
prune_identical:boolIf True, identical subtrees will not be walked.
paths:Sequence[bytes] | NoneOptional list of paths to filter to (as bytes).
Returns
Iterator[tuple[TreeEntry | None, TreeEntry | None]]
Iterator over Pairs of TreeEntry objects for each pair of entries
in the trees and their subtrees recursively. If an entry exists in one tree but not the other, the other entry will be None. If both entries exist, they are guaranteed to match.
CHANGE_ADD: str =

Undocumented

Value
'add'
CHANGE_COPY: str =

Undocumented

Value
'copy'
CHANGE_DELETE: str =

Undocumented

Value
'delete'
CHANGE_MODIFY: str =

Undocumented

Value
'modify'
CHANGE_RENAME: str =

Undocumented

Value
'rename'
CHANGE_UNCHANGED: str =

Undocumented

Value
'unchanged'
MAX_FILES: int =

Undocumented

Value
200
RENAME_CHANGE_TYPES =

Undocumented

Value
(CHANGE_RENAME, CHANGE_COPY)
RENAME_THRESHOLD: int =

Undocumented

Value
60
REWRITE_THRESHOLD: int | None =

Undocumented

Value
None
T =

Undocumented

Value
TypeVar('T')
U =

Undocumented

Value
TypeVar('U')
def _all_eq(seq: Sequence[T], key: Callable[[T], U], value: U) -> bool:

Undocumented

def _all_same(seq: Sequence[Any], key: Callable[[Any], Any]) -> bool:

Undocumented

def _common_bytes(blocks1: Mapping[int, int], blocks2: Mapping[int, int]) -> int:

Count the number of common bytes in two block count dicts.

Parameters
blocks1:Mapping[int, int]The first dict of block hashcode -> total bytes.
blocks2:Mapping[int, int]The second dict of block hashcode -> total bytes.
Returns
intThe number of bytes in common between blocks1 and blocks2. This is only approximate due to possible hash collisions.
def _count_blocks(obj: ShaFile) -> dict[int, int]:

Count the blocks in an object.

Splits the data into blocks either on lines or <=64-byte chunks of lines.

Parameters
obj:ShaFileThe object to count blocks for.
Returns
dict[int, int]A dict of block hashcode -> total bytes occurring.
def _is_tree(entry: TreeEntry | None) -> bool:

Undocumented

def _merge_entries(path: bytes, tree1: Tree, tree2: Tree) -> list[tuple[TreeEntry | None, TreeEntry | None]]:

Merge the entries of two trees.

Parameters
path:bytesA path to prepend to all tree entry names.
tree1:TreeThe first Tree object to iterate, or None.
tree2:TreeThe second Tree object to iterate, or None.
Returns
list[tuple[TreeEntry | None, TreeEntry | None]]
A list of pairs of TreeEntry objects for each pair of entries in
the trees. If an entry exists in one tree but not the other, the other entry will be None. If both entries exist, they are guaranteed to match.
def _similarity_score(obj1: ShaFile, obj2: ShaFile, block_cache: dict[ObjectID, dict[int, int]] | None = None) -> int:

Compute a similarity score for two objects.

Parameters
obj1:ShaFileThe first object to score.
obj2:ShaFileThe second object to score.
block_cache:dict[ObjectID, dict[int, int]] | NoneAn optional dict of SHA to block counts to cache results between calls.
Returns
int
The similarity score between the two objects, defined as the
number of bytes in common between the two objects divided by the maximum size, scaled to the range 0-100.
def _skip_tree(entry: TreeEntry | None, include_trees: bool) -> TreeEntry | None:

Undocumented

def _tree_change_key(entry: TreeChange) -> tuple[bytes, bytes]:

Undocumented

def _tree_entries(path: bytes, tree: Tree) -> list[TreeEntry]:

Undocumented

_BLOCK_SIZE: int =

Undocumented

Value
64
_MAX_SCORE: int =

Undocumented

Value
100