__init__.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. # Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors
  2. #
  3. # This module is part of GitPython and is released under the
  4. # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/
  5. # @PydevCodeAnalysisIgnore
  6. __all__ = [
  7. "Actor",
  8. "AmbiguousObjectName",
  9. "BadName",
  10. "BadObject",
  11. "BadObjectType",
  12. "BaseIndexEntry",
  13. "Blob",
  14. "BlobFilter",
  15. "BlockingLockFile",
  16. "CacheError",
  17. "CheckoutError",
  18. "CommandError",
  19. "Commit",
  20. "Diff",
  21. "DiffConstants",
  22. "DiffIndex",
  23. "Diffable",
  24. "FetchInfo",
  25. "Git",
  26. "GitCmdObjectDB",
  27. "GitCommandError",
  28. "GitCommandNotFound",
  29. "GitConfigParser",
  30. "GitDB",
  31. "GitError",
  32. "HEAD",
  33. "Head",
  34. "HookExecutionError",
  35. "INDEX",
  36. "IndexEntry",
  37. "IndexFile",
  38. "IndexObject",
  39. "InvalidDBRoot",
  40. "InvalidGitRepositoryError",
  41. "List", # Deprecated - import this from `typing` instead.
  42. "LockFile",
  43. "NULL_TREE",
  44. "NoSuchPathError",
  45. "ODBError",
  46. "Object",
  47. "Optional", # Deprecated - import this from `typing` instead.
  48. "ParseError",
  49. "PathLike",
  50. "PushInfo",
  51. "RefLog",
  52. "RefLogEntry",
  53. "Reference",
  54. "Remote",
  55. "RemoteProgress",
  56. "RemoteReference",
  57. "Repo",
  58. "RepositoryDirtyError",
  59. "RootModule",
  60. "RootUpdateProgress",
  61. "Sequence", # Deprecated - import from `typing`, or `collections.abc` in 3.9+.
  62. "StageType",
  63. "Stats",
  64. "Submodule",
  65. "SymbolicReference",
  66. "TYPE_CHECKING", # Deprecated - import this from `typing` instead.
  67. "Tag",
  68. "TagObject",
  69. "TagReference",
  70. "Tree",
  71. "TreeModifier",
  72. "Tuple", # Deprecated - import this from `typing` instead.
  73. "Union", # Deprecated - import this from `typing` instead.
  74. "UnmergedEntriesError",
  75. "UnsafeOptionError",
  76. "UnsafeProtocolError",
  77. "UnsupportedOperation",
  78. "UpdateProgress",
  79. "WorkTreeRepositoryUnsupported",
  80. "refresh",
  81. "remove_password_if_present",
  82. "rmtree",
  83. "safe_decode",
  84. "to_hex_sha",
  85. ]
  86. __version__ = '3.1.46'
  87. from typing import Any, List, Optional, Sequence, TYPE_CHECKING, Tuple, Union
  88. if TYPE_CHECKING:
  89. from types import ModuleType
  90. import warnings
  91. from gitdb.util import to_hex_sha
  92. from git.exc import (
  93. AmbiguousObjectName,
  94. BadName,
  95. BadObject,
  96. BadObjectType,
  97. CacheError,
  98. CheckoutError,
  99. CommandError,
  100. GitCommandError,
  101. GitCommandNotFound,
  102. GitError,
  103. HookExecutionError,
  104. InvalidDBRoot,
  105. InvalidGitRepositoryError,
  106. NoSuchPathError,
  107. ODBError,
  108. ParseError,
  109. RepositoryDirtyError,
  110. UnmergedEntriesError,
  111. UnsafeOptionError,
  112. UnsafeProtocolError,
  113. UnsupportedOperation,
  114. WorkTreeRepositoryUnsupported,
  115. )
  116. from git.types import PathLike
  117. try:
  118. from git.compat import safe_decode # @NoMove
  119. from git.config import GitConfigParser # @NoMove
  120. from git.objects import ( # @NoMove
  121. Blob,
  122. Commit,
  123. IndexObject,
  124. Object,
  125. RootModule,
  126. RootUpdateProgress,
  127. Submodule,
  128. TagObject,
  129. Tree,
  130. TreeModifier,
  131. UpdateProgress,
  132. )
  133. from git.refs import ( # @NoMove
  134. HEAD,
  135. Head,
  136. RefLog,
  137. RefLogEntry,
  138. Reference,
  139. RemoteReference,
  140. SymbolicReference,
  141. Tag,
  142. TagReference,
  143. )
  144. from git.diff import ( # @NoMove
  145. INDEX,
  146. NULL_TREE,
  147. Diff,
  148. DiffConstants,
  149. DiffIndex,
  150. Diffable,
  151. )
  152. from git.db import GitCmdObjectDB, GitDB # @NoMove
  153. from git.cmd import Git # @NoMove
  154. from git.repo import Repo # @NoMove
  155. from git.remote import FetchInfo, PushInfo, Remote, RemoteProgress # @NoMove
  156. from git.index import ( # @NoMove
  157. BaseIndexEntry,
  158. BlobFilter,
  159. CheckoutError,
  160. IndexEntry,
  161. IndexFile,
  162. StageType,
  163. # NOTE: This tells type checkers what util resolves to. We delete it, and it is
  164. # really resolved by __getattr__, which warns. See below on what to use instead.
  165. util,
  166. )
  167. from git.util import ( # @NoMove
  168. Actor,
  169. BlockingLockFile,
  170. LockFile,
  171. Stats,
  172. remove_password_if_present,
  173. rmtree,
  174. )
  175. except GitError as _exc:
  176. raise ImportError("%s: %s" % (_exc.__class__.__name__, _exc)) from _exc
  177. def _warned_import(message: str, fullname: str) -> "ModuleType":
  178. import importlib
  179. warnings.warn(message, DeprecationWarning, stacklevel=3)
  180. return importlib.import_module(fullname)
  181. def _getattr(name: str) -> Any:
  182. # TODO: If __version__ is made dynamic and lazily fetched, put that case right here.
  183. if name == "util":
  184. return _warned_import(
  185. "The expression `git.util` and the import `from git import util` actually "
  186. "reference git.index.util, and not the git.util module accessed in "
  187. '`from git.util import XYZ` or `sys.modules["git.util"]`. This potentially '
  188. "confusing behavior is currently preserved for compatibility, but may be "
  189. "changed in the future and should not be relied on.",
  190. fullname="git.index.util",
  191. )
  192. for names, prefix in (
  193. ({"head", "log", "reference", "symbolic", "tag"}, "git.refs"),
  194. ({"base", "fun", "typ"}, "git.index"),
  195. ):
  196. if name not in names:
  197. continue
  198. fullname = f"{prefix}.{name}"
  199. return _warned_import(
  200. f"{__name__}.{name} is a private alias of {fullname} and subject to "
  201. f"immediate removal. Use {fullname} instead.",
  202. fullname=fullname,
  203. )
  204. raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
  205. if not TYPE_CHECKING:
  206. # NOTE: The expression `git.util` gives git.index.util and `from git import util`
  207. # imports git.index.util, NOT git.util. It may not be feasible to change this until
  208. # the next major version, to avoid breaking code inadvertently relying on it.
  209. #
  210. # - If git.index.util *is* what you want, use (or import from) that, to avoid
  211. # confusion.
  212. #
  213. # - To use the "real" git.util module, write `from git.util import ...`, or if
  214. # necessary access it as `sys.modules["git.util"]`.
  215. #
  216. # Note also that `import git.util` technically imports the "real" git.util... but
  217. # the *expression* `git.util` after doing so is still git.index.util!
  218. #
  219. # (This situation differs from that of other indirect-submodule imports that are
  220. # unambiguously non-public and subject to immediate removal. Here, the public
  221. # git.util module, though different, makes less discoverable that the expression
  222. # `git.util` refers to a non-public attribute of the git module.)
  223. #
  224. # This had originally come about by a wildcard import. Now that all intended imports
  225. # are explicit, the intuitive but potentially incompatible binding occurs due to the
  226. # usual rules for Python submodule bindings. So for now we replace that binding with
  227. # git.index.util, delete that, and let __getattr__ handle it and issue a warning.
  228. #
  229. # For the same runtime behavior, it would be enough to forgo importing util, and
  230. # delete util as created naturally; __getattr__ would behave the same. But type
  231. # checkers would not know what util refers to when accessed as an attribute of git.
  232. del util
  233. # This is "hidden" to preserve static checking for undefined/misspelled attributes.
  234. __getattr__ = _getattr
  235. # { Initialize git executable path
  236. GIT_OK = None
  237. def refresh(path: Optional[PathLike] = None) -> None:
  238. """Convenience method for setting the git executable path.
  239. :param path:
  240. Optional path to the Git executable. If not absolute, it is resolved
  241. immediately, relative to the current directory.
  242. :note:
  243. The `path` parameter is usually omitted and cannot be used to specify a custom
  244. command whose location is looked up in a path search on each call. See
  245. :meth:`Git.refresh <git.cmd.Git.refresh>` for details on how to achieve this.
  246. :note:
  247. This calls :meth:`Git.refresh <git.cmd.Git.refresh>` and sets other global
  248. configuration according to the effect of doing so. As such, this function should
  249. usually be used instead of using :meth:`Git.refresh <git.cmd.Git.refresh>` or
  250. :meth:`FetchInfo.refresh <git.remote.FetchInfo.refresh>` directly.
  251. :note:
  252. This function is called automatically, with no arguments, at import time.
  253. """
  254. global GIT_OK
  255. GIT_OK = False
  256. if not Git.refresh(path=path):
  257. return
  258. if not FetchInfo.refresh(): # noqa: F405
  259. return # type: ignore[unreachable]
  260. GIT_OK = True
  261. try:
  262. refresh()
  263. except Exception as _exc:
  264. raise ImportError("Failed to initialize: {0}".format(_exc)) from _exc
  265. # } END initialize git executable path