"""Pydantic models of git objects.Warning--------Pydantic objects defined in this module are documented `here<../pydantic_models.html#git-objects>`_."""from__future__importannotationsimportabcfromenumimportEnumfromtypingimportClassVar,Optional,castfrompydanticimportBaseModel,ConfigDict,Field,computed_fieldfrom.constantsimportDictStrStrGitCommitRawDataType=dict[str,str|list[str]]"""Type of the data associated with a git commit object.value ``str`` is for the tree associated with a commitvalue ``list[str]`` is for the parents (there can be 0, 1 or many)."""#: Type of raw data associated with a git tree objectGitTreeRawDataType=list[DictStrStr]#: Type of raw data associated with a git tag objectGitTagRawDataType=DictStrStr
[docs]classGitObject(BaseModel,abc.ABC):"""A base class for git objects."""model_config=ConfigDict(extra="forbid")@property@abc.abstractmethoddefkind(self)->GitObjectKind:"""The object type."""@computed_field(repr=True)defis_ready(self)->bool:"""Indicates whether the object is ready to use. Note ----- See note in :func:`~git_dag.git_repository.GitInspector.get_raw_objects`. """returnself._is_ready# https://docs.pydantic.dev/2.0/usage/computed_fields/@is_ready.setter# type: ignore[no-redef]defis_ready(self,ready:bool)->None:self._is_ready=readysha:str_is_ready:bool=False
[docs]classGitTag(GitObject):"""Git (annotated) tag object."""model_config=ConfigDict(extra="forbid")kind:ClassVar[GitObjectKind]=GitObjectKind.tagname:strraw_data:GitTagRawDataType=Field(repr=False)# I keep track of deleted (annotated) tags that haven't been garbage-collectedis_deleted:bool=False_anchor:GitObject@propertydefanchor(self)->GitObject:"""Return the associated anchor. Note ----- An annotated tag can point to another tag: https://stackoverflow.com/a/19812276 """returnself._anchor@anchor.setterdefanchor(self,anchor:GitObject)->None:self._anchor=anchor@propertydeftagger(self)->str:"""Return tagger."""returnself.raw_data["taggername"]@propertydeftagger_email(self)->str:"""Return tagger email."""returnself.raw_data["taggeremail"]@propertydeftagger_date(self)->str:"""Return tagger date."""returnself.raw_data["taggerdate"]@propertydefmessage(self)->str:"""Return the message."""returnself.raw_data["message"]
[docs]classGitCommit(GitObject):"""Git commit object."""model_config=ConfigDict(extra="forbid")kind:ClassVar[GitObjectKind]=GitObjectKind.commitis_reachable:boolraw_data:GitCommitRawDataType=Field(repr=False)_tree:GitTree_parents:list[GitCommit]@propertydeftree(self)->GitTree:"""Return the associated tree (there can be exactly one)."""returnself._tree@tree.setterdeftree(self,tree:GitTree)->None:self._tree=tree@propertydefparents(self)->list[GitCommit]:"""Return the parents."""returnself._parents@parents.setterdefparents(self,parents:list[GitCommit])->None:self._parents=parents@propertydefauthor(self)->str:"""Return the author."""returncast(str,self.raw_data["author"])@propertydefauthor_email(self)->str:"""Return the author email."""returncast(str,self.raw_data["author_email"])@propertydefauthor_date(self)->str:"""Return the author date."""returncast(str,self.raw_data["author_date"])@propertydefcommitter(self)->str:"""Return the committer."""returncast(str,self.raw_data["committer"])@propertydefcommitter_email(self)->str:"""Return the committer email."""returncast(str,self.raw_data["committer_email"])@propertydefcommitter_date(self)->str:"""Return the committer date."""returncast(str,self.raw_data["committer_date"])@propertydefmessage(self)->str:"""Return the commit message."""returncast(str,self.raw_data["message"])
[docs]classGitTree(GitObject):"""Git tree object."""model_config=ConfigDict(extra="forbid")kind:ClassVar[GitObjectKind]=GitObjectKind.tree#: Raw data.raw_data:GitTreeRawDataType=Field(repr=False)#: Child trees and blobs._children:list[GitTree|GitBlob]# Set to True when it is known apriory that there would be no children# e.g., for the empty git tree objectno_children:bool=False@propertydefchildren(self)->list[GitTree|GitBlob]:"""Return the children."""ifself.no_children:return[]returnself._children@children.setterdefchildren(self,children:list[GitTree|GitBlob])->None:ifself.no_childrenandchildren:raiseTypeError("Attempting to set children when there should be none.")self._children=children
[docs]classGitTagLightweight(BaseModel):"""Git lightweight tag (this is not a ``GitObject``)."""model_config=ConfigDict(extra="forbid")name:stranchor:GitObject
classGitHead(BaseModel):"""A head (local or remote)."""model_config=ConfigDict(extra="forbid")commit:Optional[GitCommit]=Nonebranch:Optional[GitBranch]=None@propertydefis_defined(self)->bool:"""Is the HEAD defined."""returnself.commitisnotNone@propertydefis_detached(self)->bool:"""Is the HEAD detached."""returnself.branchisNonedef__repr__(self)->str:ifnotself.is_defined:return"None"ifself.is_detached:return"DETACHED"# type narrowing to make mypy happyassert(self.commitisnotNone)and(self.branchisnotNone)returnf"{self.commit.sha} ({self.branch.name})"