Skip to content

Commit ce344df

Browse files
committed
MINGW, gitpython-developers#525: FIX remote urls in config-files
+ Parse all config-urls \-->/. + Used relative daemon-paths. + Use git-daemon PORT above 10k; on Windows all below need Admin rights. +FIXED git-daemon @with_rw_and_rw_remote_repo(): + test_base.test_with_rw_remote_and_rw_repo() PASS. + test_remote.test_base() now freezes! (so still hidden win_err) + repo_test: minor finally delete test-repos created inside this repo.
1 parent 0fb10e4 commit ce344df

File tree

9 files changed

+77
-61
lines changed

9 files changed

+77
-61
lines changed

git/cmd.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,18 @@ def __setstate__(self, d):
181181
# Override this value using `Git.USE_SHELL = True`
182182
USE_SHELL = False
183183

184-
class AutoInterrupt(object):
184+
@classmethod
185+
def polish_url(cls, url):
186+
return url.replace("\\\\", "\\").replace("\\", "/")
185187

188+
class AutoInterrupt(object):
186189
"""Kill/Interrupt the stored process instance once this instance goes out of scope. It is
187190
used to prevent processes piling up in case iterators stop reading.
188191
Besides all attributes are wired through to the contained process object.
189192
190193
The wait method was overridden to perform automatic status code checking
191194
and possibly raise."""
195+
192196
__slots__ = ("proc", "args")
193197

194198
def __init__(self, proc, args):

git/remote.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
join_path,
3030
finalize_process
3131
)
32-
from git.cmd import handle_process_output
32+
from git.cmd import handle_process_output, Git
3333
from gitdb.util import join
3434
from git.compat import (defenc, force_text, is_win)
3535
import logging
@@ -570,7 +570,7 @@ def create(cls, repo, name, url, **kwargs):
570570
:raise GitCommandError: in case an origin with that name already exists"""
571571
scmd = 'add'
572572
kwargs['insert_kwargs_after'] = scmd
573-
repo.git.remote(scmd, name, url, **kwargs)
573+
repo.git.remote(scmd, name, Git.polish_url(url), **kwargs)
574574
return cls(repo, name)
575575

576576
# add is an alias

git/repo/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,7 @@ def _clone(cls, git, url, path, odb_default_type, progress, **kwargs):
897897
repo = cls(path, odbt=odbt)
898898
if repo.remotes:
899899
with repo.remotes[0].config_writer as writer:
900-
writer.set_value('url', repo.remotes[0].url.replace("\\\\", "\\").replace("\\", "/"))
900+
writer.set_value('url', Git.polish_url(repo.remotes[0].url))
901901
# END handle remote repo
902902
return repo
903903

git/test/lib/helper.py

+55-34
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,25 @@
55
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
66
from __future__ import print_function
77

8-
import os
9-
from unittest import TestCase
10-
import time
11-
import tempfile
8+
from functools import wraps
129
import io
1310
import logging
11+
import os
12+
import tempfile
13+
import textwrap
14+
import time
15+
from unittest import TestCase
1416

15-
from functools import wraps
16-
17-
from git.util import rmtree
1817
from git.compat import string_types, is_win
19-
import textwrap
18+
from git.util import rmtree, HIDE_WINDOWS_KNOWN_ERRORS
19+
20+
import os.path as osp
2021

21-
osp = os.path.dirname
2222

23-
GIT_REPO = os.environ.get("GIT_PYTHON_TEST_GIT_REPO_BASE", osp(osp(osp(osp(__file__)))))
24-
GIT_DAEMON_PORT = os.environ.get("GIT_PYTHON_TEST_GIT_DAEMON_PORT", "9418")
23+
ospd = osp.dirname
24+
25+
GIT_REPO = os.environ.get("GIT_PYTHON_TEST_GIT_REPO_BASE", ospd(ospd(ospd(ospd(__file__)))))
26+
GIT_DAEMON_PORT = os.environ.get("GIT_PYTHON_TEST_GIT_DAEMON_PORT", "19418")
2527

2628
__all__ = (
2729
'fixture_path', 'fixture', 'absolute_project_path', 'StringProcessAdapter',
@@ -35,8 +37,8 @@
3537

3638

3739
def fixture_path(name):
38-
test_dir = osp(osp(__file__))
39-
return os.path.join(test_dir, "fixtures", name)
40+
test_dir = ospd(ospd(__file__))
41+
return osp.join(test_dir, "fixtures", name)
4042

4143

4244
def fixture(name):
@@ -45,7 +47,7 @@ def fixture(name):
4547

4648

4749
def absolute_project_path():
48-
return os.path.abspath(os.path.join(osp(__file__), "..", ".."))
50+
return osp.abspath(osp.join(osp(__file__), "..", ".."))
4951

5052
#} END routines
5153

@@ -165,26 +167,31 @@ def repo_creator(self):
165167
return argument_passer
166168

167169

168-
def launch_git_daemon(temp_dir, ip, port):
170+
def launch_git_daemon(base_path, ip, port):
169171
from git import Git
170172
if is_win:
171173
## On MINGW-git, daemon exists in .\Git\mingw64\libexec\git-core\,
172174
# but if invoked as 'git daemon', it detaches from parent `git` cmd,
173175
# and then CANNOT DIE!
174176
# So, invoke it as a single command.
175-
## Cygwin-git has no daemon.
177+
## Cygwin-git has no daemon. But it can use MINGW's.
176178
#
177-
daemon_cmd = ['git-daemon', temp_dir,
179+
daemon_cmd = ['git-daemon',
178180
'--enable=receive-pack',
179181
'--listen=%s' % ip,
180-
'--port=%s' % port]
182+
'--port=%s' % port,
183+
'--base-path=%s' % base_path,
184+
base_path]
181185
gd = Git().execute(daemon_cmd, as_process=True)
182186
else:
183-
gd = Git().daemon(temp_dir,
187+
gd = Git().daemon(base_path,
184188
enable='receive-pack',
185189
listen=ip,
186190
port=port,
191+
base_path=base_path,
187192
as_process=True)
193+
# yes, I know ... fortunately, this is always going to work if sleep time is just large enough
194+
time.sleep(0.5)
188195
return gd
189196

190197

@@ -212,7 +219,8 @@ def case(self, rw_repo, rw_remote_repo)
212219
See working dir info in with_rw_repo
213220
:note: We attempt to launch our own invocation of git-daemon, which will be shutdown at the end of the test.
214221
"""
215-
from git import Remote, GitCommandError
222+
from git import Git, Remote, GitCommandError
223+
216224
assert isinstance(working_tree_ref, string_types), "Decorator requires ref name for working tree checkout"
217225

218226
def argument_passer(func):
@@ -240,23 +248,36 @@ def remote_repo_creator(self):
240248
pass
241249
crw.set(section, "receivepack", True)
242250

243-
# initialize the remote - first do it as local remote and pull, then
244-
# we change the url to point to the daemon. The daemon should be started
245-
# by the user, not by us
251+
# Initialize the remote - first do it as local remote and pull, then
252+
# we change the url to point to the daemon.
246253
d_remote = Remote.create(rw_repo, "daemon_origin", remote_repo_dir)
247254
d_remote.fetch()
248-
remote_repo_url = "git://localhost:%s%s" % (GIT_DAEMON_PORT, remote_repo_dir)
249255

256+
base_path, rel_repo_dir = osp.split(remote_repo_dir)
257+
258+
remote_repo_url = "git://localhost:%s/%s" % (GIT_DAEMON_PORT, rel_repo_dir)
250259
with d_remote.config_writer as cw:
251260
cw.set('url', remote_repo_url)
252261

253-
temp_dir = osp(_mktemp())
254-
gd = launch_git_daemon(temp_dir, '127.0.0.1', GIT_DAEMON_PORT)
255262
try:
256-
# yes, I know ... fortunately, this is always going to work if sleep time is just large enough
257-
time.sleep(0.5)
258-
# end
259-
263+
gd = launch_git_daemon(Git.polish_url(base_path), '127.0.0.1', GIT_DAEMON_PORT)
264+
except Exception as ex:
265+
if is_win:
266+
msg = textwrap.dedent("""
267+
The `git-daemon.exe` must be in PATH.
268+
For MINGW, look into .\Git\mingw64\libexec\git-core\), but problems with paths might appear.
269+
CYGWIN has no daemon, but if one exists, it gets along fine (has also paths problems)
270+
Anyhow, alternatively try starting `git-daemon` manually:""")
271+
else:
272+
msg = "Please try starting `git-daemon` manually:"
273+
msg += textwrap.dedent("""
274+
git daemon --enable=receive-pack --base-path=%s %s
275+
You can also run the daemon on a different port by passing --port=<port>"
276+
and setting the environment variable GIT_PYTHON_TEST_GIT_DAEMON_PORT to <port>
277+
""" % (base_path, base_path))
278+
raise AssertionError(ex, msg)
279+
# END make assertion
280+
else:
260281
# try to list remotes to diagnoes whether the server is up
261282
try:
262283
rw_repo.git.ls_remote(d_remote)
@@ -283,9 +304,9 @@ def remote_repo_creator(self):
283304
git daemon --enable=receive-pack '%s'
284305
You can also run the daemon on a different port by passing --port=<port>"
285306
and setting the environment variable GIT_PYTHON_TEST_GIT_DAEMON_PORT to <port>
286-
""" % temp_dir)
307+
""" % base_path)
287308
from unittest import SkipTest
288-
raise SkipTest(msg) if is_win else AssertionError(msg)
309+
raise SkipTest(msg) if HIDE_WINDOWS_KNOWN_ERRORS else AssertionError(e, msg)
289310
# END make assertion
290311
# END catch ls remote error
291312

@@ -354,7 +375,7 @@ class TestBase(TestCase):
354375

355376
def _small_repo_url(self):
356377
""":return" a path to a small, clonable repository"""
357-
return os.path.join(self.rorepo.working_tree_dir, 'git/ext/gitdb/gitdb/ext/smmap')
378+
return osp.join(self.rorepo.working_tree_dir, 'git/ext/gitdb/gitdb/ext/smmap')
358379

359380
@classmethod
360381
def setUpClass(cls):
@@ -378,7 +399,7 @@ def _make_file(self, rela_path, data, repo=None):
378399
with the given data. Returns absolute path to created file.
379400
"""
380401
repo = repo or self.rorepo
381-
abs_path = os.path.join(repo.working_tree_dir, rela_path)
402+
abs_path = osp.join(repo.working_tree_dir, rela_path)
382403
with open(abs_path, "w") as fp:
383404
fp.write(data)
384405
return abs_path

git/test/test_base.py

-11
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,6 @@ def test_with_rw_repo(self, rw_repo):
110110
assert not rw_repo.config_reader("repository").getboolean("core", "bare")
111111
assert os.path.isdir(os.path.join(rw_repo.working_tree_dir, 'lib'))
112112

113-
# @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, """
114-
# FIXME: helper.wrapper fails with:
115-
# PermissionError: [WinError 5] Access is denied:
116-
# 'C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\test_work_tree_unsupportedryfa60di\\
117-
# master_repo\\.git\\objects\\pack\\pack-bc9e0787aef9f69e1591ef38ea0a6f566ec66fe3.idx'
118-
# AND
119-
# FIXME: git-daemon failing with:
120-
# git.exc.GitCommandError: Cmd('git') failed due to: exit code(128)
121-
# cmdline: git ls-remote daemon_origin
122-
# stderr: 'fatal: bad config line 15 in file .git/config'
123-
# """)
124113
@with_rw_and_rw_remote_repo('0.1.6')
125114
def test_with_rw_remote_and_rw_repo(self, rw_repo, rw_remote_repo):
126115
assert not rw_repo.config_reader("repository").getboolean("core", "bare")

git/test/test_docs.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def tearDown(self):
1616
import gc
1717
gc.collect()
1818

19-
# @skipIf(HIDE_WINDOWS_KNOWN_ERRORS,
19+
# @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, ## ACTUALLY skipped by `git.submodule.base#L869`.
2020
# "FIXME: helper.wrapper fails with: PermissionError: [WinError 5] Access is denied: "
2121
# "'C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\test_work_tree_unsupportedryfa60di\\master_repo\\.git\\objects\\pack\\pack-bc9e0787aef9f69e1591ef38ea0a6f566ec66fe3.idx") # noqa E501
2222
@with_rw_directory

git/test/test_remote.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import tempfile
3131
import os
3232
import random
33+
from unittest.case import skipIf
34+
from git.util import HIDE_WINDOWS_KNOWN_ERRORS
3335

3436
# assure we have repeatable results
3537
random.seed(0)
@@ -384,12 +386,7 @@ def _assert_push_and_pull(self, remote, rw_repo, remote_repo):
384386
TagReference.delete(rw_repo, new_tag, other_tag)
385387
remote.push(":%s" % other_tag.path)
386388

387-
# @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, """
388-
# FIXME: git-daemon failing with:
389-
# git.exc.GitCommandError: Cmd('git') failed due to: exit code(128)
390-
# cmdline: git ls-remote daemon_origin
391-
# stderr: 'fatal: bad config line 15 in file .git/config'
392-
# """)
389+
@skipIf(HIDE_WINDOWS_KNOWN_ERRORS, "FIXME: Freezes!")
393390
@with_rw_and_rw_remote_repo('0.1.6')
394391
def test_base(self, rw_repo, remote_repo):
395392
num_remotes = 0

git/test/test_repo.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -472,12 +472,17 @@ def test_creation_deletion(self):
472472
head = self.rorepo.create_head("new_head", "HEAD~1")
473473
self.rorepo.delete_head(head)
474474

475-
tag = self.rorepo.create_tag("new_tag", "HEAD~2")
476-
self.rorepo.delete_tag(tag)
475+
try:
476+
tag = self.rorepo.create_tag("new_tag", "HEAD~2")
477+
finally:
478+
self.rorepo.delete_tag(tag)
477479
with self.rorepo.config_writer():
478480
pass
479-
remote = self.rorepo.create_remote("new_remote", "git@server:repo.git")
480-
self.rorepo.delete_remote(remote)
481+
try:
482+
remote = self.rorepo.create_remote("new_remote", "git@server:repo.git")
483+
finally:
484+
self.rorepo.delete_remote(remote)
485+
481486

482487
def test_comparison_and_hash(self):
483488
# this is only a preliminary test, more testing done in test_index

git/test/test_submodule.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ def _do_base_tests(self, rwrepo):
418418
# Error if there is no submodule file here
419419
self.failUnlessRaises(IOError, Submodule._config_parser, rwrepo, rwrepo.commit(self.k_no_subm_tag), True)
420420

421-
# @skipIf(HIDE_WINDOWS_KNOWN_ERRORS,
421+
# @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, ## ACTUALLY skipped by `git.submodule.base#L869`.
422422
# "FIXME: fails with: PermissionError: [WinError 32] The process cannot access the file because"
423423
# "it is being used by another process: "
424424
# "'C:\\Users\\ankostis\\AppData\\Local\\Temp\\tmp95c3z83bnon_bare_test_base_rw\\git\\ext\\gitdb\\gitdb\\ext\\smmap'") # noqa E501

0 commit comments

Comments
 (0)