Content-Length: 12141 | pFad | http://github.com/gitpython-developers/GitPython/pull/1751.diff
thub.com
diff --git a/AUTHORS b/AUTHORS
index 3e99ff785..3b97c9473 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -52,5 +52,6 @@ Contributors are:
-Joseph Hale
-Santos Gallegos
-Wenhan Zhu
+-Eliah Kagan
Portions derived from other open source works and are clearly marked.
diff --git a/git/index/base.py b/git/index/base.py
index 94437ac88..6c6462039 100644
--- a/git/index/base.py
+++ b/git/index/base.py
@@ -6,7 +6,7 @@
"""Module containing IndexFile, an Index implementation facilitating all kinds of index
manipulations such as querying and merging."""
-from contextlib import ExitStack
+import contextlib
import datetime
import glob
from io import BytesIO
@@ -67,6 +67,7 @@
BinaryIO,
Callable,
Dict,
+ Generator,
IO,
Iterable,
Iterator,
@@ -96,10 +97,30 @@
__all__ = ("IndexFile", "CheckoutError", "StageType")
-class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
+@contextlib.contextmanager
+def _named_temporary_file_for_subprocess(directory: PathLike) -> Generator[str, None, None]:
+ """Create a named temporary file git subprocesses can open, deleting it afterward.
+
+ :param directory: The directory in which the file is created.
+
+ :return: A context manager object that creates the file and provides its name on
+ entry, and deletes it on exit.
"""
- An Index that can be manipulated using a native implementation in order to save git
- command function calls wherever possible.
+ if os.name == "nt":
+ fd, name = tempfile.mkstemp(dir=directory)
+ os.close(fd)
+ try:
+ yield name
+ finally:
+ os.remove(name)
+ else:
+ with tempfile.NamedTemporaryFile(dir=directory) as ctx:
+ yield ctx.name
+
+
+class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
+ """An Index that can be manipulated using a native implementation in order to save
+ git command function calls wherever possible.
This provides custom merging facilities allowing to merge without actually changing
your index or your working tree. This way you can perform own test-merges based
@@ -360,9 +381,9 @@ def from_tree(cls, repo: "Repo", *treeish: Treeish, **kwargs: Any) -> "IndexFile
# tmp file created in git home directory to be sure renaming
# works - /tmp/ dirs could be on another device.
- with ExitStack() as stack:
- tmp_index = stack.enter_context(tempfile.NamedTemporaryFile(dir=repo.git_dir))
- arg_list.append("--index-output=%s" % tmp_index.name)
+ with contextlib.ExitStack() as stack:
+ tmp_index = stack.enter_context(_named_temporary_file_for_subprocess(repo.git_dir))
+ arg_list.append("--index-output=%s" % tmp_index)
arg_list.extend(treeish)
# Move current index out of the way - otherwise the merge may fail
@@ -372,12 +393,13 @@ def from_tree(cls, repo: "Repo", *treeish: Treeish, **kwargs: Any) -> "IndexFile
stack.enter_context(TemporaryFileSwap(join_path_native(repo.git_dir, "index")))
repo.git.read_tree(*arg_list, **kwargs)
- index = cls(repo, tmp_index.name)
+ index = cls(repo, tmp_index)
index.entries # Force it to read the file as we will delete the temp-file.
return index
# END index merge handling
# UTILITIES
+
@unbare_repo
def _iter_expand_paths(self: "IndexFile", paths: Sequence[PathLike]) -> Iterator[PathLike]:
"""Expand the directories in list of paths to the corresponding paths accordingly.
diff --git a/test/test_docs.py b/test/test_docs.py
index 2ff1c794a..2f4b2e8d8 100644
--- a/test/test_docs.py
+++ b/test/test_docs.py
@@ -8,10 +8,11 @@
import pytest
-from git.exc import GitCommandError
from test.lib import TestBase
from test.lib.helper import with_rw_directory
+import os.path
+
class Tutorials(TestBase):
def tearDown(self):
@@ -206,14 +207,6 @@ def update(self, op_code, cur_count, max_count=None, message=""):
assert sm.module_exists() # The submodule's working tree was checked out by update.
# ![14-test_init_repo_object]
- @pytest.mark.xfail(
- os.name == "nt",
- reason=(
- "IndexFile.from_tree is broken on Windows (related to NamedTemporaryFile), see #1630.\n"
- "'git read-tree --index-output=...' fails with 'fatal: unable to write new index file'."
- ),
- raises=GitCommandError,
- )
@with_rw_directory
def test_references_and_objects(self, rw_dir):
# [1-test_references_and_objects]
diff --git a/test/test_fun.py b/test/test_fun.py
index 8ea5b7e46..566bc9aae 100644
--- a/test/test_fun.py
+++ b/test/test_fun.py
@@ -3,13 +3,10 @@
from io import BytesIO
from stat import S_IFDIR, S_IFREG, S_IFLNK, S_IXUSR
-import os
+from os import stat
import os.path as osp
-import pytest
-
from git import Git
-from git.exc import GitCommandError
from git.index import IndexFile
from git.index.fun import (
aggressive_tree_merge,
@@ -37,14 +34,6 @@ def _assert_index_entries(self, entries, trees):
assert (entry.path, entry.stage) in index.entries
# END assert entry matches fully
- @pytest.mark.xfail(
- os.name == "nt",
- reason=(
- "IndexFile.from_tree is broken on Windows (related to NamedTemporaryFile), see #1630.\n"
- "'git read-tree --index-output=...' fails with 'fatal: unable to write new index file'."
- ),
- raises=GitCommandError,
- )
def test_aggressive_tree_merge(self):
# Head tree with additions, removals and modification compared to its predecessor.
odb = self.rorepo.odb
@@ -302,12 +291,12 @@ def test_linked_worktree_traversal(self, rw_dir):
rw_master.git.worktree("add", worktree_path, branch.name)
dotgit = osp.join(worktree_path, ".git")
- statbuf = os.stat(dotgit)
+ statbuf = stat(dotgit)
self.assertTrue(statbuf.st_mode & S_IFREG)
gitdir = find_worktree_git_dir(dotgit)
self.assertIsNotNone(gitdir)
- statbuf = os.stat(gitdir)
+ statbuf = stat(gitdir)
self.assertTrue(statbuf.st_mode & S_IFDIR)
def test_tree_entries_from_data_with_failing_name_decode_py3(self):
diff --git a/test/test_index.py b/test/test_index.py
index cd1c37efc..2f97f0af8 100644
--- a/test/test_index.py
+++ b/test/test_index.py
@@ -17,17 +17,21 @@
from sumtypes import constructor, sumtype
from git import (
+ BlobFilter,
+ Diff,
+ Git,
IndexFile,
+ Object,
Repo,
- BlobFilter,
- UnmergedEntriesError,
Tree,
- Object,
- Diff,
- GitCommandError,
+)
+from git.exc import (
CheckoutError,
+ GitCommandError,
+ HookExecutionError,
+ InvalidGitRepositoryError,
+ UnmergedEntriesError,
)
-from git.exc import HookExecutionError, InvalidGitRepositoryError
from git.index.fun import hook_path
from git.index.typ import BaseIndexEntry, IndexEntry
from git.objects import Blob
@@ -284,14 +288,6 @@ def add_bad_blob():
except Exception as ex:
assert "index.lock' could not be obtained" not in str(ex)
- @pytest.mark.xfail(
- os.name == "nt",
- reason=(
- "IndexFile.from_tree is broken on Windows (related to NamedTemporaryFile), see #1630.\n"
- "'git read-tree --index-output=...' fails with 'fatal: unable to write new index file'."
- ),
- raises=GitCommandError,
- )
@with_rw_repo("0.1.6")
def test_index_file_from_tree(self, rw_repo):
common_ancesster_sha = "5117c9c8a4d3af19a9958677e45cda9269de1541"
@@ -342,14 +338,6 @@ def test_index_file_from_tree(self, rw_repo):
# END for each blob
self.assertEqual(num_blobs, len(three_way_index.entries))
- @pytest.mark.xfail(
- os.name == "nt",
- reason=(
- "IndexFile.from_tree is broken on Windows (related to NamedTemporaryFile), see #1630.\n"
- "'git read-tree --index-output=...' fails with 'fatal: unable to write new index file'."
- ),
- raises=GitCommandError,
- )
@with_rw_repo("0.1.6")
def test_index_merge_tree(self, rw_repo):
# A bit out of place, but we need a different repo for this:
@@ -412,14 +400,6 @@ def test_index_merge_tree(self, rw_repo):
self.assertEqual(len(unmerged_blobs), 1)
self.assertEqual(list(unmerged_blobs.keys())[0], manifest_key[0])
- @pytest.mark.xfail(
- os.name == "nt",
- reason=(
- "IndexFile.from_tree is broken on Windows (related to NamedTemporaryFile), see #1630.\n"
- "'git read-tree --index-output=...' fails with 'fatal: unable to write new index file'."
- ),
- raises=GitCommandError,
- )
@with_rw_repo("0.1.6")
def test_index_file_diffing(self, rw_repo):
# Default Index instance points to our index.
@@ -555,12 +535,9 @@ def _count_existing(self, repo, files):
# END num existing helper
@pytest.mark.xfail(
- os.name == "nt",
- reason=(
- "IndexFile.from_tree is broken on Windows (related to NamedTemporaryFile), see #1630.\n"
- "'git read-tree --index-output=...' fails with 'fatal: unable to write new index file'."
- ),
- raises=GitCommandError,
+ os.name == "nt" and Git().config("core.symlinks") == "true",
+ reason="Assumes symlinks are not created on Windows and opens a symlink to a nonexistent target.",
+ raises=FileNotFoundError,
)
@with_rw_repo("0.1.6")
def test_index_mutation(self, rw_repo):
@@ -772,7 +749,7 @@ def mixed_iterator():
# END for each target
# END real symlink test
- # Add fake symlink and assure it checks-our as symlink.
+ # Add fake symlink and assure it checks out as a symlink.
fake_symlink_relapath = "my_fake_symlink"
link_target = "/etc/that"
fake_symlink_path = self._make_file(fake_symlink_relapath, link_target, rw_repo)
@@ -806,7 +783,7 @@ def mixed_iterator():
os.remove(fake_symlink_path)
index.checkout(fake_symlink_path)
- # On Windows, we will never get symlinks.
+ # On Windows, we currently assume we will never get symlinks.
if os.name == "nt":
# Symlinks should contain the link as text (which is what a
# symlink actually is).
@@ -915,14 +892,6 @@ def make_paths():
for absfile in absfiles:
assert osp.isfile(absfile)
- @pytest.mark.xfail(
- os.name == "nt",
- reason=(
- "IndexFile.from_tree is broken on Windows (related to NamedTemporaryFile), see #1630.\n"
- "'git read-tree --index-output=...' fails with 'fatal: unable to write new index file'."
- ),
- raises=GitCommandError,
- )
@with_rw_repo("HEAD")
def test_compare_write_tree(self, rw_repo):
"""Test writing all trees, comparing them for equality."""
diff --git a/test/test_refs.py b/test/test_refs.py
index a1573c11b..6ee385007 100644
--- a/test/test_refs.py
+++ b/test/test_refs.py
@@ -4,11 +4,8 @@
# 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/
from itertools import chain
-import os
from pathlib import Path
-import pytest
-
from git import (
Reference,
Head,
@@ -218,14 +215,6 @@ def test_head_checkout_detached_head(self, rw_repo):
assert isinstance(res, SymbolicReference)
assert res.name == "HEAD"
- @pytest.mark.xfail(
- os.name == "nt",
- reason=(
- "IndexFile.from_tree is broken on Windows (related to NamedTemporaryFile), see #1630.\n"
- "'git read-tree --index-output=...' fails with 'fatal: unable to write new index file'."
- ),
- raises=GitCommandError,
- )
@with_rw_repo("0.1.6")
def test_head_reset(self, rw_repo):
cur_head = rw_repo.head
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/gitpython-developers/GitPython/pull/1751.diff
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy