Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-dulwich for openSUSE:Factory checked in at 2021-11-15 15:26:21 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-dulwich (Old) and /work/SRC/openSUSE:Factory/.python-dulwich.new.1890 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-dulwich" Mon Nov 15 15:26:21 2021 rev:43 rq:931288 version:0.20.26 Changes: -------- --- /work/SRC/openSUSE:Factory/python-dulwich/python-dulwich.changes 2021-10-20 20:24:10.537374050 +0200 +++ /work/SRC/openSUSE:Factory/.python-dulwich.new.1890/python-dulwich.changes 2021-11-15 15:27:59.173850145 +0100 @@ -1,0 +2,9 @@ +Sat Nov 13 20:25:50 UTC 2021 - Dirk M??ller <[email protected]> + +- update to 0.20.26: + * Support os.PathLike arguments to Repo.stage() + * Drop support for Python 3.5 + * Add ``dulwich.porcelain._reset_file`` + * Add ``Repo.unstage`` + +------------------------------------------------------------------- Old: ---- dulwich-0.20.25.tar.gz New: ---- dulwich-0.20.26.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-dulwich.spec ++++++ --- /var/tmp/diff_new_pack.BciMvl/_old 2021-11-15 15:27:59.753850308 +0100 +++ /var/tmp/diff_new_pack.BciMvl/_new 2021-11-15 15:27:59.757850309 +0100 @@ -20,7 +20,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-dulwich -Version: 0.20.25 +Version: 0.20.26 Release: 0 Summary: Pure-Python Git Library License: Apache-2.0 OR GPL-2.0-or-later ++++++ dulwich-0.20.25.tar.gz -> dulwich-0.20.26.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/.github/workflows/pythonpackage.yml new/dulwich-0.20.26/.github/workflows/pythonpackage.yml --- old/dulwich-0.20.25/.github/workflows/pythonpackage.yml 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/.github/workflows/pythonpackage.yml 2021-10-29 02:37:19.000000000 +0200 @@ -13,7 +13,7 @@ strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [3.5, 3.6, 3.7, 3.8, 3.9, 3.10-dev, pypy3] + python-version: [3.6, 3.7, 3.8, 3.9, 3.10-dev, pypy3] exclude: # sqlite3 exit handling seems to get in the way - os: macos-latest @@ -21,12 +21,6 @@ # doesn't support passing in bytestrings to os.scandir - os: windows-latest python-version: pypy3 - # path encoding - - os: windows-latest - python-version: 3.5 - # path encoding - - os: macos-latest - python-version: 3.5 fail-fast: false steps: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/.github/workflows/pythonpublish.yml new/dulwich-0.20.26/.github/workflows/pythonpublish.yml --- old/dulwich-0.20.25/.github/workflows/pythonpublish.yml 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/.github/workflows/pythonpublish.yml 2021-10-29 02:37:19.000000000 +0200 @@ -12,16 +12,11 @@ strategy: matrix: os: [macos-latest, windows-latest] - python-version: ['3.5', '3.6', '3.7', '3.8', '3.9'] + python-version: ['3.6', '3.7', '3.8', '3.9', '3.10'] include: - os: ubuntu-latest python-version: '3.x' # path encoding - exclude: - - os: windows-latest - python-version: 3.5 - - os: macos-latest - python-version: 3.5 fail-fast: false steps: @@ -56,12 +51,12 @@ - name: Build and publish (Linux aarch64) uses: RalfG/[email protected]_aarch64 with: - python-versions: 'cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39' + python-versions: 'cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310' if: "matrix.os == 'ubuntu-latest'" - name: Build and publish (Linux) uses: RalfG/[email protected] with: - python-versions: 'cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39' + python-versions: 'cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310' env: # Temporary fix for LD_LIBRARY_PATH issue. See # https://github.com/RalfG/python-wheels-manylinux-build/issues/26 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/NEWS new/dulwich-0.20.26/NEWS --- old/dulwich-0.20.25/NEWS 2021-08-23 09:48:25.000000000 +0200 +++ new/dulwich-0.20.26/NEWS 2021-10-29 02:39:02.000000000 +0200 @@ -1,3 +1,15 @@ +0.20.26 2021-10-29 + + * Support os.PathLike arguments to Repo.stage(). + (Jan Wi??niewski, #907) + + * Drop support for Python 3.5. (Jelmer Vernoo??) + + * Add ``dulwich.porcelain._reset_file``. + (Ded_Secer) + + * Add ``Repo.unstage``. (Ded_Secer) + 0.20.25 2021-08-23 * Fix ``dulwich`` script when installed via setup.py. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/PKG-INFO new/dulwich-0.20.26/PKG-INFO --- old/dulwich-0.20.25/PKG-INFO 2021-08-23 09:48:33.554272700 +0200 +++ new/dulwich-0.20.26/PKG-INFO 2021-10-29 02:39:09.031071400 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: dulwich -Version: 0.20.25 +Version: 0.20.26 Summary: Python Git Library Home-page: https://www.dulwich.io/ Author: Jelmer Vernooij @@ -13,17 +13,17 @@ Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: License :: OSI Approved :: Apache Software License -Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Operating System :: POSIX Classifier: Operating System :: Microsoft :: Windows Classifier: Topic :: Software Development :: Version Control -Requires-Python: >=3.5 +Requires-Python: >=3.6 Provides-Extra: fastimport Provides-Extra: https Provides-Extra: pgp @@ -121,10 +121,7 @@ Supported versions of Python ---------------------------- -At the moment, Dulwich supports (and is tested on) CPython 3.5 and later and +At the moment, Dulwich supports (and is tested on) CPython 3.6 and later and Pypy. -The latest release series to support Python 2.x was the 0.19 series. See -the 0.19 branch in the Dulwich git repository. - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/README.rst new/dulwich-0.20.26/README.rst --- old/dulwich-0.20.25/README.rst 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/README.rst 2021-10-29 02:37:19.000000000 +0200 @@ -88,8 +88,5 @@ Supported versions of Python ---------------------------- -At the moment, Dulwich supports (and is tested on) CPython 3.5 and later and +At the moment, Dulwich supports (and is tested on) CPython 3.6 and later and Pypy. - -The latest release series to support Python 2.x was the 0.19 series. See -the 0.19 branch in the Dulwich git repository. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/__init__.py new/dulwich-0.20.26/dulwich/__init__.py --- old/dulwich-0.20.25/dulwich/__init__.py 2021-08-23 09:48:25.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/__init__.py 2021-10-29 02:39:02.000000000 +0200 @@ -22,4 +22,4 @@ """Python implementation of the Git file formats and protocols.""" -__version__ = (0, 20, 25) +__version__ = (0, 20, 26) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/client.py new/dulwich-0.20.26/dulwich/client.py --- old/dulwich-0.20.25/dulwich/client.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/client.py 2021-10-29 02:37:19.000000000 +0200 @@ -43,6 +43,7 @@ import logging import os import select +import shlex import socket import subprocess import sys @@ -1467,6 +1468,7 @@ port=None, password=None, key_filename=None, + ssh_command=None, ): """Connect to an SSH server. @@ -1480,6 +1482,7 @@ port: Optional SSH port to use password: Optional ssh password for login or private key key_filename: Optional path to private keyfile + ssh_command: Optional SSH command Returns: @@ -1505,6 +1508,7 @@ port=None, password=None, key_filename=None, + ssh_command=None, ): if password is not None: @@ -1512,7 +1516,10 @@ "Setting password not supported by SubprocessSSHVendor." ) - args = ["ssh", "-x"] + if ssh_command: + args = shlex.split(ssh_command) + ["-x"] + else: + args = ["ssh", "-x"] if port: args.extend(["-p", str(port)]) @@ -1547,9 +1554,12 @@ port=None, password=None, key_filename=None, + ssh_command=None, ): - if sys.platform == "win32": + if ssh_command: + args = shlex.split(ssh_command) + ["-ssh"] + elif sys.platform == "win32": args = ["plink.exe", "-ssh"] else: args = ["plink", "-ssh"] @@ -1611,6 +1621,7 @@ config=None, password=None, key_filename=None, + ssh_command=None, **kwargs ): self.host = host @@ -1618,6 +1629,9 @@ self.username = username self.password = password self.key_filename = key_filename + self.ssh_command = ssh_command or os.environ.get( + "GIT_SSH_COMMAND", os.environ.get("GIT_SSH") + ) super(SSHGitClient, self).__init__(**kwargs) self.alternative_paths = {} if vendor is not None: @@ -1667,6 +1681,9 @@ kwargs["password"] = self.password if self.key_filename is not None: kwargs["key_filename"] = self.key_filename + # GIT_SSH_COMMAND takes precendence over GIT_SSH + if self.ssh_command is not None: + kwargs["ssh_command"] = self.ssh_command con = self.ssh_vendor.run_command( self.host, argv, port=self.port, username=self.username, **kwargs ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/contrib/paramiko_vendor.py new/dulwich-0.20.26/dulwich/contrib/paramiko_vendor.py --- old/dulwich-0.20.25/dulwich/contrib/paramiko_vendor.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/contrib/paramiko_vendor.py 2021-10-29 02:37:19.000000000 +0200 @@ -44,7 +44,7 @@ @property def stderr(self): - return self.channel.makefile_stderr() + return self.channel.makefile_stderr('rb') def can_read(self): return self.channel.recv_ready() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/errors.py new/dulwich-0.20.26/dulwich/errors.py --- old/dulwich-0.20.25/dulwich/errors.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/errors.py 2021-10-29 02:37:19.000000000 +0200 @@ -21,6 +21,11 @@ """Dulwich-related exception classes and utility functions.""" + +# Please do not add more errors here, but instead add them close to the code +# that raises the error. + + import binascii diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/hooks.py new/dulwich-0.20.26/dulwich/hooks.py --- old/dulwich-0.20.25/dulwich/hooks.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/hooks.py 2021-10-29 02:37:19.000000000 +0200 @@ -193,12 +193,12 @@ ) # client_refs is a list of (oldsha, newsha, ref) - in_data = "\n".join([" ".join(ref) for ref in client_refs]) + in_data = b"\n".join([b" ".join(ref) for ref in client_refs]) out_data, err_data = p.communicate(in_data) if (p.returncode != 0) or err_data: - err_fmt = "post-receive exit code: %d\n" + "stdout:\n%s\nstderr:\n%s" + err_fmt = b"post-receive exit code: %d\n" + b"stdout:\n%s\nstderr:\n%s" err_msg = err_fmt % (p.returncode, out_data, err_data) raise HookError(err_msg.decode('utf-8', 'backslashreplace')) return out_data diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/objectspec.py new/dulwich-0.20.26/dulwich/objectspec.py --- old/dulwich-0.20.25/dulwich/objectspec.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/objectspec.py 2021-10-29 02:37:19.000000000 +0200 @@ -54,6 +54,10 @@ KeyError: If the object can not be found """ treeish = to_bytes(treeish) + try: + treeish = parse_ref(repo, treeish) + except KeyError: # treeish is commit sha + pass o = repo[treeish] if o.type_name == b"commit": return repo[o.tree] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/pack.py new/dulwich-0.20.26/dulwich/pack.py --- old/dulwich-0.20.25/dulwich/pack.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/pack.py 2021-10-29 02:37:19.000000000 +0200 @@ -1439,7 +1439,8 @@ # Unlike PackData.get_object_at, there is no need to cache offsets as # this approach by design inflates each object exactly once. todo = [(offset, obj_type_num, base_chunks)] - for offset, obj_type_num, base_chunks in todo: + while todo: + (offset, obj_type_num, base_chunks) = todo.pop() unpacked = self._resolve_object(offset, obj_type_num, base_chunks) yield self._result(unpacked) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/porcelain.py new/dulwich-0.20.26/dulwich/porcelain.py --- old/dulwich-0.20.25/dulwich/porcelain.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/porcelain.py 2021-10-29 02:37:19.000000000 +0200 @@ -53,6 +53,10 @@ These functions are meant to behave similarly to the git subcommands. Differences in behaviour are considered bugs. +Note: one of the consequences of this is that paths tend to be +interpreted relative to the current working directory rather than relative +to the repository root. + Functions should generally accept both unicode strings and bytestrings """ @@ -104,6 +108,8 @@ from dulwich.index import ( blob_from_path_and_stat, get_unstaged_changes, + build_file_from_blob, + _fs_to_tree_path, ) from dulwich.object_store import ( tree_lookup_path, @@ -218,52 +224,36 @@ path: A path, absolute or relative to the cwd Returns: A path formatted for use in e.g. an index """ - # Pathlib resolve before Python 3.6 could raises FileNotFoundError in case - # there is no file matching the path so we reuse the old implementation for - # Python 3.5 - if sys.version_info < (3, 6): - if not isinstance(path, bytes): - path = os.fsencode(path) - if not isinstance(repopath, bytes): - repopath = os.fsencode(repopath) - treepath = os.path.relpath(path, repopath) - if treepath.startswith(b".."): - err_msg = "Path %r not in repo path (%r)" % (path, repopath) - raise ValueError(err_msg) - if os.path.sep != "/": - treepath = treepath.replace(os.path.sep.encode("ascii"), b"/") - return treepath - else: - # Resolve might returns a relative path on Windows - # https://bugs.python.org/issue38671 - if sys.platform == "win32": - path = os.path.abspath(path) - - path = Path(path) - resolved_path = path.resolve() - - # Resolve and abspath seems to behave differently regarding symlinks, - # as we are doing abspath on the file path, we need to do the same on - # the repo path or they might not match - if sys.platform == "win32": - repopath = os.path.abspath(repopath) + # Resolve might returns a relative path on Windows + # https://bugs.python.org/issue38671 + if sys.platform == "win32": + path = os.path.abspath(path) + + path = Path(path) + resolved_path = path.resolve() + + # Resolve and abspath seems to behave differently regarding symlinks, + # as we are doing abspath on the file path, we need to do the same on + # the repo path or they might not match + if sys.platform == "win32": + repopath = os.path.abspath(repopath) - repopath = Path(repopath).resolve() + repopath = Path(repopath).resolve() - try: - relpath = resolved_path.relative_to(repopath) - except ValueError: - # If path is a symlink that points to a file outside the repo, we - # want the relpath for the link itself, not the resolved target - if path.is_symlink(): - parent = path.parent.resolve() - relpath = (parent / path.name).relative_to(repopath) - else: - raise - if sys.platform == "win32": - return str(relpath).replace(os.path.sep, "/").encode(tree_encoding) + try: + relpath = resolved_path.relative_to(repopath) + except ValueError: + # If path is a symlink that points to a file outside the repo, we + # want the relpath for the link itself, not the resolved target + if path.is_symlink(): + parent = path.parent.resolve() + relpath = (parent / path.name).relative_to(repopath) else: - return bytes(relpath) + raise + if sys.platform == "win32": + return str(relpath).replace(os.path.sep, "/").encode(tree_encoding) + else: + return bytes(relpath) class DivergedBranches(Error): @@ -1753,6 +1743,24 @@ r.refs.set_symbolic_ref(b"HEAD", to_set) +def reset_file(repo, file_path: str, target: bytes = b'HEAD'): + """Reset the file to specific commit or branch. + + Args: + repo: dulwich Repo object + file_path: file to reset, relative to the repository path + target: branch or commit or b'HEAD' to reset + """ + tree = parse_tree(repo, treeish=target) + file_path = _fs_to_tree_path(file_path) + + file_entry = tree.lookup_path(repo.object_store.__getitem__, file_path) + full_path = os.path.join(repo.path.encode(), file_path) + blob = repo.object_store[file_entry[1]] + mode = file_entry[0] + build_file_from_blob(blob, mode, full_path) + + def check_mailmap(repo, contact): """Check canonical name and email of contact. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/repo.py new/dulwich-0.20.26/dulwich/repo.py --- old/dulwich-0.20.25/dulwich/repo.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/repo.py 2021-10-29 02:37:19.000000000 +0200 @@ -1253,7 +1253,7 @@ # missing index file, which is treated as empty. return not self.bare - def stage(self, fs_paths): + def stage(self, fs_paths: Union[str, bytes, os.PathLike, Iterable[Union[str, bytes, os.PathLike]]]) -> None: """Stage a set of paths. Args: @@ -1262,7 +1262,7 @@ root_path_bytes = os.fsencode(self.path) - if isinstance(fs_paths, str): + if isinstance(fs_paths, (str, bytes, os.PathLike)): fs_paths = [fs_paths] fs_paths = list(fs_paths) @@ -1305,6 +1305,65 @@ index[tree_path] = index_entry_from_stat(st, blob.id, 0) index.write() + def unstage(self, fs_paths: List[str]): + """unstage specific file in the index + Args: + fs_paths: a list of files to unstage, + relative to the repository path + """ + from dulwich.index import ( + IndexEntry, + _fs_to_tree_path, + ) + + index = self.open_index() + try: + tree_id = self[b'HEAD'].tree + except KeyError: + # no head mean no commit in the repo + for fs_path in fs_paths: + tree_path = _fs_to_tree_path(fs_path) + del index[tree_path] + index.write() + return + + for fs_path in fs_paths: + tree_path = _fs_to_tree_path(fs_path) + try: + tree_entry = self.object_store[tree_id].lookup_path( + self.object_store.__getitem__, tree_path) + except KeyError: + # if tree_entry didnt exist, this file was being added, so + # remove index entry + try: + del index[tree_path] + continue + except KeyError: + raise KeyError("file '%s' not in index" % (tree_path.decode())) + + st = None + try: + st = os.lstat(os.path.join(self.path, fs_path)) + except FileNotFoundError: + pass + + index_entry = IndexEntry( + ctime=(self[b'HEAD'].commit_time, 0), + mtime=(self[b'HEAD'].commit_time, 0), + dev=st.st_dev if st else 0, + ino=st.st_ino if st else 0, + mode=tree_entry[0], + uid=st.st_uid if st else 0, + gid=st.st_gid if st else 0, + size=len(self[tree_entry[1]].data), + sha=tree_entry[1], + flags=0, + extended_flags=0 + ) + + index[tree_path] = index_entry + index.write() + def clone( self, target_path, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/tests/test_client.py new/dulwich-0.20.26/dulwich/tests/test_client.py --- old/dulwich-0.20.25/dulwich/tests/test_client.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/tests/test_client.py 2021-10-29 02:37:19.000000000 +0200 @@ -705,6 +705,7 @@ port=None, password=None, key_filename=None, + ssh_command=None, ): self.host = host self.command = command @@ -712,6 +713,7 @@ self.port = port self.password = password self.key_filename = key_filename + self.ssh_command = ssh_command class Subprocess: pass @@ -785,6 +787,21 @@ client._connect(b"relative-command", b"/~/path/to/repo") self.assertEqual("git-relative-command '~/path/to/repo'", server.command) + def test_ssh_command_precedence(self): + os.environ["GIT_SSH"] = "/path/to/ssh" + test_client = SSHGitClient("git.samba.org") + self.assertEqual(test_client.ssh_command, "/path/to/ssh") + + os.environ["GIT_SSH_COMMAND"] = "/path/to/ssh -o Option=Value" + test_client = SSHGitClient("git.samba.org") + self.assertEqual(test_client.ssh_command, "/path/to/ssh -o Option=Value") + + test_client = SSHGitClient("git.samba.org", ssh_command="ssh -o Option1=Value1") + self.assertEqual(test_client.ssh_command, "ssh -o Option1=Value1") + + del os.environ["GIT_SSH"] + del os.environ["GIT_SSH_COMMAND"] + class ReportStatusParserTests(TestCase): def test_invalid_pack(self): @@ -1230,6 +1247,26 @@ self.assertListEqual(expected, args[0]) + def test_run_with_ssh_command(self): + expected = [ + "/path/to/ssh", + "-o", + "Option=Value", + "-x", + "host", + "git-clone-url", + ] + + vendor = SubprocessSSHVendor() + command = vendor.run_command( + "host", + "git-clone-url", + ssh_command="/path/to/ssh -o Option=Value", + ) + + args = command.proc.args + self.assertListEqual(expected, args[0]) + class PLinkSSHVendorTests(TestCase): def setUp(self): @@ -1353,6 +1390,24 @@ self.assertListEqual(expected, args[0]) + def test_run_with_ssh_command(self): + expected = [ + "/path/to/plink", + "-x", + "host", + "git-clone-url", + ] + + vendor = SubprocessSSHVendor() + command = vendor.run_command( + "host", + "git-clone-url", + ssh_command="/path/to/plink", + ) + + args = command.proc.args + self.assertListEqual(expected, args[0]) + class RsyncUrlTests(TestCase): def test_simple(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/tests/test_objectspec.py new/dulwich-0.20.26/dulwich/tests/test_objectspec.py --- old/dulwich-0.20.25/dulwich/tests/test_objectspec.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/tests/test_objectspec.py 2021-10-29 02:37:19.000000000 +0200 @@ -258,3 +258,9 @@ c1, c2, c3 = build_commit_graph(r.object_store, [[1], [2, 1], [3, 1, 2]]) self.assertEqual(r[c1.tree], parse_tree(r, c1.id)) self.assertEqual(r[c1.tree], parse_tree(r, c1.tree)) + + def test_from_ref(self): + r = MemoryRepo() + c1, c2, c3 = build_commit_graph(r.object_store, [[1], [2, 1], [3, 1, 2]]) + r.refs[b'refs/heads/foo'] = c1.id + self.assertEqual(r[c1.tree], parse_tree(r, b'foo')) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/tests/test_pack.py new/dulwich-0.20.26/dulwich/tests/test_pack.py --- old/dulwich-0.20.25/dulwich/tests/test_pack.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/tests/test_pack.py 2021-10-29 02:37:19.000000000 +0200 @@ -1032,7 +1032,8 @@ (OFS_DELTA, (0, b"blob2")), ], ) - self.assertEntriesMatch([0, 1, 2], entries, self.make_pack_iter(f)) + # Delta resolution changed to DFS + self.assertEntriesMatch([0, 2, 1], entries, self.make_pack_iter(f)) def test_ofs_deltas_chain(self): f = BytesIO() @@ -1056,7 +1057,8 @@ (REF_DELTA, (1, b"blob2")), ], ) - self.assertEntriesMatch([1, 0, 2], entries, self.make_pack_iter(f)) + # Delta resolution changed to DFS + self.assertEntriesMatch([1, 2, 0], entries, self.make_pack_iter(f)) def test_ref_deltas_chain(self): f = BytesIO() @@ -1082,7 +1084,9 @@ (OFS_DELTA, (1, b"blob2")), ], ) - self.assertEntriesMatch([1, 2, 0], entries, self.make_pack_iter(f)) + + # Delta resolution changed to DFS + self.assertEntriesMatch([1, 0, 2], entries, self.make_pack_iter(f)) def test_mixed_chain(self): f = BytesIO() @@ -1094,9 +1098,9 @@ (OFS_DELTA, (0, b"blob1")), (OFS_DELTA, (1, b"blob3")), (OFS_DELTA, (0, b"bob")), - ], - ) - self.assertEntriesMatch([0, 2, 4, 1, 3], entries, self.make_pack_iter(f)) + ]) + # Delta resolution changed to DFS + self.assertEntriesMatch([0, 4, 2, 1, 3], entries, self.make_pack_iter(f)) def test_long_chain(self): n = 100 @@ -1114,7 +1118,9 @@ objects_spec.append((OFS_DELTA, (0, b"blob" + str(i).encode("ascii")))) f = BytesIO() entries = build_pack(f, objects_spec) - self.assertEntriesMatch(range(n + 1), entries, self.make_pack_iter(f)) + # Delta resolution changed to DFS + indices = [0] + list(range(100, 0, -1)) + self.assertEntriesMatch(indices, entries, self.make_pack_iter(f)) def test_ext_ref(self): (blob,) = self.store_blobs([b"blob"]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/tests/test_porcelain.py new/dulwich-0.20.26/dulwich/tests/test_porcelain.py --- old/dulwich-0.20.25/dulwich/tests/test_porcelain.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/tests/test_porcelain.py 2021-10-29 02:37:19.000000000 +0200 @@ -35,7 +35,9 @@ from dulwich import porcelain from dulwich.diff_tree import tree_changes -from dulwich.errors import CommitError +from dulwich.errors import ( + CommitError, +) from dulwich.objects import ( Blob, Tag, @@ -1317,6 +1319,73 @@ self.assertEqual([], changes) +class ResetFileTests(PorcelainTestCase): + + def test_reset_modify_file_to_commit(self): + file = 'foo' + full_path = os.path.join(self.repo.path, file) + + with open(full_path, 'w') as f: + f.write('hello') + porcelain.add(self.repo, paths=[full_path]) + sha = porcelain.commit( + self.repo, + message=b"unitest", + committer=b"Jane <[email protected]>", + author=b"John <[email protected]>", + ) + with open(full_path, 'a') as f: + f.write('something new') + porcelain.reset_file(self.repo, file, target=sha) + + with open(full_path, 'r') as f: + self.assertEqual('hello', f.read()) + + def test_reset_remove_file_to_commit(self): + file = 'foo' + full_path = os.path.join(self.repo.path, file) + + with open(full_path, 'w') as f: + f.write('hello') + porcelain.add(self.repo, paths=[full_path]) + sha = porcelain.commit( + self.repo, + message=b"unitest", + committer=b"Jane <[email protected]>", + author=b"John <[email protected]>", + ) + os.remove(full_path) + porcelain.reset_file(self.repo, file, target=sha) + + with open(full_path, 'r') as f: + self.assertEqual('hello', f.read()) + + def test_resetfile_with_dir(self): + os.mkdir(os.path.join(self.repo.path, 'new_dir')) + full_path = os.path.join(self.repo.path, 'new_dir', 'foo') + + with open(full_path, 'w') as f: + f.write('hello') + porcelain.add(self.repo, paths=[full_path]) + sha = porcelain.commit( + self.repo, + message=b"unitest", + committer=b"Jane <[email protected]>", + author=b"John <[email protected]>", + ) + with open(full_path, 'a') as f: + f.write('something new') + porcelain.commit( + self.repo, + message=b"unitest 2", + committer=b"Jane <[email protected]>", + author=b"John <[email protected]>", + ) + porcelain.reset_file(self.repo, os.path.join('new_dir', 'foo'), target=sha) + with open(full_path, 'r') as f: + self.assertEqual('hello', f.read()) + + class PushTests(PorcelainTestCase): def test_simple(self): """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich/tests/test_repository.py new/dulwich-0.20.26/dulwich/tests/test_repository.py --- old/dulwich-0.20.25/dulwich/tests/test_repository.py 2021-08-23 09:46:56.000000000 +0200 +++ new/dulwich-0.20.26/dulwich/tests/test_repository.py 2021-10-29 02:37:19.000000000 +0200 @@ -31,6 +31,7 @@ import warnings from dulwich import errors +from dulwich import porcelain from dulwich.object_store import ( tree_lookup_path, ) @@ -1226,6 +1227,87 @@ r.stage(["c"]) self.assertEqual([b"a"], list(r.open_index())) + def test_unstage_midify_file_with_dir(self): + os.mkdir(os.path.join(self._repo.path, 'new_dir')) + full_path = os.path.join(self._repo.path, 'new_dir', 'foo') + + with open(full_path, 'w') as f: + f.write('hello') + porcelain.add(self._repo, paths=[full_path]) + porcelain.commit( + self._repo, + message=b"unitest", + committer=b"Jane <[email protected]>", + author=b"John <[email protected]>", + ) + with open(full_path, 'a') as f: + f.write('something new') + self._repo.unstage(['new_dir/foo']) + status = list(porcelain.status(self._repo)) + self.assertEqual([{'add': [], 'delete': [], 'modify': []}, [b'new_dir/foo'], []], status) + + def test_unstage_while_no_commit(self): + file = 'foo' + full_path = os.path.join(self._repo.path, file) + with open(full_path, 'w') as f: + f.write('hello') + porcelain.add(self._repo, paths=[full_path]) + self._repo.unstage([file]) + status = list(porcelain.status(self._repo)) + self.assertEqual([{'add': [], 'delete': [], 'modify': []}, [], ['foo']], status) + + def test_unstage_add_file(self): + file = 'foo' + full_path = os.path.join(self._repo.path, file) + porcelain.commit( + self._repo, + message=b"unitest", + committer=b"Jane <[email protected]>", + author=b"John <[email protected]>", + ) + with open(full_path, 'w') as f: + f.write('hello') + porcelain.add(self._repo, paths=[full_path]) + self._repo.unstage([file]) + status = list(porcelain.status(self._repo)) + self.assertEqual([{'add': [], 'delete': [], 'modify': []}, [], ['foo']], status) + + def test_unstage_modify_file(self): + file = 'foo' + full_path = os.path.join(self._repo.path, file) + with open(full_path, 'w') as f: + f.write('hello') + porcelain.add(self._repo, paths=[full_path]) + porcelain.commit( + self._repo, + message=b"unitest", + committer=b"Jane <[email protected]>", + author=b"John <[email protected]>", + ) + with open(full_path, 'a') as f: + f.write('broken') + porcelain.add(self._repo, paths=[full_path]) + self._repo.unstage([file]) + status = list(porcelain.status(self._repo)) + self.assertEqual([{'add': [], 'delete': [], 'modify': []}, [b'foo'], []], status) + + def test_unstage_remove_file(self): + file = 'foo' + full_path = os.path.join(self._repo.path, file) + with open(full_path, 'w') as f: + f.write('hello') + porcelain.add(self._repo, paths=[full_path]) + porcelain.commit( + self._repo, + message=b"unitest", + committer=b"Jane <[email protected]>", + author=b"John <[email protected]>", + ) + os.remove(full_path) + self._repo.unstage([file]) + status = list(porcelain.status(self._repo)) + self.assertEqual([{'add': [], 'delete': [], 'modify': []}, [b'foo'], []], status) + @skipIf( sys.platform in ("win32", "darwin"), "tries to implicitly decode as utf8", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/dulwich.egg-info/PKG-INFO new/dulwich-0.20.26/dulwich.egg-info/PKG-INFO --- old/dulwich-0.20.25/dulwich.egg-info/PKG-INFO 2021-08-23 09:48:33.000000000 +0200 +++ new/dulwich-0.20.26/dulwich.egg-info/PKG-INFO 2021-10-29 02:39:08.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: dulwich -Version: 0.20.25 +Version: 0.20.26 Summary: Python Git Library Home-page: https://www.dulwich.io/ Author: Jelmer Vernooij @@ -13,17 +13,17 @@ Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: License :: OSI Approved :: Apache Software License -Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Operating System :: POSIX Classifier: Operating System :: Microsoft :: Windows Classifier: Topic :: Software Development :: Version Control -Requires-Python: >=3.5 +Requires-Python: >=3.6 Provides-Extra: fastimport Provides-Extra: https Provides-Extra: pgp @@ -121,10 +121,7 @@ Supported versions of Python ---------------------------- -At the moment, Dulwich supports (and is tested on) CPython 3.5 and later and +At the moment, Dulwich supports (and is tested on) CPython 3.6 and later and Pypy. -The latest release series to support Python 2.x was the 0.19 series. See -the 0.19 branch in the Dulwich git repository. - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dulwich-0.20.25/setup.py new/dulwich-0.20.26/setup.py --- old/dulwich-0.20.25/setup.py 2021-08-23 09:48:25.000000000 +0200 +++ new/dulwich-0.20.26/setup.py 2021-10-29 02:39:02.000000000 +0200 @@ -17,13 +17,13 @@ from typing import Dict, Any -if sys.version_info < (3, 5): +if sys.version_info < (3, 6): raise Exception( - 'Dulwich only supports Python 3.5 and later. ' + 'Dulwich only supports Python 3.6 and later. ' 'For 2.7 support, please install a version prior to 0.20') -dulwich_version_string = '0.20.25' +dulwich_version_string = '0.20.26' class DulwichDistribution(Distribution): @@ -88,7 +88,7 @@ "console_scripts": [ "dulwich=dulwich.cli:main", ]} - setup_kwargs['python_requires'] = '>=3.5' + setup_kwargs['python_requires'] = '>=3.6' else: scripts.append('bin/dulwich') @@ -121,11 +121,11 @@ classifiers=[ 'Development Status :: 4 - Beta', 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', 'Operating System :: POSIX',
