def __init__(self, working_dir=None): """Initialize this instance with: :param working_dir: Git directory we should work in. If None, we always work in the current directory as returned by os.getcwd(). It is meant to be the working tree directory if available, or the .git directory in case of bare repositories.""" super(Git, self).__init__() self._working_dir = expand_path(working_dir) self._git_options = () self._persistent_git_options = [] # Extra environment variables to pass to git commands self._environment = {} # cached command slots self.cat_file_header = None self.cat_file_all = None
def init(cls, path=None, mkdir=True, odbt=DefaultDBType, expand_vars=True, **kwargs): """Initialize a git repository at the given path if specified :param path: is the full path to the repo (traditionally ends with /<name>.git) or None in which case the repository will be created in the current working directory :parm mkdir: if specified will create the repository directory if it doesn't already exists. Creates the directory with a mode=0755. Only effective if a path is explicitly given :param odbt: Object DataBase type - a type which is constructed by providing the directory containing the database objects, i.e. .git/objects. It will be used to access all object data :param expand_vars: if specified, environment variables will not be escaped. This can lead to information disclosure, allowing attackers to access the contents of environment variables :parm kwargs: keyword arguments serving as additional options to the git-init command :return: ``git.Repo`` (the newly created repo)""" if path: path = expand_path(path, expand_vars) if mkdir and path and not osp.exists(path): os.makedirs(path, 0o755) # git command automatically chdir into the directory git = Git(path) git.init(**kwargs) return cls(path, odbt=odbt)
def init(cls, path=None, mkdir=True, odbt=GitCmdObjectDB, expand_vars=True, **kwargs): """Initialize a git repository at the given path if specified :param path: is the full path to the repo (traditionally ends with /<name>.git) or None in which case the repository will be created in the current working directory :param mkdir: if specified will create the repository directory if it doesn't already exists. Creates the directory with a mode=0755. Only effective if a path is explicitly given :param odbt: Object DataBase type - a type which is constructed by providing the directory containing the database objects, i.e. .git/objects. It will be used to access all object data :param expand_vars: if specified, environment variables will not be escaped. This can lead to information disclosure, allowing attackers to access the contents of environment variables :param kwargs: keyword arguments serving as additional options to the git-init command :return: ``git.Repo`` (the newly created repo)""" if path: path = expand_path(path, expand_vars) if mkdir and path and not osp.exists(path): os.makedirs(path, 0o755) # git command automatically chdir into the directory git = Git(path) git.init(**kwargs) return cls(path, odbt=odbt)
def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False, expand_vars=True): """Create a new Repo instance :param path: the path to either the root git directory or the bare git repo:: repo = Repo("/Users/mtrier/Development/git-python") repo = Repo("/Users/mtrier/Development/git-python.git") repo = Repo("~/Development/git-python.git") repo = Repo("$REPOSITORIES/Development/git-python.git") - In *Cygwin*, path may be a `'cygdrive/...'` prefixed path. - If it evaluates to false, :envvar:`GIT_DIR` is used, and if this also evals to false, the current-directory is used. :param odbt: Object DataBase type - a type which is constructed by providing the directory containing the database objects, i.e. .git/objects. It will be used to access all object data :param search_parent_directories: if True, all parent directories will be searched for a valid repo as well. Please note that this was the default behaviour in older versions of GitPython, which is considered a bug though. :raise InvalidGitRepositoryError: :raise NoSuchPathError: :return: git.Repo """ epath = path or os.getenv('GIT_DIR') if not epath: epath = os.getcwd() if Git.is_cygwin(): epath = decygpath(epath) epath = epath or path or os.getcwd() if expand_vars and ("%" in epath or "$" in epath): warnings.warn( "The use of environment variables in paths is deprecated" + "\nfor security reasons and may be removed in the future!!") epath = expand_path(epath, expand_vars) if not os.path.exists(epath): raise NoSuchPathError(epath) ## Walk up the path to find the `.git` dir. # curpath = epath while curpath: # ABOUT osp.NORMPATH # It's important to normalize the paths, as submodules will otherwise initialize their # repo instances with paths that depend on path-portions that will not exist after being # removed. It's just cleaner. if is_git_dir(curpath): self.git_dir = curpath self._working_tree_dir = os.getenv( 'GIT_WORK_TREE', os.path.dirname(self.git_dir)) break dotgit = osp.join(curpath, '.git') sm_gitpath = find_submodule_git_dir(dotgit) if sm_gitpath is not None: self.git_dir = osp.normpath(sm_gitpath) sm_gitpath = find_submodule_git_dir(dotgit) if sm_gitpath is None: sm_gitpath = find_worktree_git_dir(dotgit) if sm_gitpath is not None: self.git_dir = expand_path(sm_gitpath, expand_vars) self._working_tree_dir = curpath break if not search_parent_directories: break curpath, tail = osp.split(curpath) if not tail: break # END while curpath if self.git_dir is None: raise InvalidGitRepositoryError(epath) self._bare = False try: self._bare = self.config_reader("repository").getboolean( 'core', 'bare') except Exception: # lets not assume the option exists, although it should pass try: common_dir = open(osp.join(self.git_dir, 'commondir'), 'rt').readlines()[0].strip() self._common_dir = osp.join(self.git_dir, common_dir) except (OSError, IOError): self._common_dir = None # adjust the wd in case we are actually bare - we didn't know that # in the first place if self._bare: self._working_tree_dir = None # END working dir handling self.working_dir = self._working_tree_dir or self.common_dir self.git = self.GitCommandWrapperType(self.working_dir) # special handling, in special times args = [osp.join(self.common_dir, 'objects')] if issubclass(odbt, GitCmdObjectDB): args.append(self.git) self.odb = odbt(*args)
def __init__(self, path=None, odbt=GitCmdObjectDB, search_parent_directories=False, expand_vars=True): """Create a new Repo instance :param path: the path to either the root git directory or the bare git repo:: repo = Repo("/Users/mtrier/Development/git-python") repo = Repo("/Users/mtrier/Development/git-python.git") repo = Repo("~/Development/git-python.git") repo = Repo("$REPOSITORIES/Development/git-python.git") - In *Cygwin*, path may be a `'cygdrive/...'` prefixed path. - If it evaluates to false, :envvar:`GIT_DIR` is used, and if this also evals to false, the current-directory is used. :param odbt: Object DataBase type - a type which is constructed by providing the directory containing the database objects, i.e. .git/objects. It will be used to access all object data :param search_parent_directories: if True, all parent directories will be searched for a valid repo as well. Please note that this was the default behaviour in older versions of GitPython, which is considered a bug though. :raise InvalidGitRepositoryError: :raise NoSuchPathError: :return: git.Repo """ epath = path or os.getenv('GIT_DIR') if not epath: epath = os.getcwd() if Git.is_cygwin(): epath = decygpath(epath) epath = epath or path or os.getcwd() if not isinstance(epath, str): epath = str(epath) if expand_vars and ("%" in epath or "$" in epath): warnings.warn("The use of environment variables in paths is deprecated" + "\nfor security reasons and may be removed in the future!!") epath = expand_path(epath, expand_vars) if not os.path.exists(epath): raise NoSuchPathError(epath) ## Walk up the path to find the `.git` dir. # curpath = epath while curpath: # ABOUT osp.NORMPATH # It's important to normalize the paths, as submodules will otherwise initialize their # repo instances with paths that depend on path-portions that will not exist after being # removed. It's just cleaner. if is_git_dir(curpath): self.git_dir = curpath self._working_tree_dir = os.getenv('GIT_WORK_TREE', os.path.dirname(self.git_dir)) break dotgit = osp.join(curpath, '.git') sm_gitpath = find_submodule_git_dir(dotgit) if sm_gitpath is not None: self.git_dir = osp.normpath(sm_gitpath) sm_gitpath = find_submodule_git_dir(dotgit) if sm_gitpath is None: sm_gitpath = find_worktree_git_dir(dotgit) if sm_gitpath is not None: self.git_dir = expand_path(sm_gitpath, expand_vars) self._working_tree_dir = curpath break if not search_parent_directories: break curpath, tail = osp.split(curpath) if not tail: break # END while curpath if self.git_dir is None: raise InvalidGitRepositoryError(epath) self._bare = False try: self._bare = self.config_reader("repository").getboolean('core', 'bare') except Exception: # lets not assume the option exists, although it should pass try: common_dir = open(osp.join(self.git_dir, 'commondir'), 'rt').readlines()[0].strip() self._common_dir = osp.join(self.git_dir, common_dir) except (OSError, IOError): self._common_dir = None # adjust the wd in case we are actually bare - we didn't know that # in the first place if self._bare: self._working_tree_dir = None # END working dir handling self.working_dir = self._working_tree_dir or self.common_dir self.git = self.GitCommandWrapperType(self.working_dir) # special handling, in special times args = [osp.join(self.common_dir, 'objects')] if issubclass(odbt, GitCmdObjectDB): args.append(self.git) self.odb = odbt(*args)
def __init__(self, path: Optional[PathLike] = None, odbt: Type[GitCmdObjectDB] = GitCmdObjectDB, search_parent_directories: bool = False, expand_vars: bool = True) -> None: """Create a new Repo instance :param path: the path to either the root git directory or the bare git repo:: repo = Repo("/Users/mtrier/Development/git-python") repo = Repo("/Users/mtrier/Development/git-python.git") repo = Repo("~/Development/git-python.git") repo = Repo("$REPOSITORIES/Development/git-python.git") repo = Repo("C:\\Users\\mtrier\\Development\\git-python\\.git") - In *Cygwin*, path may be a `'cygdrive/...'` prefixed path. - If it evaluates to false, :envvar:`GIT_DIR` is used, and if this also evals to false, the current-directory is used. :param odbt: Object DataBase type - a type which is constructed by providing the directory containing the database objects, i.e. .git/objects. It will be used to access all object data :param search_parent_directories: if True, all parent directories will be searched for a valid repo as well. Please note that this was the default behaviour in older versions of GitPython, which is considered a bug though. :raise InvalidGitRepositoryError: :raise NoSuchPathError: :return: git.Repo """ epath = path or os.getenv('GIT_DIR') if not epath: epath = os.getcwd() if Git.is_cygwin(): epath = decygpath(epath) epath = epath or path or os.getcwd() if not isinstance(epath, str): epath = str(epath) if expand_vars and re.search(self.re_envvars, epath): warnings.warn("The use of environment variables in paths is deprecated" + "\nfor security reasons and may be removed in the future!!") epath = expand_path(epath, expand_vars) if epath is not None: if not os.path.exists(epath): raise NoSuchPathError(epath) ## Walk up the path to find the `.git` dir. # curpath = epath while curpath: # ABOUT osp.NORMPATH # It's important to normalize the paths, as submodules will otherwise initialize their # repo instances with paths that depend on path-portions that will not exist after being # removed. It's just cleaner. if is_git_dir(curpath): self.git_dir = curpath # from man git-config : core.worktree # Set the path to the root of the working tree. If GIT_COMMON_DIR environment # variable is set, core.worktree is ignored and not used for determining the # root of working tree. This can be overridden by the GIT_WORK_TREE environment # variable. The value can be an absolute path or relative to the path to the .git # directory, which is either specified by GIT_DIR, or automatically discovered. # If GIT_DIR is specified but none of GIT_WORK_TREE and core.worktree is specified, # the current working directory is regarded as the top level of your working tree. self._working_tree_dir = os.path.dirname(self.git_dir) if os.environ.get('GIT_COMMON_DIR') is None: gitconf = self.config_reader("repository") if gitconf.has_option('core', 'worktree'): self._working_tree_dir = gitconf.get('core', 'worktree') if 'GIT_WORK_TREE' in os.environ: self._working_tree_dir = os.getenv('GIT_WORK_TREE') break dotgit = osp.join(curpath, '.git') sm_gitpath = find_submodule_git_dir(dotgit) if sm_gitpath is not None: self.git_dir = osp.normpath(sm_gitpath) sm_gitpath = find_submodule_git_dir(dotgit) if sm_gitpath is None: sm_gitpath = find_worktree_git_dir(dotgit) if sm_gitpath is not None: self.git_dir = expand_path(sm_gitpath, expand_vars) self._working_tree_dir = curpath break if not search_parent_directories: break curpath, tail = osp.split(curpath) if not tail: break # END while curpath if self.git_dir is None: self.git_dir = cast(PathLike, self.git_dir) raise InvalidGitRepositoryError(epath) self._bare = False try: self._bare = self.config_reader("repository").getboolean('core', 'bare') except Exception: # lets not assume the option exists, although it should pass try: common_dir = open(osp.join(self.git_dir, 'commondir'), 'rt').readlines()[0].strip() self._common_dir = osp.join(self.git_dir, common_dir) except OSError: self._common_dir = None # adjust the wd in case we are actually bare - we didn't know that # in the first place if self._bare: self._working_tree_dir = None # END working dir handling self.working_dir = self._working_tree_dir or self.common_dir # type: Optional[PathLike] self.git = self.GitCommandWrapperType(self.working_dir) # special handling, in special times rootpath = osp.join(self.common_dir, 'objects') if issubclass(odbt, GitCmdObjectDB): self.odb = odbt(rootpath, self.git) else: self.odb = odbt(rootpath)