[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#986411: unblock: pristine-lfs/20210404.0-2



On Mon, 05 Apr 2021 15:26:04 +0200 Andrej Shadura <andrewsh@debian.org>
wrote:
> retitle 986411 unblock: pristine-lfs/20210404.0-2
> thanks
> 
> Chris has reported a bug (#986446): test results XML file was
> shipped with the package; I have now fixed that bug with an extra upload.

Please find attached debdiff for 20210404.0-2.

unblock pristine-lfs/20210404.0-2

-- 
Cheers,
  Andrej
diff --git a/PKG-INFO b/PKG-INFO
index 8db2f11..5b3e484 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: pristine-lfs
-Version: 20210222.0
+Version: 20210404.0
 Summary: a pristine-tar replacement that works with Git LFS
 Home-page: https://salsa.debian.org/pristine-lfs-team/pristine-lfs
 Author: Andrej Shadura
diff --git a/debian/changelog b/debian/changelog
index 9804ad5..5945e7c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,17 @@
+pristine-lfs (20210404.0-2) unstable; urgency=medium
+
+  * Make sure pytest doesn’t pollute the build directory with test
+    results which would otherwise be installed with the package
+    (Closes: #986446).
+
+ -- Andrej Shadura <andrew.shadura@collabora.co.uk>  Tue, 06 Apr 2021 11:41:59 +0200
+
+pristine-lfs (20210404.0-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Andrej Shadura <andrew.shadura@collabora.co.uk>  Sun, 04 Apr 2021 22:15:42 +0200
+
 pristine-lfs (20210222.0-1) unstable; urgency=medium
 
   * New upstream release.
diff --git a/debian/rules b/debian/rules
index 14866b0..44e71fc 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,5 +1,6 @@
 #!/usr/bin/make -f
 
+export PYBUILD_TEST_ARGS = --junit-xml=/dev/null
 
 %:
 	dh $@ --buildsystem=pybuild
diff --git a/pristine_lfs.egg-info/PKG-INFO b/pristine_lfs.egg-info/PKG-INFO
index 8db2f11..5b3e484 100644
--- a/pristine_lfs.egg-info/PKG-INFO
+++ b/pristine_lfs.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: pristine-lfs
-Version: 20210222.0
+Version: 20210404.0
 Summary: a pristine-tar replacement that works with Git LFS
 Home-page: https://salsa.debian.org/pristine-lfs-team/pristine-lfs
 Author: Andrej Shadura
diff --git a/pristine_lfs.egg-info/SOURCES.txt b/pristine_lfs.egg-info/SOURCES.txt
index 70a9467..2f79c38 100644
--- a/pristine_lfs.egg-info/SOURCES.txt
+++ b/pristine_lfs.egg-info/SOURCES.txt
@@ -6,8 +6,10 @@ pristine-lfs.rst
 setup.cfg
 setup.py
 pristine_lfs/__init__.py
+pristine_lfs/errors.py
 pristine_lfs/gitwrap.py
 pristine_lfs/gitwrap.pyi
+pristine_lfs/log.py
 pristine_lfs/main.py
 pristine_lfs/util.py
 pristine_lfs.egg-info/PKG-INFO
diff --git a/pristine_lfs.egg-info/requires.txt b/pristine_lfs.egg-info/requires.txt
index b065e88..9a19637 100644
--- a/pristine_lfs.egg-info/requires.txt
+++ b/pristine_lfs.egg-info/requires.txt
@@ -1,2 +1,2 @@
 python-debian
-sh
+sh>=1.14
diff --git a/pristine_lfs/__init__.py b/pristine_lfs/__init__.py
index 6df221a..ded6987 100644
--- a/pristine_lfs/__init__.py
+++ b/pristine_lfs/__init__.py
@@ -1,5 +1,6 @@
 from .main import (  # noqa: F401
     do_commit,
+    do_commit_files,
     do_checkout,
     do_list,
     do_import,
diff --git a/pristine_lfs/errors.py b/pristine_lfs/errors.py
new file mode 100644
index 0000000..ca1db96
--- /dev/null
+++ b/pristine_lfs/errors.py
@@ -0,0 +1,67 @@
+# pristine-lfs
+#
+# errors for pristine-lfs
+#
+# Copyright (C) 2021 Collabora Ltd
+# Copyright (C) 2021 Andrej Shadura <andrew.shadura@collabora.co.uk>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from __future__ import annotations
+
+from gettext import gettext as _
+
+from sh import ErrorReturnCode as CommandFailed  # noqa: F401
+
+
+class DifferentFilesExist(Exception):
+    files: list[str]
+
+    def __init__(self, files: list[str]):
+        self.files = files
+
+    def __str__(self):
+        return _("would overwrite files: {files}").format(files=', '.join(self.files))
+
+
+class UnsupportedHashAlgorithm(Exception):
+    algo: str
+
+    def __init__(self, algo: str):
+        self.algo = algo
+
+    def __str__(self):
+        return _("unsupported hash algorithm {algo}").format(
+            algo=self.algo,
+        )
+
+
+class GitError(Exception):
+    pass
+
+
+class GitFileNotFound(GitError):
+    filename: str
+    branch: str
+
+    def __init__(self, filename: str, branch: str):
+        self.filename = filename
+        self.branch = branch
+
+    def __str__(self):
+        return _('{filename} not found on branch {branch}').format(
+            filename=self.filename,
+            branch=self.branch,
+        )
+
+
+class GitBranchNotFound(GitError):
+    branch: str
+
+    def __init__(self, branch: str):
+        self.branch = branch
+
+    def __str__(self):
+        return _('No branch {branch} found, not even among remote branches').format(
+            branch=self.branch,
+        )
diff --git a/pristine_lfs/gitwrap.py b/pristine_lfs/gitwrap.py
index 0b0a83a..824988d 100644
--- a/pristine_lfs/gitwrap.py
+++ b/pristine_lfs/gitwrap.py
@@ -1,7 +1,7 @@
 # Wrapper for Git and Git LFS
 #
 # Copyright (C) 2021 Collabora Ltd
-# Andrej Shadura <andrew.shadura@collabora.co.uk>
+# Copyright (C) 2021 Andrej Shadura <andrew.shadura@collabora.co.uk>
 #
 # SPDX-License-Identifier: GPL-2.0-or-later
 
diff --git a/pristine_lfs/gitwrap.pyi b/pristine_lfs/gitwrap.pyi
index 200b212..c760b45 100644
--- a/pristine_lfs/gitwrap.pyi
+++ b/pristine_lfs/gitwrap.pyi
@@ -2,7 +2,7 @@
 # Extend as needed.
 #
 # Copyright (C) 2021 Collabora Ltd
-# Andrej Shadura <andrew.shadura@collabora.co.uk>
+# Copyright (C) 2021 Andrej Shadura <andrew.shadura@collabora.co.uk>
 
 from sh.contrib import git as sh_git
 
diff --git a/pristine_lfs/log.py b/pristine_lfs/log.py
new file mode 100644
index 0000000..a5b3cac
--- /dev/null
+++ b/pristine_lfs/log.py
@@ -0,0 +1,13 @@
+# pristine-lfs
+#
+# logging
+#
+# Copyright (C) 2021 Collabora Ltd
+# Copyright (C) 2021 Andrej Shadura <andrew.shadura@collabora.co.uk>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import logging
+
+
+logger = logging.getLogger("pristine-lfs")
diff --git a/pristine_lfs/main.py b/pristine_lfs/main.py
index 5cbaf66..921c312 100644
--- a/pristine_lfs/main.py
+++ b/pristine_lfs/main.py
@@ -3,7 +3,7 @@
 # store pristine tarballs in Git LFS
 #
 # Copyright (C) 2019—2021 Collabora Ltd
-# Andrej Shadura <andrew.shadura@collabora.co.uk>
+# Copyright (C) 2019—2021 Andrej Shadura <andrew.shadura@collabora.co.uk>
 #
 # SPDX-License-Identifier: GPL-2.0-or-later
 
@@ -18,6 +18,7 @@ from typing import (
     IO,
     Iterable,
     Optional,
+    Sequence,
     Union
 )
 
@@ -25,9 +26,14 @@ import sh
 from debian import deb822
 from debian.changelog import Changelog, Version
 
+from .errors import (
+    CommandFailed,
+    DifferentFilesExist,
+    GitError,
+    UnsupportedHashAlgorithm,
+)
+from .log import logger
 from .util import (
-    Abort,
-    GitFileNotFound,
     check_branch,
     checkout_lfs_file,
     checkout_package,
@@ -53,13 +59,29 @@ def do_commit(tarball: IO[bytes], branch: str, message: Optional[str] = None, fo
     commit_lfs_file(tarball, branch, message, overwrite=force_overwrite)
 
 
-def do_checkout(branch: str, tarball: Optional[str] = None, outdir: Union[str, Path] = '.', full: bool = False, **kwargs):
+def do_commit_files(tarballs: Sequence[IO[bytes]], branch: str, message: Optional[str] = None,
+                    force_overwrite: bool = False, **kwargs):
+    """
+    Commit open files to a branch using Git LFS.
+    Set force_overwrite to overwrite existing files with same names and different checksums.
+    Message may contain "%s" which gets replaced with a comma-separate list of the file committed.
+    """
+    if check_branch(branch) is None:
+        if find_remote_branches(branch):
+            track_remote_branch(branch)
+    commit_lfs_files(tarballs, branch, message, overwrite=force_overwrite)
+
+
+def do_checkout(branch: str, tarball: Optional[str] = None, outdir: Union[str, Path] = '.', full: bool = False,
+                package: Optional[str] = None, version: Union[str, Version, None] = None, **kwargs):
     """
     Check out one or multiple files.
     If tarball is non-None:
         * file name only: tarball to check out to outdir.
         * path with to file: the location where to check out to
     If tarball is None:
+        * if package and version are specified, that version
+          is checked out
         * a tarball corresponding to the latest entry in
           debian/changelog is found and checked out
 
@@ -74,10 +96,11 @@ def do_checkout(branch: str, tarball: Optional[str] = None, outdir: Union[str, P
         if path:
             outdir = path
     else:
-        changelog = Path("debian/changelog")
-        with changelog.open() as f:
-            ch = Changelog(f, max_blocks=1)
-        package, version = ch.package, ch.version
+        if not package or not version:
+            changelog = Path("debian/changelog")
+            with changelog.open() as f:
+                ch = Changelog(f, max_blocks=1)
+            package, version = ch.package, ch.version
 
     outdir = Path(outdir)
     outdir.mkdir(parents=True, exist_ok=True)
@@ -86,24 +109,24 @@ def do_checkout(branch: str, tarball: Optional[str] = None, outdir: Union[str, P
         if tarball:
             dsc_file = tarball
         else:
-            fver = Version(ch.version)
+            fver = Version(version)
             fver.epoch = None
             dsc_file = f'{package}_{fver}.dsc'
-        logging.info(_("Checking out file {} in {}").format(dsc_file, outdir))
+        logger.info(_("Checking out file {} in {}").format(dsc_file, outdir))
         checkout_lfs_file(branch, dsc_file, outdir)
         if dsc_file.endswith('.dsc'):
             with (outdir / dsc_file).open('r') as dsc:
                 d = deb822.Dsc(dsc)
-            package = d['Source']
+            package = str(d['Source'])
             version = Version(d['Version'])
             files = [f["name"] for f in d["Files"]]
             checkout_package(package, version, branch, outdir, files)
     else:
         if tarball:
-            logging.info(_("Checking out file {} in {}").format(tarball, outdir))
+            logger.info(_("Checking out file {} in {}").format(tarball, outdir))
             checkout_lfs_file(branch, tarball, outdir)
         else:
-            checkout_package(package, version, branch, outdir)
+            checkout_package(str(package), Version(version), branch, outdir)
 
 
 def do_list(branch: str, **kwargs) -> Iterable[str]:
@@ -116,7 +139,8 @@ def do_list(branch: str, **kwargs) -> Iterable[str]:
             yield f
 
 
-def do_import(dsc: IO[str], branch: str, message: Optional[str] = None, force_overwrite: bool = False, full: bool = False, **kwargs):
+def do_import(dsc: IO[str], branch: str, message: Optional[str] = None, force_overwrite: bool = False,
+              full: bool = False, **kwargs):
     """
     Import all tarballs and detached signatures related to an open .dsc file.
     Set force_overwrite to overwrite an existing file with the same name and a different checksum.
@@ -135,12 +159,13 @@ def do_import(dsc: IO[str], branch: str, message: Optional[str] = None, force_ov
         if find_remote_branches(branch):
             track_remote_branch(branch)
 
-    tarballs = [os.path.join(dsc_dir, f['name']) for f in d['Files'] if full or fnmatch(f['name'], tarball_glob) or fnmatch(f['name'], component_tarball_glob)]
+    tarballs = [os.path.join(dsc_dir, f['name']) for f in d['Files']
+                if full or fnmatch(f['name'], tarball_glob) or fnmatch(f['name'], component_tarball_glob)]
     if full:
         tarballs += [dsc.name]
 
     if tarballs:
-        logging.info("Importing: %s" % " ".join(tarballs))
+        logger.info("Importing: %s" % " ".join(tarballs))
         commit_lfs_files([open(tarball, 'rb') for tarball in tarballs], branch, message, overwrite=force_overwrite)
 
 
@@ -156,7 +181,10 @@ def do_verify(branch: str, tarball: Union[str, Path], **kwargs) -> bool:
 def main(*args):
     prog = os.path.basename(sys.argv[0])
 
-    parser = argparse.ArgumentParser(description=_('store pristine tarballs in Git LFS'), prog=prog, exit_on_error=not args)
+    parser = argparse.ArgumentParser(description=_('store pristine tarballs in Git LFS'), prog=prog)
+    if args and hasattr(parser, 'exit_on_error'):
+        parser.exit_on_error = False
+
     parser.add_argument('-v', '--verbose', action='count', help=_('be more verbose'))
     parser.add_argument('--debug', action='store_const', const=2, dest='verbose', help=_('be debuggingly verbose'))
     parser.set_defaults(verbose=0, func=lambda *x, **kw: parser.print_usage(file=sys.stderr))
@@ -173,10 +201,12 @@ def main(*args):
     # we have to do some trickery since argparse doesn’t support this syntax natively
     parser_checkout = subparsers.add_parser('checkout', help=_('checkout a tarball'))
     parser_checkout.add_argument('-b', '--branch', default='pristine-lfs', help=_('branch to store metadata on'))
-    parser_checkout.add_argument('--full', default=False, action='store_true', help=_('also check out all related files of the Debian package'))
+    parser_checkout.add_argument('--full', default=False, action='store_true',
+                                 help=_('also check out all related files of the Debian package'))
     parser_checkout.add_argument('-o', '--outdir', default='.', help=_('output directory for the tarball'))
     checkout_group = parser_checkout.add_mutually_exclusive_group(required=True)
-    checkout_group.add_argument('--auto', default=False, action='store_true', help=_('check out all tarballs required by the currently checked out Debian package'))
+    checkout_group.add_argument('--auto', default=False, action='store_true',
+                                help=_('check out all tarballs required by the currently checked out Debian package'))
     checkout_group.add_argument('tarball', nargs='?', default=None, help=_('tarball to check out'))
     parser_checkout.set_defaults(func=do_checkout)
 
@@ -187,7 +217,8 @@ def main(*args):
     parser_import = subparsers.add_parser('import-dsc', help=_('import tarballs and their signatures from a .dsc'))
     parser_import.add_argument('dsc', type=argparse.FileType('r'), help='.dsc file to use')
     parser_import.add_argument('--force-overwrite', action='store_true', help=_('overwrite already stored files'))
-    parser_import.add_argument('--full', default=False, action='store_true', help=_('also import all related files of the Debian package'))
+    parser_import.add_argument('--full', default=False, action='store_true',
+                               help=_('also import all related files of the Debian package'))
     parser_import.add_argument('-m', '--message', default=None, help=_('commit message'))
     parser_import.add_argument('-b', '--branch', default='pristine-lfs', help=_('branch to store metadata on'))
     parser_import.set_defaults(func=do_import)
@@ -211,7 +242,7 @@ def main(*args):
                 print(item)
         elif isinstance(ret, bool):
             return 0 if ret else 1
-    except sh.ErrorReturnCode as e:
+    except CommandFailed as e:
         print(_('Failed to run %s:') % e.full_cmd, file=sys.stderr)
         print(e.stderr.decode(sh.DEFAULT_ENCODING, "replace"), file=sys.stderr)
         return e.exit_code
@@ -225,6 +256,6 @@ def main(*args):
         print(file=sys.stderr)
         print(_('about: Interrupted by user'), file=sys.stderr)
         return 1
-    except (Abort, GitFileNotFound) as e:
+    except (DifferentFilesExist, GitError, UnsupportedHashAlgorithm) as e:
         print(_("abort: %s\n") % e, file=sys.stderr)
         return 1
diff --git a/pristine_lfs/util.py b/pristine_lfs/util.py
index ba7f908..48b07ef 100644
--- a/pristine_lfs/util.py
+++ b/pristine_lfs/util.py
@@ -4,14 +4,13 @@
 # This requires Git and git-lfs to be installed.
 #
 # Copyright (C) 2019—2021 Collabora Ltd
-# Andrej Shadura <andrew.shadura@collabora.co.uk>
+# Copyright (C) 2019—2021 Andrej Shadura <andrew.shadura@collabora.co.uk>
 #
 # SPDX-License-Identifier: GPL-2.0-or-later
 
 from __future__ import annotations
 
 import hashlib
-import logging
 import os
 from contextlib import contextmanager
 from fnmatch import fnmatch, fnmatchcase
@@ -22,7 +21,14 @@ from typing import IO, Any, Generator, Iterable, Mapping, Optional, Sequence, Tu
 import sh
 from debian.changelog import Version
 
+from .errors import (
+    DifferentFilesExist,
+    GitBranchNotFound,
+    GitFileNotFound,
+    UnsupportedHashAlgorithm,
+)
 from .gitwrap import git
+from .log import logger
 
 
 gitattributes = """*.tar.* filter=lfs diff=lfs merge=lfs -text
@@ -133,22 +139,6 @@ def parse_git_attributes(s: str) -> Iterable[tuple[str, Mapping[str, AttributeVa
 default_gitattributes = list(parse_git_attributes(gitattributes))
 
 
-class Abort(Exception):
-    pass
-
-
-class GitFileNotFound(Exception):
-    filename: str
-    branch: str
-
-    def __init__(self, filename: str, branch: str):
-        self.filename = filename
-        self.branch = branch
-
-    def __str__(self):
-        return _('%s not found on branch %s') % (self.filename, self.branch)
-
-
 def check_branch(name: str) -> Optional[str]:
     """
     Check a branch exists, return the hash it points at, if it does.
@@ -187,9 +177,9 @@ def find_remote_branches(name: str) -> list[tuple[str, str]]:
 
 
 def preferred_remote_branch(remote_branches: list[tuple[str, str]]) -> tuple[str, str]:
-    logging.debug("Remote branches: %r", remote_branches)
+    logger.debug("Remote branches: %r", remote_branches)
     current_remote = branch_remote(git_head())
-    logging.debug("Current remote: %r", current_remote)
+    logger.debug("Current remote: %r", current_remote)
     remote_branches = [
         (commit, ref) for (commit, ref) in remote_branches
         if current_remote and ref.startswith('refs/remotes/' + current_remote)
@@ -211,7 +201,7 @@ def find_branch(branch: str) -> str:
         if remote_branches:
             commit, branch = preferred_remote_branch(remote_branches)
         else:
-            raise Abort(_('No branch {branch} found, not even among remote branches').format(branch=branch))
+            raise GitBranchNotFound(branch)
     return branch
 
 
@@ -307,7 +297,7 @@ def commit_lfs_files(ios: Sequence[IO[bytes]], branch: str, template: str = None
             hook_path.write_text(pre_push_hook)
             hook_path.chmod(0o755)
         except IOError as e:
-            logging.warning(_('Failed to set up pre-push hook: %s') % e.strerror)
+            logger.warning(_('Failed to set up pre-push hook: %s') % e.strerror)
 
     with open_index("pristine-lfs") as index:
         # make sure we include all previously committed files
@@ -328,12 +318,12 @@ def commit_lfs_files(ios: Sequence[IO[bytes]], branch: str, template: str = None
         if check_branch(branch) is not None:
             diff = git('diff-index', '--cached', branch, index=index).strip().splitlines()
             if not diff:
-                logging.info(_("Nothing to commit"))
+                logger.info(_("Nothing to commit"))
                 return
             parsed_diff = [parse_diff_entry(d) for d in diff]
             overwritten = [d['srcname'] for d in parsed_diff if d['srchash'] != ('0' * 40) and d['srcname'] != '.gitattributes']
             if any(overwritten) and not overwrite:
-                raise Abort(_('would overwrite files: %s') % ', '.join(overwritten))
+                raise DifferentFilesExist(overwritten)
 
         if not template:
             template = "pristine-lfs data for %s"
@@ -399,7 +389,7 @@ def verify_lfs_file(branch: str, tarball: Path) -> bool:
     oid = parsed_metadata['oid']
     algo, hashsum = oid.split(':', 1)
     if algo not in supported_lfs_hashsums:
-        raise Abort(_("unsupported hash algorithm %s, cannot verify") % algo)
+        raise UnsupportedHashAlgorithm(algo)
 
     h = getattr(hashlib, algo)()
     with open(tarball, mode='rb') as f:
@@ -410,9 +400,9 @@ def verify_lfs_file(branch: str, tarball: Path) -> bool:
             h.update(chunk)
     calc_hashsum = h.hexdigest()
     if hashsum == calc_hashsum:
-        logging.info(f"{algo} hash for the tarball: {hashsum}, matches the stored one")
+        logger.info(f"{algo} hash for the tarball: {hashsum}, matches the stored one")
     else:
-        logging.warning(_("%(tarball)s does not match stored hash (expected %(stored_hash)s, got %(tarball_hash)s)") % {
+        logger.warning(_("%(tarball)s does not match stored hash (expected %(stored_hash)s, got %(tarball_hash)s)") % {
             'tarball': filename,
             'stored_hash': hashsum,
             'tarball_hash': calc_hashsum,
@@ -420,8 +410,12 @@ def verify_lfs_file(branch: str, tarball: Path) -> bool:
     return hashsum == calc_hashsum
 
 
-def checkout_package(package: str, version: Version, branch: str, outdir: Union[str, Path], requested: Optional[Sequence[str]] = None):
-    logging.info(_("Checking out files for {package} version {version} to {outdir}:").format(package=package, version=version, outdir=outdir))
+def checkout_package(package: str, version: Version, branch: str, outdir: Union[str, Path],
+                     requested: Optional[Sequence[str]] = None):
+    logger.info(_("Checking out files for {package} version {version} to {outdir}:").format(
+        package=package,
+        version=version, outdir=outdir
+    ))
     tarball_glob = f'{package}_{version.upstream_version}.orig.tar.*'
     component_tarball_glob = f'{package}_{version.upstream_version}.orig-*.tar.*'
 
@@ -433,9 +427,9 @@ def checkout_package(package: str, version: Version, branch: str, outdir: Union[
         tarballs = [f for f in files if fnmatch(f, tarball_glob) or fnmatch(f, component_tarball_glob)]
 
     for f in tarballs:
-        logging.info("         ... {}".format(f))
+        logger.info("         ... {}".format(f))
         checkout_lfs_file(branch, f, outdir)
-    logging.info(_("Done."))
+    logger.info(_("Done."))
 
 
 def parse_pointer(pointer: IO[str]) -> Iterable[tuple[str, str]]:
diff --git a/setup.cfg b/setup.cfg
index 04de573..16535af 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
 [metadata]
 name = pristine-lfs
-version = 20210222.0
+version = 20210404.0
 author = Andrej Shadura
 author_email = andrew.shadura@collabora.co.uk
 url = https://salsa.debian.org/pristine-lfs-team/pristine-lfs
@@ -28,7 +28,7 @@ packages = find:
 setup_requires = 
 	docutils >= 0.12
 install_requires = 
-	sh
+	sh >= 1.14
 	python-debian
 include_package_data = True
 tests_require = 
@@ -43,9 +43,11 @@ pristine_lfs = stubs/*
 
 [mypy]
 allow_redefinition = True
+junit_xml = mypy.xml
 
 [tool:pytest]
-addopts = --doctest-modules
+addopts = --doctest-modules --junit-xml=test-results.xml
+junit_family = xunit2
 doctest_optionflags = NORMALIZE_WHITESPACE
 markers = 
 	smoke
@@ -54,7 +56,7 @@ markers =
 doctests = yes
 max-line-length = 130
 exclude = .git,build,__pycache__,setup.py
-ignore = E121,E123,E126,E133,E226,E241,E242,E704,E501,E301,E261,E127,E128,W391,W503,W504
+ignore = E121,E123,E126,E133,E226,E241,E242,E704,E261,E127,E128,W503,W504
 
 [isort]
 multi_line_output = 3
@@ -64,6 +66,9 @@ line_length = 130
 reverse_relative = true
 default_section = THIRDPARTY
 
+[pylint.FORMAT]
+max-line-length = 130
+
 [egg_info]
 tag_build = 
 tag_date = 0
diff --git a/tests/test_checkout.py b/tests/test_checkout.py
index f3c289a..9582527 100644
--- a/tests/test_checkout.py
+++ b/tests/test_checkout.py
@@ -1,4 +1,5 @@
 from pristine_lfs import do_checkout
+from pristine_lfs.util import Version
 
 
 def test_pristine_lfs_simple_checkout(fake_pristine_lfs):
@@ -16,15 +17,33 @@ def test_pristine_lfs_auto_checkout(test_git_repo):
     outdir = repo / 'tmp-explicit'
 
     do_checkout('pristine-lfs', tarball=tarball.name, outdir=outdir)
-    assert len(list(outdir.glob('**'))) == 1, list(outdir.glob('**'))
+    assert len(list(outdir.glob('*'))) == 1, list(outdir.glob('*'))
     assert (outdir / tarball.name).is_file()
     assert (outdir / tarball.name).stat().st_size == size
 
     outdir = repo / 'tmp-auto'
 
     do_checkout('pristine-lfs', tarball=None, outdir=outdir)
-    assert len(list(outdir.glob('**'))) == 1, list(outdir.glob('**'))
+    assert len(list(outdir.glob('*'))) == 1, list(outdir.glob('*'))
     assert (outdir / tarball.name).is_file(), 'Extracted tarball not found'
     assert (outdir / tarball.name).stat().st_size == size, 'Extracted tarball of a wrong size'
 
+    outdir = repo / 'tmp-empty'
+
+    do_checkout('pristine-lfs', package='true', version='1', outdir=outdir)
+    assert len(list(outdir.glob('*'))) == 0, list(outdir.glob('*'))
+    assert not (outdir / tarball.name).is_file(), 'Found a tarball which should not be there'
+
+    do_checkout('pristine-lfs', package='true', version=Version('1'), outdir=outdir)
+    assert len(list(outdir.glob('*'))) == 0, list(outdir.glob('*'))
+    assert not (outdir / tarball.name).is_file(), 'Found a tarball which should not be there'
 
+    do_checkout('pristine-lfs', package='true', version='0', outdir=outdir)
+    assert len(list(outdir.glob('*'))) == 1, list(outdir.glob('*'))
+    assert (outdir / tarball.name).is_file(), 'Extracted tarball not found'
+
+    outdir = repo / 'tmp-empty-2'
+
+    do_checkout('pristine-lfs', package='true', version='0', outdir=outdir)
+    assert len(list(outdir.glob('*'))) == 1, list(outdir.glob('*'))
+    assert (outdir / tarball.name).is_file(), 'Extracted tarball not found'
diff --git a/tests/test_commit.py b/tests/test_commit.py
index c578d86..207b662 100644
--- a/tests/test_commit.py
+++ b/tests/test_commit.py
@@ -1,8 +1,10 @@
 from textwrap import dedent
 
+import pytest
 from sh.contrib import git
 
 from pristine_lfs import do_commit
+from pristine_lfs.errors import DifferentFilesExist
 
 
 def test_pristine_lfs_commit(fake_tarball):
@@ -24,3 +26,13 @@ def test_pristine_lfs_commit(fake_tarball):
 
     stored = repo / '.git' / 'lfs' / 'objects' / sha[:2] / sha[2:4] / sha
     assert stored.is_file(), 'Object has not been stored by LFS'
+
+
+def test_pristine_lfs_commit_overwrite(fake_tarball):
+    repo, tarball, size, sha = fake_tarball
+
+    do_commit(tarball.open('rb'), branch='pristine-lfs')
+    tarball.write_text('Text')
+
+    with pytest.raises(DifferentFilesExist):
+        do_commit(tarball.open('rb'), branch='pristine-lfs', message='blip %s %s %s')
diff --git a/tests/test_import_dsc.py b/tests/test_import_dsc.py
index e5e5a4c..df94fda 100644
--- a/tests/test_import_dsc.py
+++ b/tests/test_import_dsc.py
@@ -40,4 +40,3 @@ def test_pristine_lfs_import_dsc(fake_tarball):
 
     ret = list(do_list(branch='pristine-lfs-source'))
     assert ['true_0.dsc', 'true_0.orig.tar.gz'] == ret
-

Reply to: