GeezerVison is showing github.com — Win, #519: FIX repo TCs. · gitpython-developers/GitPython@b8b025f
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: git/cmd.py +8-4Lines changed: 8 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 45 | 45 | execute_kwargs = set(('istream', 'with_keep_cwd', 'with_extended_output', | 46 | 46 | 'with_exceptions', 'as_process', 'stdout_as_string', | 47 | 47 | 'output_stream', 'with_stdout', 'kill_after_timeout', | 48 | | - 'universal_newlines')) | | 48 | + 'universal_newlines', 'shell')) | 49 | 49 |
| 50 | 50 | log = logging.getLogger('git.cmd') | 51 | 51 | log.addHandler(logging.NullHandler()) | @@ -176,8 +176,8 @@ def __setstate__(self, d): | 176 | 176 | GIT_PYTHON_GIT_EXECUTABLE = os.environ.get(_git_exec_env_var, git_exec_name) | 177 | 177 |
| 178 | 178 | # If True, a shell will be used when executing git commands. | 179 | | - # This should only be desirable on windows, see https://github.com/gitpython-developers/GitPython/pull/126 | 180 | | - # for more information | | 179 | + # This should only be desirable on Windows, see https://github.com/gitpython-developers/GitPython/pull/126 | | 180 | + # and check `git/test_repo.py:TestRepo.test_untracked_files()` TC for an example where it is required. | 181 | 181 | # Override this value using `Git.USE_SHELL = True` | 182 | 182 | USE_SHELL = False | 183 | 183 |
| @@ -422,6 +422,7 @@ def execute(self, command, | 422 | 422 | kill_after_timeout=None, | 423 | 423 | with_stdout=True, | 424 | 424 | universal_newlines=False, | | 425 | + shell=None, | 425 | 426 | **subprocess_kwargs | 426 | 427 | ): | 427 | 428 | """Handles executing the command on the shell and consumes and returns | @@ -479,6 +480,9 @@ def execute(self, command, | 479 | 480 | :param universal_newlines: | 480 | 481 | if True, pipes will be opened as text, and lines are split at | 481 | 482 | all known line endings. | | 483 | + :param shell: | | 484 | + Whether to invoke commands through a shell (see `Popen(..., shell=True)`). | | 485 | + It overrides :attr:`USE_SHELL` if it is not `None`. | 482 | 486 | :param kill_after_timeout: | 483 | 487 | To specify a timeout in seconds for the git command, after which the process | 484 | 488 | should be killed. This will have no effect if as_process is set to True. It is | @@ -544,7 +548,7 @@ def execute(self, command, | 544 | 548 | stdin=istream, | 545 | 549 | stderr=PIPE, | 546 | 550 | stdout=PIPE if with_stdout else open(os.devnull, 'wb'), | 547 | | - shell=self.USE_SHELL, | | 551 | + shell=shell is not None and shell or self.USE_SHELL, | 548 | 552 | close_fds=(is_posix), # unsupported on windows | 549 | 553 | universal_newlines=universal_newlines, | 550 | 554 | creationflags=PROC_CREATIONFLAGS, | |
Collapse file Copy file name to clipboardExpand all lines: git/compat.py +12-1Lines changed: 12 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 7 | 7 | """utilities to help provide compatibility with python 3""" | 8 | 8 | # flake8: noqa | 9 | 9 |
| | 10 | +import locale | 10 | 11 | import os | 11 | 12 | import sys | 12 | 13 |
| | 15 | 16 | MAXSIZE, | 16 | 17 | izip, | 17 | 18 | ) | 18 | | - | 19 | 19 | from gitdb.utils.encoding import ( | 20 | 20 | string_types, | 21 | 21 | text_type, | 22 | 22 | force_bytes, | 23 | 23 | force_text | 24 | 24 | ) | 25 | 25 |
| | 26 | + | 26 | 27 | PY3 = sys.version_info[0] >= 3 | 27 | 28 | is_win = (os.name == 'nt') | 28 | 29 | is_posix = (os.name == 'posix') | @@ -76,6 +77,16 @@ def safe_encode(s): | 76 | 77 | raise TypeError('Expected bytes or text, but got %r' % (s,)) | 77 | 78 |
| 78 | 79 |
| | 80 | +def win_encode(s): | | 81 | + """Encode unicodes for process arguments on Windows.""" | | 82 | + if isinstance(s, unicode): | | 83 | + return s.encode(locale.getpreferredencoding(False)) | | 84 | + elif isinstance(s, bytes): | | 85 | + return s | | 86 | + elif s is not None: | | 87 | + raise TypeError('Expected bytes or text, but got %r' % (s,)) | | 88 | + | | 89 | + | 79 | 90 | def with_metaclass(meta, *bases): | 80 | 91 | """copied from https://github.com/Byron/bcore/blob/master/src/python/butility/future.py#L15""" | 81 | 92 | class metaclass(meta): | |
Collapse file Copy file name to clipboardExpand all lines: git/index/base.py +7-8Lines changed: 7 additions & 8 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -214,8 +214,8 @@ def write(self, file_path=None, ignore_extension_data=False): | 214 | 214 | self.entries | 215 | 215 | lfd = LockedFD(file_path or self._file_path) | 216 | 216 | stream = lfd.open(write=True, stream=True) | 217 | | - ok = False | 218 | 217 |
| | 218 | + ok = False | 219 | 219 | try: | 220 | 220 | self._serialize(stream, ignore_extension_data) | 221 | 221 | ok = True | @@ -602,14 +602,13 @@ def _store_path(self, filepath, fprogress): | 602 | 602 | stream = None | 603 | 603 | if S_ISLNK(st.st_mode): | 604 | 604 | # in PY3, readlink is string, but we need bytes. In PY2, it's just OS encoded bytes, we assume UTF-8 | 605 | | - stream = BytesIO(force_bytes(os.readlink(filepath), encoding=defenc)) | | 605 | + open_stream = lambda: BytesIO(force_bytes(os.readlink(filepath), encoding=defenc)) | 606 | 606 | else: | 607 | | - stream = open(filepath, 'rb') | 608 | | - # END handle stream | 609 | | - fprogress(filepath, False, filepath) | 610 | | - istream = self.repo.odb.store(IStream(Blob.type, st.st_size, stream)) | 611 | | - fprogress(filepath, True, filepath) | 612 | | - stream.close() | | 607 | + open_stream = lambda: open(filepath, 'rb') | | 608 | + with open_stream() as stream: | | 609 | + fprogress(filepath, False, filepath) | | 610 | + istream = self.repo.odb.store(IStream(Blob.type, st.st_size, stream)) | | 611 | + fprogress(filepath, True, filepath) | 613 | 612 | return BaseIndexEntry((stat_mode_to_index_mode(st.st_mode), | 614 | 613 | istream.binsha, 0, to_native_path_linux(filepath))) | 615 | 614 |
| |
Collapse file Copy file name to clipboardExpand all lines: git/objects/submodule/base.py +12-9Lines changed: 12 additions & 9 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 29 | 29 | ) | 30 | 30 | from git.compat import ( | 31 | 31 | string_types, | 32 | | - defenc | | 32 | + defenc, | | 33 | + is_win, | 33 | 34 | ) | 34 | 35 |
| 35 | 36 | import stat | @@ -289,14 +290,16 @@ def _write_git_file_and_module_config(cls, working_tree_dir, module_abspath): | 289 | 290 | """ | 290 | 291 | git_file = os.path.join(working_tree_dir, '.git') | 291 | 292 | rela_path = os.path.relpath(module_abspath, start=working_tree_dir) | 292 | | - fp = open(git_file, 'wb') | 293 | | - fp.write(("gitdir: %s" % rela_path).encode(defenc)) | 294 | | - fp.close() | 295 | | - | 296 | | - writer = GitConfigParser(os.path.join(module_abspath, 'config'), read_only=False, merge_includes=False) | 297 | | - writer.set_value('core', 'worktree', | 298 | | - to_native_path_linux(os.path.relpath(working_tree_dir, start=module_abspath))) | 299 | | - writer.release() | | 293 | + if is_win: | | 294 | + if os.path.isfile(git_file): | | 295 | + os.remove(git_file) | | 296 | + with open(git_file, 'wb') as fp: | | 297 | + fp.write(("gitdir: %s" % rela_path).encode(defenc)) | | 298 | + | | 299 | + with GitConfigParser(os.path.join(module_abspath, 'config'), | | 300 | + read_only=False, merge_includes=False) as writer: | | 301 | + writer.set_value('core', 'worktree', | | 302 | + to_native_path_linux(os.path.relpath(working_tree_dir, start=module_abspath))) | 300 | 303 |
| 301 | 304 | #{ Edit Interface | 302 | 305 |
| |
Collapse file Copy file name to clipboardExpand all lines: git/repo/base.py +2-6Lines changed: 2 additions & 6 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -899,12 +899,8 @@ def _clone(cls, git, url, path, odb_default_type, progress, **kwargs): | 899 | 899 | try: | 900 | 900 | proc = git.clone(url, path, with_extended_output=True, as_process=True, | 901 | 901 | v=True, **add_progress(kwargs, git, progress)) | 902 | | - if progress: | 903 | | - handle_process_output(proc, None, progress.new_message_handler(), finalize_process) | 904 | | - else: | 905 | | - (stdout, stderr) = proc.communicate() | 906 | | - finalize_process(proc, stderr=stderr) | 907 | | - # end handle progress | | 902 | + progress_handler = progress and progress.new_message_handler() or None | | 903 | + handle_process_output(proc, None, progress_handler, finalize_process) | 908 | 904 | finally: | 909 | 905 | if prev_cwd is not None: | 910 | 906 | os.chdir(prev_cwd) | |
Collapse file Copy file name to clipboardExpand all lines: git/test/test_index.py +17-18Lines changed: 17 additions & 18 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -113,9 +113,8 @@ def test_index_file_base(self): | 113 | 113 | # write the data - it must match the original | 114 | 114 | tmpfile = tempfile.mktemp() | 115 | 115 | index_merge.write(tmpfile) | 116 | | - fp = open(tmpfile, 'rb') | 117 | | - self.assertEqual(fp.read(), fixture("index_merge")) | 118 | | - fp.close() | | 116 | + with open(tmpfile, 'rb') as fp: | | 117 | + self.assertEqual(fp.read(), fixture("index_merge")) | 119 | 118 | os.remove(tmpfile) | 120 | 119 |
| 121 | 120 | def _cmp_tree_index(self, tree, index): | @@ -329,22 +328,19 @@ def test_index_file_diffing(self, rw_repo): | 329 | 328 | # reset the working copy as well to current head,to pull 'back' as well | 330 | 329 | new_data = b"will be reverted" | 331 | 330 | file_path = os.path.join(rw_repo.working_tree_dir, "CHANGES") | 332 | | - fp = open(file_path, "wb") | 333 | | - fp.write(new_data) | 334 | | - fp.close() | | 331 | + with open(file_path, "wb") as fp: | | 332 | + fp.write(new_data) | 335 | 333 | index.reset(rev_head_parent, working_tree=True) | 336 | 334 | assert not index.diff(None) | 337 | 335 | self.assertEqual(cur_branch, rw_repo.active_branch) | 338 | 336 | self.assertEqual(cur_commit, rw_repo.head.commit) | 339 | | - fp = open(file_path, 'rb') | 340 | | - try: | | 337 | + with open(file_path, 'rb') as fp: | 341 | 338 | assert fp.read() != new_data | 342 | | - finally: | 343 | | - fp.close() | 344 | 339 |
| 345 | 340 | # test full checkout | 346 | 341 | test_file = os.path.join(rw_repo.working_tree_dir, "CHANGES") | 347 | | - open(test_file, 'ab').write(b"some data") | | 342 | + with open(test_file, 'ab') as fd: | | 343 | + fd.write(b"some data") | 348 | 344 | rval = index.checkout(None, force=True, fprogress=self._fprogress) | 349 | 345 | assert 'CHANGES' in list(rval) | 350 | 346 | self._assert_fprogress([None]) | @@ -369,9 +365,8 @@ def test_index_file_diffing(self, rw_repo): | 369 | 365 |
| 370 | 366 | # checkout file with modifications | 371 | 367 | append_data = b"hello" | 372 | | - fp = open(test_file, "ab") | 373 | | - fp.write(append_data) | 374 | | - fp.close() | | 368 | + with open(test_file, "ab") as fp: | | 369 | + fp.write(append_data) | 375 | 370 | try: | 376 | 371 | index.checkout(test_file) | 377 | 372 | except CheckoutError as e: | @@ -380,7 +375,9 @@ def test_index_file_diffing(self, rw_repo): | 380 | 375 | self.assertEqual(len(e.failed_files), len(e.failed_reasons)) | 381 | 376 | self.assertIsInstance(e.failed_reasons[0], string_types) | 382 | 377 | self.assertEqual(len(e.valid_files), 0) | 383 | | - assert open(test_file, 'rb').read().endswith(append_data) | | 378 | + with open(test_file, 'rb') as fd: | | 379 | + s = fd.read() | | 380 | + self.assertTrue(s.endswith(append_data), s) | 384 | 381 | else: | 385 | 382 | raise AssertionError("Exception CheckoutError not thrown") | 386 | 383 |
| @@ -639,9 +636,10 @@ def mixed_iterator(): | 639 | 636 | if is_win: | 640 | 637 | # simlinks should contain the link as text ( which is what a | 641 | 638 | # symlink actually is ) | 642 | | - open(fake_symlink_path, 'rb').read() == link_target | | 639 | + with open(fake_symlink_path, 'rt') as fd: | | 640 | + self.assertEqual(fd.read(), link_target) | 643 | 641 | else: | 644 | | - assert S_ISLNK(os.lstat(fake_symlink_path)[ST_MODE]) | | 642 | + self.assertTrue(S_ISLNK(os.lstat(fake_symlink_path)[ST_MODE])) | 645 | 643 |
| 646 | 644 | # TEST RENAMING | 647 | 645 | def assert_mv_rval(rval): | @@ -691,7 +689,8 @@ def make_paths(): | 691 | 689 |
| 692 | 690 | for fid in range(3): | 693 | 691 | fname = 'newfile%i' % fid | 694 | | - open(fname, 'wb').write(b"abcd") | | 692 | + with open(fname, 'wb') as fd: | | 693 | + fd.write(b"abcd") | 695 | 694 | yield Blob(rw_repo, Blob.NULL_BIN_SHA, 0o100644, fname) | 696 | 695 | # END for each new file | 697 | 696 | # END path producer | |
|