commit 8e5fe3b2030d0f077880d551f160ec07ebc9ffe7 from: Jelmer Vernooij date: Sun Jun 12 22:57:50 2022 UTC Merge remote-tracking branch 'danchr/push-failing' commit - ba0fa0cc9c7e490dc4fdf07837716b4f9fde8404 commit + 8e5fe3b2030d0f077880d551f160ec07ebc9ffe7 blob - 34e8dda184436f34544f1badd646cde24bcf7851 blob + 6ebc4e09cda23a9ac99061c5d8793eb08c9a645a --- dulwich/porcelain.py +++ dulwich/porcelain.py @@ -1139,13 +1139,14 @@ def pull( path, r, progress=errstream.write, determine_wants=determine_wants ) for (lh, rh, force_ref) in selected_refs: - try: - check_diverged(r, r.refs[rh], fetch_result.refs[lh]) - except DivergedBranches: - if fast_forward: - raise - else: - raise NotImplementedError("merge is not yet supported") + if not force_ref and rh in r.refs: + try: + check_diverged(r, r.refs.get(rh), fetch_result.refs[lh]) + except DivergedBranches: + if fast_forward: + raise + else: + raise NotImplementedError("merge is not yet supported") r.refs[rh] = fetch_result.refs[lh] if selected_refs: r[b"HEAD"] = fetch_result.refs[selected_refs[0][1]] blob - 201669ebff9d296ddd2ea89404ca02dfa5debb6e blob + 6ed9cac2c3b9e595b3eba070fd0ccef979c56148 --- dulwich/tests/test_porcelain.py +++ dulwich/tests/test_porcelain.py @@ -20,6 +20,7 @@ """Tests for dulwich.porcelain.""" +import contextlib from io import BytesIO, StringIO import os import platform @@ -30,6 +31,7 @@ import subprocess import sys import tarfile import tempfile +import threading import time from unittest import skipIf @@ -48,6 +50,9 @@ from dulwich.repo import ( NoIndexPresent, Repo, ) +from dulwich.server import ( + DictBackend, +) from dulwich.tests import ( TestCase, ) @@ -55,6 +60,10 @@ from dulwich.tests.utils import ( build_commit_graph, make_commit, make_object, +) +from dulwich.web import ( + make_server, + make_wsgi_chain, ) @@ -2867,3 +2876,42 @@ class FindUniqueAbbrevTests(PorcelainTestCase): self.assertEqual( c1.id.decode('ascii')[:7], porcelain.find_unique_abbrev(self.repo.object_store, c1.id)) + + +class ServerTests(PorcelainTestCase): + @contextlib.contextmanager + def _serving(self): + with make_server('localhost', 0, self.app) as server: + thread = threading.Thread(target=server.serve_forever, daemon=True) + thread.start() + + try: + yield f"http://localhost:{server.server_port}" + + finally: + server.shutdown() + thread.join(10) + + def setUp(self): + super().setUp() + + self.served_repo_path = os.path.join(self.test_dir, "served_repo.git") + self.served_repo = Repo.init_bare(self.served_repo_path, mkdir=True) + self.addCleanup(self.served_repo.close) + + backend = DictBackend({"/": self.served_repo}) + self.app = make_wsgi_chain(backend) + + def test_pull(self): + c1, = build_commit_graph(self.served_repo.object_store, [[1]]) + self.served_repo.refs[b"refs/heads/master"] = c1.id + + with self._serving() as url: + porcelain.pull(self.repo, url, "master") + + def test_push(self): + c1, = build_commit_graph(self.repo.object_store, [[1]]) + self.repo.refs[b"refs/heads/master"] = c1.id + + with self._serving() as url: + porcelain.push(self.repo, url, "master")