Please follow PEP8 with regard to coding style.
-All functionality should be available in pure Python. Optional C implementations
-may be written for performance reasons, but should never replace the Python
-implementation. The C implementations should follow the kernel/git coding style.
+All functionality should be available in pure Python. Optional C
+implementations may be written for performance reasons, but should never
+replace the Python implementation. The C implementations should follow the
+kernel/git coding style.
+
+Where possible please include updates to NEWS along with your improvements.
-0.5.1 UNRELEASED
+0.6.1 UNRELEASED
+
+ BUG FIXES
+
+ * Fix memory leak in C implementation of sorted_tree_items. (Dave Borowitz)
+
+ TESTS
+
+ * Add tests for sorted_tree_items and C implementation. (Dave Borowitz)
+
+ CLEANUP
+
+ * Clean up file headers. (Dave Borowitz)
+
+
+0.6.0 2010-05-22
+
+note: This list is most likely incomplete for 0.6.0.
BUG FIXES
* Cope with \r in ref files on Windows. (
http://github.com/jelmer/dulwich/issues/#issue/13, Jelmer Vernooij)
+ * Fix GitFile breakage on Windows. (Anatoly Techtonik, #557585)
+
+ * Support packed ref deletion with no peeled refs. (Augie Fackler)
+
+ * Fix send pack when there is nothing to fetch. (Augie Fackler)
+
+ * Fix fetch if no progress function is specified. (Augie Fackler)
+
+ * Allow double-staging of files that are deleted in the index.
+ (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
+ empty. (Dave Borowitz)
+
+ * Always update ShaFile.id when the contents of the object get changed.
+ (Jelmer Vernooij)
+
+ * Various Python2.4-compatibility fixes. (Dave Borowitz)
+
+ * Fix thin pack handling. (Dave Borowitz)
+
FEATURES
* Add include-tag capability to server. (Dave Borowitz)
* New dulwich.fastexport module that can generate fastexport
streams. (Jelmer Vernooij)
+ * Implemented BaseRepo.__contains__. (Jelmer Vernooij)
+
+ * Add __setitem__ to DictRefsContainer. (Dave Borowitz)
+
+ * Overall improvements checking Git objects. (Dave Borowitz)
+
+ * Packs are now verified while they are received. (Dave Borowitz)
+
TESTS
* Add framework for testing compatibility with C Git. (Dave Borowitz)
+ * Add various tests for the use of non-bare repositories. (Dave Borowitz)
+
+ * Cope with diffstat not being available on all platforms.
+ (Tay Ray Chuan, Jelmer Vernooij)
+
+ * Add make_object and make_commit convenience functions to test utils.
+ (Dave Borowitz)
+
API BREAKAGES
* The 'committer' and 'message' arguments to Repo.do_commit() have
API CHANGES
- * Blob.chunked was added. (Jelmer Vernooij)
+ * The primary serialization APIs in dulwich.objects now work
+ with chunks of strings rather than with full-text strings.
+ (Jelmer Vernooij)
0.5.0 2010-03-03
#!/usr/bin/python
-# dul-daemon - Simple git-daemon a like
+# dul-daemon - Simple git-daemon-like server
# Copyright (C) 2008 John Carr <john.carr@unrouted.co.uk>
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# or (at your option) a later version of the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#!/usr/bin/python
# dul-receive-pack - git-receive-pack in python
# Copyright (C) 2008 John Carr <john.carr@unrouted.co.uk>
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# or (at your option) a later version of the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#!/usr/bin/python
# dul-upload-pack - git-upload-pack in python
# Copyright (C) 2008 John Carr <john.carr@unrouted.co.uk>
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# or (at your option) a later version of the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#!/usr/bin/python
# dul-web - HTTP-based git server
-# Copyright (C) 2010 David Borowitz <dborowitz@google.com>
+# Copyright (C) 2010 Google, Inc. <dborowitz@google.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
#!/usr/bin/python
# dulwich - Simple command-line interface to Dulwich
# Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# or (at your option) a later version of the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# __init__.py -- The git module of dulwich
# Copyright (C) 2007 James Westby <jw+debian@jameswestby.net>
# Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
-# of the License or (at your option) any later version of
+# of the License or (at your option) any later version of
# the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
import repo
import server
-__version__ = (0, 5, 1)
+__version__ = (0, 6, 0)
return strcmp(remain_a, remain_b);
}
+static void free_tree_items(struct tree_item *items, int num) {
+ int i;
+ for (i = 0; i < num; i++) {
+ Py_DECREF(items[i].tuple);
+ }
+ free(items);
+}
+
static PyObject *py_sorted_tree_items(PyObject *self, PyObject *entries)
{
struct tree_item *qsort_entries;
i = 0;
while (PyDict_Next(entries, &pos, &key, &value)) {
PyObject *py_mode, *py_int_mode, *py_sha;
-
+
+ if (!PyString_Check(key)) {
+ PyErr_SetString(PyExc_TypeError, "Name is not a string");
+ free_tree_items(qsort_entries, i);
+ return NULL;
+ }
+
if (PyTuple_Size(value) != 2) {
PyErr_SetString(PyExc_ValueError, "Tuple has invalid size");
- free(qsort_entries);
+ free_tree_items(qsort_entries, i);
return NULL;
}
py_int_mode = PyNumber_Int(py_mode);
if (!py_int_mode) {
PyErr_SetString(PyExc_TypeError, "Mode is not an integral type");
- free(qsort_entries);
+ free_tree_items(qsort_entries, i);
return NULL;
}
py_sha = PyTuple_GET_ITEM(value, 1);
- if (!PyString_CheckExact(key)) {
- PyErr_SetString(PyExc_TypeError, "Name is not a string");
- free(qsort_entries);
+ if (!PyString_Check(py_sha)) {
+ PyErr_SetString(PyExc_TypeError, "SHA is not a string");
+ Py_DECREF(py_int_mode);
+ free_tree_items(qsort_entries, i);
return NULL;
}
qsort_entries[i].name = PyString_AS_STRING(key);
qsort_entries[i].mode = PyInt_AS_LONG(py_mode);
- qsort_entries[i].tuple = PyTuple_Pack(3, key, py_mode, py_sha);
+ qsort_entries[i].tuple = PyTuple_Pack(3, key, py_int_mode, py_sha);
+ Py_DECREF(py_int_mode);
i++;
}
ret = PyList_New(num);
if (ret == NULL) {
- free(qsort_entries);
+ free_tree_items(qsort_entries, i);
PyErr_NoMemory();
return NULL;
}
"%s %s %s\0%s" % (old_sha1, new_sha1, refname,
' '.join(self._send_capabilities)))
sent_capabilities = True
- if not new_sha1 in (have, ZERO_SHA):
+ if new_sha1 not in have and new_sha1 != ZERO_SHA:
want.append(new_sha1)
self.proto.write_pkt_line(None)
if not want:
# __init__.py -- Fast export/import functionality
# Copyright (C) 2010 Jelmer Vernooij <jelmer@samba.org>
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
-# of the License or (at your option) any later version of
+# of the License or (at your option) any later version of
# the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# index.py -- File parser/write for the git index file
+# index.py -- File parser/writer for the git index file
# Copyright (C) 2008-2009 Jelmer Vernooij <jelmer@samba.org>
-
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# of the License or (at your opinion) any later version of the license.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# lru_cache.py -- Simple LRU cache for dulwich
# Copyright (C) 2006, 2008 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# misc.py -- For dealing with python2.4 oddness
# Copyright (C) 2008 Canonical Ltd.
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# of the License or (at your option) a later version.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
+
"""Misc utilities to work with python <2.6.
These utilities can all be deleted when dulwich decides it wants to stop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-
"""Access to base git objects."""
the items would be serialized.
:param entries: Dictionary mapping names to (mode, sha) tuples
- :return: Iterator over (name, mode, sha)
+ :return: Iterator over (name, mode, hexsha)
"""
for name, entry in sorted(entries.iteritems(), cmp=cmp_entry):
- yield name, entry[0], entry[1]
+ mode, hexsha = entry
+ # Stricter type checks than normal to mirror checks in the C version.
+ mode = int(mode)
+ if not isinstance(hexsha, str):
+ raise TypeError('Expected a string for SHA, got %r' % hexsha)
+ yield name, mode, hexsha
def cmp_entry((name1, value1), (name2, value2)):
-# pack.py -- For dealing wih packed git objects.
+# pack.py -- For dealing with packed git objects.
# Copyright (C) 2007 James Westby <jw+debian@jameswestby.net>
-# Copryight (C) 2008-2009 Jelmer Vernooij <jelmer@samba.org>
+# Copyright (C) 2008-2009 Jelmer Vernooij <jelmer@samba.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
def close(self):
self._file.close()
- def __del__(self):
- self.close()
-
def _get_size(self):
if self._size is not None:
return self._size
-# patch.py -- For dealing wih packed-style patches.
-# Copryight (C) 2009 Jelmer Vernooij <jelmer@samba.org>
-#
+# patch.py -- For dealing with packed-style patches.
+# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# of the License or (at your option) a later version.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# protocol.py -- Shared parts of the git protocols
-# Copryight (C) 2008 John Carr <john.carr@unrouted.co.uk>
+# Copyright (C) 2008 John Carr <john.carr@unrouted.co.uk>
# Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
#
# This program is free software; you can redistribute it and/or
-# repo.py -- For dealing wih git repositories.
+# repo.py -- For dealing with git repositories.
# Copyright (C) 2007 James Westby <jw+debian@jameswestby.net>
# Copyright (C) 2008-2009 Jelmer Vernooij <jelmer@samba.org>
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
-# of the License or (at your option) any later version of
+# of the License or (at your option) any later version of
# the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
"""Read a reference without following any references.
:param refname: The name of the reference
- :return: The contents of the ref file, or None if it does
+ :return: The contents of the ref file, or None if it does
not exist.
"""
contents = self.read_loose_ref(refname)
"""Read a loose reference and return its contents.
:param name: the refname to read
- :return: The contents of the ref file, or None if it does
+ :return: The contents of the ref file, or None if it does
not exist.
"""
raise NotImplementedError(self.read_loose_ref)
"""
# TODO: invalidate the cache on repacking
if self._packed_refs is None:
+ # set both to empty because we want _peeled_refs to be
+ # None if and only if _packed_refs is also None.
self._packed_refs = {}
+ self._peeled_refs = {}
path = os.path.join(self.path, 'packed-refs')
try:
f = GitFile(path, 'rb')
first_line = iter(f).next().rstrip()
if (first_line.startswith("# pack-refs") and " peeled" in
first_line):
- self._peeled_refs = {}
for sha, name, peeled in read_packed_refs_with_peeled(f):
self._packed_refs[name] = sha
if peeled:
def open_index(self):
"""Open the index for this repository.
-
+
:raises NoIndexPresent: If no index is present
:return: Index instance
"""
"""Fetch objects into another repository.
:param target: The target repository
- :param determine_wants: Optional function to determine what refs to
+ :param determine_wants: Optional function to determine what refs to
fetch.
:param progress: Optional progress function
"""
get_tagged=None):
"""Fetch the missing objects required for a set of revisions.
- :param determine_wants: Function that takes a dictionary with heads
+ :param determine_wants: Function that takes a dictionary with heads
and returns the list of heads to fetch.
- :param graph_walker: Object that can iterate over the list of revisions
- to fetch and has an "ack" method that will be called to acknowledge
+ :param graph_walker: Object that can iterate over the list of revisions
+ to fetch and has an "ack" method that will be called to acknowledge
that a revision is present.
- :param progress: Simple progress function that will be called with
+ :param progress: Simple progress function that will be called with
updated progress strings.
:param get_tagged: Function that returns a dict of pointed-to sha -> tag
sha for including tags.
del self.refs[name]
raise ValueError(name)
- def do_commit(self, message, committer=None,
+ def do_commit(self, message, committer=None,
author=None, commit_timestamp=None,
- commit_timezone=None, author_timestamp=None,
+ commit_timezone=None, author_timestamp=None,
author_timezone=None, tree=None):
"""Create a new commit.
:param commit_timestamp: Commit timestamp (defaults to now)
:param commit_timezone: Commit timestamp timezone (defaults to GMT)
:param author_timestamp: Author timestamp (defaults to commit timestamp)
- :param author_timezone: Author timestamp timezone
+ :param author_timezone: Author timestamp timezone
(defaults to commit timestamp timezone)
:param tree: SHA1 of the tree root to use (if not specified the current index will be committed).
:return: New commit SHA1
# server.py -- Implementation of the server side git protocols
-# Copryight (C) 2008 John Carr <john.carr@unrouted.co.uk>
+# Copyright (C) 2008 John Carr <john.carr@unrouted.co.uk>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# __init__.py -- The tests for dulwich
# Copyright (C) 2007 James Westby <jw+debian@jameswestby.net>
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
-# of the License or (at your option) any later version of
+# of the License or (at your option) any later version of
# the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
pass
shutil.rmtree(self.gitroot)
- def test_send_pack(self):
+ def assertDestEqualsSrc(self):
+ src = repo.Repo(os.path.join(self.gitroot, 'server_new.export'))
+ dest = repo.Repo(os.path.join(self.gitroot, 'dest'))
+ self.assertReposEqual(src, dest)
+
+ def _do_send_pack(self):
c = client.TCPGitClient('localhost')
srcpath = os.path.join(self.gitroot, 'server_new.export')
src = repo.Repo(srcpath)
del sendrefs['HEAD']
c.send_pack('/dest', lambda _: sendrefs,
src.object_store.generate_pack_contents)
- dest = repo.Repo(os.path.join(self.gitroot, 'dest'))
- self.assertReposEqual(src, dest)
+
+ def test_send_pack(self):
+ self._do_send_pack()
+ self.assertDestEqualsSrc()
+
+ def test_send_pack_nothing_to_send(self):
+ self._do_send_pack()
+ self.assertDestEqualsSrc()
+ # nothing to send, but shouldn't raise either.
+ self._do_send_pack()
def test_send_without_report_status(self):
c = client.TCPGitClient('localhost')
del sendrefs['HEAD']
c.send_pack('/dest', lambda _: sendrefs,
src.object_store.generate_pack_contents)
- dest = repo.Repo(os.path.join(self.gitroot, 'dest'))
- self.assertReposEqual(src, dest)
+ self.assertDestEqualsSrc()
def disable_ff_and_make_dummy_commit(self):
# disable non-fast-forward pushes to the server
self.assertEqual({'refs/heads/branch': 'non-fast-forward',
'refs/heads/master': 'non-fast-forward'},
e.ref_status)
+
+ def test_fetch_pack(self):
+ c = client.TCPGitClient('localhost')
+ dest = repo.Repo(os.path.join(self.gitroot, 'dest'))
+ refs = c.fetch('/server_new.export', dest)
+ map(lambda r: dest.refs.set_if_equals(r[0], None, r[1]), refs.items())
+ self.assertDestEqualsSrc()
+
+ def test_incremental_fetch_pack(self):
+ self.test_fetch_pack()
+ dest, dummy = self.disable_ff_and_make_dummy_commit()
+ dest.refs['refs/heads/master'] = dummy
+ c = client.TCPGitClient('localhost')
+ dest = repo.Repo(os.path.join(self.gitroot, 'server_new.export'))
+ refs = c.fetch('/dest', dest)
+ map(lambda r: dest.refs.set_if_equals(r[0], None, r[1]), refs.items())
+ self.assertDestEqualsSrc()
-# test_pack.py -- Compatibilty tests for git packs.
+# test_pack.py -- Compatibility tests for git packs.
# Copyright (C) 2010 Google, Inc.
#
# This program is free software; you can redistribute it and/or
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-"""Compatibilty tests for git packs."""
+"""Compatibility tests for git packs."""
import binascii
-# test_server.py -- Compatibilty tests for git server.
+# test_server.py -- Compatibility tests for git server.
# Copyright (C) 2010 Google, Inc.
#
# This program is free software; you can redistribute it and/or
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-"""Compatibilty tests between Dulwich and the cgit server.
+"""Compatibility tests between Dulwich and the cgit server.
Warning: these tests should be fairly stable, but when writing/debugging new
tests, deadlocks may freeze the test process such that it cannot be Ctrl-C'ed.
-# test_web.py -- Compatibilty tests for the git web server.
+# test_web.py -- Compatibility tests for the git web server.
# Copyright (C) 2010 Google, Inc.
#
# This program is free software; you can redistribute it and/or
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-"""Compatibilty tests between Dulwich and the cgit HTTP server.
+"""Compatibility tests between Dulwich and the cgit HTTP server.
Warning: these tests should be fairly stable, but when writing/debugging new
tests, deadlocks may freeze the test process such that it cannot be Ctrl-C'ed.
# test_fastexport.py -- Fast export/import functionality
# Copyright (C) 2010 Jelmer Vernooij <jelmer@samba.org>
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
-# of the License or (at your option) any later version of
+# of the License or (at your option) any later version of
# the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-
import errno
import os
import shutil
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-
"""Tests for the index."""
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-
"""Tests for the object store interface."""
# test_objects.py -- tests for objects.py
# Copyright (C) 2007 James Westby <jw+debian@jameswestby.net>
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
-# of the License or (at your option) any later version of
+# of the License or (at your option) any later version of
# the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-
"""Tests for git base objects."""
# TODO: Round-trip parse-serialize-parse and serialize-parse-serialize tests.
parse_timezone,
parse_tree,
_parse_tree_py,
+ sorted_tree_items,
+ _sorted_tree_items_py,
)
from dulwich.tests import (
TestSkipped,
self.assertCheckFails(Commit, text)
+_TREE_ITEMS = {
+ 'a.c': (0100755, 'd80c186a03f423a81b39df39dc87fd269736ca86'),
+ 'a': (stat.S_IFDIR, 'd80c186a03f423a81b39df39dc87fd269736ca86'),
+ 'a/c': (stat.S_IFDIR, 'd80c186a03f423a81b39df39dc87fd269736ca86'),
+ }
+
+_SORTED_TREE_ITEMS = [
+ ('a.c', 0100755, 'd80c186a03f423a81b39df39dc87fd269736ca86'),
+ ('a', stat.S_IFDIR, 'd80c186a03f423a81b39df39dc87fd269736ca86'),
+ ('a/c', stat.S_IFDIR, 'd80c186a03f423a81b39df39dc87fd269736ca86'),
+ ]
+
+
class TreeTests(ShaFileCheckTests):
def test_simple(self):
def test_tree_dir_sort(self):
x = Tree()
- x["a.c"] = (0100755, "d80c186a03f423a81b39df39dc87fd269736ca86")
- x["a"] = (stat.S_IFDIR, "d80c186a03f423a81b39df39dc87fd269736ca86")
- x["a/c"] = (stat.S_IFDIR, "d80c186a03f423a81b39df39dc87fd269736ca86")
- self.assertEquals(["a.c", "a", "a/c"], [p[0] for p in x.iteritems()])
+ for name, item in _TREE_ITEMS.iteritems():
+ x[name] = item
+ self.assertEquals(_SORTED_TREE_ITEMS, list(x.iteritems()))
def _do_test_parse_tree(self, parse_tree):
dir = os.path.join(os.path.dirname(__file__), 'data', 'trees')
raise TestSkipped('parse_tree extension not found')
self._do_test_parse_tree(parse_tree)
+ def _do_test_sorted_tree_items(self, sorted_tree_items):
+ def do_sort(entries):
+ return list(sorted_tree_items(entries))
+
+ self.assertEqual(_SORTED_TREE_ITEMS, do_sort(_TREE_ITEMS))
+
+ # C/Python implementations may differ in specific error types, but
+ # should all error on invalid inputs.
+ # For example, the C implementation has stricter type checks, so may
+ # raise TypeError where the Python implementation raises AttributeError.
+ errors = (TypeError, ValueError, AttributeError)
+ self.assertRaises(errors, do_sort, 'foo')
+ self.assertRaises(errors, do_sort, {'foo': (1, 2, 3)})
+
+ myhexsha = 'd80c186a03f423a81b39df39dc87fd269736ca86'
+ self.assertRaises(errors, do_sort, {'foo': ('xxx', myhexsha)})
+ self.assertRaises(errors, do_sort, {'foo': (0100755, 12345)})
+
+ def test_sorted_tree_items(self):
+ self._do_test_sorted_tree_items(_sorted_tree_items_py)
+
+ def test_sorted_tree_items_extension(self):
+ if sorted_tree_items is _sorted_tree_items_py:
+ raise TestSkipped('sorted_tree_items extension not found')
+ self._do_test_sorted_tree_items(sorted_tree_items)
+
def test_check(self):
t = Tree
sha = hex_to_sha(a_sha)
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-
"""Tests for Dulwich packs."""
# test_patch.py -- tests for patch.py
-# Copryight (C) 2010 Jelmer Vernooij <jelmer@samba.org>
-#
+# Copyright (C) 2010 Jelmer Vernooij <jelmer@samba.org>
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# of the License or (at your option) a later version.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# test_protocol.py -- Tests for the git protocol
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# or (at your option) any later version of the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-
"""Tests for the smart protocol utility functions."""
# test_repository.py -- tests for repository.py
# Copyright (C) 2007 James Westby <jw+debian@jameswestby.net>
-#
+#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
-# of the License or (at your option) any later version of
+# of the License or (at your option) any later version of
# the License.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-
"""Tests for the repository."""
from cStringIO import StringIO
def tearDown(self):
if self._repo is not None:
tear_down_repo(self._repo)
-
+
def test_simple_props(self):
r = self._repo = open_repo('a.git')
self.assertEqual(r.controldir(), r.path)
-
+
def test_ref(self):
r = self._repo = open_repo('a.git')
self.assertEqual(r.ref('refs/heads/master'),
r["refs/tags/foo"] = 'a90fa2d900a17e99b433217e988c4eb4a2e9a097'
self.assertEquals('a90fa2d900a17e99b433217e988c4eb4a2e9a097',
r["refs/tags/foo"].id)
-
+
def test_get_refs(self):
r = self._repo = open_repo('a.git')
self.assertEqual({
'refs/tags/mytag': '28237f4dc30d0d462658d6b937b08a0f0b6ef55a',
'refs/tags/mytag-packed': 'b0931cadc54336e78a1d980420e3268903b57a50',
}, r.get_refs())
-
+
def test_head(self):
r = self._repo = open_repo('a.git')
self.assertEqual(r.head(), 'a90fa2d900a17e99b433217e988c4eb4a2e9a097')
self.assertRaises(errors.NotBlobError, r.get_blob, r.head())
finally:
warnings.resetwarnings()
-
+
def test_linear_history(self):
r = self._repo = open_repo('a.git')
history = r.revision_history(r.head())
shas = [c.sha().hexdigest() for c in history]
self.assertEqual(shas, [r.head(),
'2a72d929692c41d8554c07f6301757ba18a65d91'])
-
+
def test_merge_history(self):
r = self._repo = open_repo('simple_merge.git')
history = r.revision_history(r.head())
'4cffe90e0a41ad3f5190079d7c8f036bde29cbe6',
'60dacdc733de308bb77bb76ce0fb0f9b44c9769e',
'0d89f20333fbb1d2f3a94da77f4981373d8f4310'])
-
+
def test_revision_history_missing_commit(self):
r = self._repo = open_repo('simple_merge.git')
self.assertRaises(errors.MissingCommitError, r.revision_history,
missing_sha)
-
+
def test_out_of_order_merge(self):
"""Test that revision history is ordered by date, not parent order."""
r = self._repo = open_repo('ooo_merge.git')
'f507291b64138b875c28e03469025b1ea20bc614',
'fb5b0425c7ce46959bec94d54b9a157645e114f5',
'f9e39b120c68182a4ba35349f832d0e4e61f485c'])
-
+
def test_get_tags_empty(self):
r = self._repo = open_repo('ooo_merge.git')
self.assertEqual({}, r.refs.as_dict('refs/tags'))
self.assertFalse(os.path.exists(
os.path.join(self._refs.path, 'HEAD.lock')))
+ def test_remove_packed_without_peeled(self):
+ refs_file = os.path.join(self._repo.path, 'packed-refs')
+ f = open(refs_file)
+ refs_data = f.read()
+ f.close()
+ f = open(refs_file, 'w')
+ f.write('\n'.join(l for l in refs_data.split('\n')
+ if not l or l[0] not in '#^'))
+ f.close()
+ self._repo = Repo(self._repo.path)
+ refs = self._repo.refs
+ self.assertTrue(refs.remove_if_equals(
+ 'refs/heads/packed', '42d06bd4b77fed026b154d16493e5deab78f02ec'))
def test_remove_if_equals_packed(self):
# test removing ref that is only packed
def test_read_ref(self):
self.assertEqual('ref: refs/heads/master', self._refs.read_ref("HEAD"))
- self.assertEqual('42d06bd4b77fed026b154d16493e5deab78f02ec',
+ self.assertEqual('42d06bd4b77fed026b154d16493e5deab78f02ec',
self._refs.read_ref("refs/heads/packed"))
self.assertEqual(None,
self._refs.read_ref("nonexistant"))
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-
"""Tests for the smart protocol server."""
# test_web.py -- Tests for the git HTTP server
-# Copryight (C) 2010 Google, Inc.
+# Copyright (C) 2010 Google, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# web.py -- WSGI smart-http server
-# Copryight (C) 2010 Google, Inc.
+# Copyright (C) 2010 Google, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
#!/usr/bin/python
-# Setup file for bzr-git
+# Setup file for dulwich
# Copyright (C) 2008-2010 Jelmer Vernooij <jelmer@samba.org>
try:
from distutils.core import setup, Extension
from distutils.core import Distribution
-dulwich_version_string = '0.5.1'
+dulwich_version_string = '0.6.0'
include_dirs = []
# Windows MSVC support