commit - 6324a262f6030f58bca298b384da0fbd41ba3bbc
commit + 4d8b946632b53888da3330b5a0b23cfb3aa5d258
blob - bde4be383f0965f03cce87d65ca9570aced4cdad
blob + 4273eb21cd51bec40e1b41bdf655033190bbf969
--- .flake8
+++ .flake8
[flake8]
-extend-ignore = E203, E266, E501, W293, W291
+extend-ignore = E203, E266, E501, W293, W291, W503
max-line-length = 88
max-complexity = 18
select = B,C,E,F,W,T4,B9
blob - 51594a39fc281388e601a07daaa5a7b36fbd5820
blob + 7342c577fe317795f76fe5f0045d4288dbbb048e
--- .github/workflows/pythonpackage.yml
+++ .github/workflows/pythonpackage.yml
push:
pull_request:
schedule:
- - cron: '0 6 * * *' # Daily 6AM UTC build
+ - cron: "0 6 * * *" # Daily 6AM UTC build
jobs:
build:
-
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
- python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", pypy3]
+ python-version:
+ ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11.0-rc - 3.11", pypy3]
exclude:
# sqlite3 exit handling seems to get in the way
- os: macos-latest
fail-fast: false
steps:
- - uses: actions/checkout@v2
- - name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v2
- with:
- python-version: ${{ matrix.python-version }}
- - name: Install native dependencies (Ubuntu)
- run: sudo apt-get update && sudo apt-get install -y libgpgme-dev libgpg-error-dev
- if: "matrix.os == 'ubuntu-latest'"
- - name: Install native dependencies (MacOS)
- run: brew install swig gpgme
- if: "matrix.os == 'macos-latest'"
- - name: Install dependencies
- run: |
- python -m pip install --upgrade pip
- pip install -U pip coverage codecov flake8 fastimport paramiko
- - name: Install gpg on supported platforms
- run: pip install -U gpg
- if: "matrix.os != 'windows-latest' && matrix.python-version != 'pypy3'"
- - name: Install mypy
- run: |
- pip install -U mypy types-paramiko types-certifi types-requests
- if: "matrix.python-version != 'pypy3'"
- - name: Style checks
- run: |
- python -m flake8
- - name: Typing checks
- run: |
- python -m mypy dulwich
- if: "matrix.python-version != 'pypy3'"
- - name: Build
- run: |
- python setup.py build_ext -i
- - name: Coverage test suite run
- run: |
- python -m coverage run -p -m unittest dulwich.tests.test_suite
- - name: Upload coverage details
- run: |
- codecov
+ - uses: actions/checkout@v2
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install native dependencies (Ubuntu)
+ run: sudo apt-get update && sudo apt-get install -y libgpgme-dev libgpg-error-dev
+ if: "matrix.os == 'ubuntu-latest'"
+ - name: Install native dependencies (MacOS)
+ run: brew install swig gpgme
+ if: "matrix.os == 'macos-latest'"
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install -U pip coverage flake8 fastimport paramiko urllib3
+ - name: Install gpg on supported platforms
+ run: pip install -U gpg
+ if: "matrix.os != 'windows-latest' && matrix.python-version != 'pypy3'"
+ - name: Install mypy
+ run: |
+ pip install -U mypy types-paramiko types-requests
+ if: "matrix.python-version != 'pypy3'"
+ - name: Style checks
+ run: |
+ python -m flake8
+ - name: Typing checks
+ run: |
+ python -m mypy dulwich
+ if: "matrix.python-version != 'pypy3'"
+ - name: Build
+ run: |
+ python setup.py build_ext -i
+ - name: Coverage test suite run
+ run: |
+ python -m coverage run -p -m unittest dulwich.tests.test_suite
blob - bc3dba462a887afe6041cfd1bf98a57675cc749b
blob + d13985a3fe4bd97871756d041be847aac09b442a
--- .github/workflows/pythonwheels.yml
+++ .github/workflows/pythonwheels.yml
push:
pull_request:
schedule:
- - cron: '0 6 * * *' # Daily 6AM UTC build
+ - cron: "0 6 * * *" # Daily 6AM UTC build
jobs:
build:
-
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, windows-latest]
- python-version: ['3.6', '3.7', '3.8', '3.9', '3.10']
+ python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11.0-rc - 3.11"]
+ architecture: ["x64", "x86"]
include:
- os: ubuntu-latest
- python-version: '3.x'
+ python-version: "3.x"
# path encoding
+ exclude:
+ - os: macos-latest
+ architecture: "x86"
fail-fast: true
steps:
- - uses: actions/checkout@v2
- - name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v2
- with:
- python-version: ${{ matrix.python-version }}
- - name: Install native dependencies (Ubuntu)
- run: sudo apt-get update && sudo apt-get install -y libgpgme-dev libgpg-error-dev
- if: "matrix.os == 'ubuntu-latest'"
- - name: Install native dependencies (MacOS)
- run: brew install swig gpgme
- if: "matrix.os == 'macos-latest'"
- - name: Install dependencies
- run: |
- python -m pip install --upgrade pip
- pip install setuptools wheel fastimport paramiko urllib3
- - name: Install gpg on supported platforms
- run: pip install -U gpg
- if: "matrix.os != 'windows-latest' && matrix.python-version != 'pypy3'"
- - name: Run test suite
- run: |
- python -m unittest dulwich.tests.test_suite
- - name: Build
- 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 (Linux aarch64)
- uses: RalfG/python-wheels-manylinux-build@v0.3.3-manylinux2014_aarch64
- with:
- python-versions: 'cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310'
- if: "matrix.os == 'ubuntu-latest'"
- - name: Build (Linux)
- uses: RalfG/python-wheels-manylinux-build@v0.3.1
- with:
- 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
- LD_LIBRARY_PATH: /usr/local/lib:${{ env.LD_LIBRARY_PATH }}
- if: "matrix.os == 'ubuntu-latest'"
- - name: Upload wheels (Linux)
- uses: actions/upload-artifact@v2
- # Only include *manylinux* wheels; the other wheels files are built but
- # rejected by pip.
- if: "matrix.os == 'ubuntu-latest'"
- with:
- name: dist
- path: dist/*manylinux*.whl
- - name: Upload wheels (non-Linux)
- uses: actions/upload-artifact@v2
- with:
- name: dist
- path: dist/*.whl
- if: "matrix.os != 'ubuntu-latest'"
+ - uses: actions/checkout@v2
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+ architecture: ${{ matrix.architecture }}
+ - name: Install native dependencies (Ubuntu)
+ run: sudo apt-get update && sudo apt-get install -y libgpgme-dev libgpg-error-dev
+ if: "matrix.os == 'ubuntu-latest'"
+ - name: Install native dependencies (MacOS)
+ run: brew install swig gpgme
+ if: "matrix.os == 'macos-latest'"
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install setuptools wheel fastimport paramiko urllib3
+ - name: Install gpg on supported platforms
+ run: pip install -U gpg
+ if: "matrix.os != 'windows-latest' && matrix.python-version != 'pypy3'"
+ - name: Run test suite
+ run: |
+ python -m unittest dulwich.tests.test_suite
+ - name: Build
+ 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 (Linux aarch64)
+ uses: RalfG/python-wheels-manylinux-build@v0.5.0-manylinux2014_aarch64
+ with:
+ python-versions: "cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310 cp311-cp311"
+ if: "matrix.os == 'ubuntu-latest'"
+ - name: Build (Linux)
+ uses: RalfG/python-wheels-manylinux-build@v0.5.0
+ with:
+ python-versions: "cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310 cp311-cp311"
+ env:
+ # Temporary fix for LD_LIBRARY_PATH issue. See
+ # https://github.com/RalfG/python-wheels-manylinux-build/issues/26
+ LD_LIBRARY_PATH: /usr/local/lib:${{ env.LD_LIBRARY_PATH }}
+ if: "matrix.os == 'ubuntu-latest'"
+ - name: Upload wheels (Linux)
+ uses: actions/upload-artifact@v2
+ # Only include *manylinux* wheels; the other wheels files are built but
+ # rejected by pip.
+ if: "matrix.os == 'ubuntu-latest'"
+ with:
+ name: dist
+ path: dist/*manylinux*.whl
+ - name: Upload wheels (non-Linux)
+ uses: actions/upload-artifact@v2
+ with:
+ name: dist
+ path: dist/*.whl
+ if: "matrix.os != 'ubuntu-latest'"
publish:
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/dulwich-')
steps:
- - name: Set up Python
- uses: actions/setup-python@v2
- with:
- python-version: "3.x"
- - name: Install twine
- run: |
- python -m pip install --upgrade pip
- pip install twine
- - name: Download wheels
- uses: actions/download-artifact@v2
- - name: Publish wheels
- env:
- TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
- TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
- run: twine upload dist/*.whl
+ - name: Set up Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: "3.x"
+ - name: Install twine
+ run: |
+ python -m pip install --upgrade pip
+ pip install twine
+ - name: Download wheels
+ uses: actions/download-artifact@v2
+ - name: Publish wheels
+ env:
+ TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
+ TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
+ run: twine upload dist/*.whl
blob - dd4bb87f3abccf1d8f03aede67f5fed7c74e1c5c
blob + 8a64b18818ffddc5361f7470e595d0c94e8a5bdf
--- CODE_OF_CONDUCT.md
+++ CODE_OF_CONDUCT.md
Examples of behavior that contributes to creating a positive environment
include:
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
+- Using welcoming and inclusive language
+- Being respectful of differing viewpoints and experiences
+- Gracefully accepting constructive criticism
+- Focusing on what is best for the community
+- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
-* The use of sexualized language or imagery and unwelcome sexual attention or
- advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic
- address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
- professional setting
+- The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+- Trolling, insulting/derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+- Other conduct which could reasonably be considered inappropriate in a
+ professional setting
## Our Responsibilities
## Attribution
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 1.4, available at
+<https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
-https://www.contributor-covenant.org/faq
+<https://www.contributor-covenant.org/faq>
blob - 63d3dfa8fc48ef4dfbc5f4499d7d302a6d99bd24
blob + 66b91b804fd655b96ef62cf1836895bbe1e7cc41
--- Makefile
+++ Makefile
.PHONY: apidocs
apidocs:
- pydoctor --docformat=google dulwich --project-url=https://www.dulwich.io/
+ pydoctor --intersphinx http://urllib3.readthedocs.org/en/latest/objects.inv --intersphinx http://docs.python.org/3/objects.inv --docformat=google dulwich --project-url=https://www.dulwich.io/
blob - 956ea765820765587c72d393dd007aa4fb95592a
blob + e9a4915216bd7eeacb6d4cb12ba218d4fccd1077
--- NEWS
+++ NEWS
+0.20.46 2022-09-06
+
+ * Apply insteadOf to rsync-style location strings
+ (previously it was just applied to URLs).
+ (Jelmer Vernooij, python-poetry/poetry#6329)
+
+ * Drop use of certifi, instead relying on urllib3's default
+ code to find system CAs. (Jelmer Vernooij, #1025)
+
+ * Implement timezone parsing in porcelain.
+ (springheeledjack0, #1026)
+
+ * Drop support for running without setuptools.
+ (Jelmer Vernooij)
+
+ * Ensure configuration is loaded when
+ running "dulwich clone".
+ (Jelmer Vernooij)
+
+ * Build 32 bit wheels for Windows.
+ (Benjamin Parzella)
+
+ * tests: Ignore errors when deleting GNUPG
+ home directory. Fixes spurious errors racing
+ gnupg-agent. Thanks, Matěj Cepl. Fixes #1000
+
+ * config: Support closing brackets in quotes in section
+ names. (Jelmer Vernooij, #10124)
+
+ * Various and formatting fixes. (Kian-Meng Ang)
+
+ * Document basic authentication in dulwich.porcelain.clone.
+ (TuringTux)
+
+ * Flush before calling fsync, ensuring buffers
+ are filled. (wernha)
+
+ * Support GPG commit signing. (springheeledjack0)
+
+ * Add python 3.11 support. (Saugat Pachhai)
+
+ * Allow missing GPG during tests. (Jakub Kulík)
+
+ * status: return posix-style untracked paths instead of nt-style paths on
+ win32 (Daniele Trifirò)
+
+ * Honour PATH environment when running C Git for testing.
+ (Stefan Sperling)
+
+ * Split out exception for symbolic reference loops.
+ (Jelmer Vernooij)
+
+ * Move various long-deprecated methods.
+ (Jelmer Vernooij)
+
+
+0.20.45 2022-07-15
+
+ * Add basic ``dulwich.porcelain.submodule_list`` and ``dulwich.porcelain.submodule_add``
+ (Jelmer Vernooij)
+
0.20.44 2022-06-30
* Fix reading of chunks in server. (Jelmer Vernooij, #977)
probing the filesystem for trustable permissions.
(Koen Martens)
- * Fix ``porcelain.reset`` to respect the comittish argument.
+ * Fix ``porcelain.reset`` to respect the committish argument.
(Koen Martens)
* Fix dulwich.porcelain.ls_remote() on Python 3.
* Provide strnlen() on mingw32 which doesn't have it. (Hans Kolek)
- * Set bare=true in the configuratin for bare repositories. (Dirk Neumann)
+ * Set bare=true in the configuration for bare repositories. (Dirk Neumann)
FEATURES
FEATURES
- * Move named file initilization to BaseRepo. (Dave Borowitz)
+ * Move named file initialization to BaseRepo. (Dave Borowitz)
* Add logging utilities and git/HTTP server logging. (Dave Borowitz)
* Fix RefsContainer.add_if_new to support dangling symrefs.
(Dave Borowitz)
- * Non-existant index files in non-bare repositories are now treated as
+ * Non-existent index files in non-bare repositories are now treated as
empty. (Dave Borowitz)
* Always update ShaFile.id when the contents of the object get changed.
blob - 3de0b5b9f6f458c21bdbe15bb6a586b4bbcc5588
blob + 41cceb42e189fa38d09214f9115560438252f579
--- PKG-INFO
+++ PKG-INFO
Metadata-Version: 2.1
Name: dulwich
-Version: 0.20.44
+Version: 0.20.46
Summary: Python Git Library
Home-page: https://www.dulwich.io/
Author: Jelmer Vernooij
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Operating System :: POSIX
blob - 7fefafc226806b050a4e21e0be999dd10781f958
blob + 4976b90a36c6fc3693937aa1aad00137c503c98b
--- README.swift.rst
+++ README.swift.rst
Note that for now we use the same tenant to perform the requests
-against Swift. Therefor there is only one Swift account used
+against Swift. Therefore there is only one Swift account used
for storing repositories. Each repository will be contained in
a Swift container.
a regular repository.
Note the daemon subcommands starts a Git server listening for the
-Git protocol. Therefor there is no authentication or encryption
+Git protocol. Therefore there is no authentication or encryption
at all between the cGIT client and the GIT server (Dulwich).
Note on the .info file for pack object
blob - f1f27068980f3909300a902ddb04c7da4d6a5908
blob + f5887a0d60cf9cb0fc5ce71c90417b6e9c29fa8e
--- SECURITY.md
+++ SECURITY.md
## Reporting a Vulnerability
-Please report security issues by e-mail to jelmer@jelmer.uk, ideally PGP encrypted to the key at https://jelmer.uk/D729A457.asc
+Please report security issues by e-mail to jelmer@jelmer.uk, ideally PGP
+encrypted to the key at <https://jelmer.uk/D729A457.asc>
blob - e9f070e7868757cbf3bc121a67c780ff9a47c5c1
blob + 49cd8d18d723d61d507793ee9f47c0a85ec3b0f3
--- docs/conf.py
+++ docs/conf.py
'sphinx.ext.ifconfig',
'sphinx.ext.intersphinx',
'sphinx.ext.napoleon',
- ]
+]
autoclass_content = "both"
# (source start file, target name, title, author, documentclass
# [howto/manual]).
latex_documents = [
- ('index', 'dulwich.tex', u'dulwich Documentation',
- u'Jelmer Vernooij', 'manual'),
+ ('index', 'dulwich.tex', u'dulwich Documentation',
+ 'Jelmer Vernooij', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# If false, no module index is generated.
# latex_use_modindex = True
+
+# Add mappings
+intersphinx_mapping = {
+ 'urllib3': ('http://urllib3.readthedocs.org/en/latest', None),
+ 'python': ('http://docs.python.org/3', None),
+}
blob - 0dd0d7e7a9dd117df456cdc48188f39e9425047e
blob + 9f1ea60edd3fb5e5450615dff45b2e77e3a65416
--- docs/tutorial/encoding.txt
+++ docs/tutorial/encoding.txt
.. _C git: https://github.com/git/git/blob/master/Documentation/i18n.txt
The library should be able to read *all* existing git repositories,
-irregardless of what encoding they use. This is the main reason why Dulwich
+regardless of what encoding they use. This is the main reason why Dulwich
does not convert paths to unicode strings.
A further consideration is that converting back and forth to unicode
blob - b85e29e5ad15aba4b3a8baf0de52769c5b564c84
blob + 84da8ebe22d04adc72f703508210b49b72bc7ce6
--- docs/tutorial/porcelain.txt
+++ docs/tutorial/porcelain.txt
------------------
>>> porcelain.clone("git://github.com/jelmer/dulwich", "dulwich-clone")
+
+Basic authentication works using the ``username`` and ``password`` parameters:
+ >>> porcelain.clone(
+ "https://example.com/a-private-repo.git",
+ "a-private-repo-clone",
+ username="user", password="password")
+
Commit changes
--------------
blob - 4544902ed0a6ad3a3d904cd6c64d39e9cb72860f
blob + 2577ade721f7b412ff248e3d56e938072b35bfdd
--- dulwich/__init__.py
+++ dulwich/__init__.py
"""Python implementation of the Git file formats and protocols."""
-__version__ = (0, 20, 44)
+__version__ = (0, 20, 46)
blob - 5f4baf95e0c3830b82bec31d3ad82dbe0dbfd537
blob + 57677d3241bb5f2bb8fe56a7504438610bacccdf
--- dulwich/archive.py
+++ dulwich/archive.py
if format == "gz":
# Manually correct the gzip header file modification time so that
# archives created from the same Git tree are always identical.
- # The gzip header file modification time is not currenctly
+ # The gzip header file modification time is not currently
# accessible from the tarfile API, see:
# https://bugs.python.org/issue31526
buf.seek(0)
blob - 235f80b996fbd0254f44349709de633d1769f7a9
blob + 38b805f0c7eaa07e074c0fa7683442377eeab1a2
--- dulwich/cli.py
+++ dulwich/cli.py
porcelain.rev_list(".", args)
+class cmd_submodule(Command):
+ def run(self, args):
+ parser = optparse.OptionParser()
+ options, args = parser.parse_args(args)
+ for path, sha in porcelain.submodule_list("."):
+ sys.stdout.write(' %s %s\n' % (sha, path))
+
+
class cmd_tag(Command):
def run(self, args):
parser = optparse.OptionParser()
"-r",
"--recursive",
action="store_true",
- help="Recusively list tree contents.",
+ help="Recursively list tree contents.",
)
parser.add_option("--name-only", action="store_true", help="Only display name.")
options, args = parser.parse_args(args)
def run(self, argv):
parser = argparse.ArgumentParser()
+ parser.add_argument('-f', '--force', action='store_true', help='Force')
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)
+ try:
+ porcelain.push('.', args.to_location, args.refspec or None, force=args.force)
+ except porcelain.DivergedBranches:
+ sys.stderr.write('Diverged branches; specify --force to override')
+ return 1
class cmd_remote_add(Command):
"stash": cmd_stash,
"status": cmd_status,
"symbolic-ref": cmd_symbolic_ref,
+ "submodule": cmd_submodule,
"tag": cmd_tag,
"update-server-info": cmd_update_server_info,
"upload-pack": cmd_upload_pack,
blob - 19f540e69893a800afb90122765f0e02d003faf1
blob + cf2e2c516350dafdb60847ebb3adcb2c7614f22c
--- dulwich/client.py
+++ dulwich/client.py
import socket
import subprocess
import sys
-from typing import Any, Callable, Dict, List, Optional, Set, Tuple, IO, Iterable
+from typing import (
+ Any,
+ Callable,
+ Dict,
+ List,
+ Optional,
+ Set,
+ Tuple,
+ IO,
+ Union,
+ TYPE_CHECKING,
+)
from urllib.parse import (
quote as urlquote,
urlunparse,
)
+if TYPE_CHECKING:
+ import urllib3
+
import dulwich
-from dulwich.config import get_xdg_config_home_path, Config
+from dulwich.config import get_xdg_config_home_path, Config, apply_instead_of
from dulwich.errors import (
GitProtocolError,
NotGitRepository,
"""Handle the head of a 'git-receive-pack' request.
Args:
- proto: Protocol object to read from
capabilities: List of negotiated capabilities
old_refs: Old refs, as received from the server
new_refs: Refs to change
negotiated_capabilities = self._fetch_capabilities & server_capabilities
return (negotiated_capabilities, symrefs, agent)
+
+ def archive(
+ self,
+ path,
+ committish,
+ write_data,
+ progress=None,
+ write_error=None,
+ format=None,
+ subdirs=None,
+ prefix=None,
+ ):
+ """Retrieve an archive of the specified tree.
+ """
+ raise NotImplementedError(self.archive)
def check_wants(wants, refs):
class SSHVendor(object):
"""A client side SSH implementation."""
-
- def connect_ssh(
- self,
- host,
- command,
- username=None,
- port=None,
- password=None,
- key_filename=None,
- ):
- # This function was deprecated in 0.9.1
- import warnings
- warnings.warn(
- "SSHVendor.connect_ssh has been renamed to SSHVendor.run_command",
- DeprecationWarning,
- )
- return self.run_command(
- host,
- command,
- username=username,
- port=port,
- password=password,
- key_filename=key_filename,
- )
-
def run_command(
self,
host,
if ssh_command:
import shlex
- args = shlex.split(ssh_command) + ["-x"]
+ args = shlex.split(
+ ssh_command, posix=(sys.platform != 'win32')) + ["-x"]
else:
args = ["ssh", "-x"]
if ssh_command:
import shlex
- args = shlex.split(ssh_command) + ["-ssh"]
+ args = shlex.split(
+ ssh_command, posix=(sys.platform != 'win32')) + ["-ssh"]
elif sys.platform == "win32":
args = ["plink.exe", "-ssh"]
else:
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
+ # GIT_SSH_COMMAND takes precedence over GIT_SSH
if self.ssh_command is not None:
kwargs["ssh_command"] = self.ssh_command
con = self.ssh_vendor.run_command(
def default_urllib3_manager( # noqa: C901
config, pool_manager_cls=None, proxy_manager_cls=None, **override_kwargs
-):
- """Return `urllib3` connection pool manager.
+) -> Union["urllib3.ProxyManager", "urllib3.PoolManager"]:
+ """Return urllib3 connection pool manager.
Honour detected proxy configurations.
override_kwargs: Additional arguments for `urllib3.ProxyManager`
Returns:
- `pool_manager_cls` (defaults to `urllib3.ProxyManager`) instance for
- proxy configurations, `proxy_manager_cls` (defaults to
- `urllib3.PoolManager`) instance otherwise.
+ Either pool_manager_cls (defaults to `urllib3.ProxyManager`) instance for
+ proxy configurations, proxy_manager_cls
+ (defaults to `urllib3.PoolManager`) instance otherwise
"""
proxy_server = user_agent = None
headers = {"User-agent": user_agent}
- kwargs = {}
+ kwargs = {
+ "ca_certs" : ca_certs,
+ }
if ssl_verify is True:
kwargs["cert_reqs"] = "CERT_REQUIRED"
elif ssl_verify is False:
# Default to SSL verification
kwargs["cert_reqs"] = "CERT_REQUIRED"
- if ca_certs is not None:
- kwargs["ca_certs"] = ca_certs
kwargs.update(override_kwargs)
-
- # Try really hard to find a SSL certificate path
- if "ca_certs" not in kwargs and kwargs.get("cert_reqs") != "CERT_NONE":
- try:
- import certifi
- except ImportError:
- pass
- else:
- kwargs["ca_certs"] = certifi.where()
import urllib3
data: Request data.
Returns:
- Tuple (`response`, `read`), where response is an `urllib3`
- response object with additional `content_type` and
- `redirect_location` properties, and `read` is a consumable read
+ Tuple (response, read), where response is an urllib3
+ response object with additional content_type and
+ redirect_location properties, and read is a consumable read
method for the response data.
"""
if url2pathname is None:
from urllib.request import url2pathname # type: ignore
return url2pathname(netloc + path) # type: ignore
-
-
-def iter_instead_of(config: Config, push: bool = False) -> Iterable[Tuple[str, str]]:
- """Iterate over insteadOf / pushInsteadOf values.
- """
- for section in config.sections():
- if section[0] != b'url':
- continue
- replacement = section[1]
- try:
- needles = list(config.get_multivar(section, "insteadOf"))
- except KeyError:
- needles = []
- if push:
- try:
- needles += list(config.get_multivar(section, "pushInsteadOf"))
- except KeyError:
- pass
- for needle in needles:
- yield needle.decode('utf-8'), replacement.decode('utf-8')
-def apply_instead_of(config: Config, orig_url: str, push: bool = False) -> str:
- """Apply insteadOf / pushInsteadOf to a URL.
- """
- longest_needle = ""
- updated_url = orig_url
- for needle, replacement in iter_instead_of(config, push):
- if not orig_url.startswith(needle):
- continue
- if len(longest_needle) < len(needle):
- longest_needle = needle
- updated_url = replacement + orig_url[len(needle):]
- return updated_url
-
-
def get_transport_and_path_from_url(
url: str, config: Optional[Config] = None,
operation: Optional[str] = None, **kwargs) -> Tuple[GitClient, str]:
"""
if config is not None:
url = apply_instead_of(config, url, push=(operation == "push"))
+
+ return _get_transport_and_path_from_url(
+ url, config=config, operation=operation, **kwargs)
+
+
+def _get_transport_and_path_from_url(url, config, operation, **kwargs):
parsed = urlparse(url)
if parsed.scheme == "git":
return (TCPGitClient.from_parsedurl(parsed, **kwargs), parsed.path)
def get_transport_and_path(
location: str,
+ config: Optional[Config] = None,
operation: Optional[str] = None,
**kwargs: Any
) -> Tuple[GitClient, str]:
Tuple with client instance and relative path.
"""
+ if config is not None:
+ location = apply_instead_of(config, location, push=(operation == "push"))
+
# First, try to parse it as a URL
try:
- return get_transport_and_path_from_url(location, operation=operation, **kwargs)
+ return _get_transport_and_path_from_url(
+ location, config=config, operation=operation, **kwargs)
except ValueError:
pass
blob - e52d468e3bc66f6fa295218061a2656e207ac800
blob + 7f09ae57a41e4ec5ad9871016e300ad1652086b9
--- dulwich/config.py
+++ dulwich/config.py
import os
import sys
-import warnings
from typing import (
BinaryIO,
Iterable,
from dulwich.file import GitFile
-SENTINAL = object()
+SENTINEL = object()
def lower_key(key):
def __getitem__(self, item):
return self._keyed[lower_key(item)]
- def get(self, key, default=SENTINAL):
+ def get(self, key, default=SENTINEL):
try:
return self[key]
except KeyError:
pass
- if default is SENTINAL:
+ if default is SENTINEL:
return type(self)()
return default
if lower_key(actual) == key:
yield value
- def setdefault(self, key, default=SENTINAL):
+ def setdefault(self, key, default=SENTINEL):
try:
return self[key]
except KeyError:
"""
raise NotImplementedError(self.items)
- def iteritems(self, section: SectionLike) -> Iterator[Tuple[Name, Value]]:
- """Iterate over the configuration pairs for a specific section.
-
- Args:
- section: Tuple with section name and optional subsection namee
- Returns:
- Iterator over (name, value) pairs
- """
- warnings.warn(
- "Use %s.items instead." % type(self).__name__,
- DeprecationWarning,
- stacklevel=3,
- )
- return self.items(section)
-
- def itersections(self) -> Iterator[Section]:
- warnings.warn(
- "Use %s.items instead." % type(self).__name__,
- DeprecationWarning,
- stacklevel=3,
- )
- return self.sections()
-
def sections(self) -> Iterator[Section]:
"""Iterate over the sections.
elif not string_open and character in comment_bytes:
return line[:i]
return line
+
+
+def _parse_section_header_line(line: bytes) -> Tuple[Section, bytes]:
+ # Parse section header ("[bla]")
+ line = _strip_comments(line).rstrip()
+ in_quotes = False
+ escaped = False
+ for i, c in enumerate(line):
+ if escaped:
+ escaped = False
+ continue
+ if c == ord(b'"'):
+ in_quotes = not in_quotes
+ if c == ord(b'\\'):
+ escaped = True
+ if c == ord(b']') and not in_quotes:
+ last = i
+ break
+ else:
+ raise ValueError("expected trailing ]")
+ pts = line[1:last].split(b" ", 1)
+ line = line[last + 1:]
+ section: Section
+ if len(pts) == 2:
+ if pts[1][:1] != b'"' or pts[1][-1:] != b'"':
+ raise ValueError("Invalid subsection %r" % pts[1])
+ else:
+ pts[1] = pts[1][1:-1]
+ if not _check_section_name(pts[0]):
+ raise ValueError("invalid section name %r" % pts[0])
+ section = (pts[0], pts[1])
+ else:
+ if not _check_section_name(pts[0]):
+ raise ValueError("invalid section name %r" % pts[0])
+ pts = pts[0].split(b".", 1)
+ if len(pts) == 2:
+ section = (pts[0], pts[1])
+ else:
+ section = (pts[0],)
+ return section, line
class ConfigFile(ConfigDict):
line = line[3:]
line = line.lstrip()
if setting is None:
- # Parse section header ("[bla]")
if len(line) > 0 and line[:1] == b"[":
- line = _strip_comments(line).rstrip()
- try:
- last = line.index(b"]")
- except ValueError:
- raise ValueError("expected trailing ]")
- pts = line[1:last].split(b" ", 1)
- line = line[last + 1 :]
- if len(pts) == 2:
- if pts[1][:1] != b'"' or pts[1][-1:] != b'"':
- raise ValueError("Invalid subsection %r" % pts[1])
- else:
- pts[1] = pts[1][1:-1]
- if not _check_section_name(pts[0]):
- raise ValueError("invalid section name %r" % pts[0])
- section = (pts[0], pts[1])
- else:
- if not _check_section_name(pts[0]):
- raise ValueError("invalid section name %r" % pts[0])
- pts = pts[0].split(b".", 1)
- if len(pts) == 2:
- section = (pts[0], pts[1])
- else:
- section = (pts[0],)
+ section, line = _parse_section_header_line(line)
ret._values.setdefault(section)
if _strip_comments(line).strip() == b"":
continue
sm_path = config.get(section, b"path")
sm_url = config.get(section, b"url")
yield (sm_path, sm_url, section_name)
+
+
+def iter_instead_of(config: Config, push: bool = False) -> Iterable[Tuple[str, str]]:
+ """Iterate over insteadOf / pushInsteadOf values.
+ """
+ for section in config.sections():
+ if section[0] != b'url':
+ continue
+ replacement = section[1]
+ try:
+ needles = list(config.get_multivar(section, "insteadOf"))
+ except KeyError:
+ needles = []
+ if push:
+ try:
+ needles += list(config.get_multivar(section, "pushInsteadOf"))
+ except KeyError:
+ pass
+ for needle in needles:
+ assert isinstance(needle, bytes)
+ yield needle.decode('utf-8'), replacement.decode('utf-8')
+
+
+def apply_instead_of(config: Config, orig_url: str, push: bool = False) -> str:
+ """Apply insteadOf / pushInsteadOf to a URL.
+ """
+ longest_needle = ""
+ updated_url = orig_url
+ for needle, replacement in iter_instead_of(config, push):
+ if not orig_url.startswith(needle):
+ continue
+ if len(longest_needle) < len(needle):
+ longest_needle = needle
+ updated_url = replacement + orig_url[len(needle):]
+ return updated_url
blob - 83b1638922dbd682089d554cbf247988cdb75c92
blob + 7a552ed4aedc218db9ab27c6ce475a4d5047e97a
--- dulwich/contrib/diffstat.py
+++ dulwich/contrib/diffstat.py
def main():
argv = sys.argv
- # allow diffstat.py to also be used from the comand line
+ # allow diffstat.py to also be used from the command line
if len(sys.argv) > 1:
diffpath = argv[1]
data = b""
# if no path argument to a diff file is passed in, run
# a self test. The test case includes tricky things like
- # a diff of diff, binary files, renames with futher changes
+ # a diff of diff, binary files, renames with further changes
# added files and removed files.
# All extracted from Sigil-Ebook/Sigil's github repo with
# full permission to use under this license.
blob - 33dc60fcb9d411f4a5f5eeb3ebde3eb3ecfbe9be
blob + 5b2734e7ec053960d6c3ceb6f7280d916d7de4c5
--- dulwich/contrib/release_robot.py
+++ dulwich/contrib/release_robot.py
__version__ = get_current_version()
This example assumes the tags have a leading "v" like "v0.3", and that the
-``.git`` folder is in a project folder that containts the package folder.
+``.git`` folder is in a project folder that contains the package folder.
EG::
blob - 3d76acbe73c57e9c0bbbf1bba0e533410807ccaa
blob + 80ced06cbc13f3dffe04498deecf5ab3b841babe
--- dulwich/contrib/swift.py
+++ dulwich/contrib/swift.py
"""A SwiftPackReader that mimic read and sync method
The reader allows to read a specified amount of bytes from
- a given offset of a Swift object. A read offset is kept internaly.
+ a given offset of a Swift object. A read offset is kept internally.
The reader will read from Swift a specified amount of data to complete
- its internal buffer. chunk_length specifiy the amount of data
+ its internal buffer. chunk_length specify the amount of data
to read from Swift.
"""
blob - 33496543afbf40e7153e151911ee656ebfb30b8f
blob + 712b4f6cdc8b7335a9843183ca47f47084ef94d8
--- dulwich/contrib/test_paramiko_vendor.py
+++ dulwich/contrib/test_paramiko_vendor.py
def setUp(self):
import paramiko.transport
- # reenable server functionality for tests
+ # re-enable server functionality for tests
if hasattr(paramiko.transport, "SERVER_DISABLED_BY_GENTOO"):
paramiko.transport.SERVER_DISABLED_BY_GENTOO = False
blob - 5cb540a9a23eadb6270b916c36b38c62a848db42
blob + 461f75f80d1fda5589fcb49bcce975b91e6c4ae3
--- dulwich/contrib/test_swift_smoke.py
+++ dulwich/contrib/test_swift_smoke.py
swift.SwiftRepo.init_bare(self.scon, self.conf)
tcp_client = client.TCPGitClient(self.server_address, port=self.port)
remote_refs = tcp_client.fetch(self.fakerepo, local_repo)
- # The remote repo is empty (no refs retreived)
+ # The remote repo is empty (no refs retrieved)
self.assertEqual(remote_refs, None)
def test_push_commit(self):
blob - acdec8c74d0e42c3480a4ad10ba5bf517107beca
blob + b7720277bff5eee6a77ff68886721c8bce34c548
--- dulwich/file.py
+++ dulwich/file.py
"""
if self._closed:
return
+ self._file.flush()
os.fsync(self._file.fileno())
self._file.close()
try:
blob - b9d24d359b26561781c0cfd1fff1f98ad2fc2c14
blob + a948cc91862d9784e4f957c71c6a6687fe7219dc
--- dulwich/graph.py
+++ dulwich/graph.py
cstates[pcmt] = flags
wlst.append(pcmt)
- # walk final candidates removing any superceded by _DNC by later lower LCAs
+ # walk final candidates removing any superseded by _DNC by later lower LCAs
results = []
for cmt in cands:
if not (cstates[cmt] & _DNC):
blob - e920ab831bf1663734695d8fc9e477c0ee57e676
blob + a72cde13eacc974f797a5b996998b2f02c0d8adc
--- dulwich/hooks.py
+++ dulwich/hooks.py
args = self.pre_exec_callback(*args)
try:
- ret = subprocess.call([self.filepath] + list(args), cwd=self.cwd)
+ ret = subprocess.call(
+ [os.path.relpath(self.filepath, self.cwd)] + list(args),
+ cwd=self.cwd)
if ret != 0:
if self.post_exec_callback is not None:
self.post_exec_callback(0, *args)
blob - 309d5cf95a999b0257d02ad7c3b4bd4b0848c291
blob + 3066f42d616f148f12fda51fb08f26c90a410ede
--- dulwich/index.py
+++ dulwich/index.py
This returns an index value for files, symlinks
and tree references. for directories and
- non-existant files it returns None
+ non-existent files it returns None
Args:
path: Path to create an index entry for
def iter_fresh_objects(paths, root_path, include_deleted=False, object_store=None):
- """Iterate over versions of objecs on disk referenced by index.
+ """Iterate over versions of objects on disk referenced by index.
Args:
root_path: Root path to access from
blob - 561b6f96d282da770f2ba9a6a95a372b951bfef6
blob + 358338a4708f648c0d5444f233ac5879b1232bec
--- dulwich/object_store.py
+++ dulwich/object_store.py
def __len__(self):
"""Return the number of objects."""
return len(list(self.itershas()))
-
- def empty(self):
- import warnings
-
- warnings.warn("Use bool() instead.", DeprecationWarning)
- return self._empty()
def _empty(self):
it = self.itershas()
blob - 90f7de22615ee11b67adfd203f46044e4367e7a7
blob + 07b5208743ca11cb05a40252983a001f552e86cd
--- dulwich/objects.py
+++ dulwich/objects.py
Union,
Type,
)
-import warnings
import zlib
from hashlib import sha1
name: The name of the entry, as a string.
hexsha: The hex SHA of the entry as a string.
"""
- if isinstance(name, int) and isinstance(mode, bytes):
- (name, mode) = (mode, name)
- warnings.warn(
- "Please use Tree.add(name, mode, hexsha)",
- category=DeprecationWarning,
- stacklevel=2,
- )
self._entries[name] = mode, hexsha
self._needs_serialization = True
last = field
# TODO: optionally check for duplicate parents
+
+ def sign(self, keyid: Optional[str] = None):
+ import gpg
+ with gpg.Context(armor=True) as c:
+ if keyid is not None:
+ key = c.get_key(keyid)
+ with gpg.Context(armor=True, signers=[key]) as ctx:
+ self.gpgsig, unused_result = ctx.sign(
+ self.as_raw_string(),
+ mode=gpg.constants.sig.mode.DETACH,
+ )
+ else:
+ self.gpgsig, unused_result = c.sign(
+ self.as_raw_string(), mode=gpg.constants.sig.mode.DETACH
+ )
+
+ def verify(self, keyids: Optional[Iterable[str]] = None):
+ """Verify GPG signature for this commit (if it is signed).
+
+ Args:
+ keyids: Optional iterable of trusted keyids for this commit.
+ If this commit is not signed by any key in keyids verification will
+ fail. If not specified, this function only verifies that the commit
+ has a valid signature.
+
+ Raises:
+ gpg.errors.BadSignatures: if GPG signature verification fails
+ gpg.errors.MissingSignatures: if commit was not signed by a key
+ specified in keyids
+ """
+ if self._gpgsig is None:
+ return
+ import gpg
+
+ with gpg.Context() as ctx:
+ self_without_gpgsig = self.copy()
+ self_without_gpgsig._gpgsig = None
+ self_without_gpgsig.gpgsig = None
+ data, result = ctx.verify(
+ self_without_gpgsig.as_raw_string(),
+ signature=self._gpgsig,
+ )
+ if keyids:
+ keys = [
+ ctx.get_key(key)
+ for key in keyids
+ ]
+ for key in keys:
+ for subkey in keys:
+ for sig in result.signatures:
+ if subkey.can_sign and subkey.fpr == sig.fpr:
+ return
+ raise gpg.errors.MissingSignatures(
+ result, keys, results=(data, result)
+ )
+
def _serialize(self):
chunks = []
tree_bytes = self._tree.id if isinstance(self._tree, Tree) else self._tree
blob - 82ab5bef310451e75665c1da2ce0ce6ff2b9b21e
blob + 8c92a878cb540f6095fc6bef3e09c06ec6614d3b
--- dulwich/patch.py
+++ dulwich/patch.py
diff_binary: Whether to diff files even if they
are considered binary files by is_binary().
- Note: the tuple elements should be None for nonexistant files
+ Note: the tuple elements should be None for nonexistent files
"""
(old_path, old_mode, old_id) = old_file
(new_path, new_mode, new_id) = new_file
blob - d34dac7e8a6f3a6113e2b30e97f9f4f27dbe1a1a
blob + 7136bdbcf995cac7d0671d400dac3162cf53a18a
--- dulwich/porcelain.py
+++ dulwich/porcelain.py
* remote{_add}
* receive-pack
* reset
+ * submodule_list
* rev-list
* tag{_create,_delete,_list}
* upload-pack
get_transport_and_path,
)
from dulwich.config import (
+ ConfigFile,
StackedConfig,
)
from dulwich.diff_tree import (
"""Raised when the remote already exists."""
+class TimezoneFormatError(Error):
+ """Raised when the timezone cannot be determined from a given string."""
+
+
+def parse_timezone_format(tz_str):
+ """Parse given string and attempt to return a timezone offset.
+ Different formats are considered in the following order:
+ - Git internal format: <unix timestamp> <timezone offset>
+ - RFC 2822: e.g. Mon, 20 Nov 1995 19:12:08 -0500
+ - ISO 8601: e.g. 1995-11-20T19:12:08-0500
+ Args:
+ tz_str: datetime string
+ Returns: Timezone offset as integer
+ Raises:
+ TimezoneFormatError: if timezone information cannot be extracted
+ """
+ import re
+
+ # Git internal format
+ internal_format_pattern = re.compile("^[0-9]+ [+-][0-9]{,4}$")
+ if re.match(internal_format_pattern, tz_str):
+ try:
+ tz_internal = parse_timezone(tz_str.split(" ")[1].encode(DEFAULT_ENCODING))
+ return tz_internal[0]
+ except ValueError:
+ pass
+
+ # RFC 2822
+ import email.utils
+ rfc_2822 = email.utils.parsedate_tz(tz_str)
+ if rfc_2822:
+ return rfc_2822[9]
+
+ # ISO 8601
+
+ # Supported offsets:
+ # sHHMM, sHH:MM, sHH
+ iso_8601_pattern = re.compile("[0-9] ?([+-])([0-9]{2})(?::(?=[0-9]{2}))?([0-9]{2})?$")
+ match = re.search(iso_8601_pattern, tz_str)
+ total_secs = 0
+ if match:
+ sign, hours, minutes = match.groups()
+ total_secs += int(hours) * 3600
+ if minutes:
+ total_secs += int(minutes) * 60
+ total_secs = -total_secs if sign == "-" else total_secs
+ return total_secs
+
+ # YYYY.MM.DD, MM/DD/YYYY, DD.MM.YYYY contain no timezone information
+
+ raise TimezoneFormatError(tz_str)
+
+
+def get_user_timezones():
+ """Retrieve local timezone as described in
+ https://raw.githubusercontent.com/git/git/v2.3.0/Documentation/date-formats.txt
+ Returns: A tuple containing author timezone, committer timezone
+ """
+ local_timezone = time.localtime().tm_gmtoff
+
+ if os.environ.get("GIT_AUTHOR_DATE"):
+ author_timezone = parse_timezone_format(os.environ["GIT_AUTHOR_DATE"])
+ else:
+ author_timezone = local_timezone
+ if os.environ.get("GIT_COMMITTER_DATE"):
+ commit_timezone = parse_timezone_format(os.environ["GIT_COMMITTER_DATE"])
+ else:
+ commit_timezone = local_timezone
+
+ return author_timezone, commit_timezone
+
+
def open_repo(path_or_repo):
"""Open an argument that can be a repository or a path for a repository."""
if isinstance(path_or_repo, BaseRepo):
repo=".",
message=None,
author=None,
+ author_timezone=None,
committer=None,
+ commit_timezone=None,
encoding=None,
no_verify=False,
+ signoff=False,
):
"""Create a new commit.
repo: Path to repository
message: Optional commit message
author: Optional author name and email
+ author_timezone: Author timestamp timezone
committer: Optional committer name and email
+ commit_timezone: Commit timestamp timezone
no_verify: Skip pre-commit and commit-msg hooks
+ signoff: GPG Sign the commit (bool, defaults to False,
+ pass True to use default GPG key,
+ pass a str containing Key ID to use a specific GPG key)
Returns: SHA1 of the new commit
"""
# FIXME: Support --all argument
- # FIXME: Support --signoff argument
if getattr(message, "encode", None):
message = message.encode(encoding or DEFAULT_ENCODING)
if getattr(author, "encode", None):
author = author.encode(encoding or DEFAULT_ENCODING)
if getattr(committer, "encode", None):
committer = committer.encode(encoding or DEFAULT_ENCODING)
+ local_timezone = get_user_timezones()
+ if author_timezone is None:
+ author_timezone = local_timezone[0]
+ if commit_timezone is None:
+ commit_timezone = local_timezone[1]
with open_repo_closing(repo) as r:
return r.do_commit(
message=message,
author=author,
+ author_timezone=author_timezone,
committer=committer,
+ commit_timezone=commit_timezone,
encoding=encoding,
no_verify=no_verify,
+ sign=signoff if isinstance(signoff, (str, bool)) else None,
)
origin="origin",
depth=None,
branch=None,
+ config=None,
**kwargs
):
"""Clone a local or remote git repository.
depth: Depth to fetch at
branch: Optional branch or tag to be used as HEAD in the new repository
instead of the cloned repository's HEAD.
+ config: Configuration to use
Returns: The new repository
"""
if outstream is not None:
stacklevel=3,
)
# TODO(jelmer): Capture logging output and stream to errstream
+
+ if config is None:
+ config = StackedConfig.default()
if checkout is None:
checkout = not bare
mkdir = not os.path.exists(target)
- (client, path) = get_transport_and_path(source, **kwargs)
+ (client, path) = get_transport_and_path(
+ source, config=config, **kwargs)
return client.clone(
path,
outstream.write(entry.commit.id + b"\n")
-def tag(*args, **kwargs):
- import warnings
+def _canonical_part(url: str) -> str:
+ name = url.rsplit('/', 1)[-1]
+ if name.endswith('.git'):
+ name = name[:-4]
+ return name
- warnings.warn(
- "tag has been deprecated in favour of tag_create.", DeprecationWarning
- )
- return tag_create(*args, **kwargs)
+
+def submodule_add(repo, url, path=None, name=None):
+ """Add a new submodule.
+
+ Args:
+ repo: Path to repository
+ url: URL of repository to add as submodule
+ path: Path where submodule should live
+ """
+ with open_repo_closing(repo) as r:
+ if path is None:
+ path = os.path.relpath(_canonical_part(url), r.path)
+ if name is None:
+ name = path
+
+ # TODO(jelmer): Move this logic to dulwich.submodule
+ gitmodules_path = os.path.join(r.path, ".gitmodules")
+ try:
+ config = ConfigFile.from_path(gitmodules_path)
+ except FileNotFoundError:
+ config = ConfigFile()
+ config.path = gitmodules_path
+ config.set(("submodule", name), "url", url)
+ config.set(("submodule", name), "path", path)
+ config.write_to_path()
+def submodule_list(repo):
+ """List submodules.
+
+ Args:
+ repo: Path to repository
+ """
+ from .submodule import iter_cached_submodules
+ with open_repo_closing(repo) as r:
+ for path, sha in iter_cached_submodules(r.object_store, r[r.head()].tree):
+ yield path.decode(DEFAULT_ENCODING), sha.decode(DEFAULT_ENCODING)
+
+
def tag_create(
repo,
tag,
tag_time = int(time.time())
tag_obj.tag_time = tag_time
if tag_timezone is None:
- # TODO(jelmer) Use current user timezone rather than UTC
- tag_timezone = 0
+ tag_timezone = get_user_timezones()[1]
elif isinstance(tag_timezone, str):
tag_timezone = parse_timezone(tag_timezone)
tag_obj.tag_timezone = tag_timezone
tag_id = object.id
r.refs[_make_tag_ref(tag)] = tag_id
-
-
-def list_tags(*args, **kwargs):
- import warnings
-
- warnings.warn(
- "list_tags has been deprecated in favour of tag_list.",
- DeprecationWarning,
- )
- return tag_list(*args, **kwargs)
def tag_list(repo, outstream=sys.stdout):
untracked_files: How to handle untracked files, defaults to "all":
"no": do not return untracked files
"all": include all files in untracked directories
- Using `untracked_files="no"` can be faster than "all" when the worktreee
+ Using untracked_files="no" can be faster than "all" when the worktreee
contains many untracked files/directories.
- Note: `untracked_files="normal" (`git`'s default) is not implemented.
+ Note: untracked_files="normal" (git's default) is not implemented.
Returns: GitStatus tuple,
staged - dict with lists of staged paths (diff index/HEAD)
exclude_ignored=not ignored,
untracked_files=untracked_files,
)
- untracked_changes = list(untracked_paths)
+ if sys.platform == "win32":
+ untracked_changes = [
+ path.replace(os.path.sep, "/") for path in untracked_paths
+ ]
+ else:
+ untracked_changes = list(untracked_paths)
return GitStatus(tracked_changes, unstaged_changes, untracked_changes)
objectish = "HEAD"
object = parse_object(r, objectish)
refname = _make_branch_ref(name)
- ref_message = b"branch: Created from " + objectish.encode("utf-8")
+ ref_message = b"branch: Created from " + objectish.encode(DEFAULT_ENCODING)
if force:
r.refs.set_if_equals(refname, None, object.id, message=ref_message)
else:
with open_repo_closing(repo) as r:
(remote_name, remote_location) = get_remote_repo(r, remote_location)
if message is None:
- message = b"fetch: from " + remote_location.encode("utf-8")
+ message = b"fetch: from " + remote_location.encode(DEFAULT_ENCODING)
client, path = get_transport_and_path(
remote_location, config=r.get_config_stack(), **kwargs
)
blob - 553e9cd0bddfa016637e9ced37dd844a159ec1e0
blob + 4deb48b2af49dc431e3f93e60968ddbebde3c6f5
--- dulwich/protocol.py
+++ dulwich/protocol.py
if self.report_activity:
self.report_activity(size, "read")
pkt_contents = read(size - 4)
+ except ConnectionResetError:
+ raise HangupException()
except socket.error as e:
raise GitProtocolError(e)
else:
blob - 1a1fc547e1d0a4f8c074ca2bbc52ff21d66589a7
blob + c10826614b153b5db94651475fa54a823545aa55
--- dulwich/refs.py
+++ dulwich/refs.py
LOCAL_TAG_PREFIX = b"refs/tags/"
BAD_REF_CHARS = set(b"\177 ~^:?*[")
ANNOTATED_TAG_SUFFIX = b"^{}"
+
+
+class SymrefLoop(Exception):
+ """There is a loop between one or more symrefs."""
+
+ def __init__(self, ref, depth):
+ self.ref = ref
+ self.depth = depth
def parse_symref_value(contents):
for key in keys:
try:
ret[key] = self[(base + b"/" + key).strip(b"/")]
- except KeyError:
+ except (SymrefLoop, KeyError):
continue # Unable to resolve
return ret
break
depth += 1
if depth > 5:
- raise KeyError(name)
+ raise SymrefLoop(name, depth)
return refnames, contents
-
- def _follow(self, name):
- import warnings
-
- warnings.warn(
- "RefsContainer._follow is deprecated. Use RefsContainer.follow " "instead.",
- DeprecationWarning,
- )
- refnames, contents = self.follow(name)
- if not refnames:
- return (None, contents)
- return (refnames[-1], contents)
def __contains__(self, refname):
if self.read_ref(refname):
def add_if_new(
self,
- name,
- ref,
+ name: bytes,
+ ref: bytes,
committer=None,
timestamp=None,
timezone=None,
- message=None,
+ message: Optional[bytes] = None,
):
if name in self._refs:
return False
def add_if_new(
self,
- name,
- ref,
+ name: bytes,
+ ref: bytes,
committer=None,
timestamp=None,
timezone=None,
- message=None,
+ message: Optional[bytes] = None,
):
"""Add a new reference only if it does not already exist.
refs.set_symbolic_ref(origin_ref, target_ref)
-def _set_default_branch(refs, origin, origin_head, branch, ref_message):
+def _set_default_branch(
+ refs: RefsContainer, origin: bytes, origin_head: bytes, branch: bytes,
+ ref_message: Optional[bytes]) -> bytes:
+ """Set the default branch.
+ """
origin_base = b"refs/remotes/" + origin + b"/"
if branch:
origin_ref = origin_base + branch
head_ref = LOCAL_TAG_PREFIX + branch
else:
raise ValueError(
- "%s is not a valid branch or tag" % os.fsencode(branch)
+ "%r is not a valid branch or tag" % os.fsencode(branch)
)
elif origin_head:
head_ref = origin_head
)
except KeyError:
pass
+ else:
+ raise ValueError('neither origin_head nor branch are provided')
return head_ref
blob - 80c2ad575723a1452ebcc6bd4b34a2fe267fc7e1
blob + f3cc5947a9924148753d6e4554f2ae7736582e9c
--- dulwich/repo.py
+++ dulwich/repo.py
if not SetFileAttributesW(path, FILE_ATTRIBUTE_HIDDEN):
pass # Could raise or log `ctypes.WinError()` here
- # Could implement other platform specific filesytem hiding here
+ # Could implement other platform specific filesystem hiding here
class ParentsProvider(object):
raise NotImplementedError(self._put_named_file)
def _del_named_file(self, path):
- """Delete a file in the contrl directory with the given name."""
+ """Delete a file in the control directory with the given name."""
raise NotImplementedError(self._del_named_file)
def open_index(self):
ref=b"HEAD",
merge_heads=None,
no_verify=False,
+ sign=False,
):
"""Create a new commit.
ref: Optional ref to commit to (defaults to current branch)
merge_heads: Merge heads (defaults to .git/MERGE_HEAD)
no_verify: Skip pre-commit and commit-msg hooks
+ sign: GPG Sign the commit (bool, defaults to False,
+ pass True to use default GPG key,
+ pass a str containing Key ID to use a specific GPG key)
Returns:
New commit SHA1
raise CommitError(e)
except KeyError: # no hook defined, message not modified
c.message = message
+
+ keyid = sign if isinstance(sign, str) else None
if ref is None:
# Create a dangling commit
c.parents = merge_heads
+ if sign:
+ c.sign(keyid)
self.object_store.add_object(c)
else:
try:
old_head = self.refs[ref]
c.parents = [old_head] + merge_heads
+ if sign:
+ c.sign(keyid)
self.object_store.add_object(c)
ok = self.refs.set_if_equals(
ref,
)
except KeyError:
c.parents = merge_heads
+ if sign:
+ c.sign(keyid)
self.object_store.add_object(c)
ok = self.refs.add_if_new(
ref,
class Repo(BaseRepo):
"""A git repository backed by local disk.
- To open an existing repository, call the contructor with
+ To open an existing repository, call the constructor with
the path of the repository.
To create a new repository, use the Repo.init class method.
Attributes:
- path (str): Path to the working copy (if it exists) or repository control
- directory (if the repository is bare)
- bare (bool): Whether this is a bare repository
+ path: Path to the working copy (if it exists) or repository control
+ directory (if the repository is bare)
+ bare: Whether this is a bare repository
"""
+ path: str
+ bare: bool
+
def __init__(
self,
root: str,
) -> None:
hidden_path = os.path.join(root, CONTROLDIR)
if bare is None:
- if (os.path.isfile(hidden_path) or
- os.path.isdir(os.path.join(hidden_path, OBJECTDIR))):
+ 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))):
+ elif (os.path.isdir(os.path.join(root, OBJECTDIR))
+ and os.path.isdir(os.path.join(root, REFSDIR))):
bare = True
else:
raise NotGitRepository(
from dulwich.index import (
IndexEntry,
_fs_to_tree_path,
- )
+ )
index = self.open_index()
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
+ # if tree_entry didn't exist, this file was being added, so
# remove index entry
try:
del index[tree_path]
blob - 1c5b03526d737831f8872f51a0ceb8c74793d356
blob + ab5f3ec7f9931bad0bd426620502fce33dca91d3
--- dulwich/server.py
+++ dulwich/server.py
client_refs = []
ref = self.proto.read_pkt_line()
- # if ref is none then client doesnt want to send us anything..
+ # if ref is none then client doesn't want to send us anything..
if ref is None:
return
blob - 1309ecf8cfb5dd6c274538d8b5c94b1fb54b04b2
blob + c1e093590e4f93b4ec4b8c329f5c256f9c6db414
--- dulwich/tests/__init__.py
+++ dulwich/tests/__init__.py
def setUp(self):
super(TestCase, self).setUp()
self._old_home = os.environ.get("HOME")
- os.environ["HOME"] = "/nonexistant"
+ os.environ["HOME"] = "/nonexistent"
os.environ["GIT_CONFIG_NOSYSTEM"] = "1"
def tearDown(self):
blob - 2f9cad482119221abd0c24c55b4ca10bc7b7726b
blob + e9d5d2d169b195a3546aa33e229474629a402f21
--- dulwich/tests/compat/test_client.py
+++ dulwich/tests/compat/test_client.py
-# test_client.py -- Compatibilty tests for git client.
+# test_client.py -- Compatibility tests for git client.
# Copyright (C) 2010 Google, Inc.
#
# Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
# License, Version 2.0.
#
-"""Compatibilty tests between the Dulwich client and the cgit server."""
+"""Compatibility tests between the Dulwich client and the cgit server."""
import copy
from io import BytesIO
def test_fetch_pack_no_side_band_64k(self):
DulwichClientTestBase.test_fetch_pack_no_side_band_64k(self)
+ def test_send_remove_branch(self):
+ # This test fails intermittently on my machine, probably due to some sort
+ # of race condition. Probably also related to #1015
+ self.skipTest('skip flaky test; see #1015')
+
class TestSSHVendor(object):
@staticmethod
def run_command(
blob - b05cad7d0302332a192dddeb0a64512a04d9ede1
blob + e0aed812aed92c29043ca7cb0b9fc0093d3b296e
--- dulwich/tests/compat/test_porcelain.py
+++ dulwich/tests/compat/test_porcelain.py
'GNUPGHOME': os.environ['GNUPGHOME'],
'GIT_COMMITTER_NAME': 'Joe Example',
'GIT_COMMITTER_EMAIL': 'joe@example.com',
- },
+ },
)
tag = self.repo[b"refs/tags/verifyme"]
self.assertNotEqual(tag.signature, None)
blob - bec350c7c68f4a937259f741e537d7be21dd6541
blob + 71a48fd691bb7dfd344632f49253cc2f1caee162
--- dulwich/tests/compat/utils.py
+++ dulwich/tests/compat/utils.py
_DEFAULT_GIT = "git"
_VERSION_LEN = 4
_REPOS_DATA_DIR = os.path.abspath(
- os.path.join(os.path.dirname(__file__), os.pardir, "data", "repos")
+ os.path.join(
+ os.path.dirname(__file__), os.pardir, os.pardir, os.pardir,
+ "testdata", "repos")
)
Args:
required_version: A tuple of ints of the form (major, minor, point,
- sub-point); ommitted components default to 0.
+ sub-point); omitted components default to 0.
git_path: Path to the git executable; defaults to the version in
the system path.
Raises:
env = popen_kwargs.pop("env", {})
env["LC_ALL"] = env["LANG"] = "C"
+ env["PATH"] = os.getenv("PATH")
args = [git_path] + args
popen_kwargs["stdin"] = subprocess.PIPE
blob - 1942d238fd2e742022b145383e67863d02862c08 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/blobs/11/11111111111111111111111111111111111111 and /dev/null differ
blob - 8f8ed37f1e6b8f0af781c26daa8f31ae9bd2167d (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/blobs/6f/670c0fb53f9463760b7295fbb814e965fb20c8 and /dev/null differ
blob - 7bef12912d59b8fab01801f66978456947e6ce59 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/blobs/95/4a536f7819d40e6f637f849ee187dd10066349 and /dev/null differ
blob - 8c901c5b89f920a740af8b23b771ef4019cdb665 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/blobs/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 and /dev/null differ
blob - b4c3a1d99a4d24753afd83c3e179bd428b24764c (mode 755)
blob + /dev/null
--- dulwich/tests/data/commits/0d/89f20333fbb1d2f3a94da77f4981373d8f4310
+++ /dev/null
-xK
-@])z53==-&e=i:"Z=H)r芔>4wYԯMx|q=s)&6Dh6{Ym/LXg?
\ No newline at end of file
blob - 69c6dff1ab6b88df371b5f539df78e705d1f05a5 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/commits/5d/ac377bdded4c9aeb8dff595f0faeebcc8498cc and /dev/null differ
blob - 9e1d72632e9aa355b6f3efed9aa13f3a1259c426 (mode 644)
blob + /dev/null
--- dulwich/tests/data/commits/60/dacdc733de308bb77bb76ce0fb0f9b44c9769e
+++ /dev/null
-x
-0E]+f/N"]g *5"O.υɗia UBERr[P\ʋ
-Tz靖-zN0Q
-)ZOEv,pIop['lǺ<|fֶk)PGX{&K0?yMQ
\ No newline at end of file
blob - 96f9998c0a1883d2b96b5088650eec063a5d3e97 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/indexes/index and /dev/null differ
blob - ca0454de928844663ddb20a0369f1d9af0391c72 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/packs/pack-bc63ddad95e7321ee734ea11a7a62d314e0d7481.idx and /dev/null differ
blob - e2754b2777a048fd7e83b22d77a89462c2394d2f (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/packs/pack-bc63ddad95e7321ee734ea11a7a62d314e0d7481.pack and /dev/null differ
blob - 26cc331fb8748e2cf588db343a1c2f8242d4b692 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/.gitattributes
+++ /dev/null
-*.export eol=lf
blob - cb089cd89a7d7686d284d8761201649346b5aa1c (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/a.git/HEAD
+++ /dev/null
-ref: refs/heads/master
blob - f13a21bc5735e6b8bcf4423ce6645fcf32a1fafd (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/a.git/objects/28/237f4dc30d0d462658d6b937b08a0f0b6ef55a
+++ /dev/null
-x5A
-0a9\@i""L1T"uPMA7o~2(0H\uB\]MNc+H!0&5Zi-)~ ߓ~ÏsP~Gl֮`јkN0
\ No newline at end of file
blob - dfc9847b6f39818fb3a16abd03a52cca8b0488df (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/a.git/objects/2a/72d929692c41d8554c07f6301757ba18a65d91 and /dev/null differ
blob - 00d4a694a367c8bef7c4fae99f1f18e6edfa1e53 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/a.git/objects/4e/f30bbfe26431a69c3820d3a683df54d688f2ec and /dev/null differ
blob - 522a3def4bbdd7178cd5f5758fd7f51831e394ea (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/a.git/objects/4f/2e6529203aa6d44b5af6e3292c837ceda003f9 and /dev/null differ
blob - 8a8432a9e223891b4250ec4ac8631b55b346017d (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/a.git/objects/7d/9a07d797595ef11344549b8d08198e48c15364 and /dev/null differ
blob - a044c5926c95969c522e5fabc37161ca65232d57 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/a.git/objects/a2/96d0bb611188cabb256919f36bc30117cca005 and /dev/null differ
blob - 7d172f39d4e00239ca900fc7f1b94ee2f145db36 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/a.git/objects/a9/0fa2d900a17e99b433217e988c4eb4a2e9a097 and /dev/null differ
blob - e8b676a287932c6cce97f02dbf8ae805babc6f72 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/a.git/objects/b0/931cadc54336e78a1d980420e3268903b57a50
+++ /dev/null
-x-[
-0**I75T[oRWo
-w*`e/i7sjpیhjkL[c7L><2ݏ 1Jrtqصh̰ɾ֥2v
\ No newline at end of file
blob - 81b997b636b0ddc243de5d5c11eb9e4a93450bf2 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/a.git/objects/ff/d47d45845a8f6576491e1edb97e3fe6a850e7f and /dev/null differ
blob - daf2fc46e6e666c83d5da3aeb78a10abdcfd37b1 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/a.git/packed-refs
+++ /dev/null
-# pack-refs with: peeled
-b0931cadc54336e78a1d980420e3268903b57a50 refs/tags/mytag-packed
-^2a72d929692c41d8554c07f6301757ba18a65d91
blob - e28347ea6dc57992bb974ef79daa09d8c760e075 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/a.git/refs/heads/master
+++ /dev/null
-a90fa2d900a17e99b433217e988c4eb4a2e9a097
blob - cb5c1106d769d9358863fd29b0d869de55b9ce83 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/a.git/refs/tags/mytag
+++ /dev/null
-28237f4dc30d0d462658d6b937b08a0f0b6ef55a
blob - cb089cd89a7d7686d284d8761201649346b5aa1c (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/empty.git/HEAD
+++ /dev/null
-ref: refs/heads/master
blob - 90e16477bddfa48ec34154f9d7211aac4e32a511 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/empty.git/config
+++ /dev/null
-[core]
- repositoryformatversion = 0
- filemode = false
- bare = true
- symlinks = false
- ignorecase = true
- hideDotFiles = dotGitOnly
blob - c96a04f008ee21e260b28f7701595ed59e2839e3 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/empty.git/objects/info/.gitignore
+++ /dev/null
-*
-!.gitignore
\ No newline at end of file
blob - c96a04f008ee21e260b28f7701595ed59e2839e3 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/empty.git/objects/pack/.gitignore
+++ /dev/null
-*
-!.gitignore
\ No newline at end of file
blob - c96a04f008ee21e260b28f7701595ed59e2839e3 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/empty.git/refs/heads/.gitignore
+++ /dev/null
-*
-!.gitignore
\ No newline at end of file
blob - c96a04f008ee21e260b28f7701595ed59e2839e3 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/empty.git/refs/tags/.gitignore
+++ /dev/null
-*
-!.gitignore
\ No newline at end of file
blob - 48bdc140b6ec1a433f0d765bbb5affb6fd0200a3 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/issue88_expect_ack_nak_client.export
+++ /dev/null
-reset refs/heads/master
-commit refs/heads/master
-mark :1
-author User <user@localhost> 1427183369 +1300
-committer User <user@localhost> 1427183369 +1300
-data 6
-empty
-
-blob
-mark :2
-data 35
-We will reproduce a problem here.
-
-commit refs/heads/master
-mark :3
-author User <user@localhost> 1427183376 +1300
-committer User <user@localhost> 1427183376 +1300
-data 11
-demo file.
-from :1
-M 100644 :2 demo.txt
-
-blob
-mark :4
-data 62
-We will reproduce a problem here.
-
-This will take some time.
-
-commit refs/heads/master
-mark :5
-author User <user@localhost> 1427185135 +1300
-committer User <user@localhost> 1427185135 +1300
-data 13
-added a line
-from :3
-M 100644 :4 demo.txt
-
-blob
-mark :6
-data 57
-We will reproduce a problem here.
-
-We will change these.
-
-commit refs/heads/master
-mark :7
-author User <user@localhost> 1427185245 +1300
-committer User <user@localhost> 1427185245 +1300
-data 14
-replace a line
-from :5
-M 100644 :6 demo.txt
-
-blob
-mark :8
-data 52
-We will change these.
-
-Then issues will be proven.
-
-commit refs/heads/master
-mark :9
-author User <user@localhost> 1427185343 +1300
-committer User <user@localhost> 1427185343 +1300
-data 13
-Yes we will.
-from :7
-M 100644 :8 demo.txt
-
-blob
-mark :10
-data 69
-We will change these.
-
-Then issues will be proven once and for all.
-
-commit refs/heads/master
-mark :11
-author User <user@localhost> 1427185440 +1300
-committer User <user@localhost> 1427185440 +1300
-data 6
-sure.
-from :9
-M 100644 :10 demo.txt
-
-blob
-mark :12
-data 0
-
-commit refs/heads/master
-mark :13
-author User <user@localhost> 1427185512 +1300
-committer User <user@localhost> 1427185516 +1300
-data 26
-not an actual readme, yet
-from :11
-M 100644 :12 readme.txt
-
-blob
-mark :14
-data 61
-This will for sure we will prove a problem exist somewhere.
-
-blob
-mark :15
-data 49
-okay fine add something here this is only a test
-
-commit refs/heads/master
-mark :16
-author User <user@localhost> 1427185569 +1300
-committer User <user@localhost> 1427185569 +1300
-data 12
-more things
-from :13
-M 100644 :14 demo.txt
-M 100644 :15 readme.txt
-
-blob
-mark :17
-data 100
-This will for sure we will prove a problem exist somewhere.
-
-Just that we need a few more commits.
-
-commit refs/heads/master
-mark :18
-author User <user@localhost> 1427185659 +1300
-committer User <user@localhost> 1427185659 +1300
-data 13
-one more try
-from :16
-M 100644 :17 demo.txt
-
-blob
-mark :19
-data 54
-It might have something to do with number of commits?
-
-commit refs/heads/master
-mark :20
-author User <user@localhost> 1427185905 +1300
-committer User <user@localhost> 1427185905 +1300
-data 18
-is this number 9?
-from :18
-M 100644 :19 commitcount
-
-blob
-mark :21
-data 123
-This will for sure we will prove a problem exist somewhere.
-
-Just that we need a few more commits.
-
-Hey look we need more
-
-commit refs/heads/master
-mark :22
-author User <user@localhost> 1427185922 +1300
-committer User <user@localhost> 1427185922 +1300
-data 5
-cool
-from :20
-M 100644 :21 demo.txt
-
-blob
-mark :23
-data 50
-Okay fine add something here this is only a test.
-
-commit refs/heads/master
-mark :24
-author User <user@localhost> 1427185936 +1300
-committer User <user@localhost> 1427185936 +1300
-data 7
-readme
-from :22
-M 100644 :23 readme.txt
-
-blob
-mark :25
-data 74
-Okay come on this is getting boring.
-
-Yes I went and edit all the things.
-
-commit refs/heads/master
-mark :26
-author User <user@localhost> 1427185954 +1300
-committer User <user@localhost> 1427185954 +1300
-data 14
-remove a line
-from :24
-M 100644 :25 demo.txt
-
-blob
-mark :27
-data 186
-Okay come on this is getting boring.
-
-Yes I went and edit all the things.
-
-Of course, making test data can be somewhat tedious, especially a
-minimum set that can be easily reproduced.
-
-commit refs/heads/master
-mark :28
-author User <user@localhost> 1427185996 +1300
-committer User <user@localhost> 1427185996 +1300
-data 25
-Getting serious mode on.
-from :26
-M 100644 :27 demo.txt
-
-blob
-mark :29
-data 48
-This is taking a bit longer than I remembered.
-
-commit refs/heads/master
-mark :30
-author User <user@localhost> 1427186065 +1300
-committer User <user@localhost> 1427186065 +1300
-data 40
-At least we will have things minimized.
-from :28
-M 100644 :29 demo.txt
-
-blob
-mark :31
-data 11
-there yet?
-
-commit refs/heads/master
-mark :32
-author User <user@localhost> 1427186080 +1300
-committer User <user@localhost> 1427186080 +1300
-data 7
-are we
-from :30
-M 100644 :31 demo.txt
-
-blob
-mark :33
-data 237
-This should be the head commit for the client repo for testing out
-the failure case reported in issue 88. Just do a git pull from the
-repo that includes the following commit that is hosted with dulwich.
-The issue should be reproduced.
-
-commit refs/heads/master
-mark :34
-author User <user@localhost> 1427186109 +1300
-committer User <user@localhost> 1427186109 +1300
-data 6
-okay?
-from :32
-M 100644 :33 readme.txt
blob - 6897693c08c6d44ed57dd8af26d9aeb45379679b (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/issue88_expect_ack_nak_other.export
+++ /dev/null
-blob
-mark :1
-data 33
-We will sneak in a blob like so.
-
-reset refs/heads/master
-commit refs/heads/master
-mark :2
-author User <user@localhost> 1427183369 +1300
-committer User <user@localhost> 1427183369 +1300
-data 7
-sneaky
-M 100644 :1 problem.questionmark
-
-blob
-mark :3
-data 35
-We will introduce a problem here.
-
-
-commit refs/heads/master
-mark :4
-author User <user@localhost> 1427183376 +1300
-committer User <user@localhost> 1427183376 +1300
-data 11
-demo file.
-from :2
-M 100644 :3 demo.rst
-
-blob
-mark :5
-data 62
-We will introduce a problem here.
-
-This will take some time.
-
-
-commit refs/heads/master
-mark :6
-author User <user@localhost> 1427185135 +1300
-committer User <user@localhost> 1427185135 +1300
-data 13
-added a line
-from :4
-M 100644 :5 demo.rst
-
-blob
-mark :7
-data 57
-We will introduce a problem here.
-
-We will change these.
-
-commit refs/heads/master
-mark :8
-author User <user@localhost> 1427185245 +1300
-committer User <user@localhost> 1427185245 +1300
-data 14
-replace a linefrom :6
-M 100644 :7 demo.rst
-
-blob
-mark :9
-data 52
-We will change these.
-
-Then issues will be proven.
-
-
-commit refs/heads/master
-mark :10
-author User <user@localhost> 1427185343 +1300
-committer User <user@localhost> 1427185343 +1300
-data 13
-Yes we will.
-from :8
-M 100644 :9 demo.rst
-
-blob
-mark :11
-data 72
-We will change these.
-
-Then issues will be construed once and for all.
-
-commit refs/heads/master
-mark :12
-author User <user@localhost> 1427185440 +1300
-committer User <user@localhost> 1427185440 +1300
-data 6
-sure.
-from :10
-M 100644 :11 demo.rst
-
-blob
-mark :13
-data 0
-
-commit refs/heads/master
-mark :14
-author User <user@localhost> 1427185512 +1300
-committer User <user@localhost> 1427185516 +1300
-data 26
-not an actual readme, yet
-from :12
-M 100644 :13 emdaer.txt
-
-blob
-mark :15
-data 58
-This will for sure we will prove issues exist somewhere.
-
-
-blob
-mark :16
-data 49
-okay fine add something here this is only a test
-
-commit refs/heads/master
-mark :17
-author User <user@localhost> 1427185569 +1300
-committer User <user@localhost> 1427185569 +1300
-data 12
-more things
-from :14
-M 100644 :15 demo.rst
-M 100644 :16 emdaer.txt
-
-blob
-mark :18
-data 97
-This will for sure prove issue exist somewhere.
-
-Just that we need a few more commits as usual.
-
-
-commit refs/heads/master
-mark :19
-author User <user@localhost> 1427185659 +1300
-committer User <user@localhost> 1427185659 +1300
-data 13
-one more try
-from :17
-M 100644 :18 demo.rst
-
-blob
-mark :20
-data 54
-It might have something to do with number of commits?
-
-commit refs/heads/master
-mark :21
-author User <user@localhost> 1427185905 +1300
-committer User <user@localhost> 1427185905 +1300
-data 18
-is this number 9?
-from :19
-M 100644 :20 count
-
-blob
-mark :22
-data 119
-This will for sure we will prove issues exist somewhere.
-
-Just that we need a few more commits.
-
-Hey look we need more
-
-commit refs/heads/master
-mark :23
-author User <user@localhost> 1427185922 +1300
-committer User <user@localhost> 1427185922 +1300
-data 5
-cool
-from :21
-M 100644 :22 demo.rst
-
-blob
-mark :24
-data 50
-Okay fine add something here this is only a test.
-
-commit refs/heads/master
-mark :25
-author User <user@localhost> 1427185936 +1300
-committer User <user@localhost> 1427185936 +1300
-data 7
-readme
-from :23
-M 100644 :24 emdaer.txt
-
-blob
-mark :26
-data 74
-Okay come on this is getting boring.
-
-Yes I went and edit all the things.
-
-commit refs/heads/master
-mark :27
-author User <user@localhost> 1427185954 +1300
-committer User <user@localhost> 1427185954 +1300
-data 14
-remove a line
-from :25
-M 100644 :26 demo.rst
-
-blob
-mark :28
-data 186
-Okay come on this is getting boring.
-
-Yes I went and edit all the things.
-
-Of course, making test data can be somewhat tedious, especially a
-minimum set that can be easily reproduced.
-
-commit refs/heads/master
-mark :29
-author User <user@localhost> 1427185996 +1300
-committer User <user@localhost> 1427185996 +1300
-data 25
-Getting serious mode on.
-from :27
-M 100644 :28 demo.rst
-
-blob
-mark :30
-data 48
-This is taking a bit longer than I remembered.
-
-
-commit refs/heads/master
-mark :31
-author User <user@localhost> 1427186065 +1300
-committer User <user@localhost> 1427186065 +1300
-data 40
-At least we will have things minimized.
-from :29
-M 100644 :30 demo.rst
-
-blob
-mark :32
-data 11
-there yet?
-
-commit refs/heads/master
-mark :33
-author User <user@localhost> 1427186080 +1300
-committer User <user@localhost> 1427186080 +1300
-data 7
-are we
-from :31
-M 100644 :32 demo.rst
-
-blob
-mark :34
-data 237
-This should be the head commit for the client repo for testing out
-the failure case reported in issue 88. Just do a git pull from the
-repo that includes the following commit that is hosted with dulwich.
-The issue should be reproduced.
-
-
-commit refs/heads/master
-mark :35
-author User <user@localhost> 1427186109 +1300
-committer User <user@localhost> 1427186109 +1300
-data 6
-okay?
-from :33
-M 100644 :34 emdaer.txt
-
-blob
-mark :36
-data 394
-This should be the commit that will trigger the bug noted in issue 88
-(https://github.com/jelmer/dulwich/issues/88). To reproduce, run git
-fast-import using this fast-export and host this using dulwich, and
-then make a copy of this, strip out this blob and the following commit
-block, import to another git repo and then git clone from the previous.
-
-Naturally, this is part of the test case.
-
-commit refs/heads/master
-mark :37
-author User <user@localhost> 1427244891 +1300
-committer User <user@localhost> 1427248186 +1300
-data 49
-Added instructions on how to use this to readme.
-from :35
-M 100644 :36 emdaer.txt
-
blob - 0124fb32fe9d31db068b58fbaa68dbcf880fd3cb (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/issue88_expect_ack_nak_server.export
+++ /dev/null
-reset refs/heads/master
-commit refs/heads/master
-mark :1
-author User <user@localhost> 1427183369 +1300
-committer User <user@localhost> 1427183369 +1300
-data 6
-empty
-
-blob
-mark :2
-data 35
-We will reproduce a problem here.
-
-commit refs/heads/master
-mark :3
-author User <user@localhost> 1427183376 +1300
-committer User <user@localhost> 1427183376 +1300
-data 11
-demo file.
-from :1
-M 100644 :2 demo.txt
-
-blob
-mark :4
-data 62
-We will reproduce a problem here.
-
-This will take some time.
-
-commit refs/heads/master
-mark :5
-author User <user@localhost> 1427185135 +1300
-committer User <user@localhost> 1427185135 +1300
-data 13
-added a line
-from :3
-M 100644 :4 demo.txt
-
-blob
-mark :6
-data 57
-We will reproduce a problem here.
-
-We will change these.
-
-commit refs/heads/master
-mark :7
-author User <user@localhost> 1427185245 +1300
-committer User <user@localhost> 1427185245 +1300
-data 14
-replace a line
-from :5
-M 100644 :6 demo.txt
-
-blob
-mark :8
-data 52
-We will change these.
-
-Then issues will be proven.
-
-commit refs/heads/master
-mark :9
-author User <user@localhost> 1427185343 +1300
-committer User <user@localhost> 1427185343 +1300
-data 13
-Yes we will.
-from :7
-M 100644 :8 demo.txt
-
-blob
-mark :10
-data 69
-We will change these.
-
-Then issues will be proven once and for all.
-
-commit refs/heads/master
-mark :11
-author User <user@localhost> 1427185440 +1300
-committer User <user@localhost> 1427185440 +1300
-data 6
-sure.
-from :9
-M 100644 :10 demo.txt
-
-blob
-mark :12
-data 0
-
-commit refs/heads/master
-mark :13
-author User <user@localhost> 1427185512 +1300
-committer User <user@localhost> 1427185516 +1300
-data 26
-not an actual readme, yet
-from :11
-M 100644 :12 readme.txt
-
-blob
-mark :14
-data 61
-This will for sure we will prove a problem exist somewhere.
-
-blob
-mark :15
-data 49
-okay fine add something here this is only a test
-
-commit refs/heads/master
-mark :16
-author User <user@localhost> 1427185569 +1300
-committer User <user@localhost> 1427185569 +1300
-data 12
-more things
-from :13
-M 100644 :14 demo.txt
-M 100644 :15 readme.txt
-
-blob
-mark :17
-data 100
-This will for sure we will prove a problem exist somewhere.
-
-Just that we need a few more commits.
-
-commit refs/heads/master
-mark :18
-author User <user@localhost> 1427185659 +1300
-committer User <user@localhost> 1427185659 +1300
-data 13
-one more try
-from :16
-M 100644 :17 demo.txt
-
-blob
-mark :19
-data 54
-It might have something to do with number of commits?
-
-commit refs/heads/master
-mark :20
-author User <user@localhost> 1427185905 +1300
-committer User <user@localhost> 1427185905 +1300
-data 18
-is this number 9?
-from :18
-M 100644 :19 commitcount
-
-blob
-mark :21
-data 123
-This will for sure we will prove a problem exist somewhere.
-
-Just that we need a few more commits.
-
-Hey look we need more
-
-commit refs/heads/master
-mark :22
-author User <user@localhost> 1427185922 +1300
-committer User <user@localhost> 1427185922 +1300
-data 5
-cool
-from :20
-M 100644 :21 demo.txt
-
-blob
-mark :23
-data 50
-Okay fine add something here this is only a test.
-
-commit refs/heads/master
-mark :24
-author User <user@localhost> 1427185936 +1300
-committer User <user@localhost> 1427185936 +1300
-data 7
-readme
-from :22
-M 100644 :23 readme.txt
-
-blob
-mark :25
-data 74
-Okay come on this is getting boring.
-
-Yes I went and edit all the things.
-
-commit refs/heads/master
-mark :26
-author User <user@localhost> 1427185954 +1300
-committer User <user@localhost> 1427185954 +1300
-data 14
-remove a line
-from :24
-M 100644 :25 demo.txt
-
-blob
-mark :27
-data 186
-Okay come on this is getting boring.
-
-Yes I went and edit all the things.
-
-Of course, making test data can be somewhat tedious, especially a
-minimum set that can be easily reproduced.
-
-commit refs/heads/master
-mark :28
-author User <user@localhost> 1427185996 +1300
-committer User <user@localhost> 1427185996 +1300
-data 25
-Getting serious mode on.
-from :26
-M 100644 :27 demo.txt
-
-blob
-mark :29
-data 48
-This is taking a bit longer than I remembered.
-
-commit refs/heads/master
-mark :30
-author User <user@localhost> 1427186065 +1300
-committer User <user@localhost> 1427186065 +1300
-data 40
-At least we will have things minimized.
-from :28
-M 100644 :29 demo.txt
-
-blob
-mark :31
-data 11
-there yet?
-
-commit refs/heads/master
-mark :32
-author User <user@localhost> 1427186080 +1300
-committer User <user@localhost> 1427186080 +1300
-data 7
-are we
-from :30
-M 100644 :31 demo.txt
-
-blob
-mark :33
-data 237
-This should be the head commit for the client repo for testing out
-the failure case reported in issue 88. Just do a git pull from the
-repo that includes the following commit that is hosted with dulwich.
-The issue should be reproduced.
-
-commit refs/heads/master
-mark :34
-author User <user@localhost> 1427186109 +1300
-committer User <user@localhost> 1427186109 +1300
-data 6
-okay?
-from :32
-M 100644 :33 readme.txt
-
-blob
-mark :35
-data 394
-This should be the commit that will trigger the bug noted in issue 88
-(https://github.com/jelmer/dulwich/issues/88). To reproduce, run git
-fast-import using this fast-export and host this using dulwich, and
-then make a copy of this, strip out this blob and the following commit
-block, import to another git repo and then git clone from the previous.
-
-Naturally, this is part of the test case.
-
-commit refs/heads/master
-mark :36
-author User <user@localhost> 1427244891 +1300
-committer User <user@localhost> 1427248186 +1300
-data 49
-Added instructions on how to use this to readme.
-from :34
-M 100644 :35 readme.txt
-
blob - cb089cd89a7d7686d284d8761201649346b5aa1c (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/ooo_merge.git/HEAD
+++ /dev/null
-ref: refs/heads/master
blob - cbe43c2ebd526cac5d66a4d0f614abf4d77c3e59 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/ooo_merge.git/objects/29/69be3e8ee1c0222396a5611407e4769f14e54b and /dev/null differ
blob - 3f3699b36e39f0046a19227248c45215b0f5e452 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/ooo_merge.git/objects/38/74e9c60a6d149c44c928140f250d81e6381520 and /dev/null differ
blob - 95c3c19bbeaeda10c619530ac6ea902ae1c0cdd4 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/ooo_merge.git/objects/6f/670c0fb53f9463760b7295fbb814e965fb20c8 and /dev/null differ
blob - 2569779c10cc06f9e3639d73183c80b6fbd8f243 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/ooo_merge.git/objects/70/c190eb48fa8bbb50ddc692a17b44cb781af7f6 and /dev/null differ
blob - e88303b28d023fc86c939c7480d259df081ea402 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/ooo_merge.git/objects/76/01d7f6231db6a57f7bbb79ee52e4d462fd44d1
+++ /dev/null
-xAj1E)L%[PJօ46CftxӲzL
-`MH*[dL:^l8++Pb+46nhb&ei?:檵SH@mD
-r_-ᗮxMY_~{aU*Z{<Fx0<w_LY
\ No newline at end of file
blob - 610b7dfa3a19490625df89ba689ce6efe928d9eb (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/ooo_merge.git/objects/90/182552c4a85a45ec2a835cadc3451bebdfe870 and /dev/null differ
blob - 7bef12912d59b8fab01801f66978456947e6ce59 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/ooo_merge.git/objects/95/4a536f7819d40e6f637f849ee187dd10066349 and /dev/null differ
blob - 165943d626144b8c1aa9859bfac35e4cb7afda09 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/ooo_merge.git/objects/b2/a2766a2879c209ab1176e7e778b81ae422eeaa and /dev/null differ
blob - 4438cdd7cad0280b0d0e50bc44d975d20f441b0e (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/ooo_merge.git/objects/f5/07291b64138b875c28e03469025b1ea20bc614 and /dev/null differ
blob - d5a5677b135f4c653d3853bdb9b5c5b4d8dc95f8 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/ooo_merge.git/objects/f9/e39b120c68182a4ba35349f832d0e4e61f485c
+++ /dev/null
-x
-0ay$Yb6)=7qB)>2
-CW%>rT&I@$P5iX莥7y w:^o_|Q[IZSsVIEy?
\ No newline at end of file
blob - 5bda024ac879ef55da75751f82e4c7e9e417ad69 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/ooo_merge.git/objects/fb/5b0425c7ce46959bec94d54b9a157645e114f5 and /dev/null differ
blob - 34c0a7949167c0d22872f6e5a5707a4cbe1621c4 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/ooo_merge.git/refs/heads/master
+++ /dev/null
-7601d7f6231db6a57f7bbb79ee52e4d462fd44d1
blob - cb089cd89a7d7686d284d8761201649346b5aa1c (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/refs.git/HEAD
+++ /dev/null
-ref: refs/heads/master
blob - 6160481e0d0f5c125699a9e97daba274708564ec (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/refs.git/objects/3b/9e5457140e738c2dcd39bf6d7acf88379b90d1 and /dev/null differ
blob - 478d0379acec45352e22d368d2b6711b9285ef36 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/refs.git/objects/3e/c9c43c84ff242e3ef4a9fc5bc111fd780a76a8
+++ /dev/null
-x-Q
-0D)-mV^i66.~{#Cm]rwyu=u5^[o<H<*y?ƴ,()a߈2<)$8xR.4YktPaԵ
-q?W)'ǧ6
\ No newline at end of file
blob - 1be455a300b50e3b834ff22744acb008d64ca20a (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/refs.git/objects/42/d06bd4b77fed026b154d16493e5deab78f02ec and /dev/null differ
blob - 7e69c0efaf3324e3bde674e3bc90b4370466e315 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/refs.git/objects/a1/8114c31713746a33a2e70d9914d1ef3e781425 and /dev/null differ
blob - 777d49daa06e828ec64f48b9f3c14396d3fae3a5 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/refs.git/objects/cd/a609072918d7b70057b6bef9f4c2537843fcfe
+++ /dev/null
-x-Q
-0D)m7iV^i6bIEOo
-~c`Av.;Zyku<*^Zox\T4
-< 4.Lam
-Fj#e/s=SRYBcQk
-eZ-\r?)Y9
\ No newline at end of file
blob - e40b2074233e9aef431a50bf761970cb7ccc50d9 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/refs.git/objects/df/6800012397fb85c56e7418dd4eb9405dee075c and /dev/null differ
blob - bf2f9e36e89d2085d2a1f03e477d1344b1be8a2f (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/refs.git/packed-refs
+++ /dev/null
-# pack-refs with: peeled
-df6800012397fb85c56e7418dd4eb9405dee075c refs/tags/refs-0.1
-^42d06bd4b77fed026b154d16493e5deab78f02ec
-42d06bd4b77fed026b154d16493e5deab78f02ec refs/heads/packed
blob - 2623a489ebb544326db1702067b25f08c63e517e (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/refs.git/refs/heads/40-char-ref-aaaaaaaaaaaaaaaaaa
+++ /dev/null
-42d06bd4b77fed026b154d16493e5deab78f02ec
blob - ed2f1caab8d539a193a6167080d82e8ac540d2b4 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/refs.git/refs/heads/loop
+++ /dev/null
-ref: refs/heads/loop
blob - 2623a489ebb544326db1702067b25f08c63e517e (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/refs.git/refs/heads/master
+++ /dev/null
-42d06bd4b77fed026b154d16493e5deab78f02ec
blob - 7ac75665748fe576c76fa53d29733f1f62ba2bd3 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/refs.git/refs/tags/refs-0.2
+++ /dev/null
-3ec9c43c84ff242e3ef4a9fc5bc111fd780a76a8
blob - 25d48cae10efef0a108d2e255e836223bced827e (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/server_new.export
+++ /dev/null
-blob
-mark :1
-data 13
-foo contents
-
-reset refs/heads/master
-commit refs/heads/master
-mark :2
-author Dave Borowitz <dborowitz@google.com> 1265755064 -0800
-committer Dave Borowitz <dborowitz@google.com> 1265755064 -0800
-data 16
-initial checkin
-M 100644 :1 foo
-
-blob
-mark :3
-data 13
-baz contents
-
-blob
-mark :4
-data 21
-updated foo contents
-
-commit refs/heads/master
-mark :5
-author Dave Borowitz <dborowitz@google.com> 1265755140 -0800
-committer Dave Borowitz <dborowitz@google.com> 1265755140 -0800
-data 15
-master checkin
-from :2
-M 100644 :3 baz
-M 100644 :4 foo
-
-blob
-mark :6
-data 24
-updated foo contents v2
-
-commit refs/heads/master
-mark :7
-author Dave Borowitz <dborowitz@google.com> 1265755287 -0800
-committer Dave Borowitz <dborowitz@google.com> 1265755287 -0800
-data 17
-master checkin 2
-from :5
-M 100644 :6 foo
-
-blob
-mark :8
-data 24
-updated foo contents v3
-
-commit refs/heads/master
-mark :9
-author Dave Borowitz <dborowitz@google.com> 1265755295 -0800
-committer Dave Borowitz <dborowitz@google.com> 1265755295 -0800
-data 17
-master checkin 3
-from :7
-M 100644 :8 foo
-
-blob
-mark :10
-data 22
-branched bar contents
-
-blob
-mark :11
-data 22
-branched foo contents
-
-commit refs/heads/branch
-mark :12
-author Dave Borowitz <dborowitz@google.com> 1265755111 -0800
-committer Dave Borowitz <dborowitz@google.com> 1265755111 -0800
-data 15
-branch checkin
-from :2
-M 100644 :10 bar
-M 100644 :11 foo
-
-blob
-mark :13
-data 25
-branched bar contents v2
-
-commit refs/heads/branch
-mark :14
-author Dave Borowitz <dborowitz@google.com> 1265755319 -0800
-committer Dave Borowitz <dborowitz@google.com> 1265755319 -0800
-data 17
-branch checkin 2
-from :12
-M 100644 :13 bar
-
-reset refs/heads/master
-from :9
-
blob - b02a3391baf0453d7341623ba62f814edb2769c7 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/server_old.export
+++ /dev/null
-blob
-mark :1
-data 13
-foo contents
-
-reset refs/heads/master
-commit refs/heads/master
-mark :2
-author Dave Borowitz <dborowitz@google.com> 1265755064 -0800
-committer Dave Borowitz <dborowitz@google.com> 1265755064 -0800
-data 16
-initial checkin
-M 100644 :1 foo
-
-blob
-mark :3
-data 22
-branched bar contents
-
-blob
-mark :4
-data 22
-branched foo contents
-
-commit refs/heads/branch
-mark :5
-author Dave Borowitz <dborowitz@google.com> 1265755111 -0800
-committer Dave Borowitz <dborowitz@google.com> 1265755111 -0800
-data 15
-branch checkin
-from :2
-M 100644 :3 bar
-M 100644 :4 foo
-
-blob
-mark :6
-data 13
-baz contents
-
-blob
-mark :7
-data 21
-updated foo contents
-
-commit refs/heads/master
-mark :8
-author Dave Borowitz <dborowitz@google.com> 1265755140 -0800
-committer Dave Borowitz <dborowitz@google.com> 1265755140 -0800
-data 15
-master checkin
-from :2
-M 100644 :6 baz
-M 100644 :7 foo
-
-reset refs/heads/master
-from :8
-
blob - cb089cd89a7d7686d284d8761201649346b5aa1c (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/simple_merge.git/HEAD
+++ /dev/null
-ref: refs/heads/master
blob - b4c3a1d99a4d24753afd83c3e179bd428b24764c (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/simple_merge.git/objects/0d/89f20333fbb1d2f3a94da77f4981373d8f4310
+++ /dev/null
-xK
-@])z53==-&e=i:"Z=H)r芔>4wYԯMx|q=s)&6Dh6{Ym/LXg?
\ No newline at end of file
blob - a2247b203f986dcb9c22184b1aae17353960c5b4 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/simple_merge.git/objects/1b/6318f651a534b38f9c7aedeebbd56c1e896853 and /dev/null differ
blob - 3dec0bf77a94a1664e95bd056f41ddb563072c89 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/simple_merge.git/objects/29/69be3e8ee1c0222396a5611407e4769f14e54b and /dev/null differ
blob - a73c46c7b6800a9df41452174604dcf600efd325 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/simple_merge.git/objects/4c/ffe90e0a41ad3f5190079d7c8f036bde29cbe6
+++ /dev/null
-xK
-1D]L~=pݝ2Fo-U:.UUAI!KU.!kj
-FN
-*R{QofwSQ[!)G;]g8Шw863Mˇ/_m1 tSK0]i*'pCO
\ No newline at end of file
blob - 69c6dff1ab6b88df371b5f539df78e705d1f05a5 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/simple_merge.git/objects/5d/ac377bdded4c9aeb8dff595f0faeebcc8498cc and /dev/null differ
blob - 9e1d72632e9aa355b6f3efed9aa13f3a1259c426 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/simple_merge.git/objects/60/dacdc733de308bb77bb76ce0fb0f9b44c9769e
+++ /dev/null
-x
-0E]+f/N"]g *5"O.υɗia UBERr[P\ʋ
-Tz靖-zN0Q
-)ZOEv,pIop['lǺ<|fֶk)PGX{&K0?yMQ
\ No newline at end of file
blob - 8f8ed37f1e6b8f0af781c26daa8f31ae9bd2167d (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/simple_merge.git/objects/6f/670c0fb53f9463760b7295fbb814e965fb20c8 and /dev/null differ
blob - 2569779c10cc06f9e3639d73183c80b6fbd8f243 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/simple_merge.git/objects/70/c190eb48fa8bbb50ddc692a17b44cb781af7f6 and /dev/null differ
blob - 610b7dfa3a19490625df89ba689ce6efe928d9eb (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/simple_merge.git/objects/90/182552c4a85a45ec2a835cadc3451bebdfe870 and /dev/null differ
blob - 7bef12912d59b8fab01801f66978456947e6ce59 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/simple_merge.git/objects/95/4a536f7819d40e6f637f849ee187dd10066349 and /dev/null differ
blob - 67706b5810550b826b747525ac1924499c87a6d2 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/simple_merge.git/objects/ab/64bbdcc51b170d21588e5c5d391ee5c0c96dfd
+++ /dev/null
-xM
-0]$cL";/:3bmo|6=~SgU@c̍bUA)ƙ{ulR+ld&z7ږm{IiKt.pmQx?|ݨ!־c仴?s9r4/mO+
\ No newline at end of file
blob - d45835e8201d096288a79b38053dbe259d5475b5 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/simple_merge.git/objects/d4/bdad6549dfedf25d3b89d21f506aff575b28a7 and /dev/null differ
blob - dce887e80f980d37bb634a0e7c99c5e062292fbd (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/simple_merge.git/objects/d8/0c186a03f423a81b39df39dc87fd269736ca86 and /dev/null differ
blob - 8c901c5b89f920a740af8b23b771ef4019cdb665 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/repos/simple_merge.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 and /dev/null differ
blob - c6b8285fbdb5a417f490579d79252fc6d2d03c97 (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/simple_merge.git/refs/heads/master
+++ /dev/null
-5dac377bdded4c9aeb8dff595f0faeebcc8498cc
blob - c493b47db9e7c5cf34da754182f3b099e44a64fc (mode 644)
blob + /dev/null
--- dulwich/tests/data/repos/submodule/dotgit
+++ /dev/null
-gitdir: ./a.git
blob - 8c85e3a618f862f3df42941e44592d22f75f7695 (mode 644)
blob + /dev/null
--- dulwich/tests/data/tags/71/033db03a03c6a36721efcf1968dd8f8e0cf023
+++ /dev/null
-xmMO@=x#݅QnIMEQ
-mʿG'sL2OSz,$1vqnaJb+0u3mMr
-adɢs,=RB bY(֝cQ Yjn!p 7# ݜ5!X[GپM}n}]8m9pzd%
-!#f|X`fBKD%'sKCӝ5\<a5EDpDd-=n
-oKk=ʽn~6iM
\ No newline at end of file
blob - 2569779c10cc06f9e3639d73183c80b6fbd8f243 (mode 644)
blob + /dev/null
Binary files dulwich/tests/data/trees/70/c190eb48fa8bbb50ddc692a17b44cb781af7f6 and /dev/null differ
blob - d8c00b557f47b03af641d3e2624c4142616b8c12
blob + 767fe94a49c684c5c481bf515a8b19c4892dfe1c
--- dulwich/tests/test_client.py
+++ dulwich/tests/test_client.py
PLinkSSHVendor,
HangupException,
GitProtocolError,
- apply_instead_of,
check_wants,
default_urllib3_manager,
get_credentials_from_store,
]
),
)
-
-
-class ApplyInsteadOfTests(TestCase):
- def test_none(self):
- config = ConfigDict()
- self.assertEqual(
- 'https://example.com/', apply_instead_of(config, 'https://example.com/'))
-
- def test_apply(self):
- config = ConfigDict()
- config.set(
- ('url', 'https://samba.org/'), 'insteadOf', 'https://example.com/')
- self.assertEqual(
- 'https://samba.org/',
- apply_instead_of(config, 'https://example.com/'))
-
- def test_apply_multiple(self):
- config = ConfigDict()
- config.set(
- ('url', 'https://samba.org/'), 'insteadOf', 'https://blah.com/')
- config.set(
- ('url', 'https://samba.org/'), 'insteadOf', 'https://example.com/')
- self.assertEqual(
- [b'https://blah.com/', b'https://example.com/'],
- list(config.get_multivar(('url', 'https://samba.org/'), 'insteadOf')))
- self.assertEqual(
- 'https://samba.org/',
- apply_instead_of(config, 'https://example.com/'))
blob - 39f58c87262e96c0e28783e3f312a4fb7c29a5b9
blob + eea02e2c2e0e67ddfcd48c3e07731957da5f22fa
--- dulwich/tests/test_config.py
+++ dulwich/tests/test_config.py
_escape_value,
_parse_string,
parse_submodules,
+ apply_instead_of,
)
from dulwich.tests import (
TestCase,
cf = self.from_file(b'[branch "foo#bar"] # a comment\nbar= foo\n')
self.assertEqual(ConfigFile({(b"branch", b"foo#bar"): {b"bar": b"foo"}}), cf)
+ def test_closing_bracket_within_section_string(self):
+ cf = self.from_file(b'[branch "foo]bar"] # a comment\nbar= foo\n')
+ self.assertEqual(ConfigFile({(b"branch", b"foo]bar"): {b"bar": b"foo"}}), cf)
+
def test_from_file_section(self):
cf = self.from_file(b"[core]\nfoo = bar\n")
self.assertEqual(b"bar", cf.get((b"core",), b"foo"))
def test_default_backends(self):
StackedConfig.default_backends()
- @skipIf(sys.platform != "win32", "Windows specfic config location.")
+ @skipIf(sys.platform != "win32", "Windows specific config location.")
def test_windows_config_from_path(self):
from dulwich.config import get_win_system_paths
paths,
)
- @skipIf(sys.platform != "win32", "Windows specfic config location.")
+ @skipIf(sys.platform != "win32", "Windows specific config location.")
def test_windows_config_from_reg(self):
import winreg
],
got,
)
+
+
+class ApplyInsteadOfTests(TestCase):
+ def test_none(self):
+ config = ConfigDict()
+ self.assertEqual(
+ 'https://example.com/', apply_instead_of(config, 'https://example.com/'))
+
+ def test_apply(self):
+ config = ConfigDict()
+ config.set(
+ ('url', 'https://samba.org/'), 'insteadOf', 'https://example.com/')
+ self.assertEqual(
+ 'https://samba.org/',
+ apply_instead_of(config, 'https://example.com/'))
+
+ def test_apply_multiple(self):
+ config = ConfigDict()
+ config.set(
+ ('url', 'https://samba.org/'), 'insteadOf', 'https://blah.com/')
+ config.set(
+ ('url', 'https://samba.org/'), 'insteadOf', 'https://example.com/')
+ self.assertEqual(
+ [b'https://blah.com/', b'https://example.com/'],
+ list(config.get_multivar(('url', 'https://samba.org/'), 'insteadOf')))
+ self.assertEqual(
+ 'https://samba.org/',
+ apply_instead_of(config, 'https://example.com/'))
blob - c5868953bb5193a9aafb12a6d72a65c2f85865a5
blob + 2606aea97affdc0c3080d0cf82b96489da5f485b
--- dulwich/tests/test_greenthreads.py
+++ dulwich/tests/test_greenthreads.py
finder = GreenThreadsMissingObjectFinder(
self.store, wants[0 : int(self.cmt_amount / 2)], wants
)
- # sha_done will contains commit id and sha of blob refered in tree
+ # sha_done will contains commit id and sha of blob referred in tree
self.assertEqual(len(finder.sha_done), (self.cmt_amount / 2) * 2)
self.assertEqual(len(finder.objects_to_send), self.cmt_amount / 2)
blob - aa6731815124912c8a1ef32acd6911c633d9f21b
blob + 7d3a784c21ef83ef16dea99da7ab608c060ca8a7
--- dulwich/tests/test_index.py
+++ dulwich/tests/test_index.py
class IndexTestCase(TestCase):
- datadir = os.path.join(os.path.dirname(__file__), "data/indexes")
+ datadir = os.path.join(os.path.dirname(__file__), "../../testdata/indexes")
def get_simple_index(self, name):
return Index(os.path.join(self.datadir, name))
blob - 7c8256d34bc4d081583f9b5e430ec7a0c110513f
blob + d4a8fa52be5698b2f3e2d6928251cbcff44c45e5
--- dulwich/tests/test_objects.py
+++ dulwich/tests/test_objects.py
)
import os
import stat
-import warnings
from contextlib import contextmanager
from dulwich.errors import (
"""Test decompression of blobs"""
def get_sha_file(self, cls, base, sha):
- dir = os.path.join(os.path.dirname(__file__), "data", base)
+ dir = os.path.join(os.path.dirname(__file__), "..", "..", "testdata", base)
return cls.from_path(hex_to_filename(dir, sha))
def get_blob(self, sha):
myhexsha = b"d80c186a03f423a81b39df39dc87fd269736ca86"
x = Tree()
x.add(b"myname", 0o100755, myhexsha)
- self.assertEqual(x[b"myname"], (0o100755, myhexsha))
- self.assertEqual(b"100755 myname\0" + hex_to_sha(myhexsha), x.as_raw_string())
-
- def test_add_old_order(self):
- myhexsha = b"d80c186a03f423a81b39df39dc87fd269736ca86"
- x = Tree()
- warnings.simplefilter("ignore", DeprecationWarning)
- try:
- x.add(0o100755, b"myname", myhexsha)
- finally:
- warnings.resetwarnings()
self.assertEqual(x[b"myname"], (0o100755, myhexsha))
self.assertEqual(b"100755 myname\0" + hex_to_sha(myhexsha), x.as_raw_string())
self.assertEqual(_SORTED_TREE_ITEMS, x.items())
def _do_test_parse_tree(self, parse_tree):
- dir = os.path.join(os.path.dirname(__file__), "data", "trees")
+ dir = os.path.join(os.path.dirname(__file__), "..", "..", "testdata", "trees")
o = Tree.from_path(hex_to_filename(dir, tree_sha))
self.assertEqual(
[(b"a", 0o100644, a_sha), (b"b", 0o100644, b_sha)],
blob - d8708c906ad2ff1a57620d5fdf265b91bc023077
blob + a5bb9cbf013dd735a91e3776810dd09da5c423e1
--- dulwich/tests/test_pack.py
+++ dulwich/tests/test_pack.py
self.tempdir = tempfile.mkdtemp()
self.addCleanup(shutil.rmtree, self.tempdir)
- datadir = os.path.abspath(os.path.join(os.path.dirname(__file__), "data/packs"))
+ datadir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../testdata/packs"))
def get_pack_index(self, sha):
"""Returns a PackIndex from the datadir with the given sha"""
blob - 6ed9cac2c3b9e595b3eba070fd0ccef979c56148
blob + c19cf0ed1f69cc6e61b11467e2c5bfd9ca157737
--- dulwich/tests/test_porcelain.py
+++ dulwich/tests/test_porcelain.py
make_wsgi_chain,
)
+try:
+ import gpg
+except ImportError:
+ gpg = None
+
def flat_walk_dir(dir_to_walk):
for dirpath, _, filenames in os.walk(dir_to_walk):
rel_dirpath = os.path.relpath(dirpath, dir_to_walk)
self.assertLess(time.time() - ts, 50)
+@skipIf(gpg is None, "gpg is not available")
class PorcelainGpgTestCase(PorcelainTestCase):
DEFAULT_KEY = """
-----BEGIN PGP PRIVATE KEY BLOCK-----
super(PorcelainGpgTestCase, self).setUp()
self.gpg_dir = os.path.join(self.test_dir, "gpg")
os.mkdir(self.gpg_dir, mode=0o700)
- self.addCleanup(shutil.rmtree, self.gpg_dir)
+ # Ignore errors when deleting GNUPGHOME, because of race conditions
+ # (e.g. the gpg-agent socket having been deleted). See
+ # https://github.com/jelmer/dulwich/issues/1000
+ self.addCleanup(shutil.rmtree, self.gpg_dir, ignore_errors=True)
self._old_gnupghome = os.environ.get("GNUPGHOME")
os.environ["GNUPGHOME"] = self.gpg_dir
if self._old_gnupghome is None:
author="Joe <joe@example.com>",
committer="Bob <bob@example.com>",
no_verify=True,
+ )
+ self.assertIsInstance(sha, bytes)
+ self.assertEqual(len(sha), 40)
+
+ def test_timezone(self):
+ c1, c2, c3 = build_commit_graph(
+ self.repo.object_store, [[1], [2, 1], [3, 1, 2]]
+ )
+ self.repo.refs[b"refs/heads/foo"] = c3.id
+ sha = porcelain.commit(
+ self.repo.path,
+ message="Some message",
+ author="Joe <joe@example.com>",
+ author_timezone=18000,
+ committer="Bob <bob@example.com>",
+ commit_timezone=18000,
+ )
+ self.assertIsInstance(sha, bytes)
+ self.assertEqual(len(sha), 40)
+
+ commit = self.repo.get_object(sha)
+ self.assertEqual(commit._author_timezone, 18000)
+ self.assertEqual(commit._commit_timezone, 18000)
+
+ os.environ["GIT_AUTHOR_DATE"] = os.environ["GIT_COMMITTER_DATE"] = "1995-11-20T19:12:08-0501"
+
+ sha = porcelain.commit(
+ self.repo.path,
+ message="Some message",
+ author="Joe <joe@example.com>",
+ committer="Bob <bob@example.com>",
+ )
+ self.assertIsInstance(sha, bytes)
+ self.assertEqual(len(sha), 40)
+
+ commit = self.repo.get_object(sha)
+ self.assertEqual(commit._author_timezone, -18060)
+ self.assertEqual(commit._commit_timezone, -18060)
+
+ del os.environ["GIT_AUTHOR_DATE"]
+ del os.environ["GIT_COMMITTER_DATE"]
+ local_timezone = time.localtime().tm_gmtoff
+
+ sha = porcelain.commit(
+ self.repo.path,
+ message="Some message",
+ author="Joe <joe@example.com>",
+ committer="Bob <bob@example.com>",
+ )
+ self.assertIsInstance(sha, bytes)
+ self.assertEqual(len(sha), 40)
+
+ commit = self.repo.get_object(sha)
+ self.assertEqual(commit._author_timezone, local_timezone)
+ self.assertEqual(commit._commit_timezone, local_timezone)
+
+
+@skipIf(platform.python_implementation() == "PyPy" or sys.platform == "win32", "gpgme not easily available or supported on Windows and PyPy")
+class CommitSignTests(PorcelainGpgTestCase):
+
+ def test_default_key(self):
+ c1, c2, c3 = build_commit_graph(
+ self.repo.object_store, [[1], [2, 1], [3, 1, 2]]
+ )
+ self.repo.refs[b"HEAD"] = c3.id
+ cfg = self.repo.get_config()
+ cfg.set(("user",), "signingKey", PorcelainGpgTestCase.DEFAULT_KEY_ID)
+ self.import_default_key()
+
+ sha = porcelain.commit(
+ self.repo.path,
+ message="Some message",
+ author="Joe <joe@example.com>",
+ committer="Bob <bob@example.com>",
+ signoff=True,
+ )
+ self.assertIsInstance(sha, bytes)
+ self.assertEqual(len(sha), 40)
+
+ commit = self.repo.get_object(sha)
+ # GPG Signatures aren't deterministic, so we can't do a static assertion.
+ commit.verify()
+ commit.verify(keyids=[PorcelainGpgTestCase.DEFAULT_KEY_ID])
+
+ self.import_non_default_key()
+ self.assertRaises(
+ gpg.errors.MissingSignatures,
+ commit.verify,
+ keyids=[PorcelainGpgTestCase.NON_DEFAULT_KEY_ID],
+ )
+
+ commit.committer = b"Alice <alice@example.com>"
+ self.assertRaises(
+ gpg.errors.BadSignatures,
+ commit.verify,
+ )
+
+ def test_non_default_key(self):
+ c1, c2, c3 = build_commit_graph(
+ self.repo.object_store, [[1], [2, 1], [3, 1, 2]]
+ )
+ self.repo.refs[b"HEAD"] = c3.id
+ cfg = self.repo.get_config()
+ cfg.set(("user",), "signingKey", PorcelainGpgTestCase.DEFAULT_KEY_ID)
+ self.import_non_default_key()
+
+ sha = porcelain.commit(
+ self.repo.path,
+ message="Some message",
+ author="Joe <joe@example.com>",
+ committer="Bob <bob@example.com>",
+ signoff=PorcelainGpgTestCase.NON_DEFAULT_KEY_ID,
)
self.assertIsInstance(sha, bytes)
self.assertEqual(len(sha), 40)
+ commit = self.repo.get_object(sha)
+ # GPG Signatures aren't deterministic, so we can't do a static assertion.
+ commit.verify()
+
+class TimezoneTests(PorcelainTestCase):
+
+ def put_envs(self, value):
+ os.environ["GIT_AUTHOR_DATE"] = os.environ["GIT_COMMITTER_DATE"] = value
+
+ def fallback(self, value):
+ self.put_envs(value)
+ self.assertRaises(porcelain.TimezoneFormatError, porcelain.get_user_timezones)
+
+ def test_internal_format(self):
+ self.put_envs("0 +0500")
+ self.assertTupleEqual((18000, 18000), porcelain.get_user_timezones())
+
+ def test_rfc_2822(self):
+ self.put_envs("Mon, 20 Nov 1995 19:12:08 -0500")
+ self.assertTupleEqual((-18000, -18000), porcelain.get_user_timezones())
+
+ self.put_envs("Mon, 20 Nov 1995 19:12:08")
+ self.assertTupleEqual((0, 0), porcelain.get_user_timezones())
+
+ def test_iso8601(self):
+ self.put_envs("1995-11-20T19:12:08-0501")
+ self.assertTupleEqual((-18060, -18060), porcelain.get_user_timezones())
+
+ self.put_envs("1995-11-20T19:12:08+0501")
+ self.assertTupleEqual((18060, 18060), porcelain.get_user_timezones())
+
+ self.put_envs("1995-11-20T19:12:08-05:01")
+ self.assertTupleEqual((-18060, -18060), porcelain.get_user_timezones())
+
+ self.put_envs("1995-11-20 19:12:08-05")
+ self.assertTupleEqual((-18000, -18000), porcelain.get_user_timezones())
+
+ # https://github.com/git/git/blob/96b2d4fa927c5055adc5b1d08f10a5d7352e2989/t/t6300-for-each-ref.sh#L128
+ self.put_envs("2006-07-03 17:18:44 +0200")
+ self.assertTupleEqual((7200, 7200), porcelain.get_user_timezones())
+
+ def test_missing_or_malformed(self):
+ # TODO: add more here
+ self.fallback("0 + 0500")
+ self.fallback("a +0500")
+
+ self.fallback("1995-11-20T19:12:08")
+ self.fallback("1995-11-20T19:12:08-05:")
+
+ self.fallback("1995.11.20")
+ self.fallback("11/20/1995")
+ self.fallback("20.11.1995")
+
+ def test_different_envs(self):
+ os.environ["GIT_AUTHOR_DATE"] = "0 +0500"
+ os.environ["GIT_COMMITTER_DATE"] = "0 +0501"
+ self.assertTupleEqual((18000, 18060), porcelain.get_user_timezones())
+
+ def test_no_envs(self):
+ local_timezone = time.localtime().tm_gmtoff
+
+ self.put_envs("0 +0500")
+ self.assertTupleEqual((18000, 18000), porcelain.get_user_timezones())
+
+ del os.environ["GIT_COMMITTER_DATE"]
+ self.assertTupleEqual((18000, local_timezone), porcelain.get_user_timezones())
+
+ self.put_envs("0 +0500")
+ del os.environ["GIT_AUTHOR_DATE"]
+ self.assertTupleEqual((local_timezone, 18000), porcelain.get_user_timezones())
+
+ self.put_envs("0 +0500")
+ del os.environ["GIT_AUTHOR_DATE"]
+ del os.environ["GIT_COMMITTER_DATE"]
+ self.assertTupleEqual((local_timezone, local_timezone), porcelain.get_user_timezones())
+
+
class CleanTests(PorcelainTestCase):
def put_files(self, tracked, ignored, untracked, empty_dirs):
"""Put the described files in the wd"""
with tempfile.TemporaryDirectory() as parent:
target_path = os.path.join(parent, "target")
self.assertRaises(
- Exception, porcelain.clone, "/nonexistant/repo", target_path
+ Exception, porcelain.clone, "/nonexistent/repo", target_path
)
self.assertFalse(os.path.exists(target_path))
class TagCreateSignTests(PorcelainGpgTestCase):
def test_default_key(self):
- import gpg
-
c1, c2, c3 = build_commit_graph(
self.repo.object_store, [[1], [2, 1], [3, 1, 2]]
)
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 SubmoduleTests(PorcelainTestCase):
+
+ def test_empty(self):
+ porcelain.commit(
+ repo=self.repo.path,
+ message=b"init",
+ author=b"author <email>",
+ committer=b"committer <email>",
+ )
+
+ self.assertEqual([], list(porcelain.submodule_list(self.repo)))
+
+ def test_add(self):
+ porcelain.submodule_add(self.repo, "../bar.git", "bar")
+ with open('%s/.gitmodules' % self.repo.path, 'r') as f:
+ self.assertEqual("""\
+[submodule "bar"]
+\turl = ../bar.git
+\tpath = bar
+""", f.read())
class PushTests(PorcelainTestCase):
with self.assertRaises(ValueError):
porcelain.status(self.repo.path, untracked_files="antani")
+ def test_status_untracked_path(self):
+ untracked_dir = os.path.join(self.repo_path, "untracked_dir")
+ os.mkdir(untracked_dir)
+ untracked_file = os.path.join(untracked_dir, "untracked_file")
+ with open(untracked_file, "w") as fh:
+ fh.write("untracked")
+
+ _, _, untracked = porcelain.status(self.repo.path, untracked_files="all")
+ self.assertEqual(untracked, ["untracked_dir/untracked_file"])
+
def test_status_crlf_mismatch(self):
# First make a commit as if the file has been added on a Linux system
# or with core.autocrlf=True
blob - 47e38a2eb776e39b8b38ad685df9bd3adcc4cc3c
blob + c381f42b0df713b8fdc8f87fce1f8808467913eb
--- dulwich/tests/test_refs.py
+++ dulwich/tests/test_refs.py
from dulwich.refs import (
DictRefsContainer,
InfoRefsContainer,
+ SymrefLoop,
check_ref_format,
_split_ref_line,
parse_symref_value,
self.assertEqual(nines, self._refs[b"refs/heads/master"])
self.assertTrue(
- self._refs.set_if_equals(b"refs/heads/nonexistant", ZERO_SHA, nines)
+ self._refs.set_if_equals(b"refs/heads/nonexistent", ZERO_SHA, nines)
)
- self.assertEqual(nines, self._refs[b"refs/heads/nonexistant"])
+ self.assertEqual(nines, self._refs[b"refs/heads/nonexistent"])
def test_add_if_new(self):
nines = b"9" * 40
),
self._refs.follow(b"refs/heads/master"),
)
- self.assertRaises(KeyError, self._refs.follow, b"refs/heads/loop")
+ self.assertRaises(SymrefLoop, self._refs.follow, b"refs/heads/loop")
def test_delitem(self):
RefsContainerTests.test_delitem(self)
b"42d06bd4b77fed026b154d16493e5deab78f02ec",
self._refs.read_ref(b"refs/heads/packed"),
)
- self.assertEqual(None, self._refs.read_ref(b"nonexistant"))
+ self.assertEqual(None, self._refs.read_ref(b"nonexistent"))
def test_read_loose_ref(self):
self._refs[b"refs/heads/foo"] = b"df6800012397fb85c56e7418dd4eb9405dee075c"
blob - f22f5e41630931d817e697658b60699119fd3b6f
blob + 1d07c0d1cc7ea9dbb3bb7476150aa2919ff70703
--- dulwich/tests/test_repository.py
+++ dulwich/tests/test_repository.py
def test_clone_no_head(self):
temp_dir = self.mkdtemp()
self.addCleanup(shutil.rmtree, temp_dir)
- repo_dir = os.path.join(os.path.dirname(__file__), "data", "repos")
+ repo_dir = os.path.join(os.path.dirname(__file__), "..", "..", "testdata", "repos")
dest_dir = os.path.join(temp_dir, "a.git")
shutil.copytree(os.path.join(repo_dir, "a.git"), dest_dir, symlinks=True)
r = Repo(dest_dir)
blob - 09f92cb3838a676b8a81a17b53c8fda9d746cf6d
blob + f6b9d592a693c0057ae0abb952093c99406ddc5b
--- dulwich/tests/utils.py
+++ dulwich/tests/utils.py
"""
if temp_dir is None:
temp_dir = tempfile.mkdtemp()
- repo_dir = os.path.join(os.path.dirname(__file__), "data", "repos", name)
+ repo_dir = os.path.join(os.path.dirname(__file__), "..", "..", "testdata", "repos", name)
temp_repo_dir = os.path.join(temp_dir, name)
shutil.copytree(repo_dir, temp_repo_dir, symlinks=True)
return Repo(temp_repo_dir)
blob - /dev/null
blob + dc98d8792450299ff187445bbf197eda758a6580 (mode 644)
--- /dev/null
+++ dulwich/submodule.py
+# config.py - Reading and writing Git config files
+# Copyright (C) 2011-2013 Jelmer Vernooij <jelmer@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.
+#
+
+"""Working with Git submodules.
+"""
+
+from typing import Iterator, Tuple
+from .objects import S_ISGITLINK
+
+
+def iter_cached_submodules(store, root_tree_id: bytes) -> Iterator[Tuple[str, bytes]]:
+ """iterate over cached submodules.
+
+ Args:
+ store: Object store to iterate
+ root_tree_id: SHA of root tree
+
+ Returns:
+ Iterator over over (path, sha) tuples
+ """
+ for entry in store.iter_tree_contents(root_tree_id):
+ if S_ISGITLINK(entry.mode):
+ yield entry.path, entry.sha
blob - 3de0b5b9f6f458c21bdbe15bb6a586b4bbcc5588
blob + 41cceb42e189fa38d09214f9115560438252f579
--- dulwich.egg-info/PKG-INFO
+++ dulwich.egg-info/PKG-INFO
Metadata-Version: 2.1
Name: dulwich
-Version: 0.20.44
+Version: 0.20.46
Summary: Python Git Library
Home-page: https://www.dulwich.io/
Author: Jelmer Vernooij
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Operating System :: POSIX
blob - 0ced704f94567aab055500a6215305a5a139b053
blob + cfa030d35106e11f5f4ba7c7bb238183eb0d959a
--- dulwich.egg-info/SOURCES.txt
+++ dulwich.egg-info/SOURCES.txt
dulwich/server.py
dulwich/stash.py
dulwich/stdint.h
+dulwich/submodule.py
dulwich/walk.py
dulwich/web.py
dulwich.egg-info/PKG-INFO
dulwich/tests/compat/test_utils.py
dulwich/tests/compat/test_web.py
dulwich/tests/compat/utils.py
-dulwich/tests/data/blobs/11/11111111111111111111111111111111111111
-dulwich/tests/data/blobs/6f/670c0fb53f9463760b7295fbb814e965fb20c8
-dulwich/tests/data/blobs/95/4a536f7819d40e6f637f849ee187dd10066349
-dulwich/tests/data/blobs/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
-dulwich/tests/data/commits/0d/89f20333fbb1d2f3a94da77f4981373d8f4310
-dulwich/tests/data/commits/5d/ac377bdded4c9aeb8dff595f0faeebcc8498cc
-dulwich/tests/data/commits/60/dacdc733de308bb77bb76ce0fb0f9b44c9769e
-dulwich/tests/data/indexes/index
-dulwich/tests/data/packs/pack-bc63ddad95e7321ee734ea11a7a62d314e0d7481.idx
-dulwich/tests/data/packs/pack-bc63ddad95e7321ee734ea11a7a62d314e0d7481.pack
-dulwich/tests/data/repos/.gitattributes
-dulwich/tests/data/repos/issue88_expect_ack_nak_client.export
-dulwich/tests/data/repos/issue88_expect_ack_nak_other.export
-dulwich/tests/data/repos/issue88_expect_ack_nak_server.export
-dulwich/tests/data/repos/server_new.export
-dulwich/tests/data/repos/server_old.export
-dulwich/tests/data/repos/a.git/HEAD
-dulwich/tests/data/repos/a.git/packed-refs
-dulwich/tests/data/repos/a.git/objects/28/237f4dc30d0d462658d6b937b08a0f0b6ef55a
-dulwich/tests/data/repos/a.git/objects/2a/72d929692c41d8554c07f6301757ba18a65d91
-dulwich/tests/data/repos/a.git/objects/4e/f30bbfe26431a69c3820d3a683df54d688f2ec
-dulwich/tests/data/repos/a.git/objects/4f/2e6529203aa6d44b5af6e3292c837ceda003f9
-dulwich/tests/data/repos/a.git/objects/7d/9a07d797595ef11344549b8d08198e48c15364
-dulwich/tests/data/repos/a.git/objects/a2/96d0bb611188cabb256919f36bc30117cca005
-dulwich/tests/data/repos/a.git/objects/a9/0fa2d900a17e99b433217e988c4eb4a2e9a097
-dulwich/tests/data/repos/a.git/objects/b0/931cadc54336e78a1d980420e3268903b57a50
-dulwich/tests/data/repos/a.git/objects/ff/d47d45845a8f6576491e1edb97e3fe6a850e7f
-dulwich/tests/data/repos/a.git/refs/heads/master
-dulwich/tests/data/repos/a.git/refs/tags/mytag
-dulwich/tests/data/repos/empty.git/HEAD
-dulwich/tests/data/repos/empty.git/config
-dulwich/tests/data/repos/empty.git/objects/info/.gitignore
-dulwich/tests/data/repos/empty.git/objects/pack/.gitignore
-dulwich/tests/data/repos/empty.git/refs/heads/.gitignore
-dulwich/tests/data/repos/empty.git/refs/tags/.gitignore
-dulwich/tests/data/repos/ooo_merge.git/HEAD
-dulwich/tests/data/repos/ooo_merge.git/objects/29/69be3e8ee1c0222396a5611407e4769f14e54b
-dulwich/tests/data/repos/ooo_merge.git/objects/38/74e9c60a6d149c44c928140f250d81e6381520
-dulwich/tests/data/repos/ooo_merge.git/objects/6f/670c0fb53f9463760b7295fbb814e965fb20c8
-dulwich/tests/data/repos/ooo_merge.git/objects/70/c190eb48fa8bbb50ddc692a17b44cb781af7f6
-dulwich/tests/data/repos/ooo_merge.git/objects/76/01d7f6231db6a57f7bbb79ee52e4d462fd44d1
-dulwich/tests/data/repos/ooo_merge.git/objects/90/182552c4a85a45ec2a835cadc3451bebdfe870
-dulwich/tests/data/repos/ooo_merge.git/objects/95/4a536f7819d40e6f637f849ee187dd10066349
-dulwich/tests/data/repos/ooo_merge.git/objects/b2/a2766a2879c209ab1176e7e778b81ae422eeaa
-dulwich/tests/data/repos/ooo_merge.git/objects/f5/07291b64138b875c28e03469025b1ea20bc614
-dulwich/tests/data/repos/ooo_merge.git/objects/f9/e39b120c68182a4ba35349f832d0e4e61f485c
-dulwich/tests/data/repos/ooo_merge.git/objects/fb/5b0425c7ce46959bec94d54b9a157645e114f5
-dulwich/tests/data/repos/ooo_merge.git/refs/heads/master
-dulwich/tests/data/repos/refs.git/HEAD
-dulwich/tests/data/repos/refs.git/packed-refs
-dulwich/tests/data/repos/refs.git/objects/3b/9e5457140e738c2dcd39bf6d7acf88379b90d1
-dulwich/tests/data/repos/refs.git/objects/3e/c9c43c84ff242e3ef4a9fc5bc111fd780a76a8
-dulwich/tests/data/repos/refs.git/objects/42/d06bd4b77fed026b154d16493e5deab78f02ec
-dulwich/tests/data/repos/refs.git/objects/a1/8114c31713746a33a2e70d9914d1ef3e781425
-dulwich/tests/data/repos/refs.git/objects/cd/a609072918d7b70057b6bef9f4c2537843fcfe
-dulwich/tests/data/repos/refs.git/objects/df/6800012397fb85c56e7418dd4eb9405dee075c
-dulwich/tests/data/repos/refs.git/refs/heads/40-char-ref-aaaaaaaaaaaaaaaaaa
-dulwich/tests/data/repos/refs.git/refs/heads/loop
-dulwich/tests/data/repos/refs.git/refs/heads/master
-dulwich/tests/data/repos/refs.git/refs/tags/refs-0.2
-dulwich/tests/data/repos/simple_merge.git/HEAD
-dulwich/tests/data/repos/simple_merge.git/objects/0d/89f20333fbb1d2f3a94da77f4981373d8f4310
-dulwich/tests/data/repos/simple_merge.git/objects/1b/6318f651a534b38f9c7aedeebbd56c1e896853
-dulwich/tests/data/repos/simple_merge.git/objects/29/69be3e8ee1c0222396a5611407e4769f14e54b
-dulwich/tests/data/repos/simple_merge.git/objects/4c/ffe90e0a41ad3f5190079d7c8f036bde29cbe6
-dulwich/tests/data/repos/simple_merge.git/objects/5d/ac377bdded4c9aeb8dff595f0faeebcc8498cc
-dulwich/tests/data/repos/simple_merge.git/objects/60/dacdc733de308bb77bb76ce0fb0f9b44c9769e
-dulwich/tests/data/repos/simple_merge.git/objects/6f/670c0fb53f9463760b7295fbb814e965fb20c8
-dulwich/tests/data/repos/simple_merge.git/objects/70/c190eb48fa8bbb50ddc692a17b44cb781af7f6
-dulwich/tests/data/repos/simple_merge.git/objects/90/182552c4a85a45ec2a835cadc3451bebdfe870
-dulwich/tests/data/repos/simple_merge.git/objects/95/4a536f7819d40e6f637f849ee187dd10066349
-dulwich/tests/data/repos/simple_merge.git/objects/ab/64bbdcc51b170d21588e5c5d391ee5c0c96dfd
-dulwich/tests/data/repos/simple_merge.git/objects/d4/bdad6549dfedf25d3b89d21f506aff575b28a7
-dulwich/tests/data/repos/simple_merge.git/objects/d8/0c186a03f423a81b39df39dc87fd269736ca86
-dulwich/tests/data/repos/simple_merge.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
-dulwich/tests/data/repos/simple_merge.git/refs/heads/master
-dulwich/tests/data/repos/submodule/dotgit
-dulwich/tests/data/tags/71/033db03a03c6a36721efcf1968dd8f8e0cf023
-dulwich/tests/data/trees/70/c190eb48fa8bbb50ddc692a17b44cb781af7f6
examples/clone.py
examples/config.py
examples/diff.py
examples/gcs.py
examples/latest_change.py
examples/memoryrepo.py
-examples/rename-branch.py
\ No newline at end of file
+examples/rename-branch.py
+testdata/blobs/11/11111111111111111111111111111111111111
+testdata/blobs/6f/670c0fb53f9463760b7295fbb814e965fb20c8
+testdata/blobs/95/4a536f7819d40e6f637f849ee187dd10066349
+testdata/blobs/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
+testdata/commits/0d/89f20333fbb1d2f3a94da77f4981373d8f4310
+testdata/commits/5d/ac377bdded4c9aeb8dff595f0faeebcc8498cc
+testdata/commits/60/dacdc733de308bb77bb76ce0fb0f9b44c9769e
+testdata/indexes/index
+testdata/packs/pack-bc63ddad95e7321ee734ea11a7a62d314e0d7481.idx
+testdata/packs/pack-bc63ddad95e7321ee734ea11a7a62d314e0d7481.pack
+testdata/repos/.gitattributes
+testdata/repos/issue88_expect_ack_nak_client.export
+testdata/repos/issue88_expect_ack_nak_other.export
+testdata/repos/issue88_expect_ack_nak_server.export
+testdata/repos/server_new.export
+testdata/repos/server_old.export
+testdata/repos/a.git/HEAD
+testdata/repos/a.git/packed-refs
+testdata/repos/a.git/objects/28/237f4dc30d0d462658d6b937b08a0f0b6ef55a
+testdata/repos/a.git/objects/2a/72d929692c41d8554c07f6301757ba18a65d91
+testdata/repos/a.git/objects/4e/f30bbfe26431a69c3820d3a683df54d688f2ec
+testdata/repos/a.git/objects/4f/2e6529203aa6d44b5af6e3292c837ceda003f9
+testdata/repos/a.git/objects/7d/9a07d797595ef11344549b8d08198e48c15364
+testdata/repos/a.git/objects/a2/96d0bb611188cabb256919f36bc30117cca005
+testdata/repos/a.git/objects/a9/0fa2d900a17e99b433217e988c4eb4a2e9a097
+testdata/repos/a.git/objects/b0/931cadc54336e78a1d980420e3268903b57a50
+testdata/repos/a.git/objects/ff/d47d45845a8f6576491e1edb97e3fe6a850e7f
+testdata/repos/a.git/refs/heads/master
+testdata/repos/a.git/refs/tags/mytag
+testdata/repos/empty.git/HEAD
+testdata/repos/empty.git/config
+testdata/repos/empty.git/objects/info/.gitignore
+testdata/repos/empty.git/objects/pack/.gitignore
+testdata/repos/empty.git/refs/heads/.gitignore
+testdata/repos/empty.git/refs/tags/.gitignore
+testdata/repos/ooo_merge.git/HEAD
+testdata/repos/ooo_merge.git/objects/29/69be3e8ee1c0222396a5611407e4769f14e54b
+testdata/repos/ooo_merge.git/objects/38/74e9c60a6d149c44c928140f250d81e6381520
+testdata/repos/ooo_merge.git/objects/6f/670c0fb53f9463760b7295fbb814e965fb20c8
+testdata/repos/ooo_merge.git/objects/70/c190eb48fa8bbb50ddc692a17b44cb781af7f6
+testdata/repos/ooo_merge.git/objects/76/01d7f6231db6a57f7bbb79ee52e4d462fd44d1
+testdata/repos/ooo_merge.git/objects/90/182552c4a85a45ec2a835cadc3451bebdfe870
+testdata/repos/ooo_merge.git/objects/95/4a536f7819d40e6f637f849ee187dd10066349
+testdata/repos/ooo_merge.git/objects/b2/a2766a2879c209ab1176e7e778b81ae422eeaa
+testdata/repos/ooo_merge.git/objects/f5/07291b64138b875c28e03469025b1ea20bc614
+testdata/repos/ooo_merge.git/objects/f9/e39b120c68182a4ba35349f832d0e4e61f485c
+testdata/repos/ooo_merge.git/objects/fb/5b0425c7ce46959bec94d54b9a157645e114f5
+testdata/repos/ooo_merge.git/refs/heads/master
+testdata/repos/refs.git/HEAD
+testdata/repos/refs.git/packed-refs
+testdata/repos/refs.git/objects/3b/9e5457140e738c2dcd39bf6d7acf88379b90d1
+testdata/repos/refs.git/objects/3e/c9c43c84ff242e3ef4a9fc5bc111fd780a76a8
+testdata/repos/refs.git/objects/42/d06bd4b77fed026b154d16493e5deab78f02ec
+testdata/repos/refs.git/objects/a1/8114c31713746a33a2e70d9914d1ef3e781425
+testdata/repos/refs.git/objects/cd/a609072918d7b70057b6bef9f4c2537843fcfe
+testdata/repos/refs.git/objects/df/6800012397fb85c56e7418dd4eb9405dee075c
+testdata/repos/refs.git/refs/heads/40-char-ref-aaaaaaaaaaaaaaaaaa
+testdata/repos/refs.git/refs/heads/loop
+testdata/repos/refs.git/refs/heads/master
+testdata/repos/refs.git/refs/tags/refs-0.2
+testdata/repos/simple_merge.git/HEAD
+testdata/repos/simple_merge.git/objects/0d/89f20333fbb1d2f3a94da77f4981373d8f4310
+testdata/repos/simple_merge.git/objects/1b/6318f651a534b38f9c7aedeebbd56c1e896853
+testdata/repos/simple_merge.git/objects/29/69be3e8ee1c0222396a5611407e4769f14e54b
+testdata/repos/simple_merge.git/objects/4c/ffe90e0a41ad3f5190079d7c8f036bde29cbe6
+testdata/repos/simple_merge.git/objects/5d/ac377bdded4c9aeb8dff595f0faeebcc8498cc
+testdata/repos/simple_merge.git/objects/60/dacdc733de308bb77bb76ce0fb0f9b44c9769e
+testdata/repos/simple_merge.git/objects/6f/670c0fb53f9463760b7295fbb814e965fb20c8
+testdata/repos/simple_merge.git/objects/70/c190eb48fa8bbb50ddc692a17b44cb781af7f6
+testdata/repos/simple_merge.git/objects/90/182552c4a85a45ec2a835cadc3451bebdfe870
+testdata/repos/simple_merge.git/objects/95/4a536f7819d40e6f637f849ee187dd10066349
+testdata/repos/simple_merge.git/objects/ab/64bbdcc51b170d21588e5c5d391ee5c0c96dfd
+testdata/repos/simple_merge.git/objects/d4/bdad6549dfedf25d3b89d21f506aff575b28a7
+testdata/repos/simple_merge.git/objects/d8/0c186a03f423a81b39df39dc87fd269736ca86
+testdata/repos/simple_merge.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
+testdata/repos/simple_merge.git/refs/heads/master
+testdata/repos/submodule/dotgit
+testdata/tags/71/033db03a03c6a36721efcf1968dd8f8e0cf023
+testdata/trees/70/c190eb48fa8bbb50ddc692a17b44cb781af7f6
\ No newline at end of file
blob - 480a2c67cf189b71abcf69eaa147f9f4f0259abf
blob + dc8ea2de09c23fbff85f876f58f1090dd0fe993c
--- dulwich.egg-info/requires.txt
+++ dulwich.egg-info/requires.txt
-certifi
-urllib3>=1.24.1
+urllib3>=1.25
[fastimport]
fastimport
[https]
-urllib3[secure]>=1.24.1
+urllib3>=1.24.1
[paramiko]
paramiko
blob - cff1307d6ca8b1c57376e9b7516adddb3701ab04
blob + d9de11354f71ee2763db9b3690c6a41e2b7a0172
--- requirements.txt
+++ requirements.txt
-urllib3[secure]>=1.23
+urllib3>=1.23
blob - 3c557ab7db8b44fb11b1ad1d677fee8ec3467d63
blob + 9484ff8bf2849b5df232bb50a2398d6e158b4bdd
--- setup.py
+++ setup.py
#!/usr/bin/python3
# encoding: utf-8
# Setup file for dulwich
-# Copyright (C) 2008-2016 Jelmer Vernooij <jelmer@jelmer.uk>
+# Copyright (C) 2008-2022 Jelmer Vernooij <jelmer@jelmer.uk>
-try:
- from setuptools import setup, Extension
-except ImportError:
- from distutils.core import setup, Extension
- has_setuptools = False
-else:
- has_setuptools = True
-from distutils.core import Distribution
+from setuptools import setup, Extension, Distribution
import io
import os
import sys
-from typing import Dict, Any
if sys.version_info < (3, 6):
'For 2.7 support, please install a version prior to 0.20')
-dulwich_version_string = '0.20.44'
+dulwich_version_string = '0.20.46'
class DulwichDistribution(Distribution):
for line in out.splitlines():
line = line.decode("utf8")
# Also parse only first digit, because 3.2.1 can't be parsed nicely
- if (line.startswith('Xcode') and
- int(line.split()[1].split('.')[0]) >= 4):
+ if (line.startswith('Xcode')
+ and int(line.split()[1].split('.')[0]) >= 4):
os.environ['ARCHFLAGS'] = ''
tests_require = ['fastimport']
Extension('dulwich._diff_tree', ['dulwich/_diff_tree.c']),
]
-setup_kwargs = {} # type: Dict[str, Any]
scripts = ['bin/dul-receive-pack', 'bin/dul-upload-pack']
-if has_setuptools:
- setup_kwargs['extras_require'] = {
- 'fastimport': ['fastimport'],
- 'https': ['urllib3[secure]>=1.24.1'],
- 'pgp': ['gpg'],
- 'paramiko': ['paramiko'],
- }
- setup_kwargs['install_requires'] = ['urllib3>=1.24.1', 'certifi']
- setup_kwargs['include_package_data'] = True
- setup_kwargs['test_suite'] = 'dulwich.tests.test_suite'
- setup_kwargs['tests_require'] = tests_require
- setup_kwargs['entry_points'] = {
- "console_scripts": [
- "dulwich=dulwich.cli:main",
- ]}
- setup_kwargs['python_requires'] = '>=3.6'
-else:
- scripts.append('bin/dulwich')
with io.open(os.path.join(os.path.dirname(__file__), "README.rst"),
"GitHub": "https://github.com/dulwich/dulwich",
},
keywords="git vcs",
- packages=['dulwich', 'dulwich.tests', 'dulwich.tests.compat',
- 'dulwich.contrib'],
+ packages=['dulwich', 'dulwich.cloud', 'dulwich.tests',
+ 'dulwich.tests.compat', 'dulwich.contrib'],
package_data={'': ['../docs/tutorial/*.txt', 'py.typed']},
scripts=scripts,
ext_modules=ext_modules,
zip_safe=False,
- distclass=DulwichDistribution,
+ distclass=DulwichDistribution, # type: ignore
+ install_requires=['urllib3>=1.25'],
+ include_package_data=True,
+ test_suite='dulwich.tests.test_suite',
+ tests_require=tests_require,
+ entry_points={
+ "console_scripts": ["dulwich=dulwich.cli:main"]
+ },
+ python_requires='>=3.6',
classifiers=[
'Development Status :: 4 - Beta',
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Operating System :: POSIX',
'Operating System :: Microsoft :: Windows',
'Topic :: Software Development :: Version Control',
],
- **setup_kwargs
- )
+ extras_require={
+ 'fastimport': ['fastimport'],
+ 'https': ['urllib3>=1.24.1'],
+ 'pgp': ['gpg'],
+ 'paramiko': ['paramiko'],
+ })
blob - db78d5a81eb707ec8a87ab85c170e6637e71acae
blob + e4e0e18e675d4c4c09c4a3baf39baa5e42b85a7f
--- status.yaml
+++ status.yaml
---
configuration:
- - key: core.compression
- status: supported
- - key: core.looseCompression
- status: supported
- - key: core.packCompression
- status: supported
- - key: core.filemode
- status: supported
- - key: http.proxy
- status: supported
- - key: http.useragent
- status: supported
- - key: http.sslVerify
- status: supported
- - key: http.sslCAInfo
- status: supported
- - key: i18n.commitEncoding
- status: supported
- - key: core.excludsFile
- status: supported
- - key: user.name
- status: supported
- - key: user.email
- status: supported
- - key: core.protectNTFS
- status: supported
- - key: core.ignorecase
- status: supported
+ - key: core.compression
+ status: supported
+ - key: core.looseCompression
+ status: supported
+ - key: core.packCompression
+ status: supported
+ - key: core.filemode
+ status: supported
+ - key: http.proxy
+ status: supported
+ - key: http.useragent
+ status: supported
+ - key: http.sslVerify
+ status: supported
+ - key: http.sslCAInfo
+ status: supported
+ - key: i18n.commitEncoding
+ status: supported
+ - key: core.excludsFile
+ status: supported
+ - key: user.name
+ status: supported
+ - key: user.email
+ status: supported
+ - key: core.protectNTFS
+ status: supported
+ - key: core.ignorecase
+ status: supported
blob - /dev/null
blob + 1942d238fd2e742022b145383e67863d02862c08 (mode 644)
Binary files /dev/null and testdata/blobs/11/11111111111111111111111111111111111111 differ
blob - /dev/null
blob + 8f8ed37f1e6b8f0af781c26daa8f31ae9bd2167d (mode 644)
Binary files /dev/null and testdata/blobs/6f/670c0fb53f9463760b7295fbb814e965fb20c8 differ
blob - /dev/null
blob + 7bef12912d59b8fab01801f66978456947e6ce59 (mode 644)
Binary files /dev/null and testdata/blobs/95/4a536f7819d40e6f637f849ee187dd10066349 differ
blob - /dev/null
blob + 8c901c5b89f920a740af8b23b771ef4019cdb665 (mode 644)
Binary files /dev/null and testdata/blobs/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
blob - /dev/null
blob + b4c3a1d99a4d24753afd83c3e179bd428b24764c (mode 755)
--- /dev/null
+++ testdata/commits/0d/89f20333fbb1d2f3a94da77f4981373d8f4310
+xK
+@])z53==-&e=i:"Z=H)r芔>4wYԯMx|q=s)&6Dh6{Ym/LXg?
\ No newline at end of file
blob - /dev/null
blob + 69c6dff1ab6b88df371b5f539df78e705d1f05a5 (mode 644)
Binary files /dev/null and testdata/commits/5d/ac377bdded4c9aeb8dff595f0faeebcc8498cc differ
blob - /dev/null
blob + 9e1d72632e9aa355b6f3efed9aa13f3a1259c426 (mode 644)
--- /dev/null
+++ testdata/commits/60/dacdc733de308bb77bb76ce0fb0f9b44c9769e
+x
+0E]+f/N"]g *5"O.υɗia UBERr[P\ʋ
+Tz靖-zN0Q
+)ZOEv,pIop['lǺ<|fֶk)PGX{&K0?yMQ
\ No newline at end of file
blob - /dev/null
blob + 96f9998c0a1883d2b96b5088650eec063a5d3e97 (mode 644)
Binary files /dev/null and testdata/indexes/index differ
blob - /dev/null
blob + ca0454de928844663ddb20a0369f1d9af0391c72 (mode 644)
Binary files /dev/null and testdata/packs/pack-bc63ddad95e7321ee734ea11a7a62d314e0d7481.idx differ
blob - /dev/null
blob + e2754b2777a048fd7e83b22d77a89462c2394d2f (mode 644)
Binary files /dev/null and testdata/packs/pack-bc63ddad95e7321ee734ea11a7a62d314e0d7481.pack differ
blob - /dev/null
blob + 26cc331fb8748e2cf588db343a1c2f8242d4b692 (mode 644)
--- /dev/null
+++ testdata/repos/.gitattributes
+*.export eol=lf
blob - /dev/null
blob + cb089cd89a7d7686d284d8761201649346b5aa1c (mode 644)
--- /dev/null
+++ testdata/repos/a.git/HEAD
+ref: refs/heads/master
blob - /dev/null
blob + f13a21bc5735e6b8bcf4423ce6645fcf32a1fafd (mode 644)
--- /dev/null
+++ testdata/repos/a.git/objects/28/237f4dc30d0d462658d6b937b08a0f0b6ef55a
+x5A
+0a9\@i""L1T"uPMA7o~2(0H\uB\]MNc+H!0&5Zi-)~ ߓ~ÏsP~Gl֮`јkN0
\ No newline at end of file
blob - /dev/null
blob + dfc9847b6f39818fb3a16abd03a52cca8b0488df (mode 644)
Binary files /dev/null and testdata/repos/a.git/objects/2a/72d929692c41d8554c07f6301757ba18a65d91 differ
blob - /dev/null
blob + 00d4a694a367c8bef7c4fae99f1f18e6edfa1e53 (mode 644)
Binary files /dev/null and testdata/repos/a.git/objects/4e/f30bbfe26431a69c3820d3a683df54d688f2ec differ
blob - /dev/null
blob + 522a3def4bbdd7178cd5f5758fd7f51831e394ea (mode 644)
Binary files /dev/null and testdata/repos/a.git/objects/4f/2e6529203aa6d44b5af6e3292c837ceda003f9 differ
blob - /dev/null
blob + 8a8432a9e223891b4250ec4ac8631b55b346017d (mode 644)
Binary files /dev/null and testdata/repos/a.git/objects/7d/9a07d797595ef11344549b8d08198e48c15364 differ
blob - /dev/null
blob + a044c5926c95969c522e5fabc37161ca65232d57 (mode 644)
Binary files /dev/null and testdata/repos/a.git/objects/a2/96d0bb611188cabb256919f36bc30117cca005 differ
blob - /dev/null
blob + 7d172f39d4e00239ca900fc7f1b94ee2f145db36 (mode 644)
Binary files /dev/null and testdata/repos/a.git/objects/a9/0fa2d900a17e99b433217e988c4eb4a2e9a097 differ
blob - /dev/null
blob + e8b676a287932c6cce97f02dbf8ae805babc6f72 (mode 644)
--- /dev/null
+++ testdata/repos/a.git/objects/b0/931cadc54336e78a1d980420e3268903b57a50
+x-[
+0**I75T[oRWo
+w*`e/i7sjpیhjkL[c7L><2ݏ 1Jrtqصh̰ɾ֥2v
\ No newline at end of file
blob - /dev/null
blob + 81b997b636b0ddc243de5d5c11eb9e4a93450bf2 (mode 644)
Binary files /dev/null and testdata/repos/a.git/objects/ff/d47d45845a8f6576491e1edb97e3fe6a850e7f differ
blob - /dev/null
blob + daf2fc46e6e666c83d5da3aeb78a10abdcfd37b1 (mode 644)
--- /dev/null
+++ testdata/repos/a.git/packed-refs
+# pack-refs with: peeled
+b0931cadc54336e78a1d980420e3268903b57a50 refs/tags/mytag-packed
+^2a72d929692c41d8554c07f6301757ba18a65d91
blob - /dev/null
blob + e28347ea6dc57992bb974ef79daa09d8c760e075 (mode 644)
--- /dev/null
+++ testdata/repos/a.git/refs/heads/master
+a90fa2d900a17e99b433217e988c4eb4a2e9a097
blob - /dev/null
blob + cb5c1106d769d9358863fd29b0d869de55b9ce83 (mode 644)
--- /dev/null
+++ testdata/repos/a.git/refs/tags/mytag
+28237f4dc30d0d462658d6b937b08a0f0b6ef55a
blob - /dev/null
blob + cb089cd89a7d7686d284d8761201649346b5aa1c (mode 644)
--- /dev/null
+++ testdata/repos/empty.git/HEAD
+ref: refs/heads/master
blob - /dev/null
blob + 90e16477bddfa48ec34154f9d7211aac4e32a511 (mode 644)
--- /dev/null
+++ testdata/repos/empty.git/config
+[core]
+ repositoryformatversion = 0
+ filemode = false
+ bare = true
+ symlinks = false
+ ignorecase = true
+ hideDotFiles = dotGitOnly
blob - /dev/null
blob + c96a04f008ee21e260b28f7701595ed59e2839e3 (mode 644)
--- /dev/null
+++ testdata/repos/empty.git/objects/info/.gitignore
+*
+!.gitignore
\ No newline at end of file
blob - /dev/null
blob + c96a04f008ee21e260b28f7701595ed59e2839e3 (mode 644)
--- /dev/null
+++ testdata/repos/empty.git/objects/pack/.gitignore
+*
+!.gitignore
\ No newline at end of file
blob - /dev/null
blob + c96a04f008ee21e260b28f7701595ed59e2839e3 (mode 644)
--- /dev/null
+++ testdata/repos/empty.git/refs/heads/.gitignore
+*
+!.gitignore
\ No newline at end of file
blob - /dev/null
blob + c96a04f008ee21e260b28f7701595ed59e2839e3 (mode 644)
--- /dev/null
+++ testdata/repos/empty.git/refs/tags/.gitignore
+*
+!.gitignore
\ No newline at end of file
blob - /dev/null
blob + 48bdc140b6ec1a433f0d765bbb5affb6fd0200a3 (mode 644)
--- /dev/null
+++ testdata/repos/issue88_expect_ack_nak_client.export
+reset refs/heads/master
+commit refs/heads/master
+mark :1
+author User <user@localhost> 1427183369 +1300
+committer User <user@localhost> 1427183369 +1300
+data 6
+empty
+
+blob
+mark :2
+data 35
+We will reproduce a problem here.
+
+commit refs/heads/master
+mark :3
+author User <user@localhost> 1427183376 +1300
+committer User <user@localhost> 1427183376 +1300
+data 11
+demo file.
+from :1
+M 100644 :2 demo.txt
+
+blob
+mark :4
+data 62
+We will reproduce a problem here.
+
+This will take some time.
+
+commit refs/heads/master
+mark :5
+author User <user@localhost> 1427185135 +1300
+committer User <user@localhost> 1427185135 +1300
+data 13
+added a line
+from :3
+M 100644 :4 demo.txt
+
+blob
+mark :6
+data 57
+We will reproduce a problem here.
+
+We will change these.
+
+commit refs/heads/master
+mark :7
+author User <user@localhost> 1427185245 +1300
+committer User <user@localhost> 1427185245 +1300
+data 14
+replace a line
+from :5
+M 100644 :6 demo.txt
+
+blob
+mark :8
+data 52
+We will change these.
+
+Then issues will be proven.
+
+commit refs/heads/master
+mark :9
+author User <user@localhost> 1427185343 +1300
+committer User <user@localhost> 1427185343 +1300
+data 13
+Yes we will.
+from :7
+M 100644 :8 demo.txt
+
+blob
+mark :10
+data 69
+We will change these.
+
+Then issues will be proven once and for all.
+
+commit refs/heads/master
+mark :11
+author User <user@localhost> 1427185440 +1300
+committer User <user@localhost> 1427185440 +1300
+data 6
+sure.
+from :9
+M 100644 :10 demo.txt
+
+blob
+mark :12
+data 0
+
+commit refs/heads/master
+mark :13
+author User <user@localhost> 1427185512 +1300
+committer User <user@localhost> 1427185516 +1300
+data 26
+not an actual readme, yet
+from :11
+M 100644 :12 readme.txt
+
+blob
+mark :14
+data 61
+This will for sure we will prove a problem exist somewhere.
+
+blob
+mark :15
+data 49
+okay fine add something here this is only a test
+
+commit refs/heads/master
+mark :16
+author User <user@localhost> 1427185569 +1300
+committer User <user@localhost> 1427185569 +1300
+data 12
+more things
+from :13
+M 100644 :14 demo.txt
+M 100644 :15 readme.txt
+
+blob
+mark :17
+data 100
+This will for sure we will prove a problem exist somewhere.
+
+Just that we need a few more commits.
+
+commit refs/heads/master
+mark :18
+author User <user@localhost> 1427185659 +1300
+committer User <user@localhost> 1427185659 +1300
+data 13
+one more try
+from :16
+M 100644 :17 demo.txt
+
+blob
+mark :19
+data 54
+It might have something to do with number of commits?
+
+commit refs/heads/master
+mark :20
+author User <user@localhost> 1427185905 +1300
+committer User <user@localhost> 1427185905 +1300
+data 18
+is this number 9?
+from :18
+M 100644 :19 commitcount
+
+blob
+mark :21
+data 123
+This will for sure we will prove a problem exist somewhere.
+
+Just that we need a few more commits.
+
+Hey look we need more
+
+commit refs/heads/master
+mark :22
+author User <user@localhost> 1427185922 +1300
+committer User <user@localhost> 1427185922 +1300
+data 5
+cool
+from :20
+M 100644 :21 demo.txt
+
+blob
+mark :23
+data 50
+Okay fine add something here this is only a test.
+
+commit refs/heads/master
+mark :24
+author User <user@localhost> 1427185936 +1300
+committer User <user@localhost> 1427185936 +1300
+data 7
+readme
+from :22
+M 100644 :23 readme.txt
+
+blob
+mark :25
+data 74
+Okay come on this is getting boring.
+
+Yes I went and edit all the things.
+
+commit refs/heads/master
+mark :26
+author User <user@localhost> 1427185954 +1300
+committer User <user@localhost> 1427185954 +1300
+data 14
+remove a line
+from :24
+M 100644 :25 demo.txt
+
+blob
+mark :27
+data 186
+Okay come on this is getting boring.
+
+Yes I went and edit all the things.
+
+Of course, making test data can be somewhat tedious, especially a
+minimum set that can be easily reproduced.
+
+commit refs/heads/master
+mark :28
+author User <user@localhost> 1427185996 +1300
+committer User <user@localhost> 1427185996 +1300
+data 25
+Getting serious mode on.
+from :26
+M 100644 :27 demo.txt
+
+blob
+mark :29
+data 48
+This is taking a bit longer than I remembered.
+
+commit refs/heads/master
+mark :30
+author User <user@localhost> 1427186065 +1300
+committer User <user@localhost> 1427186065 +1300
+data 40
+At least we will have things minimized.
+from :28
+M 100644 :29 demo.txt
+
+blob
+mark :31
+data 11
+there yet?
+
+commit refs/heads/master
+mark :32
+author User <user@localhost> 1427186080 +1300
+committer User <user@localhost> 1427186080 +1300
+data 7
+are we
+from :30
+M 100644 :31 demo.txt
+
+blob
+mark :33
+data 237
+This should be the head commit for the client repo for testing out
+the failure case reported in issue 88. Just do a git pull from the
+repo that includes the following commit that is hosted with dulwich.
+The issue should be reproduced.
+
+commit refs/heads/master
+mark :34
+author User <user@localhost> 1427186109 +1300
+committer User <user@localhost> 1427186109 +1300
+data 6
+okay?
+from :32
+M 100644 :33 readme.txt
blob - /dev/null
blob + 6897693c08c6d44ed57dd8af26d9aeb45379679b (mode 644)
--- /dev/null
+++ testdata/repos/issue88_expect_ack_nak_other.export
+blob
+mark :1
+data 33
+We will sneak in a blob like so.
+
+reset refs/heads/master
+commit refs/heads/master
+mark :2
+author User <user@localhost> 1427183369 +1300
+committer User <user@localhost> 1427183369 +1300
+data 7
+sneaky
+M 100644 :1 problem.questionmark
+
+blob
+mark :3
+data 35
+We will introduce a problem here.
+
+
+commit refs/heads/master
+mark :4
+author User <user@localhost> 1427183376 +1300
+committer User <user@localhost> 1427183376 +1300
+data 11
+demo file.
+from :2
+M 100644 :3 demo.rst
+
+blob
+mark :5
+data 62
+We will introduce a problem here.
+
+This will take some time.
+
+
+commit refs/heads/master
+mark :6
+author User <user@localhost> 1427185135 +1300
+committer User <user@localhost> 1427185135 +1300
+data 13
+added a line
+from :4
+M 100644 :5 demo.rst
+
+blob
+mark :7
+data 57
+We will introduce a problem here.
+
+We will change these.
+
+commit refs/heads/master
+mark :8
+author User <user@localhost> 1427185245 +1300
+committer User <user@localhost> 1427185245 +1300
+data 14
+replace a linefrom :6
+M 100644 :7 demo.rst
+
+blob
+mark :9
+data 52
+We will change these.
+
+Then issues will be proven.
+
+
+commit refs/heads/master
+mark :10
+author User <user@localhost> 1427185343 +1300
+committer User <user@localhost> 1427185343 +1300
+data 13
+Yes we will.
+from :8
+M 100644 :9 demo.rst
+
+blob
+mark :11
+data 72
+We will change these.
+
+Then issues will be construed once and for all.
+
+commit refs/heads/master
+mark :12
+author User <user@localhost> 1427185440 +1300
+committer User <user@localhost> 1427185440 +1300
+data 6
+sure.
+from :10
+M 100644 :11 demo.rst
+
+blob
+mark :13
+data 0
+
+commit refs/heads/master
+mark :14
+author User <user@localhost> 1427185512 +1300
+committer User <user@localhost> 1427185516 +1300
+data 26
+not an actual readme, yet
+from :12
+M 100644 :13 emdaer.txt
+
+blob
+mark :15
+data 58
+This will for sure we will prove issues exist somewhere.
+
+
+blob
+mark :16
+data 49
+okay fine add something here this is only a test
+
+commit refs/heads/master
+mark :17
+author User <user@localhost> 1427185569 +1300
+committer User <user@localhost> 1427185569 +1300
+data 12
+more things
+from :14
+M 100644 :15 demo.rst
+M 100644 :16 emdaer.txt
+
+blob
+mark :18
+data 97
+This will for sure prove issue exist somewhere.
+
+Just that we need a few more commits as usual.
+
+
+commit refs/heads/master
+mark :19
+author User <user@localhost> 1427185659 +1300
+committer User <user@localhost> 1427185659 +1300
+data 13
+one more try
+from :17
+M 100644 :18 demo.rst
+
+blob
+mark :20
+data 54
+It might have something to do with number of commits?
+
+commit refs/heads/master
+mark :21
+author User <user@localhost> 1427185905 +1300
+committer User <user@localhost> 1427185905 +1300
+data 18
+is this number 9?
+from :19
+M 100644 :20 count
+
+blob
+mark :22
+data 119
+This will for sure we will prove issues exist somewhere.
+
+Just that we need a few more commits.
+
+Hey look we need more
+
+commit refs/heads/master
+mark :23
+author User <user@localhost> 1427185922 +1300
+committer User <user@localhost> 1427185922 +1300
+data 5
+cool
+from :21
+M 100644 :22 demo.rst
+
+blob
+mark :24
+data 50
+Okay fine add something here this is only a test.
+
+commit refs/heads/master
+mark :25
+author User <user@localhost> 1427185936 +1300
+committer User <user@localhost> 1427185936 +1300
+data 7
+readme
+from :23
+M 100644 :24 emdaer.txt
+
+blob
+mark :26
+data 74
+Okay come on this is getting boring.
+
+Yes I went and edit all the things.
+
+commit refs/heads/master
+mark :27
+author User <user@localhost> 1427185954 +1300
+committer User <user@localhost> 1427185954 +1300
+data 14
+remove a line
+from :25
+M 100644 :26 demo.rst
+
+blob
+mark :28
+data 186
+Okay come on this is getting boring.
+
+Yes I went and edit all the things.
+
+Of course, making test data can be somewhat tedious, especially a
+minimum set that can be easily reproduced.
+
+commit refs/heads/master
+mark :29
+author User <user@localhost> 1427185996 +1300
+committer User <user@localhost> 1427185996 +1300
+data 25
+Getting serious mode on.
+from :27
+M 100644 :28 demo.rst
+
+blob
+mark :30
+data 48
+This is taking a bit longer than I remembered.
+
+
+commit refs/heads/master
+mark :31
+author User <user@localhost> 1427186065 +1300
+committer User <user@localhost> 1427186065 +1300
+data 40
+At least we will have things minimized.
+from :29
+M 100644 :30 demo.rst
+
+blob
+mark :32
+data 11
+there yet?
+
+commit refs/heads/master
+mark :33
+author User <user@localhost> 1427186080 +1300
+committer User <user@localhost> 1427186080 +1300
+data 7
+are we
+from :31
+M 100644 :32 demo.rst
+
+blob
+mark :34
+data 237
+This should be the head commit for the client repo for testing out
+the failure case reported in issue 88. Just do a git pull from the
+repo that includes the following commit that is hosted with dulwich.
+The issue should be reproduced.
+
+
+commit refs/heads/master
+mark :35
+author User <user@localhost> 1427186109 +1300
+committer User <user@localhost> 1427186109 +1300
+data 6
+okay?
+from :33
+M 100644 :34 emdaer.txt
+
+blob
+mark :36
+data 394
+This should be the commit that will trigger the bug noted in issue 88
+(https://github.com/jelmer/dulwich/issues/88). To reproduce, run git
+fast-import using this fast-export and host this using dulwich, and
+then make a copy of this, strip out this blob and the following commit
+block, import to another git repo and then git clone from the previous.
+
+Naturally, this is part of the test case.
+
+commit refs/heads/master
+mark :37
+author User <user@localhost> 1427244891 +1300
+committer User <user@localhost> 1427248186 +1300
+data 49
+Added instructions on how to use this to readme.
+from :35
+M 100644 :36 emdaer.txt
+
blob - /dev/null
blob + 0124fb32fe9d31db068b58fbaa68dbcf880fd3cb (mode 644)
--- /dev/null
+++ testdata/repos/issue88_expect_ack_nak_server.export
+reset refs/heads/master
+commit refs/heads/master
+mark :1
+author User <user@localhost> 1427183369 +1300
+committer User <user@localhost> 1427183369 +1300
+data 6
+empty
+
+blob
+mark :2
+data 35
+We will reproduce a problem here.
+
+commit refs/heads/master
+mark :3
+author User <user@localhost> 1427183376 +1300
+committer User <user@localhost> 1427183376 +1300
+data 11
+demo file.
+from :1
+M 100644 :2 demo.txt
+
+blob
+mark :4
+data 62
+We will reproduce a problem here.
+
+This will take some time.
+
+commit refs/heads/master
+mark :5
+author User <user@localhost> 1427185135 +1300
+committer User <user@localhost> 1427185135 +1300
+data 13
+added a line
+from :3
+M 100644 :4 demo.txt
+
+blob
+mark :6
+data 57
+We will reproduce a problem here.
+
+We will change these.
+
+commit refs/heads/master
+mark :7
+author User <user@localhost> 1427185245 +1300
+committer User <user@localhost> 1427185245 +1300
+data 14
+replace a line
+from :5
+M 100644 :6 demo.txt
+
+blob
+mark :8
+data 52
+We will change these.
+
+Then issues will be proven.
+
+commit refs/heads/master
+mark :9
+author User <user@localhost> 1427185343 +1300
+committer User <user@localhost> 1427185343 +1300
+data 13
+Yes we will.
+from :7
+M 100644 :8 demo.txt
+
+blob
+mark :10
+data 69
+We will change these.
+
+Then issues will be proven once and for all.
+
+commit refs/heads/master
+mark :11
+author User <user@localhost> 1427185440 +1300
+committer User <user@localhost> 1427185440 +1300
+data 6
+sure.
+from :9
+M 100644 :10 demo.txt
+
+blob
+mark :12
+data 0
+
+commit refs/heads/master
+mark :13
+author User <user@localhost> 1427185512 +1300
+committer User <user@localhost> 1427185516 +1300
+data 26
+not an actual readme, yet
+from :11
+M 100644 :12 readme.txt
+
+blob
+mark :14
+data 61
+This will for sure we will prove a problem exist somewhere.
+
+blob
+mark :15
+data 49
+okay fine add something here this is only a test
+
+commit refs/heads/master
+mark :16
+author User <user@localhost> 1427185569 +1300
+committer User <user@localhost> 1427185569 +1300
+data 12
+more things
+from :13
+M 100644 :14 demo.txt
+M 100644 :15 readme.txt
+
+blob
+mark :17
+data 100
+This will for sure we will prove a problem exist somewhere.
+
+Just that we need a few more commits.
+
+commit refs/heads/master
+mark :18
+author User <user@localhost> 1427185659 +1300
+committer User <user@localhost> 1427185659 +1300
+data 13
+one more try
+from :16
+M 100644 :17 demo.txt
+
+blob
+mark :19
+data 54
+It might have something to do with number of commits?
+
+commit refs/heads/master
+mark :20
+author User <user@localhost> 1427185905 +1300
+committer User <user@localhost> 1427185905 +1300
+data 18
+is this number 9?
+from :18
+M 100644 :19 commitcount
+
+blob
+mark :21
+data 123
+This will for sure we will prove a problem exist somewhere.
+
+Just that we need a few more commits.
+
+Hey look we need more
+
+commit refs/heads/master
+mark :22
+author User <user@localhost> 1427185922 +1300
+committer User <user@localhost> 1427185922 +1300
+data 5
+cool
+from :20
+M 100644 :21 demo.txt
+
+blob
+mark :23
+data 50
+Okay fine add something here this is only a test.
+
+commit refs/heads/master
+mark :24
+author User <user@localhost> 1427185936 +1300
+committer User <user@localhost> 1427185936 +1300
+data 7
+readme
+from :22
+M 100644 :23 readme.txt
+
+blob
+mark :25
+data 74
+Okay come on this is getting boring.
+
+Yes I went and edit all the things.
+
+commit refs/heads/master
+mark :26
+author User <user@localhost> 1427185954 +1300
+committer User <user@localhost> 1427185954 +1300
+data 14
+remove a line
+from :24
+M 100644 :25 demo.txt
+
+blob
+mark :27
+data 186
+Okay come on this is getting boring.
+
+Yes I went and edit all the things.
+
+Of course, making test data can be somewhat tedious, especially a
+minimum set that can be easily reproduced.
+
+commit refs/heads/master
+mark :28
+author User <user@localhost> 1427185996 +1300
+committer User <user@localhost> 1427185996 +1300
+data 25
+Getting serious mode on.
+from :26
+M 100644 :27 demo.txt
+
+blob
+mark :29
+data 48
+This is taking a bit longer than I remembered.
+
+commit refs/heads/master
+mark :30
+author User <user@localhost> 1427186065 +1300
+committer User <user@localhost> 1427186065 +1300
+data 40
+At least we will have things minimized.
+from :28
+M 100644 :29 demo.txt
+
+blob
+mark :31
+data 11
+there yet?
+
+commit refs/heads/master
+mark :32
+author User <user@localhost> 1427186080 +1300
+committer User <user@localhost> 1427186080 +1300
+data 7
+are we
+from :30
+M 100644 :31 demo.txt
+
+blob
+mark :33
+data 237
+This should be the head commit for the client repo for testing out
+the failure case reported in issue 88. Just do a git pull from the
+repo that includes the following commit that is hosted with dulwich.
+The issue should be reproduced.
+
+commit refs/heads/master
+mark :34
+author User <user@localhost> 1427186109 +1300
+committer User <user@localhost> 1427186109 +1300
+data 6
+okay?
+from :32
+M 100644 :33 readme.txt
+
+blob
+mark :35
+data 394
+This should be the commit that will trigger the bug noted in issue 88
+(https://github.com/jelmer/dulwich/issues/88). To reproduce, run git
+fast-import using this fast-export and host this using dulwich, and
+then make a copy of this, strip out this blob and the following commit
+block, import to another git repo and then git clone from the previous.
+
+Naturally, this is part of the test case.
+
+commit refs/heads/master
+mark :36
+author User <user@localhost> 1427244891 +1300
+committer User <user@localhost> 1427248186 +1300
+data 49
+Added instructions on how to use this to readme.
+from :34
+M 100644 :35 readme.txt
+
blob - /dev/null
blob + cb089cd89a7d7686d284d8761201649346b5aa1c (mode 644)
--- /dev/null
+++ testdata/repos/ooo_merge.git/HEAD
+ref: refs/heads/master
blob - /dev/null
blob + cbe43c2ebd526cac5d66a4d0f614abf4d77c3e59 (mode 644)
Binary files /dev/null and testdata/repos/ooo_merge.git/objects/29/69be3e8ee1c0222396a5611407e4769f14e54b differ
blob - /dev/null
blob + 3f3699b36e39f0046a19227248c45215b0f5e452 (mode 644)
Binary files /dev/null and testdata/repos/ooo_merge.git/objects/38/74e9c60a6d149c44c928140f250d81e6381520 differ
blob - /dev/null
blob + 95c3c19bbeaeda10c619530ac6ea902ae1c0cdd4 (mode 644)
Binary files /dev/null and testdata/repos/ooo_merge.git/objects/6f/670c0fb53f9463760b7295fbb814e965fb20c8 differ
blob - /dev/null
blob + 2569779c10cc06f9e3639d73183c80b6fbd8f243 (mode 644)
Binary files /dev/null and testdata/repos/ooo_merge.git/objects/70/c190eb48fa8bbb50ddc692a17b44cb781af7f6 differ
blob - /dev/null
blob + e88303b28d023fc86c939c7480d259df081ea402 (mode 644)
--- /dev/null
+++ testdata/repos/ooo_merge.git/objects/76/01d7f6231db6a57f7bbb79ee52e4d462fd44d1
+xAj1E)L%[PJօ46CftxӲzL
+`MH*[dL:^l8++Pb+46nhb&ei?:檵SH@mD
+r_-ᗮxMY_~{aU*Z{<Fx0<w_LY
\ No newline at end of file
blob - /dev/null
blob + 610b7dfa3a19490625df89ba689ce6efe928d9eb (mode 644)
Binary files /dev/null and testdata/repos/ooo_merge.git/objects/90/182552c4a85a45ec2a835cadc3451bebdfe870 differ
blob - /dev/null
blob + 7bef12912d59b8fab01801f66978456947e6ce59 (mode 644)
Binary files /dev/null and testdata/repos/ooo_merge.git/objects/95/4a536f7819d40e6f637f849ee187dd10066349 differ
blob - /dev/null
blob + 165943d626144b8c1aa9859bfac35e4cb7afda09 (mode 644)
Binary files /dev/null and testdata/repos/ooo_merge.git/objects/b2/a2766a2879c209ab1176e7e778b81ae422eeaa differ
blob - /dev/null
blob + 4438cdd7cad0280b0d0e50bc44d975d20f441b0e (mode 644)
Binary files /dev/null and testdata/repos/ooo_merge.git/objects/f5/07291b64138b875c28e03469025b1ea20bc614 differ
blob - /dev/null
blob + d5a5677b135f4c653d3853bdb9b5c5b4d8dc95f8 (mode 644)
--- /dev/null
+++ testdata/repos/ooo_merge.git/objects/f9/e39b120c68182a4ba35349f832d0e4e61f485c
+x
+0ay$Yb6)=7qB)>2
+CW%>rT&I@$P5iX莥7y w:^o_|Q[IZSsVIEy?
\ No newline at end of file
blob - /dev/null
blob + 5bda024ac879ef55da75751f82e4c7e9e417ad69 (mode 644)
Binary files /dev/null and testdata/repos/ooo_merge.git/objects/fb/5b0425c7ce46959bec94d54b9a157645e114f5 differ
blob - /dev/null
blob + 34c0a7949167c0d22872f6e5a5707a4cbe1621c4 (mode 644)
--- /dev/null
+++ testdata/repos/ooo_merge.git/refs/heads/master
+7601d7f6231db6a57f7bbb79ee52e4d462fd44d1
blob - /dev/null
blob + cb089cd89a7d7686d284d8761201649346b5aa1c (mode 644)
--- /dev/null
+++ testdata/repos/refs.git/HEAD
+ref: refs/heads/master
blob - /dev/null
blob + 6160481e0d0f5c125699a9e97daba274708564ec (mode 644)
Binary files /dev/null and testdata/repos/refs.git/objects/3b/9e5457140e738c2dcd39bf6d7acf88379b90d1 differ
blob - /dev/null
blob + 478d0379acec45352e22d368d2b6711b9285ef36 (mode 644)
--- /dev/null
+++ testdata/repos/refs.git/objects/3e/c9c43c84ff242e3ef4a9fc5bc111fd780a76a8
+x-Q
+0D)-mV^i66.~{#Cm]rwyu=u5^[o<H<*y?ƴ,()a߈2<)$8xR.4YktPaԵ
+q?W)'ǧ6
\ No newline at end of file
blob - /dev/null
blob + 1be455a300b50e3b834ff22744acb008d64ca20a (mode 644)
Binary files /dev/null and testdata/repos/refs.git/objects/42/d06bd4b77fed026b154d16493e5deab78f02ec differ
blob - /dev/null
blob + 7e69c0efaf3324e3bde674e3bc90b4370466e315 (mode 644)
Binary files /dev/null and testdata/repos/refs.git/objects/a1/8114c31713746a33a2e70d9914d1ef3e781425 differ
blob - /dev/null
blob + 777d49daa06e828ec64f48b9f3c14396d3fae3a5 (mode 644)
--- /dev/null
+++ testdata/repos/refs.git/objects/cd/a609072918d7b70057b6bef9f4c2537843fcfe
+x-Q
+0D)m7iV^i6bIEOo
+~c`Av.;Zyku<*^Zox\T4
+< 4.Lam
+Fj#e/s=SRYBcQk
+eZ-\r?)Y9
\ No newline at end of file
blob - /dev/null
blob + e40b2074233e9aef431a50bf761970cb7ccc50d9 (mode 644)
Binary files /dev/null and testdata/repos/refs.git/objects/df/6800012397fb85c56e7418dd4eb9405dee075c differ
blob - /dev/null
blob + bf2f9e36e89d2085d2a1f03e477d1344b1be8a2f (mode 644)
--- /dev/null
+++ testdata/repos/refs.git/packed-refs
+# pack-refs with: peeled
+df6800012397fb85c56e7418dd4eb9405dee075c refs/tags/refs-0.1
+^42d06bd4b77fed026b154d16493e5deab78f02ec
+42d06bd4b77fed026b154d16493e5deab78f02ec refs/heads/packed
blob - /dev/null
blob + 2623a489ebb544326db1702067b25f08c63e517e (mode 644)
--- /dev/null
+++ testdata/repos/refs.git/refs/heads/40-char-ref-aaaaaaaaaaaaaaaaaa
+42d06bd4b77fed026b154d16493e5deab78f02ec
blob - /dev/null
blob + ed2f1caab8d539a193a6167080d82e8ac540d2b4 (mode 644)
--- /dev/null
+++ testdata/repos/refs.git/refs/heads/loop
+ref: refs/heads/loop
blob - /dev/null
blob + 2623a489ebb544326db1702067b25f08c63e517e (mode 644)
--- /dev/null
+++ testdata/repos/refs.git/refs/heads/master
+42d06bd4b77fed026b154d16493e5deab78f02ec
blob - /dev/null
blob + 7ac75665748fe576c76fa53d29733f1f62ba2bd3 (mode 644)
--- /dev/null
+++ testdata/repos/refs.git/refs/tags/refs-0.2
+3ec9c43c84ff242e3ef4a9fc5bc111fd780a76a8
blob - /dev/null
blob + 25d48cae10efef0a108d2e255e836223bced827e (mode 644)
--- /dev/null
+++ testdata/repos/server_new.export
+blob
+mark :1
+data 13
+foo contents
+
+reset refs/heads/master
+commit refs/heads/master
+mark :2
+author Dave Borowitz <dborowitz@google.com> 1265755064 -0800
+committer Dave Borowitz <dborowitz@google.com> 1265755064 -0800
+data 16
+initial checkin
+M 100644 :1 foo
+
+blob
+mark :3
+data 13
+baz contents
+
+blob
+mark :4
+data 21
+updated foo contents
+
+commit refs/heads/master
+mark :5
+author Dave Borowitz <dborowitz@google.com> 1265755140 -0800
+committer Dave Borowitz <dborowitz@google.com> 1265755140 -0800
+data 15
+master checkin
+from :2
+M 100644 :3 baz
+M 100644 :4 foo
+
+blob
+mark :6
+data 24
+updated foo contents v2
+
+commit refs/heads/master
+mark :7
+author Dave Borowitz <dborowitz@google.com> 1265755287 -0800
+committer Dave Borowitz <dborowitz@google.com> 1265755287 -0800
+data 17
+master checkin 2
+from :5
+M 100644 :6 foo
+
+blob
+mark :8
+data 24
+updated foo contents v3
+
+commit refs/heads/master
+mark :9
+author Dave Borowitz <dborowitz@google.com> 1265755295 -0800
+committer Dave Borowitz <dborowitz@google.com> 1265755295 -0800
+data 17
+master checkin 3
+from :7
+M 100644 :8 foo
+
+blob
+mark :10
+data 22
+branched bar contents
+
+blob
+mark :11
+data 22
+branched foo contents
+
+commit refs/heads/branch
+mark :12
+author Dave Borowitz <dborowitz@google.com> 1265755111 -0800
+committer Dave Borowitz <dborowitz@google.com> 1265755111 -0800
+data 15
+branch checkin
+from :2
+M 100644 :10 bar
+M 100644 :11 foo
+
+blob
+mark :13
+data 25
+branched bar contents v2
+
+commit refs/heads/branch
+mark :14
+author Dave Borowitz <dborowitz@google.com> 1265755319 -0800
+committer Dave Borowitz <dborowitz@google.com> 1265755319 -0800
+data 17
+branch checkin 2
+from :12
+M 100644 :13 bar
+
+reset refs/heads/master
+from :9
+
blob - /dev/null
blob + b02a3391baf0453d7341623ba62f814edb2769c7 (mode 644)
--- /dev/null
+++ testdata/repos/server_old.export
+blob
+mark :1
+data 13
+foo contents
+
+reset refs/heads/master
+commit refs/heads/master
+mark :2
+author Dave Borowitz <dborowitz@google.com> 1265755064 -0800
+committer Dave Borowitz <dborowitz@google.com> 1265755064 -0800
+data 16
+initial checkin
+M 100644 :1 foo
+
+blob
+mark :3
+data 22
+branched bar contents
+
+blob
+mark :4
+data 22
+branched foo contents
+
+commit refs/heads/branch
+mark :5
+author Dave Borowitz <dborowitz@google.com> 1265755111 -0800
+committer Dave Borowitz <dborowitz@google.com> 1265755111 -0800
+data 15
+branch checkin
+from :2
+M 100644 :3 bar
+M 100644 :4 foo
+
+blob
+mark :6
+data 13
+baz contents
+
+blob
+mark :7
+data 21
+updated foo contents
+
+commit refs/heads/master
+mark :8
+author Dave Borowitz <dborowitz@google.com> 1265755140 -0800
+committer Dave Borowitz <dborowitz@google.com> 1265755140 -0800
+data 15
+master checkin
+from :2
+M 100644 :6 baz
+M 100644 :7 foo
+
+reset refs/heads/master
+from :8
+
blob - /dev/null
blob + cb089cd89a7d7686d284d8761201649346b5aa1c (mode 644)
--- /dev/null
+++ testdata/repos/simple_merge.git/HEAD
+ref: refs/heads/master
blob - /dev/null
blob + b4c3a1d99a4d24753afd83c3e179bd428b24764c (mode 644)
--- /dev/null
+++ testdata/repos/simple_merge.git/objects/0d/89f20333fbb1d2f3a94da77f4981373d8f4310
+xK
+@])z53==-&e=i:"Z=H)r芔>4wYԯMx|q=s)&6Dh6{Ym/LXg?
\ No newline at end of file
blob - /dev/null
blob + a2247b203f986dcb9c22184b1aae17353960c5b4 (mode 644)
Binary files /dev/null and testdata/repos/simple_merge.git/objects/1b/6318f651a534b38f9c7aedeebbd56c1e896853 differ
blob - /dev/null
blob + 3dec0bf77a94a1664e95bd056f41ddb563072c89 (mode 644)
Binary files /dev/null and testdata/repos/simple_merge.git/objects/29/69be3e8ee1c0222396a5611407e4769f14e54b differ
blob - /dev/null
blob + a73c46c7b6800a9df41452174604dcf600efd325 (mode 644)
--- /dev/null
+++ testdata/repos/simple_merge.git/objects/4c/ffe90e0a41ad3f5190079d7c8f036bde29cbe6
+xK
+1D]L~=pݝ2Fo-U:.UUAI!KU.!kj
+FN
+*R{QofwSQ[!)G;]g8Шw863Mˇ/_m1 tSK0]i*'pCO
\ No newline at end of file
blob - /dev/null
blob + 69c6dff1ab6b88df371b5f539df78e705d1f05a5 (mode 644)
Binary files /dev/null and testdata/repos/simple_merge.git/objects/5d/ac377bdded4c9aeb8dff595f0faeebcc8498cc differ
blob - /dev/null
blob + 9e1d72632e9aa355b6f3efed9aa13f3a1259c426 (mode 644)
--- /dev/null
+++ testdata/repos/simple_merge.git/objects/60/dacdc733de308bb77bb76ce0fb0f9b44c9769e
+x
+0E]+f/N"]g *5"O.υɗia UBERr[P\ʋ
+Tz靖-zN0Q
+)ZOEv,pIop['lǺ<|fֶk)PGX{&K0?yMQ
\ No newline at end of file
blob - /dev/null
blob + 8f8ed37f1e6b8f0af781c26daa8f31ae9bd2167d (mode 644)
Binary files /dev/null and testdata/repos/simple_merge.git/objects/6f/670c0fb53f9463760b7295fbb814e965fb20c8 differ
blob - /dev/null
blob + 2569779c10cc06f9e3639d73183c80b6fbd8f243 (mode 644)
Binary files /dev/null and testdata/repos/simple_merge.git/objects/70/c190eb48fa8bbb50ddc692a17b44cb781af7f6 differ
blob - /dev/null
blob + 610b7dfa3a19490625df89ba689ce6efe928d9eb (mode 644)
Binary files /dev/null and testdata/repos/simple_merge.git/objects/90/182552c4a85a45ec2a835cadc3451bebdfe870 differ
blob - /dev/null
blob + 7bef12912d59b8fab01801f66978456947e6ce59 (mode 644)
Binary files /dev/null and testdata/repos/simple_merge.git/objects/95/4a536f7819d40e6f637f849ee187dd10066349 differ
blob - /dev/null
blob + 67706b5810550b826b747525ac1924499c87a6d2 (mode 644)
--- /dev/null
+++ testdata/repos/simple_merge.git/objects/ab/64bbdcc51b170d21588e5c5d391ee5c0c96dfd
+xM
+0]$cL";/:3bmo|6=~SgU@c̍bUA)ƙ{ulR+ld&z7ږm{IiKt.pmQx?|ݨ!־c仴?s9r4/mO+
\ No newline at end of file
blob - /dev/null
blob + d45835e8201d096288a79b38053dbe259d5475b5 (mode 644)
Binary files /dev/null and testdata/repos/simple_merge.git/objects/d4/bdad6549dfedf25d3b89d21f506aff575b28a7 differ
blob - /dev/null
blob + dce887e80f980d37bb634a0e7c99c5e062292fbd (mode 644)
Binary files /dev/null and testdata/repos/simple_merge.git/objects/d8/0c186a03f423a81b39df39dc87fd269736ca86 differ
blob - /dev/null
blob + 8c901c5b89f920a740af8b23b771ef4019cdb665 (mode 644)
Binary files /dev/null and testdata/repos/simple_merge.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
blob - /dev/null
blob + c6b8285fbdb5a417f490579d79252fc6d2d03c97 (mode 644)
--- /dev/null
+++ testdata/repos/simple_merge.git/refs/heads/master
+5dac377bdded4c9aeb8dff595f0faeebcc8498cc
blob - /dev/null
blob + c493b47db9e7c5cf34da754182f3b099e44a64fc (mode 644)
--- /dev/null
+++ testdata/repos/submodule/dotgit
+gitdir: ./a.git
blob - /dev/null
blob + 8c85e3a618f862f3df42941e44592d22f75f7695 (mode 644)
--- /dev/null
+++ testdata/tags/71/033db03a03c6a36721efcf1968dd8f8e0cf023
+xmMO@=x#݅QnIMEQ
+mʿG'sL2OSz,$1vqnaJb+0u3mMr
+adɢs,=RB bY(֝cQ Yjn!p 7# ݜ5!X[GپM}n}]8m9pzd%
+!#f|X`fBKD%'sKCӝ5\<a5EDpDd-=n
+oKk=ʽn~6iM
\ No newline at end of file
blob - /dev/null
blob + 2569779c10cc06f9e3639d73183c80b6fbd8f243 (mode 644)
Binary files /dev/null and testdata/trees/70/c190eb48fa8bbb50ddc692a17b44cb781af7f6 differ