Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3b1cfcc

Browse filesBrowse files
committed
cygwin, #533: Allow '/cygdrive/c/' paths on repo init
- Cygwin TCs failing: - PY2: err: 13, fail: 2 - PY3: err: 12, fail: 2
1 parent 57d0537 commit 3b1cfcc
Copy full SHA for 3b1cfcc

File tree

4 files changed

+75
-29
lines changed
Filter options

4 files changed

+75
-29
lines changed

‎git/repo/base.py

Copy file name to clipboardExpand all lines: git/repo/base.py
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
from git.objects import Submodule, RootModule, Commit
3636
from git.refs import HEAD, Head, Reference, TagReference
3737
from git.remote import Remote, add_progress, to_progress_instance
38-
from git.util import Actor, finalize_process
38+
from git.util import Actor, finalize_process, decygpath
3939

4040
from .fun import rev_parse, is_git_dir, find_git_dir, touch
4141

@@ -99,6 +99,8 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals
9999
repo = Repo("~/Development/git-python.git")
100100
repo = Repo("$REPOSITORIES/Development/git-python.git")
101101
102+
In *Cygwin*, path may be a `'cygdrive/...'` prefixed path.
103+
102104
:param odbt:
103105
Object DataBase type - a type which is constructed by providing
104106
the directory containing the database objects, i.e. .git/objects. It will
@@ -111,6 +113,9 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals
111113
:raise InvalidGitRepositoryError:
112114
:raise NoSuchPathError:
113115
:return: git.Repo """
116+
if path and Git.is_cygwin():
117+
path = decygpath(path)
118+
114119
epath = _expand_path(path or os.getcwd())
115120
self.git = None # should be set for __del__ not to fail in case we raise
116121
if not os.path.exists(epath):

‎git/test/test_repo.py

Copy file name to clipboardExpand all lines: git/test/test_repo.py
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
assert_true,
5151
raises
5252
)
53-
from git.util import HIDE_WINDOWS_KNOWN_ERRORS
53+
from git.util import HIDE_WINDOWS_KNOWN_ERRORS, cygpath
5454
from git.test.lib import with_rw_directory
5555
from git.util import join_path_native, rmtree, rmfile
5656
from gitdb.util import bin_to_hex
@@ -913,6 +913,8 @@ def test_work_tree_unsupported(self, rw_dir):
913913
rw_master = self.rorepo.clone(join_path_native(rw_dir, 'master_repo'))
914914
rw_master.git.checkout('HEAD~10')
915915
worktree_path = join_path_native(rw_dir, 'worktree_repo')
916+
if Git.is_cygwin():
917+
worktree_path = cygpath(worktree_path)
916918
try:
917919
rw_master.git.worktree('add', worktree_path, 'master')
918920
except Exception as ex:

‎git/test/test_util.py

Copy file name to clipboardExpand all lines: git/test/test_util.py
+53-26Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,34 @@
2929
Actor,
3030
IterableList,
3131
cygpath,
32+
decygpath
33+
)
34+
35+
36+
_norm_cygpath_pairs = (
37+
(r'foo\bar', 'foo/bar'),
38+
(r'foo/bar', 'foo/bar'),
39+
40+
(r'C:\Users', '/cygdrive/c/Users'),
41+
(r'C:\d/e', '/cygdrive/c/d/e'),
42+
43+
('C:\\', '/cygdrive/c/'),
44+
45+
(r'\\server\C$\Users', '//server/C$/Users'),
46+
(r'\\server\C$', '//server/C$'),
47+
('\\\\server\\c$\\', '//server/c$/'),
48+
(r'\\server\BAR/', '//server/BAR/'),
49+
50+
(r'D:/Apps', '/cygdrive/d/Apps'),
51+
(r'D:/Apps\fOO', '/cygdrive/d/Apps/fOO'),
52+
(r'D:\Apps/123', '/cygdrive/d/Apps/123'),
53+
)
54+
55+
_unc_cygpath_pairs = (
56+
(r'\\?\a:\com', '/cygdrive/a/com'),
57+
(r'\\?\a:/com', '/cygdrive/a/com'),
58+
59+
(r'\\?\UNC\server\D$\Apps', '//server/D$/Apps'),
3260
)
3361

3462

@@ -54,46 +82,45 @@ def setup(self):
5482
"array": [42],
5583
}
5684

85+
@skipIf(not is_win, "Paths specifically for Windows.")
86+
@ddt.idata(_norm_cygpath_pairs + _unc_cygpath_pairs)
87+
def test_cygpath_ok(self, case):
88+
wpath, cpath = case
89+
cwpath = cygpath(wpath)
90+
self.assertEqual(cwpath, cpath, wpath)
91+
5792
@skipIf(not is_win, "Paths specifically for Windows.")
5893
@ddt.data(
59-
(r'foo\bar', 'foo/bar'),
60-
(r'foo/bar', 'foo/bar'),
6194
(r'./bar', 'bar'),
6295
(r'.\bar', 'bar'),
6396
(r'../bar', '../bar'),
6497
(r'..\bar', '../bar'),
6598
(r'../bar/.\foo/../chu', '../bar/chu'),
66-
67-
(r'C:\Users', '/cygdrive/c/Users'),
68-
(r'C:\d/e', '/cygdrive/c/d/e'),
69-
70-
(r'\\?\a:\com', '/cygdrive/a/com'),
71-
(r'\\?\a:/com', '/cygdrive/a/com'),
72-
73-
(r'\\server\C$\Users', '//server/C$/Users'),
74-
(r'\\server\C$', '//server/C$'),
75-
(r'\\server\BAR/', '//server/BAR/'),
76-
(r'\\?\UNC\server\D$\Apps', '//server/D$/Apps'),
77-
78-
(r'D:/Apps', '/cygdrive/d/Apps'),
79-
(r'D:/Apps\fOO', '/cygdrive/d/Apps/fOO'),
80-
(r'D:\Apps/123', '/cygdrive/d/Apps/123'),
8199
)
82-
def test_cygpath_ok(self, case):
100+
def test_cygpath_norm_ok(self, case):
83101
wpath, cpath = case
84-
self.assertEqual(cygpath(wpath), cpath or wpath)
102+
cwpath = cygpath(wpath)
103+
self.assertEqual(cwpath, cpath or wpath, wpath)
85104

86105
@skipIf(not is_win, "Paths specifically for Windows.")
87106
@ddt.data(
88-
(r'C:Relative', None),
89-
(r'D:Apps\123', None),
90-
(r'D:Apps/123', None),
91-
(r'\\?\a:rel', None),
92-
(r'\\share\a:rel', None),
107+
r'C:',
108+
r'C:Relative',
109+
r'D:Apps\123',
110+
r'D:Apps/123',
111+
r'\\?\a:rel',
112+
r'\\share\a:rel',
93113
)
94-
def test_cygpath_invalids(self, case):
114+
def test_cygpath_invalids(self, wpath):
115+
cwpath = cygpath(wpath)
116+
self.assertEqual(cwpath, wpath.replace('\\', '/'), wpath)
117+
118+
@skipIf(not is_win, "Paths specifically for Windows.")
119+
@ddt.idata(_norm_cygpath_pairs)
120+
def test_decygpath(self, case):
95121
wpath, cpath = case
96-
self.assertEqual(cygpath(wpath), cpath or wpath.replace('\\', '/'))
122+
wcpath = decygpath(cpath)
123+
self.assertEqual(wcpath, wpath.replace('/', '\\'), cpath)
97124

98125
def test_it_should_dashify(self):
99126
assert_equal('this-is-my-argument', dashify('this_is_my_argument'))

‎git/util.py

Copy file name to clipboardExpand all lines: git/util.py
+13-1Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def _cygexpath(drive, path):
222222
# It's an error, leave it alone just slashes)
223223
p = path
224224
else:
225-
p = osp.normpath(osp.expandvars(os.path.expanduser(path)))
225+
p = path and osp.normpath(osp.expandvars(os.path.expanduser(path)))
226226
if osp.isabs(p):
227227
if drive:
228228
# Confusing, maybe a remote system should expand vars.
@@ -278,6 +278,18 @@ def cygpath(path):
278278
return path
279279

280280

281+
_decygpath_regex = re.compile(r"/cygdrive/(\w)(/.*)?")
282+
283+
284+
def decygpath(path):
285+
m = _decygpath_regex.match(path)
286+
if m:
287+
drive, rest_path = m.groups()
288+
path = '%s:%s' % (drive.upper(), rest_path or '')
289+
290+
return path.replace('/', '\\')
291+
292+
281293
#: Store boolean flags denoting if a specific Git executable
282294
#: is from a Cygwin installation (since `cache_lru()` unsupported on PY2).
283295
_is_cygwin_cache = {}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.