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-05-20 19:23:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-dulwich (Old)
 and      /work/SRC/openSUSE:Factory/.python-dulwich.new.2988 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-dulwich"

Thu May 20 19:23:26 2021 rev:39 rq:894165 version:0.20.21

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-dulwich/python-dulwich.changes    
2021-04-26 16:38:59.326014935 +0200
+++ /work/SRC/openSUSE:Factory/.python-dulwich.new.2988/python-dulwich.changes  
2021-05-20 19:23:50.778245087 +0200
@@ -1,0 +2,9 @@
+Tue May 18 21:55:33 UTC 2021 - Dirk M??ller <dmuel...@suse.com>
+
+- update to 0.20.21:
+ * Add basic support for a GcsObjectStore that stores
+   pack files in gcs.
+ * In porcelain.push, default to local active branch.
+ * Support fetching symrefs.
+
+-------------------------------------------------------------------

Old:
----
  dulwich-0.20.20.tar.gz

New:
----
  dulwich-0.20.21.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-dulwich.spec ++++++
--- /var/tmp/diff_new_pack.jAnqB7/_old  2021-05-20 19:23:51.190243344 +0200
+++ /var/tmp/diff_new_pack.jAnqB7/_new  2021-05-20 19:23:51.194243327 +0200
@@ -20,7 +20,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-dulwich
-Version:        0.20.20
+Version:        0.20.21
 Release:        0
 Summary:        Pure-Python Git Library
 License:        Apache-2.0 OR GPL-2.0-or-later

++++++ dulwich-0.20.20.tar.gz -> dulwich-0.20.21.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/.github/workflows/pythonpublish.yml 
new/dulwich-0.20.21/.github/workflows/pythonpublish.yml
--- old/dulwich-0.20.20/.github/workflows/pythonpublish.yml     2021-03-03 
14:30:17.000000000 +0100
+++ new/dulwich-0.20.21/.github/workflows/pythonpublish.yml     2021-03-26 
00:38:11.000000000 +0100
@@ -41,6 +41,14 @@
       run: |
         python setup.py sdist bdist_wheel
       if: "matrix.os != 'ubuntu-latest'"
+    - uses: docker/setup-qemu-action@v1
+      name: Set up QEMU
+      if: "matrix.os == 'ubuntu-latest'"
+    - name: Build and publish (Linux aarch64)
+      uses: RalfG/python-wheels-manylinux-build@v0.3.3-manylinux2014_aarch64
+      with:
+        python-versions: 'cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39'
+      if: "matrix.os == 'ubuntu-latest'"
     - name: Build and publish (Linux)
       uses: RalfG/python-wheels-manylinux-build@v0.3.1
       with:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/NEWS new/dulwich-0.20.21/NEWS
--- old/dulwich-0.20.20/NEWS    2021-03-03 14:31:34.000000000 +0100
+++ new/dulwich-0.20.21/NEWS    2021-03-26 00:39:32.000000000 +0100
@@ -1,3 +1,17 @@
+%(version)s    %(date)s
+
+ * Add basic support for a GcsObjectStore that stores
+   pack files in gcs. (Jelmer Vernoo??)
+
+ * In porcelain.push, default to local active branch.
+   (Jelmer Vernoo??, #846)
+
+ * Support fetching symrefs.
+   (Jelmer Vernoo??, #485, #847)
+
+ * Add aarch64 wheel building.
+   (odidev, Jelmer Vernooij)
+
 0.20.20        2021-03-03
 
  * Implement ``Stash.drop``. (Peter Rowlands)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/PKG-INFO new/dulwich-0.20.21/PKG-INFO
--- old/dulwich-0.20.20/PKG-INFO        2021-03-03 14:31:44.457976600 +0100
+++ new/dulwich-0.20.21/PKG-INFO        2021-03-26 00:39:35.891547400 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: dulwich
-Version: 0.20.20
+Version: 0.20.21
 Summary: Python Git Library
 Home-page: https://www.dulwich.io/
 Author: Jelmer Vernooij
@@ -9,7 +9,10 @@
 Project-URL: Bug Tracker, https://github.com/dulwich/dulwich/issues
 Project-URL: Repository, https://www.dulwich.io/code/
 Project-URL: GitHub, https://github.com/dulwich/dulwich
-Description: This is the Dulwich project.
+Description: Dulwich
+        =======
+        
+        This is the Dulwich project.
         
         It aims to provide an interface to git repos (both local and remote) 
that
         doesn't call out to git directly but instead uses pure Python.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/README.rst 
new/dulwich-0.20.21/README.rst
--- old/dulwich-0.20.20/README.rst      2021-03-03 14:30:17.000000000 +0100
+++ new/dulwich-0.20.21/README.rst      2021-03-26 00:38:11.000000000 +0100
@@ -1,3 +1,6 @@
+Dulwich
+=======
+
 This is the Dulwich project.
 
 It aims to provide an interface to git repos (both local and remote) that
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich/__init__.py 
new/dulwich-0.20.21/dulwich/__init__.py
--- old/dulwich-0.20.20/dulwich/__init__.py     2021-03-03 14:31:34.000000000 
+0100
+++ new/dulwich-0.20.21/dulwich/__init__.py     2021-03-26 00:39:32.000000000 
+0100
@@ -22,4 +22,4 @@
 
 """Python implementation of the Git file formats and protocols."""
 
-__version__ = (0, 20, 20)
+__version__ = (0, 20, 21)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich/cli.py 
new/dulwich-0.20.21/dulwich/cli.py
--- old/dulwich-0.20.20/dulwich/cli.py  2021-03-03 14:30:17.000000000 +0100
+++ new/dulwich-0.20.21/dulwich/cli.py  2021-03-26 00:38:11.000000000 +0100
@@ -31,6 +31,7 @@
 import os
 import sys
 from getopt import getopt
+import argparse
 import optparse
 import signal
 from typing import Dict, Type
@@ -64,49 +65,54 @@
 
 class cmd_archive(Command):
     def run(self, args):
-        parser = optparse.OptionParser()
-        parser.add_option(
+        parser = argparse.ArgumentParser()
+        parser.add_argument(
             "--remote",
             type=str,
             help="Retrieve archive from specified remote repo",
         )
-        options, args = parser.parse_args(args)
-        committish = args.pop(0)
-        if options.remote:
-            client, path = get_transport_and_path(options.remote)
+        parser.add_argument('committish', type=str, nargs='?')
+        args = parser.parse_args(args)
+        if args.remote:
+            client, path = get_transport_and_path(args.remote)
             client.archive(
                 path,
-                committish,
+                args.committish,
                 sys.stdout.write,
                 write_error=sys.stderr.write,
             )
         else:
             porcelain.archive(
-                ".", committish, outstream=sys.stdout, errstream=sys.stderr
+                ".", args.committish, outstream=sys.stdout.buffer,
+                errstream=sys.stderr
             )
 
 
 class cmd_add(Command):
-    def run(self, args):
-        opts, args = getopt(args, "", [])
+    def run(self, argv):
+        parser = argparse.ArgumentParser()
+        args = parser.parse_args(argv)
 
         porcelain.add(".", paths=args)
 
 
 class cmd_rm(Command):
-    def run(self, args):
-        opts, args = getopt(args, "", [])
+    def run(self, argv):
+        parser = argparse.ArgumentParser()
+        args = parser.parse_args(argv)
 
         porcelain.rm(".", paths=args)
 
 
 class cmd_fetch_pack(Command):
-    def run(self, args):
-        opts, args = getopt(args, "", ["all"])
-        opts = dict(opts)
-        client, path = get_transport_and_path(args.pop(0))
+    def run(self, argv):
+        parser = argparse.ArgumentParser()
+        parser.add_argument('--all', action='store_true')
+        parser.add_argument('location', nargs='?', type=str)
+        args = parser.parse_args(argv)
+        client, path = get_transport_and_path(args.location)
         r = Repo(".")
-        if "--all" in opts:
+        if args.all:
             determine_wants = r.object_store.determine_wants_all
         else:
 
@@ -290,9 +296,11 @@
 
 
 class cmd_show(Command):
-    def run(self, args):
-        opts, args = getopt(args, "", [])
-        porcelain.show(".", args)
+    def run(self, argv):
+        parser = argparse.ArgumentParser()
+        parser.add_argument('objectish', type=str, nargs='*')
+        args = parser.parse_args(argv)
+        porcelain.show(".", args.objectish or None)
 
 
 class cmd_diff_tree(Command):
@@ -544,15 +552,13 @@
 
 
 class cmd_push(Command):
-    def run(self, args):
-        parser = optparse.OptionParser()
-        options, args = parser.parse_args(args)
-        if len(args) < 2:
-            print("Usage: dulwich push TO-LOCATION REFSPEC..")
-            sys.exit(1)
-        to_location = args[0]
-        refspecs = args[1:]
-        porcelain.push(".", to_location, refspecs)
+
+    def run(self, argv):
+        parser = argparse.ArgumentParser()
+        parser.add_argument('to_location', type=str)
+        parser.add_argument('refspec', type=str, nargs='*')
+        args = parser.parse_args(argv)
+        porcelain.push('.', args.to_location, args.refspec or None)
 
 
 class cmd_remote_add(Command):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich/client.py 
new/dulwich-0.20.21/dulwich/client.py
--- old/dulwich-0.20.20/dulwich/client.py       2021-03-03 14:30:17.000000000 
+0100
+++ new/dulwich-0.20.21/dulwich/client.py       2021-03-26 00:38:11.000000000 
+0100
@@ -40,6 +40,7 @@
 
 from contextlib import closing
 from io import BytesIO, BufferedReader
+import logging
 import os
 import select
 import socket
@@ -111,6 +112,9 @@
 )
 
 
+logger = logging.getLogger(__name__)
+
+
 class InvalidWants(Exception):
     """Invalid wants."""
 
@@ -626,6 +630,9 @@
                 )
 
             if old_sha1 != new_sha1:
+                logger.debug(
+                    'Sending updated ref %r: %r -> %r',
+                    refname, old_sha1, new_sha1)
                 if sent_capabilities:
                     proto.write_pkt_line(old_sha1 + b" " + new_sha1 + b" " + 
refname)
                 else:
@@ -873,7 +880,7 @@
         self._remote_path_encoding = path_encoding
         super(TraditionalGitClient, self).__init__(**kwargs)
 
-    def _connect(self, cmd, path):
+    async def _connect(self, cmd, path):
         """Create a connection to the server.
 
         This method is abstract - concrete implementations should
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich/cloud/gcs.py 
new/dulwich-0.20.21/dulwich/cloud/gcs.py
--- old/dulwich-0.20.20/dulwich/cloud/gcs.py    1970-01-01 01:00:00.000000000 
+0100
+++ new/dulwich-0.20.21/dulwich/cloud/gcs.py    2021-03-26 00:38:11.000000000 
+0100
@@ -0,0 +1,82 @@
+# object_store.py -- Object store for git objects
+# Copyright (C) 2021 Jelmer Vernooij <jel...@jelmer.uk>
+#
+# Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
+# General Public License as public by the Free Software Foundation; version 2.0
+# or (at your option) any later version. You can redistribute it and/or
+# modify it under the terms of either of these two licenses.
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# You should have received a copy of the licenses; if not, see
+# <http://www.gnu.org/licenses/> for a copy of the GNU General Public License
+# and <http://www.apache.org/licenses/LICENSE-2.0> for a copy of the Apache
+# License, Version 2.0.
+#
+
+
+"""Storage of repositories on GCS."""
+
+import posixpath
+import tempfile
+
+from ..object_store import BucketBasedObjectStore
+from ..pack import PackData, Pack, load_pack_index_file
+
+
+# TODO(jelmer): For performance, read ranges?
+
+
+class GcsObjectStore(BucketBasedObjectStore):
+
+    def __init__(self, bucket, subpath=''):
+        super(GcsObjectStore, self).__init__()
+        self.bucket = bucket
+        self.subpath = subpath
+
+    def __repr__(self):
+        return "%s(%r, subpath=%r)" % (
+            type(self).__name__, self.bucket, self.subpath)
+
+    def _remove_pack(self, name):
+        self.bucket.delete_blobs([
+            posixpath.join(self.subpath, name) + '.' + ext
+            for ext in ['pack', 'idx']])
+
+    def _iter_pack_names(self):
+        packs = {}
+        for blob in self.bucket.list_blobs(prefix=self.subpath):
+            name, ext = posixpath.splitext(posixpath.basename(blob.name))
+            packs.setdefault(name, set()).add(ext)
+        for name, exts in packs.items():
+            if exts == set(['.pack', '.idx']):
+                yield name
+
+    def _load_pack_data(self, name):
+        b = self.bucket.blob(posixpath.join(self.subpath, name + '.pack'))
+        f = tempfile.SpooledTemporaryFile()
+        b.download_to_file(f)
+        f.seek(0)
+        return PackData(name + '.pack', f)
+
+    def _load_pack_index(self, name):
+        b = self.bucket.blob(posixpath.join(self.subpath, name + '.idx'))
+        f = tempfile.SpooledTemporaryFile()
+        b.download_to_file(f)
+        f.seek(0)
+        return load_pack_index_file(name + '.idx', f)
+
+    def _get_pack(self, name):
+        return Pack.from_lazy_objects(
+            lambda: self._load_pack_data(name),
+            lambda: self._load_pack_index(name))
+
+    def _upload_pack(self, basename, pack_file, index_file):
+        idxblob = self.bucket.blob(posixpath.join(self.subpath, basename + 
'.idx'))
+        datablob = self.bucket.blob(posixpath.join(self.subpath, basename + 
'.pack'))
+        idxblob.upload_from_file(index_file)
+        datablob.upload_from_file(pack_file)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich/hooks.py 
new/dulwich-0.20.21/dulwich/hooks.py
--- old/dulwich-0.20.20/dulwich/hooks.py        2021-03-03 14:30:17.000000000 
+0100
+++ new/dulwich-0.20.21/dulwich/hooks.py        2021-03-26 00:38:11.000000000 
+0100
@@ -200,7 +200,7 @@
             if (p.returncode != 0) or err_data:
                 err_fmt = "post-receive exit code: %d\n" + 
"stdout:\n%s\nstderr:\n%s"
                 err_msg = err_fmt % (p.returncode, out_data, err_data)
-                raise HookError(err_msg)
+                raise HookError(err_msg.decode('utf-8', 'backslashreplace'))
             return out_data
         except OSError as err:
             raise HookError(repr(err))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich/object_store.py 
new/dulwich-0.20.21/dulwich/object_store.py
--- old/dulwich-0.20.20/dulwich/object_store.py 2021-03-03 14:30:17.000000000 
+0100
+++ new/dulwich-0.20.21/dulwich/object_store.py 2021-03-26 00:38:11.000000000 
+0100
@@ -53,6 +53,7 @@
     PackData,
     PackInflater,
     PackFileDisappeared,
+    load_pack_index_file,
     iter_sha1,
     pack_objects_to_data,
     write_pack_header,
@@ -1471,3 +1472,85 @@
         if kind != b"P":
             continue
         yield os.fsdecode(name)
+
+
+class BucketBasedObjectStore(PackBasedObjectStore):
+    """Object store implementation that uses a bucket store like S3 as backend.
+    """
+
+    def _iter_loose_objects(self):
+        """Iterate over the SHAs of all loose objects."""
+        return iter([])
+
+    def _get_loose_object(self, sha):
+        return None
+
+    def _remove_loose_object(self, sha):
+        # Doesn't exist..
+        pass
+
+    def _remove_pack(self, name):
+        raise NotImplementedError(self._remove_pack)
+
+    def _iter_pack_names(self):
+        raise NotImplementedError(self._iter_pack_names)
+
+    def _get_pack(self, name):
+        raise NotImplementedError(self._get_pack)
+
+    def _update_pack_cache(self):
+        pack_files = set(self._iter_pack_names())
+
+        # Open newly appeared pack files
+        new_packs = []
+        for f in pack_files:
+            if f not in self._pack_cache:
+                pack = self._get_pack(f)
+                new_packs.append(pack)
+                self._pack_cache[f] = pack
+        # Remove disappeared pack files
+        for f in set(self._pack_cache) - pack_files:
+            self._pack_cache.pop(f).close()
+        return new_packs
+
+    def _upload_pack(self, basename, pack_file, index_file):
+        raise NotImplementedError
+
+    def add_pack(self):
+        """Add a new pack to this object store.
+
+        Returns: Fileobject to write to, a commit function to
+            call when the pack is finished and an abort
+            function.
+        """
+        import tempfile
+
+        pf = tempfile.SpooledTemporaryFile()
+
+        def commit():
+            if pf.tell() == 0:
+                pf.close()
+                return None
+
+            pf.seek(0)
+            p = PackData(pf.name, pf)
+            entries = p.sorted_entries()
+            basename = iter_sha1(entry[0] for entry in entries).decode('ascii')
+            idxf = tempfile.SpooledTemporaryFile()
+            checksum = p.get_stored_checksum()
+            write_pack_index_v2(idxf, entries, checksum)
+            idxf.seek(0)
+            idx = load_pack_index_file(basename + '.idx', idxf)
+            for pack in self.packs:
+                if pack.get_stored_checksum() == p.get_stored_checksum():
+                    p.close()
+                    idx.close()
+                    return pack
+            pf.seek(0)
+            idxf.seek(0)
+            self._upload_pack(basename, pf, idxf)
+            final_pack = Pack.from_objects(p, idx)
+            self._add_cached_pack(basename, final_pack)
+            return final_pack
+
+        return pf, commit, pf.close
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich/objectspec.py 
new/dulwich-0.20.21/dulwich/objectspec.py
--- old/dulwich-0.20.20/dulwich/objectspec.py   2021-03-03 14:30:17.000000000 
+0100
+++ new/dulwich-0.20.21/dulwich/objectspec.py   2021-03-26 00:38:11.000000000 
+0100
@@ -20,6 +20,8 @@
 
 """Object specification."""
 
+from typing import Union, List, Tuple
+
 
 def to_bytes(text):
     if getattr(text, "encode", None) is not None:
@@ -118,7 +120,10 @@
     return (lh, rh, force)
 
 
-def parse_reftuples(lh_container, rh_container, refspecs, force=False):
+def parse_reftuples(
+        lh_container, rh_container,
+        refspecs: Union[bytes, List[bytes], List[Tuple[bytes, bytes]]],
+        force: bool = False):
     """Parse a list of reftuple specs to a list of reftuples.
 
     Args:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich/porcelain.py 
new/dulwich-0.20.21/dulwich/porcelain.py
--- old/dulwich-0.20.20/dulwich/porcelain.py    2021-03-03 14:30:17.000000000 
+0100
+++ new/dulwich-0.20.21/dulwich/porcelain.py    2021-03-26 00:38:11.000000000 
+0100
@@ -475,8 +475,8 @@
             depth=depth,
             **kwargs
         )
-        # TODO(jelmer): Support symref capability,
-        # https://github.com/jelmer/dulwich/issues/485
+        for key, target in fetch_result.symrefs.items():
+            r.refs.set_symbolic_ref(key, target)
         try:
             head = r[fetch_result.refs[b"HEAD"]]
         except KeyError:
@@ -1065,6 +1065,8 @@
 
     # Open the repo
     with open_repo_closing(repo) as r:
+        if refspecs is None:
+            refspecs = [active_branch(r)]
         (remote_name, remote_location) = get_remote_repo(r, remote_location)
 
         # Get the client and path
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich/repo.py 
new/dulwich-0.20.21/dulwich/repo.py
--- old/dulwich-0.20.20/dulwich/repo.py 2021-03-03 14:30:17.000000000 +0100
+++ new/dulwich-0.20.21/dulwich/repo.py 2021-03-26 00:38:11.000000000 +0100
@@ -1034,26 +1034,31 @@
     To create a new repository, use the Repo.init class method.
     """
 
-    def __init__(self, root):
+    def __init__(self, root, object_store=None, bare=None):
         hidden_path = os.path.join(root, CONTROLDIR)
-        if os.path.isdir(os.path.join(hidden_path, OBJECTDIR)):
-            self.bare = False
-            self._controldir = hidden_path
-        elif os.path.isdir(os.path.join(root, OBJECTDIR)) and os.path.isdir(
-            os.path.join(root, REFSDIR)
-        ):
-            self.bare = True
-            self._controldir = root
-        elif os.path.isfile(hidden_path):
-            self.bare = False
-            with open(hidden_path, "r") as f:
-                path = read_gitfile(f)
-            self.bare = False
-            self._controldir = os.path.join(root, path)
+        if bare is None:
+            if (os.path.isfile(hidden_path) or
+                    os.path.isdir(os.path.join(hidden_path, OBJECTDIR))):
+                bare = False
+            elif (os.path.isdir(os.path.join(root, OBJECTDIR)) and
+                    os.path.isdir(os.path.join(root, REFSDIR))):
+                bare = True
+            else:
+                raise NotGitRepository(
+                    "No git repository was found at %(path)s" % dict(path=root)
+                )
+
+        self.bare = bare
+        if bare is False:
+            if os.path.isfile(hidden_path):
+                with open(hidden_path, "r") as f:
+                    path = read_gitfile(f)
+                self.bare = False
+                self._controldir = os.path.join(root, path)
+            else:
+                self._controldir = hidden_path
         else:
-            raise NotGitRepository(
-                "No git repository was found at %(path)s" % dict(path=root)
-            )
+            self._controldir = root
         commondir = self.get_named_file(COMMONDIR)
         if commondir is not None:
             with commondir:
@@ -1071,9 +1076,10 @@
             format_version = 0
         if format_version != 0:
             raise UnsupportedVersion(format_version)
-        object_store = DiskObjectStore.from_config(
-            os.path.join(self.commondir(), OBJECTDIR), config
-        )
+        if object_store is None:
+            object_store = DiskObjectStore.from_config(
+                os.path.join(self.commondir(), OBJECTDIR), config
+            )
         refs = DiskRefsContainer(
             self.commondir(), self._controldir, logger=self._write_reflog
         )
@@ -1428,11 +1434,12 @@
         self._put_named_file("description", description)
 
     @classmethod
-    def _init_maybe_bare(cls, path, bare):
+    def _init_maybe_bare(cls, path, controldir, bare, object_store=None):
         for d in BASE_DIRECTORIES:
-            os.mkdir(os.path.join(path, *d))
-        DiskObjectStore.init(os.path.join(path, OBJECTDIR))
-        ret = cls(path)
+            os.mkdir(os.path.join(controldir, *d))
+        if object_store is None:
+            object_store = DiskObjectStore.init(os.path.join(controldir, 
OBJECTDIR))
+        ret = cls(path, bare=bare, object_store=object_store)
         ret.refs.set_symbolic_ref(b"HEAD", DEFAULT_REF)
         ret._init_files(bare)
         return ret
@@ -1451,8 +1458,7 @@
         controldir = os.path.join(path, CONTROLDIR)
         os.mkdir(controldir)
         _set_filesystem_hidden(controldir)
-        cls._init_maybe_bare(controldir, False)
-        return cls(path)
+        return cls._init_maybe_bare(path, controldir, False)
 
     @classmethod
     def _init_new_working_directory(cls, path, main_repo, identifier=None, 
mkdir=False):
@@ -1493,7 +1499,7 @@
         return r
 
     @classmethod
-    def init_bare(cls, path, mkdir=False):
+    def init_bare(cls, path, mkdir=False, object_store=None):
         """Create a new bare repository.
 
         ``path`` should already exist and be an empty directory.
@@ -1504,7 +1510,7 @@
         """
         if mkdir:
             os.mkdir(path)
-        return cls._init_maybe_bare(path, True)
+        return cls._init_maybe_bare(path, path, True, 
object_store=object_store)
 
     create = init_bare
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich/server.py 
new/dulwich-0.20.21/dulwich/server.py
--- old/dulwich-0.20.20/dulwich/server.py       2021-03-03 14:30:17.000000000 
+0100
+++ new/dulwich-0.20.21/dulwich/server.py       2021-03-26 00:38:11.000000000 
+0100
@@ -1038,7 +1038,7 @@
             if output:
                 self.proto.write_sideband(SIDE_BAND_CHANNEL_PROGRESS, output)
         except HookError as err:
-            self.proto.write_sideband(SIDE_BAND_CHANNEL_FATAL, repr(err))
+            self.proto.write_sideband(SIDE_BAND_CHANNEL_FATAL, 
str(err).encode('utf-8'))
 
     def handle(self) -> None:
         if self.advertise_refs or not self.stateless_rpc:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich/stash.py 
new/dulwich-0.20.21/dulwich/stash.py
--- old/dulwich-0.20.20/dulwich/stash.py        2021-03-03 14:30:17.000000000 
+0100
+++ new/dulwich-0.20.21/dulwich/stash.py        2021-03-26 00:38:11.000000000 
+0100
@@ -99,6 +99,7 @@
             tree=index_tree_id,
             message=b"Index stash",
             merge_heads=[self._repo.head()],
+            no_verify=True,
             **commit_kwargs
         )
 
@@ -123,6 +124,7 @@
             tree=stash_tree_id,
             message=message,
             merge_heads=[index_commit_id],
+            no_verify=True,
             **commit_kwargs
         )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich/tests/test_porcelain.py 
new/dulwich-0.20.21/dulwich/tests/test_porcelain.py
--- old/dulwich-0.20.20/dulwich/tests/test_porcelain.py 2021-03-03 
14:30:17.000000000 +0100
+++ new/dulwich-0.20.21/dulwich/tests/test_porcelain.py 2021-03-26 
00:38:11.000000000 +0100
@@ -424,6 +424,26 @@
         self.assertRaises(Exception, porcelain.clone, "/nonexistant/repo", 
target_path)
         self.assertFalse(os.path.exists(target_path))
 
+    def test_fetch_symref(self):
+        f1_1 = make_object(Blob, data=b"f1")
+        trees = {1: [(b"f1", f1_1), (b"f2", f1_1)]}
+        [c1] = build_commit_graph(self.repo.object_store, [[1]], trees)
+        self.repo.refs.set_symbolic_ref(b'HEAD', b'refs/heads/else')
+        self.repo.refs[b"refs/heads/else"] = c1.id
+        target_path = tempfile.mkdtemp()
+        errstream = BytesIO()
+        self.addCleanup(shutil.rmtree, target_path)
+        r = porcelain.clone(
+            self.repo.path, target_path, checkout=False, errstream=errstream
+        )
+        self.addCleanup(r.close)
+        self.assertEqual(r.path, target_path)
+        target_repo = Repo(target_path)
+        self.assertEqual(0, len(target_repo.open_index()))
+        self.assertEqual(c1.id, target_repo.refs[b"refs/heads/else"])
+        self.assertEqual(c1.id, target_repo.refs[b"HEAD"])
+        self.assertEqual({b'HEAD': b'refs/heads/else'}, 
target_repo.refs.get_symrefs())
+
 
 class InitTests(TestCase):
     def test_non_bare(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich.egg-info/PKG-INFO 
new/dulwich-0.20.21/dulwich.egg-info/PKG-INFO
--- old/dulwich-0.20.20/dulwich.egg-info/PKG-INFO       2021-03-03 
14:31:44.000000000 +0100
+++ new/dulwich-0.20.21/dulwich.egg-info/PKG-INFO       2021-03-26 
00:39:35.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: dulwich
-Version: 0.20.20
+Version: 0.20.21
 Summary: Python Git Library
 Home-page: https://www.dulwich.io/
 Author: Jelmer Vernooij
@@ -9,7 +9,10 @@
 Project-URL: Bug Tracker, https://github.com/dulwich/dulwich/issues
 Project-URL: Repository, https://www.dulwich.io/code/
 Project-URL: GitHub, https://github.com/dulwich/dulwich
-Description: This is the Dulwich project.
+Description: Dulwich
+        =======
+        
+        This is the Dulwich project.
         
         It aims to provide an interface to git repos (both local and remote) 
that
         doesn't call out to git directly but instead uses pure Python.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/dulwich.egg-info/SOURCES.txt 
new/dulwich-0.20.21/dulwich.egg-info/SOURCES.txt
--- old/dulwich-0.20.20/dulwich.egg-info/SOURCES.txt    2021-03-03 
14:31:44.000000000 +0100
+++ new/dulwich-0.20.21/dulwich.egg-info/SOURCES.txt    2021-03-26 
00:39:35.000000000 +0100
@@ -94,6 +94,8 @@
 dulwich.egg-info/entry_points.txt
 dulwich.egg-info/requires.txt
 dulwich.egg-info/top_level.txt
+dulwich/cloud/__init__.py
+dulwich/cloud/gcs.py
 dulwich/contrib/README.md
 dulwich/contrib/__init__.py
 dulwich/contrib/diffstat.py
@@ -232,5 +234,6 @@
 examples/clone.py
 examples/config.py
 examples/diff.py
+examples/gcs.py
 examples/latest_change.py
 examples/memoryrepo.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/examples/gcs.py 
new/dulwich-0.20.21/examples/gcs.py
--- old/dulwich-0.20.20/examples/gcs.py 1970-01-01 01:00:00.000000000 +0100
+++ new/dulwich-0.20.21/examples/gcs.py 2021-03-26 00:38:11.000000000 +0100
@@ -0,0 +1,14 @@
+#!/usr/bin/python3
+
+from dulwich.repo import Repo
+from dulwich.cloud.gcs import GcsObjectStore
+
+import tempfile
+
+from google.cloud import storage
+
+client = storage.Client()
+bucket = client.get_bucket('mybucket')
+
+gcs_object_store = GcsObjectStore(bucket, 'path')
+r = Repo.init_bare(tempfile.mkdtemp(), object_store=gcs_object_store)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/setup.py new/dulwich-0.20.21/setup.py
--- old/dulwich-0.20.20/setup.py        2021-03-03 14:31:34.000000000 +0100
+++ new/dulwich-0.20.21/setup.py        2021-03-26 00:39:32.000000000 +0100
@@ -23,7 +23,7 @@
         'For 2.7 support, please install a version prior to 0.20')
 
 
-dulwich_version_string = '0.20.20'
+dulwich_version_string = '0.20.21'
 
 
 class DulwichDistribution(Distribution):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dulwich-0.20.20/tox.ini new/dulwich-0.20.21/tox.ini
--- old/dulwich-0.20.20/tox.ini 2021-03-03 14:30:17.000000000 +0100
+++ new/dulwich-0.20.21/tox.ini 2021-03-26 00:38:11.000000000 +0100
@@ -1,6 +1,6 @@
 [tox]
 downloadcache = {toxworkdir}/cache/
-envlist = pypy, pypy-noext, py35, py35-noext, py36, py36-noext, py37, 
py37-noext, py38, py38-noext
+envlist = py35, py35-noext, py36, py36-noext, py37, py37-noext, py38, 
py38-noext
 
 [testenv]
 

Reply via email to