From e6e23ed24b35c6154b4ee0da5ae51cd5688e5e67 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Thu, 13 Oct 2016 15:35:51 +0200 Subject: cygwin, #533: Try to make it work with Cygwin's Git. + Make `Git.polish_url()` convert paths into Cygwin-friendly paths. + Add utility and soe TCs for funcs for detecting cygwin and converting abs-paths to `/cygdrive/c/...`. - Cygwin TCs failing: - PY2: err: 14, fail: 3 - PY3: err: 13, fail: 3 --- git/repo/base.py | 75 +++++++++++++++++++++++--------------------------------- 1 file changed, 30 insertions(+), 45 deletions(-) (limited to 'git/repo/base.py') diff --git a/git/repo/base.py b/git/repo/base.py index c5cdce7c..09380af8 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -4,39 +4,11 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.exc import ( - InvalidGitRepositoryError, - NoSuchPathError, - GitCommandError -) -from git.cmd import ( - Git, - handle_process_output -) -from git.refs import ( - HEAD, - Head, - Reference, - TagReference, -) -from git.objects import ( - Submodule, - RootModule, - Commit -) -from git.util import ( - Actor, - finalize_process -) -from git.index import IndexFile -from git.config import GitConfigParser -from git.remote import ( - Remote, - add_progress, - to_progress_instance -) - -from git.db import GitCmdObjectDB +from collections import namedtuple +import logging +import os +import re +import sys from gitdb.util import ( join, @@ -44,11 +16,9 @@ from gitdb.util import ( hex_to_bin ) -from .fun import ( - rev_parse, - is_git_dir, - find_git_dir, - touch, +from git.cmd import ( + Git, + handle_process_output ) from git.compat import ( text_type, @@ -58,12 +28,17 @@ from git.compat import ( range, is_win, ) +from git.config import GitConfigParser +from git.db import GitCmdObjectDB +from git.exc import InvalidGitRepositoryError, NoSuchPathError, GitCommandError +from git.index import IndexFile +from git.objects import Submodule, RootModule, Commit +from git.refs import HEAD, Head, Reference, TagReference +from git.remote import Remote, add_progress, to_progress_instance +from git.util import Actor, finalize_process + +from .fun import rev_parse, is_git_dir, find_git_dir, touch -import os -import sys -import re -import logging -from collections import namedtuple log = logging.getLogger(__name__) @@ -875,12 +850,22 @@ class Repo(object): progress = to_progress_instance(progress) odbt = kwargs.pop('odbt', odb_default_type) - proc = git.clone(url, path, with_extended_output=True, as_process=True, + + ## A bug win cygwin's Git, when `--bare` + # it prepends the basename of the `url` into the `path:: + # git clone --bare /cygwin/a/foo.git C:\\Work + # becomes:: + # git clone --bare /cygwin/a/foo.git /cygwin/a/C:\\Work + # + clone_path = (Git.polish_url(path) + if Git.is_cygwin() and 'bare' in kwargs + else path) + proc = git.clone(Git.polish_url(url), clone_path, with_extended_output=True, as_process=True, v=True, **add_progress(kwargs, git, progress)) if progress: handle_process_output(proc, None, progress.new_message_handler(), finalize_process) else: - (stdout, stderr) = proc.communicate() # FIXME: Will block of outputs are big! + (stdout, stderr) = proc.communicate() # FIXME: Will block if outputs are big! log.debug("Cmd(%s)'s unused stdout: %s", getattr(proc, 'args', ''), stdout) finalize_process(proc, stderr=stderr) -- cgit v1.2.1 From 57d053792d1cde6f97526d28abfae4928a61e20f Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Fri, 14 Oct 2016 12:09:24 +0200 Subject: cygwin, #533: Polish also --git-separate-dir - Cygwin TCs failing: - PY2: err: 13, fail: 3 - PY3: err: 12, fail: 3 --- git/repo/base.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'git/repo/base.py') diff --git a/git/repo/base.py b/git/repo/base.py index 09380af8..077ba4af 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -851,15 +851,18 @@ class Repo(object): odbt = kwargs.pop('odbt', odb_default_type) - ## A bug win cygwin's Git, when `--bare` - # it prepends the basename of the `url` into the `path:: - # git clone --bare /cygwin/a/foo.git C:\\Work + ## A bug win cygwin's Git, when `--bare` or `--separate-git-dir` + # it prepends the cwd or(?) the `url` into the `path, so:: + # git clone --bare /cygwin/d/foo.git C:\\Work # becomes:: - # git clone --bare /cygwin/a/foo.git /cygwin/a/C:\\Work + # git clone --bare /cygwin/d/foo.git /cygwin/d/C:\\Work # clone_path = (Git.polish_url(path) - if Git.is_cygwin() and 'bare' in kwargs + if Git.is_cygwin() and 'bare'in kwargs else path) + sep_dir = kwargs.get('separate_git_dir') + if sep_dir: + kwargs['separate_git_dir'] = Git.polish_url(sep_dir) proc = git.clone(Git.polish_url(url), clone_path, with_extended_output=True, as_process=True, v=True, **add_progress(kwargs, git, progress)) if progress: -- cgit v1.2.1 From 3b1cfcc629e856b1384b811b8cf30b92a1e34fe1 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Fri, 14 Oct 2016 16:43:52 +0200 Subject: cygwin, #533: Allow '/cygdrive/c/' paths on repo init - Cygwin TCs failing: - PY2: err: 13, fail: 2 - PY3: err: 12, fail: 2 --- git/repo/base.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'git/repo/base.py') diff --git a/git/repo/base.py b/git/repo/base.py index 077ba4af..6355615e 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -35,7 +35,7 @@ from git.index import IndexFile from git.objects import Submodule, RootModule, Commit from git.refs import HEAD, Head, Reference, TagReference from git.remote import Remote, add_progress, to_progress_instance -from git.util import Actor, finalize_process +from git.util import Actor, finalize_process, decygpath from .fun import rev_parse, is_git_dir, find_git_dir, touch @@ -99,6 +99,8 @@ class Repo(object): repo = Repo("~/Development/git-python.git") repo = Repo("$REPOSITORIES/Development/git-python.git") + In *Cygwin*, path may be a `'cygdrive/...'` prefixed path. + :param odbt: Object DataBase type - a type which is constructed by providing the directory containing the database objects, i.e. .git/objects. It will @@ -111,6 +113,9 @@ class Repo(object): :raise InvalidGitRepositoryError: :raise NoSuchPathError: :return: git.Repo """ + if path and Git.is_cygwin(): + path = decygpath(path) + epath = _expand_path(path or os.getcwd()) self.git = None # should be set for __del__ not to fail in case we raise if not os.path.exists(epath): -- cgit v1.2.1 From 0210e394e0776d0b7097bf666bebd690ed0c0e4f Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 15 Oct 2016 13:11:16 +0200 Subject: src: import os.path as osp --- git/repo/base.py | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) (limited to 'git/repo/base.py') diff --git a/git/repo/base.py b/git/repo/base.py index 6355615e..af923bde 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -10,12 +10,6 @@ import os import re import sys -from gitdb.util import ( - join, - isfile, - hex_to_bin -) - from git.cmd import ( Git, handle_process_output @@ -36,6 +30,13 @@ from git.objects import Submodule, RootModule, Commit from git.refs import HEAD, Head, Reference, TagReference from git.remote import Remote, add_progress, to_progress_instance from git.util import Actor, finalize_process, decygpath +from gitdb.util import ( + join, + isfile, + hex_to_bin +) + +import os.path as osp from .fun import rev_parse, is_git_dir, find_git_dir, touch @@ -54,7 +55,7 @@ __all__ = ('Repo',) def _expand_path(p): - return os.path.abspath(os.path.expandvars(os.path.expanduser(p))) + return osp.abspath(osp.expandvars(osp.expanduser(p))) class Repo(object): @@ -100,7 +101,7 @@ class Repo(object): repo = Repo("$REPOSITORIES/Development/git-python.git") In *Cygwin*, path may be a `'cygdrive/...'` prefixed path. - + :param odbt: Object DataBase type - a type which is constructed by providing the directory containing the database objects, i.e. .git/objects. It will @@ -118,7 +119,7 @@ class Repo(object): epath = _expand_path(path or os.getcwd()) self.git = None # should be set for __del__ not to fail in case we raise - if not os.path.exists(epath): + if not osp.exists(epath): raise NoSuchPathError(epath) self.working_dir = None @@ -128,24 +129,24 @@ class Repo(object): # walk up the path to find the .git dir while curpath: - # ABOUT os.path.NORMPATH + # 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 = os.path.normpath(curpath) - self._working_tree_dir = os.path.dirname(self.git_dir) + self.git_dir = osp.normpath(curpath) + self._working_tree_dir = osp.dirname(self.git_dir) break gitpath = find_git_dir(join(curpath, '.git')) if gitpath is not None: - self.git_dir = os.path.normpath(gitpath) + self.git_dir = osp.normpath(gitpath) self._working_tree_dir = curpath break if not search_parent_directories: break - curpath, dummy = os.path.split(curpath) + curpath, dummy = osp.split(curpath) if not dummy: break # END while curpath @@ -361,12 +362,12 @@ class Repo(object): if config_level == "system": return "/etc/gitconfig" elif config_level == "user": - config_home = os.environ.get("XDG_CONFIG_HOME") or os.path.join(os.environ.get("HOME", '~'), ".config") - return os.path.normpath(os.path.expanduser(join(config_home, "git", "config"))) + config_home = os.environ.get("XDG_CONFIG_HOME") or osp.join(os.environ.get("HOME", '~'), ".config") + return osp.normpath(osp.expanduser(join(config_home, "git", "config"))) elif config_level == "global": - return os.path.normpath(os.path.expanduser("~/.gitconfig")) + return osp.normpath(osp.expanduser("~/.gitconfig")) elif config_level == "repository": - return os.path.normpath(join(self.git_dir, "config")) + return osp.normpath(join(self.git_dir, "config")) raise ValueError("Invalid configuration level: %r" % config_level) @@ -511,11 +512,11 @@ class Repo(object): def _get_daemon_export(self): filename = join(self.git_dir, self.DAEMON_EXPORT_FILE) - return os.path.exists(filename) + return osp.exists(filename) def _set_daemon_export(self, value): filename = join(self.git_dir, self.DAEMON_EXPORT_FILE) - fileexists = os.path.exists(filename) + fileexists = osp.exists(filename) if value and not fileexists: touch(filename) elif not value and fileexists: @@ -532,7 +533,7 @@ class Repo(object): :return: list of strings being pathnames of alternates""" alternates_path = join(self.git_dir, 'objects', 'info', 'alternates') - if os.path.exists(alternates_path): + if osp.exists(alternates_path): with open(alternates_path, 'rb') as f: alts = f.read().decode(defenc) return alts.strip().splitlines() @@ -841,7 +842,7 @@ class Repo(object): :return: ``git.Repo`` (the newly created repo)""" if path: path = _expand_path(path) - if mkdir and path and not os.path.exists(path): + if mkdir and path and not osp.exists(path): os.makedirs(path, 0o755) # git command automatically chdir into the directory @@ -879,7 +880,7 @@ class Repo(object): # our git command could have a different working dir than our actual # environment, hence we prepend its working dir if required - if not os.path.isabs(path) and git.working_dir: + if not osp.isabs(path) and git.working_dir: path = join(git._working_dir, path) # adjust remotes - there may be operating systems which use backslashes, @@ -958,7 +959,7 @@ class Repo(object): """ if self.bare: return False - return os.path.isfile(os.path.join(self.working_tree_dir, '.git')) + return osp.isfile(osp.join(self.working_tree_dir, '.git')) rev_parse = rev_parse -- cgit v1.2.1 From b02662d4e870a34d2c6d97d4f702fcc1311e5177 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 15 Oct 2016 13:42:33 +0200 Subject: src: reduce needless deps to `gitdb.util` --- git/repo/base.py | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) (limited to 'git/repo/base.py') diff --git a/git/repo/base.py b/git/repo/base.py index af923bde..20b3fa27 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -29,12 +29,7 @@ from git.index import IndexFile from git.objects import Submodule, RootModule, Commit from git.refs import HEAD, Head, Reference, TagReference from git.remote import Remote, add_progress, to_progress_instance -from git.util import Actor, finalize_process, decygpath -from gitdb.util import ( - join, - isfile, - hex_to_bin -) +from git.util import Actor, finalize_process, decygpath, hex_to_bin import os.path as osp @@ -138,7 +133,7 @@ class Repo(object): self._working_tree_dir = osp.dirname(self.git_dir) break - gitpath = find_git_dir(join(curpath, '.git')) + gitpath = find_git_dir(osp.join(curpath, '.git')) if gitpath is not None: self.git_dir = osp.normpath(gitpath) self._working_tree_dir = curpath @@ -171,7 +166,7 @@ class Repo(object): self.git = self.GitCommandWrapperType(self.working_dir) # special handling, in special times - args = [join(self.git_dir, 'objects')] + args = [osp.join(self.git_dir, 'objects')] if issubclass(odbt, GitCmdObjectDB): args.append(self.git) self.odb = odbt(*args) @@ -193,12 +188,12 @@ class Repo(object): # Description property def _get_description(self): - filename = join(self.git_dir, 'description') + filename = osp.join(self.git_dir, 'description') with open(filename, 'rb') as fp: return fp.read().rstrip().decode(defenc) def _set_description(self, descr): - filename = join(self.git_dir, 'description') + filename = osp.join(self.git_dir, 'description') with open(filename, 'wb') as fp: fp.write((descr + '\n').encode(defenc)) @@ -363,11 +358,11 @@ class Repo(object): return "/etc/gitconfig" elif config_level == "user": config_home = os.environ.get("XDG_CONFIG_HOME") or osp.join(os.environ.get("HOME", '~'), ".config") - return osp.normpath(osp.expanduser(join(config_home, "git", "config"))) + return osp.normpath(osp.expanduser(osp.join(config_home, "git", "config"))) elif config_level == "global": return osp.normpath(osp.expanduser("~/.gitconfig")) elif config_level == "repository": - return osp.normpath(join(self.git_dir, "config")) + return osp.normpath(osp.join(self.git_dir, "config")) raise ValueError("Invalid configuration level: %r" % config_level) @@ -511,11 +506,11 @@ class Repo(object): return True def _get_daemon_export(self): - filename = join(self.git_dir, self.DAEMON_EXPORT_FILE) + filename = osp.join(self.git_dir, self.DAEMON_EXPORT_FILE) return osp.exists(filename) def _set_daemon_export(self, value): - filename = join(self.git_dir, self.DAEMON_EXPORT_FILE) + filename = osp.join(self.git_dir, self.DAEMON_EXPORT_FILE) fileexists = osp.exists(filename) if value and not fileexists: touch(filename) @@ -531,7 +526,7 @@ class Repo(object): """The list of alternates for this repo from which objects can be retrieved :return: list of strings being pathnames of alternates""" - alternates_path = join(self.git_dir, 'objects', 'info', 'alternates') + alternates_path = osp.join(self.git_dir, 'objects', 'info', 'alternates') if osp.exists(alternates_path): with open(alternates_path, 'rb') as f: @@ -551,9 +546,9 @@ class Repo(object): :note: The method does not check for the existance of the paths in alts as the caller is responsible.""" - alternates_path = join(self.git_dir, 'objects', 'info', 'alternates') + alternates_path = osp.join(self.git_dir, 'objects', 'info', 'alternates') if not alts: - if isfile(alternates_path): + if osp.isfile(alternates_path): os.remove(alternates_path) else: with open(alternates_path, 'wb') as f: @@ -582,7 +577,7 @@ class Repo(object): default_args.append(path) if index: # diff index against HEAD - if isfile(self.index.path) and \ + if osp.isfile(self.index.path) and \ len(self.git.diff('--cached', *default_args)): return True # END index handling @@ -881,7 +876,7 @@ class Repo(object): # our git command could have a different working dir than our actual # environment, hence we prepend its working dir if required if not osp.isabs(path) and git.working_dir: - path = join(git._working_dir, path) + path = osp.join(git._working_dir, path) # adjust remotes - there may be operating systems which use backslashes, # These might be given as initial paths, but when handling the config file -- cgit v1.2.1 From b2efa1b19061ad6ed9d683ba98a88b18bff3bfd9 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sun, 16 Oct 2016 02:44:37 +0200 Subject: cygwin, #533: FIX submodules detection (~10TCs fixed) + Decygpath sm's `.git` file contents. + Polish another path in `git add`; actually no main-code changes, just a replace \-->/ on a relative(!) path to make cygwin-git to work. - REGRESSION `test_git_submodules_and_add_sm_with_new_commit` asks for user/email settings. - Cygwin TCs failing: - PY2: err: 2, fail: 1 - PY3: err: 2, fail: 1 --- git/repo/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git/repo/base.py') diff --git a/git/repo/base.py b/git/repo/base.py index 20b3fa27..21d129e9 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -109,7 +109,7 @@ class Repo(object): :raise InvalidGitRepositoryError: :raise NoSuchPathError: :return: git.Repo """ - if path and Git.is_cygwin(): + if Git.is_cygwin(): path = decygpath(path) epath = _expand_path(path or os.getcwd()) -- cgit v1.2.1