Skip to content

Commit dc5b0e5

Browse files
committed
MINGW, gitpython-developers#525: FIX remote urls in config-files
+ Parse most remote & 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. + util: delete unused `absolute_project_path()`.
1 parent 0fb10e4 commit dc5b0e5

File tree

9 files changed

+81
-69
lines changed

9 files changed

+81
-69
lines changed

Diff for: 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):

Diff for: 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

Diff for: 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

Diff for: git/test/lib/helper.py

+54-38
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,28 @@
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
21+
2022

21-
osp = os.path.dirname
23+
ospd = osp.dirname
2224

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")
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__ = (
27-
'fixture_path', 'fixture', 'absolute_project_path', 'StringProcessAdapter',
29+
'fixture_path', 'fixture', 'StringProcessAdapter',
2830
'with_rw_directory', 'with_rw_repo', 'with_rw_and_rw_remote_repo', 'TestBase', 'TestCase',
2931
'GIT_REPO', 'GIT_DAEMON_PORT'
3032
)
@@ -35,18 +37,13 @@
3537

3638

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

4142

4243
def fixture(name):
4344
with open(fixture_path(name), 'rb') as fd:
4445
return fd.read()
4546

46-
47-
def absolute_project_path():
48-
return os.path.abspath(os.path.join(osp(__file__), "..", ".."))
49-
5047
#} END routines
5148

5249
#{ Adapters
@@ -165,26 +162,31 @@ def repo_creator(self):
165162
return argument_passer
166163

167164

168-
def launch_git_daemon(temp_dir, ip, port):
165+
def launch_git_daemon(base_path, ip, port):
169166
from git import Git
170167
if is_win:
171168
## On MINGW-git, daemon exists in .\Git\mingw64\libexec\git-core\,
172169
# but if invoked as 'git daemon', it detaches from parent `git` cmd,
173170
# and then CANNOT DIE!
174171
# So, invoke it as a single command.
175-
## Cygwin-git has no daemon.
172+
## Cygwin-git has no daemon. But it can use MINGW's.
176173
#
177-
daemon_cmd = ['git-daemon', temp_dir,
174+
daemon_cmd = ['git-daemon',
178175
'--enable=receive-pack',
179176
'--listen=%s' % ip,
180-
'--port=%s' % port]
177+
'--port=%s' % port,
178+
'--base-path=%s' % base_path,
179+
base_path]
181180
gd = Git().execute(daemon_cmd, as_process=True)
182181
else:
183-
gd = Git().daemon(temp_dir,
182+
gd = Git().daemon(base_path,
184183
enable='receive-pack',
185184
listen=ip,
186185
port=port,
186+
base_path=base_path,
187187
as_process=True)
188+
# yes, I know ... fortunately, this is always going to work if sleep time is just large enough
189+
time.sleep(0.5)
188190
return gd
189191

190192

@@ -212,7 +214,8 @@ def case(self, rw_repo, rw_remote_repo)
212214
See working dir info in with_rw_repo
213215
:note: We attempt to launch our own invocation of git-daemon, which will be shutdown at the end of the test.
214216
"""
215-
from git import Remote, GitCommandError
217+
from git import Git, Remote, GitCommandError
218+
216219
assert isinstance(working_tree_ref, string_types), "Decorator requires ref name for working tree checkout"
217220

218221
def argument_passer(func):
@@ -240,23 +243,36 @@ def remote_repo_creator(self):
240243
pass
241244
crw.set(section, "receivepack", True)
242245

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
246+
# Initialize the remote - first do it as local remote and pull, then
247+
# we change the url to point to the daemon.
246248
d_remote = Remote.create(rw_repo, "daemon_origin", remote_repo_dir)
247249
d_remote.fetch()
248-
remote_repo_url = "git://localhost:%s%s" % (GIT_DAEMON_PORT, remote_repo_dir)
249250

251+
base_path, rel_repo_dir = osp.split(remote_repo_dir)
252+
253+
remote_repo_url = "git://localhost:%s/%s" % (GIT_DAEMON_PORT, rel_repo_dir)
250254
with d_remote.config_writer as cw:
251255
cw.set('url', remote_repo_url)
252256

253-
temp_dir = osp(_mktemp())
254-
gd = launch_git_daemon(temp_dir, '127.0.0.1', GIT_DAEMON_PORT)
255257
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-
258+
gd = launch_git_daemon(Git.polish_url(base_path), '127.0.0.1', GIT_DAEMON_PORT)
259+
except Exception as ex:
260+
if is_win:
261+
msg = textwrap.dedent("""
262+
The `git-daemon.exe` must be in PATH.
263+
For MINGW, look into .\Git\mingw64\libexec\git-core\), but problems with paths might appear.
264+
CYGWIN has no daemon, but if one exists, it gets along fine (has also paths problems)
265+
Anyhow, alternatively try starting `git-daemon` manually:""")
266+
else:
267+
msg = "Please try starting `git-daemon` manually:"
268+
msg += textwrap.dedent("""
269+
git daemon --enable=receive-pack --base-path=%s %s
270+
You can also run the daemon on a different port by passing --port=<port>"
271+
and setting the environment variable GIT_PYTHON_TEST_GIT_DAEMON_PORT to <port>
272+
""" % (base_path, base_path))
273+
raise AssertionError(ex, msg)
274+
# END make assertion
275+
else:
260276
# try to list remotes to diagnoes whether the server is up
261277
try:
262278
rw_repo.git.ls_remote(d_remote)
@@ -283,9 +299,9 @@ def remote_repo_creator(self):
283299
git daemon --enable=receive-pack '%s'
284300
You can also run the daemon on a different port by passing --port=<port>"
285301
and setting the environment variable GIT_PYTHON_TEST_GIT_DAEMON_PORT to <port>
286-
""" % temp_dir)
302+
""" % base_path)
287303
from unittest import SkipTest
288-
raise SkipTest(msg) if is_win else AssertionError(msg)
304+
raise SkipTest(msg) if HIDE_WINDOWS_KNOWN_ERRORS else AssertionError(e, msg)
289305
# END make assertion
290306
# END catch ls remote error
291307

@@ -354,7 +370,7 @@ class TestBase(TestCase):
354370

355371
def _small_repo_url(self):
356372
""":return" a path to a small, clonable repository"""
357-
return os.path.join(self.rorepo.working_tree_dir, 'git/ext/gitdb/gitdb/ext/smmap')
373+
return osp.join(self.rorepo.working_tree_dir, 'git/ext/gitdb/gitdb/ext/smmap')
358374

359375
@classmethod
360376
def setUpClass(cls):
@@ -378,7 +394,7 @@ def _make_file(self, rela_path, data, repo=None):
378394
with the given data. Returns absolute path to created file.
379395
"""
380396
repo = repo or self.rorepo
381-
abs_path = os.path.join(repo.working_tree_dir, rela_path)
397+
abs_path = osp.join(repo.working_tree_dir, rela_path)
382398
with open(abs_path, "w") as fp:
383399
fp.write(data)
384400
return abs_path

Diff for: 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")

Diff for: 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

Diff for: git/test/test_remote.py

+9-10
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@
2828
from git.util import IterableList, rmtree
2929
from git.compat import string_types
3030
import tempfile
31-
import os
31+
import os.path as osp
3232
import random
33+
from unittest.case import skipIf
34+
from git.util import HIDE_WINDOWS_KNOWN_ERRORS
35+
from git.cmd import Git
3336

3437
# assure we have repeatable results
3538
random.seed(0)
@@ -105,7 +108,7 @@ def tearDown(self):
105108
gc.collect()
106109

107110
def _print_fetchhead(self, repo):
108-
with open(os.path.join(repo.git_dir, "FETCH_HEAD")):
111+
with open(osp.join(repo.git_dir, "FETCH_HEAD")):
109112
pass
110113

111114
def _do_test_fetch_result(self, results, remote):
@@ -156,7 +159,7 @@ def _commit_random_file(self, repo):
156159
# Create a file with a random name and random data and commit it to repo.
157160
# Return the commited absolute file path
158161
index = repo.index
159-
new_file = self._make_file(os.path.basename(tempfile.mktemp()), str(random.random()), repo)
162+
new_file = self._make_file(osp.basename(tempfile.mktemp()), str(random.random()), repo)
160163
index.add([new_file])
161164
index.commit("Committing %s" % new_file)
162165
return new_file
@@ -263,7 +266,8 @@ def get_info(res, remote, name):
263266
# must clone with a local path for the repo implementation not to freak out
264267
# as it wants local paths only ( which I can understand )
265268
other_repo = remote_repo.clone(other_repo_dir, shared=False)
266-
remote_repo_url = "git://localhost:%s%s" % (GIT_DAEMON_PORT, remote_repo.git_dir)
269+
remote_repo_url = osp.basename(remote_repo.git_dir) # git-daemon runs with appropriate `--base-path`.
270+
remote_repo_url = Git.polish_url("git://localhost:%s/%s" % (GIT_DAEMON_PORT, remote_repo_url))
267271

268272
# put origin to git-url
269273
other_origin = other_repo.remotes.origin
@@ -384,12 +388,7 @@ def _assert_push_and_pull(self, remote, rw_repo, remote_repo):
384388
TagReference.delete(rw_repo, new_tag, other_tag)
385389
remote.push(":%s" % other_tag.path)
386390

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-
# """)
391+
@skipIf(HIDE_WINDOWS_KNOWN_ERRORS, "FIXME: Freezes!")
393392
@with_rw_and_rw_remote_repo('0.1.6')
394393
def test_base(self, rw_repo, remote_repo):
395394
num_remotes = 0

Diff for: git/test/test_repo.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -472,12 +472,16 @@ 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)
481485

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

Diff for: 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)