summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2009-10-11 16:49:05 +0200
committerSebastian Thiel <byronimo@gmail.com>2009-10-11 16:49:05 +0200
commit9374a916588d9fe7169937ba262c86ad710cfa74 (patch)
treedfe77a02cfa3fbe34563326cea95e92694d21b9a
parent20f202d83bdf1f332a3cb8f010bcf8bf3c2807bd (diff)
downloadgitpython-9374a916588d9fe7169937ba262c86ad710cfa74.tar.gz
converted all spaces to tabs ( 4 spaces = 1 tab ) just to allow me and my editor to work with the files properly. Can convert it back for releaes
-rw-r--r--ez_setup.py322
-rw-r--r--lib/git/__init__.py2
-rw-r--r--lib/git/actor.py74
-rw-r--r--lib/git/base.py488
-rw-r--r--lib/git/blob.py306
-rw-r--r--lib/git/cmd.py388
-rw-r--r--lib/git/commit.py556
-rw-r--r--lib/git/diff.py140
-rw-r--r--lib/git/errors.py32
-rw-r--r--lib/git/head.py106
-rw-r--r--lib/git/repo.py918
-rw-r--r--lib/git/stats.py102
-rw-r--r--lib/git/tag.py224
-rw-r--r--lib/git/tree.py188
-rw-r--r--lib/git/utils.py24
-rw-r--r--setup.py106
-rw-r--r--test/git/test_actor.py28
-rw-r--r--test/git/test_blob.py158
-rw-r--r--test/git/test_commit.py394
-rw-r--r--test/git/test_diff.py30
-rw-r--r--test/git/test_git.py94
-rw-r--r--test/git/test_head.py38
-rw-r--r--test/git/test_repo.py402
-rw-r--r--test/git/test_stats.py34
-rw-r--r--test/git/test_tree.py234
-rw-r--r--test/git/test_utils.py18
-rw-r--r--test/testlib/__init__.py2
-rw-r--r--test/testlib/asserts.py30
-rw-r--r--test/testlib/helper.py8
29 files changed, 2723 insertions, 2723 deletions
diff --git a/ez_setup.py b/ez_setup.py
index 3031ad0d..50d0075b 100644
--- a/ez_setup.py
+++ b/ez_setup.py
@@ -4,8 +4,8 @@
If you want to use setuptools in your package's setup.py, just include this
file in the same directory with it, and add this to the top of your setup.py::
- from ez_setup import use_setuptools
- use_setuptools()
+ from ez_setup import use_setuptools
+ use_setuptools()
If you want to require a specific version of setuptools, set a download
mirror, or use an alternate download directory, you can do so by supplying
@@ -15,106 +15,106 @@ This file can also be run as a script to install or upgrade setuptools.
"""
import sys
DEFAULT_VERSION = "0.6c3"
-DEFAULT_URL = "http://cheeseshop.python.org/packages/%s/s/setuptools/" % sys.version[:3]
+DEFAULT_URL = "http://cheeseshop.python.org/packages/%s/s/setuptools/" % sys.version[:3]
md5_data = {
- 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
- 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
- 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
- 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
- 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
- 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
- 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
- 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
- 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
- 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
- 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
- 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
- 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
- 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
- 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
+ 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
+ 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
+ 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
+ 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
+ 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
+ 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
+ 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
+ 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
+ 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
+ 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
+ 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
+ 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
+ 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
+ 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
+ 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
}
import sys, os
def _validate_md5(egg_name, data):
- if egg_name in md5_data:
- from md5 import md5
- digest = md5(data).hexdigest()
- if digest != md5_data[egg_name]:
- print >>sys.stderr, (
- "md5 validation of %s failed! (Possible download problem?)"
- % egg_name
- )
- sys.exit(2)
- return data
+ if egg_name in md5_data:
+ from md5 import md5
+ digest = md5(data).hexdigest()
+ if digest != md5_data[egg_name]:
+ print >>sys.stderr, (
+ "md5 validation of %s failed! (Possible download problem?)"
+ % egg_name
+ )
+ sys.exit(2)
+ return data
def use_setuptools(
- version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
- download_delay=15
+ version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+ download_delay=15
):
- """Automatically find/download setuptools and make it available on sys.path
-
- `version` should be a valid setuptools version number that is available
- as an egg for download under the `download_base` URL (which should end with
- a '/'). `to_dir` is the directory where setuptools will be downloaded, if
- it is not already available. If `download_delay` is specified, it should
- be the number of seconds that will be paused before initiating a download,
- should one be required. If an older version of setuptools is installed,
- this routine will print a message to ``sys.stderr`` and raise SystemExit in
- an attempt to abort the calling script.
- """
- try:
- import setuptools
- if setuptools.__version__ == '0.0.1':
- print >>sys.stderr, (
- "You have an obsolete version of setuptools installed. Please\n"
- "remove it from your system entirely before rerunning this script."
- )
- sys.exit(2)
- except ImportError:
- egg = download_setuptools(version, download_base, to_dir, download_delay)
- sys.path.insert(0, egg)
- import setuptools; setuptools.bootstrap_install_from = egg
-
- import pkg_resources
- try:
- pkg_resources.require("setuptools>="+version)
-
- except pkg_resources.VersionConflict, e:
- # XXX could we install in a subprocess here?
- print >>sys.stderr, (
- "The required version of setuptools (>=%s) is not available, and\n"
- "can't be installed while this script is running. Please install\n"
- " a more recent version first.\n\n(Currently using %r)"
- ) % (version, e.args[0])
- sys.exit(2)
+ """Automatically find/download setuptools and make it available on sys.path
+
+ `version` should be a valid setuptools version number that is available
+ as an egg for download under the `download_base` URL (which should end with
+ a '/'). `to_dir` is the directory where setuptools will be downloaded, if
+ it is not already available. If `download_delay` is specified, it should
+ be the number of seconds that will be paused before initiating a download,
+ should one be required. If an older version of setuptools is installed,
+ this routine will print a message to ``sys.stderr`` and raise SystemExit in
+ an attempt to abort the calling script.
+ """
+ try:
+ import setuptools
+ if setuptools.__version__ == '0.0.1':
+ print >>sys.stderr, (
+ "You have an obsolete version of setuptools installed. Please\n"
+ "remove it from your system entirely before rerunning this script."
+ )
+ sys.exit(2)
+ except ImportError:
+ egg = download_setuptools(version, download_base, to_dir, download_delay)
+ sys.path.insert(0, egg)
+ import setuptools; setuptools.bootstrap_install_from = egg
+
+ import pkg_resources
+ try:
+ pkg_resources.require("setuptools>="+version)
+
+ except pkg_resources.VersionConflict, e:
+ # XXX could we install in a subprocess here?
+ print >>sys.stderr, (
+ "The required version of setuptools (>=%s) is not available, and\n"
+ "can't be installed while this script is running. Please install\n"
+ " a more recent version first.\n\n(Currently using %r)"
+ ) % (version, e.args[0])
+ sys.exit(2)
def download_setuptools(
- version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
- delay = 15
+ version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+ delay = 15
):
- """Download setuptools from a specified location and return its filename
-
- `version` should be a valid setuptools version number that is available
- as an egg for download under the `download_base` URL (which should end
- with a '/'). `to_dir` is the directory where the egg will be downloaded.
- `delay` is the number of seconds to pause before an actual download attempt.
- """
- import urllib2, shutil
- egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
- url = download_base + egg_name
- saveto = os.path.join(to_dir, egg_name)
- src = dst = None
- if not os.path.exists(saveto): # Avoid repeated downloads
- try:
- from distutils import log
- if delay:
- log.warn("""
+ """Download setuptools from a specified location and return its filename
+
+ `version` should be a valid setuptools version number that is available
+ as an egg for download under the `download_base` URL (which should end
+ with a '/'). `to_dir` is the directory where the egg will be downloaded.
+ `delay` is the number of seconds to pause before an actual download attempt.
+ """
+ import urllib2, shutil
+ egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
+ url = download_base + egg_name
+ saveto = os.path.join(to_dir, egg_name)
+ src = dst = None
+ if not os.path.exists(saveto): # Avoid repeated downloads
+ try:
+ from distutils import log
+ if delay:
+ log.warn("""
---------------------------------------------------------------------------
This script requires setuptools version %s to run (even to display
-help). I will attempt to download it for you (from
+help). I will attempt to download it for you (from
%s), but
you may need to enable firewall access for this script first.
I will start the download in %d seconds.
@@ -125,96 +125,96 @@ I will start the download in %d seconds.
and place it in this directory before rerunning this script.)
---------------------------------------------------------------------------""",
- version, download_base, delay, url
- ); from time import sleep; sleep(delay)
- log.warn("Downloading %s", url)
- src = urllib2.urlopen(url)
- # Read/write all in one block, so we don't create a corrupt file
- # if the download is interrupted.
- data = _validate_md5(egg_name, src.read())
- dst = open(saveto,"wb"); dst.write(data)
- finally:
- if src: src.close()
- if dst: dst.close()
- return os.path.realpath(saveto)
+ version, download_base, delay, url
+ ); from time import sleep; sleep(delay)
+ log.warn("Downloading %s", url)
+ src = urllib2.urlopen(url)
+ # Read/write all in one block, so we don't create a corrupt file
+ # if the download is interrupted.
+ data = _validate_md5(egg_name, src.read())
+ dst = open(saveto,"wb"); dst.write(data)
+ finally:
+ if src: src.close()
+ if dst: dst.close()
+ return os.path.realpath(saveto)
def main(argv, version=DEFAULT_VERSION):
- """Install or upgrade setuptools and EasyInstall"""
-
- try:
- import setuptools
- except ImportError:
- egg = None
- try:
- egg = download_setuptools(version, delay=0)
- sys.path.insert(0,egg)
- from setuptools.command.easy_install import main
- return main(list(argv)+[egg]) # we're done here
- finally:
- if egg and os.path.exists(egg):
- os.unlink(egg)
- else:
- if setuptools.__version__ == '0.0.1':
- # tell the user to uninstall obsolete version
- use_setuptools(version)
-
- req = "setuptools>="+version
- import pkg_resources
- try:
- pkg_resources.require(req)
- except pkg_resources.VersionConflict:
- try:
- from setuptools.command.easy_install import main
- except ImportError:
- from easy_install import main
- main(list(argv)+[download_setuptools(delay=0)])
- sys.exit(0) # try to force an exit
- else:
- if argv:
- from setuptools.command.easy_install import main
- main(argv)
- else:
- print "Setuptools version",version,"or greater has been installed."
- print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
+ """Install or upgrade setuptools and EasyInstall"""
+
+ try:
+ import setuptools
+ except ImportError:
+ egg = None
+ try:
+ egg = download_setuptools(version, delay=0)
+ sys.path.insert(0,egg)
+ from setuptools.command.easy_install import main
+ return main(list(argv)+[egg]) # we're done here
+ finally:
+ if egg and os.path.exists(egg):
+ os.unlink(egg)
+ else:
+ if setuptools.__version__ == '0.0.1':
+ # tell the user to uninstall obsolete version
+ use_setuptools(version)
+
+ req = "setuptools>="+version
+ import pkg_resources
+ try:
+ pkg_resources.require(req)
+ except pkg_resources.VersionConflict:
+ try:
+ from setuptools.command.easy_install import main
+ except ImportError:
+ from easy_install import main
+ main(list(argv)+[download_setuptools(delay=0)])
+ sys.exit(0) # try to force an exit
+ else:
+ if argv:
+ from setuptools.command.easy_install import main
+ main(argv)
+ else:
+ print "Setuptools version",version,"or greater has been installed."
+ print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
def update_md5(filenames):
- """Update our built-in md5 registry"""
+ """Update our built-in md5 registry"""
- import re
- from md5 import md5
+ import re
+ from md5 import md5
- for name in filenames:
- base = os.path.basename(name)
- f = open(name,'rb')
- md5_data[base] = md5(f.read()).hexdigest()
- f.close()
+ for name in filenames:
+ base = os.path.basename(name)
+ f = open(name,'rb')
+ md5_data[base] = md5(f.read()).hexdigest()
+ f.close()
- data = [" %r: %r,\n" % it for it in md5_data.items()]
- data.sort()
- repl = "".join(data)
+ data = [" %r: %r,\n" % it for it in md5_data.items()]
+ data.sort()
+ repl = "".join(data)
- import inspect
- srcfile = inspect.getsourcefile(sys.modules[__name__])
- f = open(srcfile, 'rb'); src = f.read(); f.close()
+ import inspect
+ srcfile = inspect.getsourcefile(sys.modules[__name__])
+ f = open(srcfile, 'rb'); src = f.read(); f.close()
- match = re.search("\nmd5_data = {\n([^}]+)}", src)
- if not match:
- print >>sys.stderr, "Internal error!"
- sys.exit(2)
+ match = re.search("\nmd5_data = {\n([^}]+)}", src)
+ if not match:
+ print >>sys.stderr, "Internal error!"
+ sys.exit(2)
- src = src[:match.start(1)] + repl + src[match.end(1):]
- f = open(srcfile,'w')
- f.write(src)
- f.close()
+ src = src[:match.start(1)] + repl + src[match.end(1):]
+ f = open(srcfile,'w')
+ f.write(src)
+ f.close()
if __name__=='__main__':
- if len(sys.argv)>2 and sys.argv[1]=='--md5update':
- update_md5(sys.argv[2:])
- else:
- main(sys.argv[1:])
+ if len(sys.argv)>2 and sys.argv[1]=='--md5update':
+ update_md5(sys.argv[2:])
+ else:
+ main(sys.argv[1:])
diff --git a/lib/git/__init__.py b/lib/git/__init__.py
index 28d14d0c..45cb4673 100644
--- a/lib/git/__init__.py
+++ b/lib/git/__init__.py
@@ -24,4 +24,4 @@ from git.utils import dashify
from git.utils import touch
__all__ = [ name for name, obj in locals().items()
- if not (name.startswith('_') or inspect.ismodule(obj)) ]
+ if not (name.startswith('_') or inspect.ismodule(obj)) ]
diff --git a/lib/git/actor.py b/lib/git/actor.py
index 28f50e73..f1aeda9b 100644
--- a/lib/git/actor.py
+++ b/lib/git/actor.py
@@ -7,40 +7,40 @@
import re
class Actor(object):
- """Actors hold information about a person acting on the repository. They
- can be committers and authors or anything with a name and an email as
- mentioned in the git log entries."""
- # precompiled regex
- name_only_regex = re.compile( r'<.+>' )
- name_email_regex = re.compile( r'(.*) <(.+?)>' )
-
- def __init__(self, name, email):
- self.name = name
- self.email = email
-
- def __str__(self):
- return self.name
-
- def __repr__(self):
- return '<git.Actor "%s <%s>">' % (self.name, self.email)
-
- @classmethod
- def from_string(cls, string):
- """
- Create an Actor from a string.
-
- ``str``
- is the string, which is expected to be in regular git format
-
- Format
- John Doe <jdoe@example.com>
-
- Returns
- Actor
- """
- if cls.name_only_regex.search(string):
- m = cls.name_email_regex.search(string)
- name, email = m.groups()
- return Actor(name, email)
- else:
- return Actor(string, None)
+ """Actors hold information about a person acting on the repository. They
+ can be committers and authors or anything with a name and an email as
+ mentioned in the git log entries."""
+ # precompiled regex
+ name_only_regex = re.compile( r'<.+>' )
+ name_email_regex = re.compile( r'(.*) <(.+?)>' )
+
+ def __init__(self, name, email):
+ self.name = name
+ self.email = email
+
+ def __str__(self):
+ return self.name
+
+ def __repr__(self):
+ return '<git.Actor "%s <%s>">' % (self.name, self.email)
+
+ @classmethod
+ def from_string(cls, string):
+ """
+ Create an Actor from a string.
+
+ ``str``
+ is the string, which is expected to be in regular git format
+
+ Format
+ John Doe <jdoe@example.com>
+
+ Returns
+ Actor
+ """
+ if cls.name_only_regex.search(string):
+ m = cls.name_email_regex.search(string)
+ name, email = m.groups()
+ return Actor(name, email)
+ else:
+ return Actor(string, None)
diff --git a/lib/git/base.py b/lib/git/base.py
index 84dd0754..1f8e085d 100644
--- a/lib/git/base.py
+++ b/lib/git/base.py
@@ -6,249 +6,249 @@
import os
class LazyMixin(object):
- lazy_properties = []
-
- __slots__ = "__baked__"
-
- def __init__(self):
- self.__baked__ = False
-
- def __getattribute__(self, attr):
- val = object.__getattribute__(self, attr)
- if val is not None:
- return val
- else:
- self.__prebake__()
- return object.__getattribute__(self, attr)
-
- def __bake__(self):
- """ This method should be overridden in the derived class. """
- raise NotImplementedError(" '__bake__' method has not been implemented.")
-
- def __prebake__(self):
- if self.__baked__:
- return
- self.__bake__()
- self.__baked__ = True
-
- def __bake_it__(self):
- self.__baked__ = True
-
-
+ lazy_properties = []
+
+ __slots__ = "__baked__"
+
+ def __init__(self):
+ self.__baked__ = False
+
+ def __getattribute__(self, attr):
+ val = object.__getattribute__(self, attr)
+ if val is not None:
+ return val
+ else:
+ self.__prebake__()
+ return object.__getattribute__(self, attr)
+
+ def __bake__(self):
+ """ This method should be overridden in the derived class. """
+ raise NotImplementedError(" '__bake__' method has not been implemented.")
+
+ def __prebake__(self):
+ if self.__baked__:
+ return
+ self.__bake__()
+ self.__baked__ = True
+
+ def __bake_it__(self):
+ self.__baked__ = True
+
+
class Object(LazyMixin):
- """
- Implements an Object which may be Blobs, Trees, Commits and Tags
- """
- TYPES = ("blob", "tree", "commit", "tag")
- __slots__ = ("repo", "id", "size")
- type = None # to be set by subclass
-
- def __init__(self, repo, id, size=None):
- """
- Initialize an object by identifying it by its id. All keyword arguments
- will be set on demand if None.
-
- ``repo``
- repository this object is located in
-
- ``id``
- SHA1 or ref suitable for git-rev-parse
-
- ``size``
- Size of the object's data in bytes
- """
- super(Object,self).__init__()
- self.repo = repo
- self.id = id
- self.size = size
-
- def __bake__(self):
- """
- Retrieve object information
- """
- self.size = int(self.repo.git.cat_file(self.id, s=True).rstrip())
-
- def __eq__(self, other):
- """
- Returns
- True if the objects have the same SHA1
- """
- return self.id == other.id
-
- def __ne__(self, other):
- """
- Returns
- True if the objects do not have the same SHA1
- """
- return self.id != other.id
-
- def __hash__(self):
- """
- Returns
- Hash of our id allowing objects to be used in dicts and sets
- """
- return hash(self.id)
-
- def __str__(self):
- """
- Returns
- string of our SHA1 as understood by all git commands
- """
- return self.id
-
- def __repr__(self):
- """
- Returns
- string with pythonic representation of our object
- """
- return '<git.%s "%s">' % (self.__class__.__name__, self.id)
-
- @classmethod
- def get_type_by_name(cls, object_type_name):
- """
- Returns
- type suitable to handle the given object type name.
- Use the type to create new instances.
-
- ``object_type_name``
- Member of TYPES
-
- Raises
- ValueError: In case object_type_name is unknown
- """
- if object_type_name == "commit":
- import commit
- return commit.Commit
- elif object_type_name == "tag":
- import tag
- return tag.TagObject
- elif object_type_name == "blob":
- import blob
- return blob.Blob
- elif object_type_name == "tree":
- import tree
- return tree.Tree
- else:
- raise ValueError("Cannot handle unknown object type: %s" % object_type_name)
-
-
+ """
+ Implements an Object which may be Blobs, Trees, Commits and Tags
+ """
+ TYPES = ("blob", "tree", "commit", "tag")
+ __slots__ = ("repo", "id", "size")
+ type = None # to be set by subclass
+
+ def __init__(self, repo, id, size=None):
+ """
+ Initialize an object by identifying it by its id. All keyword arguments
+ will be set on demand if None.
+
+ ``repo``
+ repository this object is located in
+
+ ``id``
+ SHA1 or ref suitable for git-rev-parse
+
+ ``size``
+ Size of the object's data in bytes
+ """
+ super(Object,self).__init__()
+ self.repo = repo
+ self.id = id
+ self.size = size
+
+ def __bake__(self):
+ """
+ Retrieve object information
+ """
+ self.size = int(self.repo.git.cat_file(self.id, s=True).rstrip())
+
+ def __eq__(self, other):
+ """
+ Returns
+ True if the objects have the same SHA1
+ """
+ return self.id == other.id
+
+ def __ne__(self, other):
+ """
+ Returns
+ True if the objects do not have the same SHA1
+ """
+ return self.id != other.id
+
+ def __hash__(self):
+ """
+ Returns
+ Hash of our id allowing objects to be used in dicts and sets
+ """
+ return hash(self.id)
+
+ def __str__(self):
+ """
+ Returns
+ string of our SHA1 as understood by all git commands
+ """
+ return self.id
+
+ def __repr__(self):
+ """
+ Returns
+ string with pythonic representation of our object
+ """
+ return '<git.%s "%s">' % (self.__class__.__name__, self.id)
+
+ @classmethod
+ def get_type_by_name(cls, object_type_name):
+ """
+ Returns
+ type suitable to handle the given object type name.
+ Use the type to create new instances.
+
+ ``object_type_name``
+ Member of TYPES
+
+ Raises
+ ValueError: In case object_type_name is unknown
+ """
+ if object_type_name == "commit":
+ import commit
+ return commit.Commit
+ elif object_type_name == "tag":
+ import tag
+ return tag.TagObject
+ elif object_type_name == "blob":
+ import blob
+ return blob.Blob
+ elif object_type_name == "tree":
+ import tree
+ return tree.Tree
+ else:
+ raise ValueError("Cannot handle unknown object type: %s" % object_type_name)
+
+
class Ref(object):
- """
- Represents a named reference to any object
- """
- __slots__ = ("path", "object")
-
- def __init__(self, path, object = None):
- """
- Initialize this instance
-
- ``path``
- Path relative to the .git/ directory pointing to the ref in question, i.e.
- refs/heads/master
-
- ``object``
- Object instance, will be retrieved on demand if None
- """
- self.path = path
- self.object = object
-
- def __str__(self):
- return self.name()
-
- def __repr__(self):
- return '<git.%s "%s">' % (self.__class__.__name__, self.path)
-
- def __eq__(self, other):
- return self.path == other.path and self.object == other.object
-
- def __ne__(self, other):
- return not ( self == other )
-
- def __hash__(self):
- return hash(self.path)
-
- @property
- def name(self):
- """
- Returns
- Name of this reference
- """
- return os.path.basename(self.path)
-
- @classmethod
- def find_all(cls, repo, common_path = "refs", **kwargs):
- """
- Find all refs in the repository
-
- ``repo``
- is the Repo
-
- ``common_path``
- Optional keyword argument to the path which is to be shared by all
- returned Ref objects
-
- ``kwargs``
- Additional options given as keyword arguments, will be passed
- to git-for-each-ref
-
- Returns
- git.Ref[]
-
- List is sorted by committerdate
- The returned objects are compatible to the Ref base, but represent the
- actual type, such as Head or Tag
- """
-
- options = {'sort': "committerdate",
- 'format': "%(refname)%00%(objectname)%00%(objecttype)%00%(objectsize)"}
-
- options.update(kwargs)
-
- output = repo.git.for_each_ref(common_path, **options)
- return cls.list_from_string(repo, output)
-
- @classmethod
- def list_from_string(cls, repo, text):
- """
- Parse out ref information into a list of Ref compatible objects
-
- ``repo``
- is the Repo
- ``text``
- is the text output from the git-for-each-ref command
-
- Returns
- git.Ref[]
-
- list of Ref objects
- """
- heads = []
-
- for line in text.splitlines():
- heads.append(cls.from_string(repo, line))
-
- return heads
-
- @classmethod
- def from_string(cls, repo, line):
- """
- Create a new Ref instance from the given string.
-
- ``repo``
- is the Repo
-
- ``line``
- is the formatted ref information
-
- Format::
-
- name: [a-zA-Z_/]+
- <null byte>
- id: [0-9A-Fa-f]{40}
-
- Returns
- git.Head
- """
- full_path, hexsha, type_name, object_size = line.split("\x00")
- obj = Object.get_type_by_name(type_name)(repo, hexsha, object_size)
- return cls(full_path, obj)
+ """
+ Represents a named reference to any object
+ """
+ __slots__ = ("path", "object")
+
+ def __init__(self, path, object = None):
+ """
+ Initialize this instance
+
+ ``path``
+ Path relative to the .git/ directory pointing to the ref in question, i.e.
+ refs/heads/master
+
+ ``object``
+ Object instance, will be retrieved on demand if None
+ """
+ self.path = path
+ self.object = object
+
+ def __str__(self):
+ return self.name()
+
+ def __repr__(self):
+ return '<git.%s "%s">' % (self.__class__.__name__, self.path)
+
+ def __eq__(self, other):
+ return self.path == other.path and self.object == other.object
+
+ def __ne__(self, other):
+ return not ( self == other )
+
+ def __hash__(self):
+ return hash(self.path)
+
+ @property
+ def name(self):
+ """
+ Returns
+ Name of this reference
+ """
+ return os.path.basename(self.path)
+
+ @classmethod
+ def find_all(cls, repo, common_path = "refs", **kwargs):
+ """
+ Find all refs in the repository
+
+ ``repo``
+ is the Repo
+
+ ``common_path``
+ Optional keyword argument to the path which is to be shared by all
+ returned Ref objects
+
+ ``kwargs``
+ Additional options given as keyword arguments, will be passed
+ to git-for-each-ref
+
+ Returns
+ git.Ref[]
+
+ List is sorted by committerdate
+ The returned objects are compatible to the Ref base, but represent the
+ actual type, such as Head or Tag
+ """
+
+ options = {'sort': "committerdate",
+ 'format': "%(refname)%00%(objectname)%00%(objecttype)%00%(objectsize)"}
+
+ options.update(kwargs)
+
+ output = repo.git.for_each_ref(common_path, **options)
+ return cls.list_from_string(repo, output)
+
+ @classmethod
+ def list_from_string(cls, repo, text):
+ """
+ Parse out ref information into a list of Ref compatible objects
+
+ ``repo``
+ is the Repo
+ ``text``
+ is the text output from the git-for-each-ref command
+
+ Returns
+ git.Ref[]
+
+ list of Ref objects
+ """
+ heads = []
+
+ for line in text.splitlines():
+ heads.append(cls.from_string(repo, line))
+
+ return heads
+
+ @classmethod
+ def from_string(cls, repo, line):
+ """
+ Create a new Ref instance from the given string.
+
+ ``repo``
+ is the Repo
+
+ ``line``
+ is the formatted ref information
+
+ Format::
+
+ name: [a-zA-Z_/]+
+ <null byte>
+ id: [0-9A-Fa-f]{40}
+
+ Returns
+ git.Head
+ """
+ full_path, hexsha, type_name, object_size = line.split("\x00")
+ obj = Object.get_type_by_name(type_name)(repo, hexsha, object_size)
+ return cls(full_path, obj)
diff --git a/lib/git/blob.py b/lib/git/blob.py
index 3ecd3a38..d1b928cd 100644
--- a/lib/git/blob.py
+++ b/lib/git/blob.py
@@ -13,159 +13,159 @@ from commit import Commit
import base
class Blob(base.Object):
- """A Blob encapsulates a git blob object"""
- DEFAULT_MIME_TYPE = "text/plain"
- type = "blob"
- __slots__ = ("mode", "path", "_data_stored")
-
- # precompiled regex
- re_whitespace = re.compile(r'\s+')
- re_hexsha_only = re.compile('^[0-9A-Fa-f]{40}$')
- re_author_committer_start = re.compile(r'^(author|committer)')
- re_tab_full_line = re.compile(r'^\t(.*)$')
-
- def __init__(self, repo, id, mode=None, path=None):
- """
- Create an unbaked Blob containing just the specified attributes
-
- ``repo``
- is the Repo
-
- ``id``
- is the git object id
-
- ``mode``
- is the file mode
-
- ``path``
- is the path to the file
-
- Returns
- git.Blob
- """
- super(Blob,self).__init__(repo, id, "blob")
- self.mode = mode
- self.path = path
- self._data_stored = None
-
- @property
- def data(self):
- """
- The binary contents of this blob.
-
- Returns
- str
-
- NOTE
- The data will be cached after the first access.
- """
- self._data_stored = self._data_stored or self.repo.git.cat_file(self.id, p=True, with_raw_output=True)
- return self._data_stored
-
- @property
- def mime_type(self):
- """
- The mime type of this file (based on the filename)
-
- Returns
- str
-
- NOTE
- Defaults to 'text/plain' in case the actual file type is unknown.
- """
- guesses = None
- if self.path:
- guesses = mimetypes.guess_type(self.path)
- return guesses and guesses[0] or self.DEFAULT_MIME_TYPE
-
- @property
- def basename(self):
- """
- Returns
- The basename of the Blobs file path
- """
- return os.path.basename(self.path)
-
- @classmethod
- def blame(cls, repo, commit, file):
- """
- The blame information for the given file at the given commit
-
- Returns
- list: [git.Commit, list: [<line>]]
- A list of tuples associating a Commit object with a list of lines that
- changed within the given commit. The Commit objects will be given in order
- of appearance.
- """
- data = repo.git.blame(commit, '--', file, p=True)
- commits = {}
- blames = []
- info = None
-
- for line in data.splitlines():
- parts = cls.re_whitespace.split(line, 1)
- firstpart = parts[0]
- if cls.re_hexsha_only.search(firstpart):
- # handles
- # 634396b2f541a9f2d58b00be1a07f0c358b999b3 1 1 7 - indicates blame-data start
- # 634396b2f541a9f2d58b00be1a07f0c358b999b3 2 2
- digits = parts[-1].split(" ")
- if len(digits) == 3:
+ """A Blob encapsulates a git blob object"""
+ DEFAULT_MIME_TYPE = "text/plain"
+ type = "blob"
+ __slots__ = ("mode", "path", "_data_stored")
+
+ # precompiled regex
+ re_whitespace = re.compile(r'\s+')
+ re_hexsha_only = re.compile('^[0-9A-Fa-f]{40}$')
+ re_author_committer_start = re.compile(r'^(author|committer)')
+ re_tab_full_line = re.compile(r'^\t(.*)$')
+
+ def __init__(self, repo, id, mode=None, path=None):
+ """
+ Create an unbaked Blob containing just the specified attributes
+
+ ``repo``
+ is the Repo
+
+ ``id``
+ is the git object id
+
+ ``mode``
+ is the file mode
+
+ ``path``
+ is the path to the file
+
+ Returns
+ git.Blob
+ """
+ super(Blob,self).__init__(repo, id, "blob")
+ self.mode = mode
+ self.path = path
+ self._data_stored = None
+
+ @property
+ def data(self):
+ """
+ The binary contents of this blob.
+
+ Returns
+ str
+
+ NOTE
+ The data will be cached after the first access.
+ """
+ self._data_stored = self._data_stored or self.repo.git.cat_file(self.id, p=True, with_raw_output=True)
+ return self._data_stored
+
+ @property
+ def mime_type(self):
+ """
+ The mime type of this file (based on the filename)
+
+ Returns
+ str
+
+ NOTE
+ Defaults to 'text/plain' in case the actual file type is unknown.
+ """
+ guesses = None
+ if self.path:
+ guesses = mimetypes.guess_type(self.path)
+ return guesses and guesses[0] or self.DEFAULT_MIME_TYPE
+
+ @property
+ def basename(self):
+ """
+ Returns
+ The basename of the Blobs file path
+ """
+ return os.path.basename(self.path)
+
+ @classmethod
+ def blame(cls, repo, commit, file):
+ """
+ The blame information for the given file at the given commit
+
+ Returns
+ list: [git.Commit, list: [<line>]]
+ A list of tuples associating a Commit object with a list of lines that
+ changed within the given commit. The Commit objects will be given in order
+ of appearance.
+ """
+ data = repo.git.blame(commit, '--', file, p=True)
+ commits = {}
+ blames = []
+ info = None
+
+ for line in data.splitlines():
+ parts = cls.re_whitespace.split(line, 1)
+ firstpart = parts[0]
+ if cls.re_hexsha_only.search(firstpart):
+ # handles
+ # 634396b2f541a9f2d58b00be1a07f0c358b999b3 1 1 7 - indicates blame-data start
+ # 634396b2f541a9f2d58b00be1a07f0c358b999b3 2 2
+ digits = parts[-1].split(" ")
+ if len(digits) == 3:
info = {'id': firstpart}
blames.append([None, []])
# END blame data initialization
- else:
- m = cls.re_author_committer_start.search(firstpart)
- if m:
- # handles:
- # author Tom Preston-Werner
- # author-mail <tom@mojombo.com>
- # author-time 1192271832
- # author-tz -0700
- # committer Tom Preston-Werner
- # committer-mail <tom@mojombo.com>
- # committer-time 1192271832
- # committer-tz -0700 - IGNORED BY US
- role = m.group(0)
- if firstpart.endswith('-mail'):
- info["%s_email" % role] = parts[-1]
- elif firstpart.endswith('-time'):
- info["%s_date" % role] = time.gmtime(int(parts[-1]))
- elif role == firstpart:
- info[role] = parts[-1]
- # END distinguish mail,time,name
- else:
- # handle
- # filename lib/grit.rb
- # summary add Blob
- # <and rest>
- if firstpart.startswith('filename'):
- info['filename'] = parts[-1]
- elif firstpart.startswith('summary'):
- info['summary'] = parts[-1]
- elif firstpart == '':
- if info:
- sha = info['id']
- c = commits.get(sha)
- if c is None:
- c = Commit( repo, id=sha,
- author=Actor.from_string(info['author'] + ' ' + info['author_email']),
- authored_date=info['author_date'],
- committer=Actor.from_string(info['committer'] + ' ' + info['committer_email']),
- committed_date=info['committer_date'],
- message=info['summary'])
- commits[sha] = c
- # END if commit objects needs initial creation
- m = cls.re_tab_full_line.search(line)
- text, = m.groups()
- blames[-1][0] = c
- blames[-1][1].append( text )
- info = None
- # END if we collected commit info
- # END distinguish filename,summary,rest
- # END distinguish author|committer vs filename,summary,rest
- # END distinguish hexsha vs other information
- return blames
-
- def __repr__(self):
- return '<git.Blob "%s">' % self.id
+ else:
+ m = cls.re_author_committer_start.search(firstpart)
+ if m:
+ # handles:
+ # author Tom Preston-Werner
+ # author-mail <tom@mojombo.com>
+ # author-time 1192271832
+ # author-tz -0700
+ # committer Tom Preston-Werner
+ # committer-mail <tom@mojombo.com>
+ # committer-time 1192271832
+ # committer-tz -0700 - IGNORED BY US
+ role = m.group(0)
+ if firstpart.endswith('-mail'):
+ info["%s_email" % role] = parts[-1]
+ elif firstpart.endswith('-time'):
+ info["%s_date" % role] = time.gmtime(int(parts[-1]))
+ elif role == firstpart:
+ info[role] = parts[-1]
+ # END distinguish mail,time,name
+ else:
+ # handle
+ # filename lib/grit.rb
+ # summary add Blob
+ # <and rest>
+ if firstpart.startswith('filename'):
+ info['filename'] = parts[-1]
+ elif firstpart.startswith('summary'):
+ info['summary'] = parts[-1]
+ elif firstpart == '':
+ if info:
+ sha = info['id']
+ c = commits.get(sha)
+ if c is None:
+ c = Commit( repo, id=sha,
+ author=Actor.from_string(info['author'] + ' ' + info['author_email']),
+ authored_date=info['author_date'],
+ committer=Actor.from_string(info['committer'] + ' ' + info['committer_email']),
+ committed_date=info['committer_date'],
+ message=info['summary'])
+ commits[sha] = c
+ # END if commit objects needs initial creation
+ m = cls.re_tab_full_line.search(line)
+ text, = m.groups()
+ blames[-1][0] = c
+ blames[-1][1].append( text )
+ info = None
+ # END if we collected commit info
+ # END distinguish filename,summary,rest
+ # END distinguish author|committer vs filename,summary,rest
+ # END distinguish hexsha vs other information
+ return blames
+
+ def __repr__(self):
+ return '<git.Blob "%s">' % self.id
diff --git a/lib/git/cmd.py b/lib/git/cmd.py
index 21e235b1..940e35d1 100644
--- a/lib/git/cmd.py
+++ b/lib/git/cmd.py
@@ -13,208 +13,208 @@ from errors import GitCommandError
GIT_PYTHON_TRACE = os.environ.get("GIT_PYTHON_TRACE", False)
execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output',
- 'with_exceptions', 'with_raw_output')
+ 'with_exceptions', 'with_raw_output')
extra = {}
if sys.platform == 'win32':
- extra = {'shell': True}
+ extra = {'shell': True}
class Git(object):
- """
- The Git class manages communication with the Git binary.
-
+ """
+ The Git class manages communication with the Git binary.
+
It provides a convenient interface to calling the Git binary, such as in::
g = Git( git_dir )
- g.init() # calls 'git init' program
+ g.init() # calls 'git init' program
rval = g.ls_files() # calls 'git ls-files' program
``Debugging``
- Set the GIT_PYTHON_TRACE environment variable print each invocation
- of the command to stdout.
- Set its value to 'full' to see details about the returned values.
- """
- def __init__(self, git_dir=None):
- """
- Initialize this instance with:
-
- ``git_dir``
- Git directory we should work in. If None, we always work in the current
- directory as returned by os.getcwd()
- """
- super(Git, self).__init__()
- self.git_dir = git_dir
-
- def __getattr__(self, name):
- """
- A convenience method as it allows to call the command as if it was
- an object.
- Returns
- Callable object that will execute call _call_process with your arguments.
- """
- if name[:1] == '_':
- raise AttributeError(name)
- return lambda *args, **kwargs: self._call_process(name, *args, **kwargs)
-
- @property
- def get_dir(self):
- """
- Returns
- Git directory we are working on
- """
- return self.git_dir
-
- def execute(self, command,
- istream=None,
- with_keep_cwd=False,
- with_extended_output=False,
- with_exceptions=True,
- with_raw_output=False,
- ):
- """
- Handles executing the command on the shell and consumes and returns
- the returned information (stdout)
-
- ``command``
- The command argument list to execute.
- It should be a string, or a sequence of program arguments. The
- program to execute is the first item in the args sequence or string.
-
- ``istream``
- Standard input filehandle passed to subprocess.Popen.
-
- ``with_keep_cwd``
- Whether to use the current working directory from os.getcwd().
- GitPython uses get_work_tree() as its working directory by
- default and get_git_dir() for bare repositories.
-
- ``with_extended_output``
- Whether to return a (status, stdout, stderr) tuple.
-
- ``with_exceptions``
- Whether to raise an exception when git returns a non-zero status.
-
- ``with_raw_output``
- Whether to avoid stripping off trailing whitespace.
-
- Returns::
-
- str(output) # extended_output = False (Default)
- tuple(int(status), str(stdout), str(stderr)) # extended_output = True
-
- Raise
- GitCommandError
-
- NOTE
- If you add additional keyword arguments to the signature of this method,
- you must update the execute_kwargs tuple housed in this module.
- """
- if GIT_PYTHON_TRACE and not GIT_PYTHON_TRACE == 'full':
- print ' '.join(command)
-
- # Allow the user to have the command executed in their working dir.
- if with_keep_cwd or self.git_dir is None:
- cwd = os.getcwd()
- else:
- cwd=self.git_dir
-
- # Start the process
- proc = subprocess.Popen(command,
- cwd=cwd,
- stdin=istream,
- stderr=subprocess.PIPE,
- stdout=subprocess.PIPE,
- **extra
- )
-
- # Wait for the process to return
- try:
- stdout_value = proc.stdout.read()
- stderr_value = proc.stderr.read()
- status = proc.wait()
- finally:
- proc.stdout.close()
- proc.stderr.close()
-
- # Strip off trailing whitespace by default
- if not with_raw_output:
- stdout_value = stdout_value.rstrip()
- stderr_value = stderr_value.rstrip()
-
- if with_exceptions and status != 0:
- raise GitCommandError(command, status, stderr_value)
-
- if GIT_PYTHON_TRACE == 'full':
- if stderr_value:
- print "%s -> %d: '%s' !! '%s'" % (command, status, stdout_value, stderr_value)
- elif stdout_value:
- print "%s -> %d: '%s'" % (command, status, stdout_value)
- else:
- print "%s -> %d" % (command, status)
-
- # Allow access to the command's status code
- if with_extended_output:
- return (status, stdout_value, stderr_value)
- else:
- return stdout_value
-
- def transform_kwargs(self, **kwargs):
- """
- Transforms Python style kwargs into git command line options.
- """
- args = []
- for k, v in kwargs.items():
- if len(k) == 1:
- if v is True:
- args.append("-%s" % k)
- elif type(v) is not bool:
- args.append("-%s%s" % (k, v))
- else:
- if v is True:
- args.append("--%s" % dashify(k))
- elif type(v) is not bool:
- args.append("--%s=%s" % (dashify(k), v))
- return args
-
- def _call_process(self, method, *args, **kwargs):
- """
- Run the given git command with the specified arguments and return
- the result as a String
-
- ``method``
- is the command. Contained "_" characters will be converted to dashes,
- such as in 'ls_files' to call 'ls-files'.
-
- ``args``
- is the list of arguments
-
- ``kwargs``
- is a dict of keyword arguments.
- This function accepts the same optional keyword arguments
- as execute().
-
- Examples::
- git.rev_list('master', max_count=10, header=True)
-
- Returns
- Same as execute()
- """
-
- # Handle optional arguments prior to calling transform_kwargs
- # otherwise these'll end up in args, which is bad.
- _kwargs = {}
- for kwarg in execute_kwargs:
- try:
- _kwargs[kwarg] = kwargs.pop(kwarg)
- except KeyError:
- pass
-
- # Prepare the argument list
- opt_args = self.transform_kwargs(**kwargs)
- ext_args = map(str, args)
- args = opt_args + ext_args
-
- call = ["git", dashify(method)]
- call.extend(args)
-
- return self.execute(call, **_kwargs)
+ Set the GIT_PYTHON_TRACE environment variable print each invocation
+ of the command to stdout.
+ Set its value to 'full' to see details about the returned values.
+ """
+ def __init__(self, git_dir=None):
+ """
+ Initialize this instance with:
+
+ ``git_dir``
+ Git directory we should work in. If None, we always work in the current
+ directory as returned by os.getcwd()
+ """
+ super(Git, self).__init__()
+ self.git_dir = git_dir
+
+ def __getattr__(self, name):
+ """
+ A convenience method as it allows to call the command as if it was
+ an object.
+ Returns
+ Callable object that will execute call _call_process with your arguments.
+ """
+ if name[:1] == '_':
+ raise AttributeError(name)
+ return lambda *args, **kwargs: self._call_process(name, *args, **kwargs)
+
+ @property
+ def get_dir(self):
+ """
+ Returns
+ Git directory we are working on
+ """
+ return self.git_dir
+
+ def execute(self, command,
+ istream=None,
+ with_keep_cwd=False,
+ with_extended_output=False,
+ with_exceptions=True,
+ with_raw_output=False,
+ ):
+ """
+ Handles executing the command on the shell and consumes and returns
+ the returned information (stdout)
+
+ ``command``
+ The command argument list to execute.
+ It should be a string, or a sequence of program arguments. The
+ program to execute is the first item in the args sequence or string.
+
+ ``istream``
+ Standard input filehandle passed to subprocess.Popen.
+
+ ``with_keep_cwd``
+ Whether to use the current working directory from os.getcwd().
+ GitPython uses get_work_tree() as its working directory by
+ default and get_git_dir() for bare repositories.
+
+ ``with_extended_output``
+ Whether to return a (status, stdout, stderr) tuple.
+
+ ``with_exceptions``
+ Whether to raise an exception when git returns a non-zero status.
+
+ ``with_raw_output``
+ Whether to avoid stripping off trailing whitespace.
+
+ Returns::
+
+ str(output) # extended_output = False (Default)
+ tuple(int(status), str(stdout), str(stderr)) # extended_output = True
+
+ Raise
+ GitCommandError
+
+ NOTE
+ If you add additional keyword arguments to the signature of this method,
+ you must update the execute_kwargs tuple housed in this module.
+ """
+ if GIT_PYTHON_TRACE and not GIT_PYTHON_TRACE == 'full':
+ print ' '.join(command)
+
+ # Allow the user to have the command executed in their working dir.
+ if with_keep_cwd or self.git_dir is None:
+ cwd = os.getcwd()
+ else:
+ cwd=self.git_dir
+
+ # Start the process
+ proc = subprocess.Popen(command,
+ cwd=cwd,
+ stdin=istream,
+ stderr=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ **extra
+ )
+
+ # Wait for the process to return
+ try:
+ stdout_value = proc.stdout.read()
+ stderr_value = proc.stderr.read()
+ status = proc.wait()
+ finally:
+ proc.stdout.close()
+ proc.stderr.close()
+
+ # Strip off trailing whitespace by default
+ if not with_raw_output:
+ stdout_value = stdout_value.rstrip()
+ stderr_value = stderr_value.rstrip()
+
+ if with_exceptions and status != 0:
+ raise GitCommandError(command, status, stderr_value)
+
+ if GIT_PYTHON_TRACE == 'full':
+ if stderr_value:
+ print "%s -> %d: '%s' !! '%s'" % (command, status, stdout_value, stderr_value)
+ elif stdout_value:
+ print "%s -> %d: '%s'" % (command, status, stdout_value)
+ else:
+ print "%s -> %d" % (command, status)
+
+ # Allow access to the command's status code
+ if with_extended_output:
+ return (status, stdout_value, stderr_value)
+ else:
+ return stdout_value
+
+ def transform_kwargs(self, **kwargs):
+ """
+ Transforms Python style kwargs into git command line options.
+ """
+ args = []
+ for k, v in kwargs.items():
+ if len(k) == 1:
+ if v is True:
+ args.append("-%s" % k)
+ elif type(v) is not bool:
+ args.append("-%s%s" % (k, v))
+ else:
+ if v is True:
+ args.append("--%s" % dashify(k))
+ elif type(v) is not bool:
+ args.append("--%s=%s" % (dashify(k), v))
+ return args
+
+ def _call_process(self, method, *args, **kwargs):
+ """
+ Run the given git command with the specified arguments and return
+ the result as a String
+
+ ``method``
+ is the command. Contained "_" characters will be converted to dashes,
+ such as in 'ls_files' to call 'ls-files'.
+
+ ``args``
+ is the list of arguments
+
+ ``kwargs``
+ is a dict of keyword arguments.
+ This function accepts the same optional keyword arguments
+ as execute().
+
+ Examples::
+ git.rev_list('master', max_count=10, header=True)
+
+ Returns
+ Same as execute()
+ """
+
+ # Handle optional arguments prior to calling transform_kwargs
+ # otherwise these'll end up in args, which is bad.
+ _kwargs = {}
+ for kwarg in execute_kwargs:
+ try:
+ _kwargs[kwarg] = kwargs.pop(kwarg)
+ except KeyError:
+ pass
+
+ # Prepare the argument list
+ opt_args = self.transform_kwargs(**kwargs)
+ ext_args = map(str, args)
+ args = opt_args + ext_args
+
+ call = ["git", dashify(method)]
+ call.extend(args)
+
+ return self.execute(call, **_kwargs)
diff --git a/lib/git/commit.py b/lib/git/commit.py
index 73fb8e7a..1ae84799 100644
--- a/lib/git/commit.py
+++ b/lib/git/commit.py
@@ -14,281 +14,281 @@ import stats
import base
class Commit(base.Object):
- """
- Wraps a git Commit object.
-
- This class will act lazily on some of its attributes and will query the
- value on demand only if it involves calling the git binary.
- """
- # precompiled regex
- re_actor_epoch = re.compile(r'^.+? (.*) (\d+) .*$')
-
- # object configuration
- type = "commit"
-
- def __init__(self, repo, id, tree=None, author=None, authored_date=None,
- committer=None, committed_date=None, message=None, parents=None):
- """
- Instantiate a new Commit. All keyword arguments taking None as default will
- be implicitly set if id names a valid sha.
-
- The parameter documentation indicates the type of the argument after a colon ':'.
-
- ``id``
- is the sha id of the commit
-
- ``parents`` : list( Commit, ... )
- is a list of commit ids
-
- ``tree`` : Tree
- is the corresponding tree id
-
- ``author`` : Actor
- is the author string ( will be implicitly converted into an Actor object )
-
- ``authored_date`` : (tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst )
- is the authored DateTime
-
- ``committer`` : Actor
- is the committer string
-
- ``committed_date`` : (tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst)
- is the committed DateTime
-
- ``message`` : string
- is the commit message
-
- Returns
- git.Commit
- """
- super(Commit,self).__init__(repo, id, "commit")
- self.parents = None
- self.tree = None
- self.author = author
- self.authored_date = authored_date
- self.committer = committer
- self.committed_date = committed_date
- self.message = message
-
- if self.id:
- if parents is not None:
- self.parents = [Commit(repo, p) for p in parents]
- if tree is not None:
- self.tree = Tree(repo, id=tree)
-
- def __eq__(self, other):
- return self.id == other.id
-
- def __ne__(self, other):
- return self.id != other.id
-
- def __bake__(self):
- """
- Called by LazyMixin superclass when the first uninitialized member needs
- to be set as it is queried.
- """
- super(Commit, self).__bake__()
- temp = Commit.find_all(self.repo, self.id, max_count=1)[0]
- self.parents = temp.parents
- self.tree = temp.tree
- self.author = temp.author
- self.authored_date = temp.authored_date
- self.committer = temp.committer
- self.committed_date = temp.committed_date
- self.message = temp.message
-
- @property
- def id_abbrev(self):
- """
- Returns
- First 7 bytes of the commit's sha id as an abbreviation of the full string.
- """
- return self.id[0:7]
-
- @property
- def summary(self):
- """
- Returns
- First line of the commit message.
- """
- return self.message.split('\n', 1)[0]
-
- @classmethod
- def count(cls, repo, ref, path=''):
- """
- Count the number of commits reachable from this ref
-
- ``repo``
- is the Repo
-
- ``ref``
- is the ref from which to begin (SHA1 or name)
-
- ``path``
- is an optinal path
-
- Returns
- int
- """
- return len(repo.git.rev_list(ref, '--', path).strip().splitlines())
-
- @classmethod
- def find_all(cls, repo, ref, path='', **kwargs):
- """
- Find all commits matching the given criteria.
-
- ``repo``
- is the Repo
-
- ``ref``
- is the ref from which to begin (SHA1 or name)
-
- ``path``
- is an optinal path, if set only Commits that include the path
- will be considered
-
- ``kwargs``
- optional keyword arguments to git where
- ``max_count`` is the maximum number of commits to fetch
- ``skip`` is the number of commits to skip
-
- Returns
- git.Commit[]
- """
- options = {'pretty': 'raw'}
- options.update(kwargs)
-
- output = repo.git.rev_list(ref, '--', path, **options)
- return cls.list_from_string(repo, output)
-
- @classmethod
- def list_from_string(cls, repo, text):
- """
- Parse out commit information into a list of Commit objects
-
- ``repo``
- is the Repo
-
- ``text``
- is the text output from the git-rev-list command (raw format)
-
- Returns
- git.Commit[]
- """
- lines = [l for l in text.splitlines() if l.strip('\r\n')]
-
- commits = []
-
- while lines:
- id = lines.pop(0).split()[1]
- tree = lines.pop(0).split()[1]
-
- parents = []
- while lines and lines[0].startswith('parent'):
- parents.append(lines.pop(0).split()[-1])
- author, authored_date = cls._actor(lines.pop(0))
- committer, committed_date = cls._actor(lines.pop(0))
-
- messages = []
- while lines and lines[0].startswith(' '):
- messages.append(lines.pop(0).strip())
-
- message = '\n'.join(messages)
-
- commits.append(Commit(repo, id=id, parents=parents, tree=tree, author=author, authored_date=authored_date,
- committer=committer, committed_date=committed_date, message=message))
-
- return commits
-
- @classmethod
- def diff(cls, repo, a, b=None, paths=None):
- """
- Creates diffs between a tree and the index or between two trees:
-
- ``repo``
- is the Repo
-
- ``a``
- is a named commit
-
- ``b``
- is an optional named commit. Passing a list assumes you
- wish to omit the second named commit and limit the diff to the
- given paths.
-
- ``paths``
- is a list of paths to limit the diff to.
-
- Returns
- git.Diff[]::
-
- between tree and the index if only a is given
- between two trees if a and b are given and are commits
- """
- paths = paths or []
-
- if isinstance(b, list):
- paths = b
- b = None
-
- if paths:
- paths.insert(0, "--")
-
- if b:
- paths.insert(0, b)
- paths.insert(0, a)
- text = repo.git.diff('-M', full_index=True, *paths)
- return diff.Diff.list_from_string(repo, text)
-
- @property
- def diffs(self):
- """
- Returns
- git.Diff[]
- Diffs between this commit and its first parent or all changes if this
- commit is the first commit and has no parent.
- """
- if not self.parents:
- d = self.repo.git.show(self.id, '-M', full_index=True, pretty='raw')
- return diff.Diff.list_from_string(self.repo, d)
- else:
- return self.diff(self.repo, self.parents[0].id, self.id)
-
- @property
- def stats(self):
- """
- Create a git stat from changes between this commit and its first parent
- or from all changes done if this is the very first commit.
-
- Return
- git.Stats
- """
- if not self.parents:
- text = self.repo.git.diff_tree(self.id, '--', numstat=True, root=True)
- text2 = ""
- for line in text.splitlines()[1:]:
- (insertions, deletions, filename) = line.split("\t")
- text2 += "%s\t%s\t%s\n" % (insertions, deletions, filename)
- text = text2
- else:
- text = self.repo.git.diff(self.parents[0].id, self.id, '--', numstat=True)
- return stats.Stats.list_from_string(self.repo, text)
-
- def __str__(self):
- """ Convert commit to string which is SHA1 """
- return self.id
-
- def __repr__(self):
- return '<git.Commit "%s">' % self.id
-
- @classmethod
- def _actor(cls, line):
- """
- Parse out the actor (author or committer) info
-
- Returns
- [Actor, gmtime(acted at time)]
- """
- m = cls.re_actor_epoch.search(line)
- actor, epoch = m.groups()
- return (Actor.from_string(actor), time.gmtime(int(epoch)))
+ """
+ Wraps a git Commit object.
+
+ This class will act lazily on some of its attributes and will query the
+ value on demand only if it involves calling the git binary.
+ """
+ # precompiled regex
+ re_actor_epoch = re.compile(r'^.+? (.*) (\d+) .*$')
+
+ # object configuration
+ type = "commit"
+
+ def __init__(self, repo, id, tree=None, author=None, authored_date=None,
+ committer=None, committed_date=None, message=None, parents=None):
+ """
+ Instantiate a new Commit. All keyword arguments taking None as default will
+ be implicitly set if id names a valid sha.
+
+ The parameter documentation indicates the type of the argument after a colon ':'.
+
+ ``id``
+ is the sha id of the commit
+
+ ``parents`` : list( Commit, ... )
+ is a list of commit ids
+
+ ``tree`` : Tree
+ is the corresponding tree id
+
+ ``author`` : Actor
+ is the author string ( will be implicitly converted into an Actor object )
+
+ ``authored_date`` : (tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst )
+ is the authored DateTime
+
+ ``committer`` : Actor
+ is the committer string
+
+ ``committed_date`` : (tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst)
+ is the committed DateTime
+
+ ``message`` : string
+ is the commit message
+
+ Returns
+ git.Commit
+ """
+ super(Commit,self).__init__(repo, id, "commit")
+ self.parents = None
+ self.tree = None
+ self.author = author
+ self.authored_date = authored_date
+ self.committer = committer
+ self.committed_date = committed_date
+ self.message = message
+
+ if self.id:
+ if parents is not None:
+ self.parents = [Commit(repo, p) for p in parents]
+ if tree is not None:
+ self.tree = Tree(repo, id=tree)
+
+ def __eq__(self, other):
+ return self.id == other.id
+
+ def __ne__(self, other):
+ return self.id != other.id
+
+ def __bake__(self):
+ """
+ Called by LazyMixin superclass when the first uninitialized member needs
+ to be set as it is queried.
+ """
+ super(Commit, self).__bake__()
+ temp = Commit.find_all(self.repo, self.id, max_count=1)[0]
+ self.parents = temp.parents
+ self.tree = temp.tree
+ self.author = temp.author
+ self.authored_date = temp.authored_date
+ self.committer = temp.committer
+ self.committed_date = temp.committed_date
+ self.message = temp.message
+
+ @property
+ def id_abbrev(self):
+ """
+ Returns
+ First 7 bytes of the commit's sha id as an abbreviation of the full string.
+ """
+ return self.id[0:7]
+
+ @property
+ def summary(self):
+ """
+ Returns
+ First line of the commit message.
+ """
+ return self.message.split('\n', 1)[0]
+
+ @classmethod
+ def count(cls, repo, ref, path=''):
+ """
+ Count the number of commits reachable from this ref
+
+ ``repo``
+ is the Repo
+
+ ``ref``
+ is the ref from which to begin (SHA1 or name)
+
+ ``path``
+ is an optinal path
+
+ Returns
+ int
+ """
+ return len(repo.git.rev_list(ref, '--', path).strip().splitlines())
+
+ @classmethod
+ def find_all(cls, repo, ref, path='', **kwargs):
+ """
+ Find all commits matching the given criteria.
+
+ ``repo``
+ is the Repo
+
+ ``ref``
+ is the ref from which to begin (SHA1 or name)
+
+ ``path``
+ is an optinal path, if set only Commits that include the path
+ will be considered
+
+ ``kwargs``
+ optional keyword arguments to git where
+ ``max_count`` is the maximum number of commits to fetch
+ ``skip`` is the number of commits to skip
+
+ Returns
+ git.Commit[]
+ """
+ options = {'pretty': 'raw'}
+ options.update(kwargs)
+
+ output = repo.git.rev_list(ref, '--', path, **options)
+ return cls.list_from_string(repo, output)
+
+ @classmethod
+ def list_from_string(cls, repo, text):
+ """
+ Parse out commit information into a list of Commit objects
+
+ ``repo``
+ is the Repo
+
+ ``text``
+ is the text output from the git-rev-list command (raw format)
+
+ Returns
+ git.Commit[]
+ """
+ lines = [l for l in text.splitlines() if l.strip('\r\n')]
+
+ commits = []
+
+ while lines:
+ id = lines.pop(0).split()[1]
+ tree = lines.pop(0).split()[1]
+
+ parents = []
+ while lines and lines[0].startswith('parent'):
+ parents.append(lines.pop(0).split()[-1])
+ author, authored_date = cls._actor(lines.pop(0))
+ committer, committed_date = cls._actor(lines.pop(0))
+
+ messages = []
+ while lines and lines[0].startswith(' '):
+ messages.append(lines.pop(0).strip())
+
+ message = '\n'.join(messages)
+
+ commits.append(Commit(repo, id=id, parents=parents, tree=tree, author=author, authored_date=authored_date,
+ committer=committer, committed_date=committed_date, message=message))
+
+ return commits
+
+ @classmethod
+ def diff(cls, repo, a, b=None, paths=None):
+ """
+ Creates diffs between a tree and the index or between two trees:
+
+ ``repo``
+ is the Repo
+
+ ``a``
+ is a named commit
+
+ ``b``
+ is an optional named commit. Passing a list assumes you
+ wish to omit the second named commit and limit the diff to the
+ given paths.
+
+ ``paths``
+ is a list of paths to limit the diff to.
+
+ Returns
+ git.Diff[]::
+
+ between tree and the index if only a is given
+ between two trees if a and b are given and are commits
+ """
+ paths = paths or []
+
+ if isinstance(b, list):
+ paths = b
+ b = None
+
+ if paths:
+ paths.insert(0, "--")
+
+ if b:
+ paths.insert(0, b)
+ paths.insert(0, a)
+ text = repo.git.diff('-M', full_index=True, *paths)
+ return diff.Diff.list_from_string(repo, text)
+
+ @property
+ def diffs(self):
+ """
+ Returns
+ git.Diff[]
+ Diffs between this commit and its first parent or all changes if this
+ commit is the first commit and has no parent.
+ """
+ if not self.parents:
+ d = self.repo.git.show(self.id, '-M', full_index=True, pretty='raw')
+ return diff.Diff.list_from_string(self.repo, d)
+ else:
+ return self.diff(self.repo, self.parents[0].id, self.id)
+
+ @property
+ def stats(self):
+ """
+ Create a git stat from changes between this commit and its first parent
+ or from all changes done if this is the very first commit.
+
+ Return
+ git.Stats
+ """
+ if not self.parents:
+ text = self.repo.git.diff_tree(self.id, '--', numstat=True, root=True)
+ text2 = ""
+ for line in text.splitlines()[1:]:
+ (insertions, deletions, filename) = line.split("\t")
+ text2 += "%s\t%s\t%s\n" % (insertions, deletions, filename)
+ text = text2
+ else:
+ text = self.repo.git.diff(self.parents[0].id, self.id, '--', numstat=True)
+ return stats.Stats.list_from_string(self.repo, text)
+
+ def __str__(self):
+ """ Convert commit to string which is SHA1 """
+ return self.id
+
+ def __repr__(self):
+ return '<git.Commit "%s">' % self.id
+
+ @classmethod
+ def _actor(cls, line):
+ """
+ Parse out the actor (author or committer) info
+
+ Returns
+ [Actor, gmtime(acted at time)]
+ """
+ m = cls.re_actor_epoch.search(line)
+ actor, epoch = m.groups()
+ return (Actor.from_string(actor), time.gmtime(int(epoch)))
diff --git a/lib/git/diff.py b/lib/git/diff.py
index 75450d70..ef58cb0e 100644
--- a/lib/git/diff.py
+++ b/lib/git/diff.py
@@ -8,30 +8,30 @@ import re
import blob
class Diff(object):
- """
- A Diff contains diff information between two commits.
-
- It contains two sides a and b of the diff, members are prefixed with
- "a" and "b" respectively to inidcate that.
-
- Diffs keep information about the changed blob objects, the file mode, renames,
- deletions and new files.
-
- There are a few cases where None has to be expected as member variable value:
-
- ``New File``::
-
- a_mode is None
- a_blob is None
-
- ``Deleted File``::
-
- b_mode is None
- b_blob is NOne
- """
-
- # precompiled regex
- re_header = re.compile(r"""
+ """
+ A Diff contains diff information between two commits.
+
+ It contains two sides a and b of the diff, members are prefixed with
+ "a" and "b" respectively to inidcate that.
+
+ Diffs keep information about the changed blob objects, the file mode, renames,
+ deletions and new files.
+
+ There are a few cases where None has to be expected as member variable value:
+
+ ``New File``::
+
+ a_mode is None
+ a_blob is None
+
+ ``Deleted File``::
+
+ b_mode is None
+ b_blob is NOne
+ """
+
+ # precompiled regex
+ re_header = re.compile(r"""
#^diff[ ]--git
[ ]a/(?P<a_path>\S+)[ ]b/(?P<b_path>\S+)\n
(?:^similarity[ ]index[ ](?P<similarity_index>\d+)%\n
@@ -44,58 +44,58 @@ class Diff(object):
(?:^index[ ](?P<a_blob_id>[0-9A-Fa-f]+)
\.\.(?P<b_blob_id>[0-9A-Fa-f]+)[ ]?(?P<b_mode>.+)?(?:\n|$))?
""", re.VERBOSE | re.MULTILINE)
- re_is_null_hexsha = re.compile( r'^0{40}$' )
+ re_is_null_hexsha = re.compile( r'^0{40}$' )
- def __init__(self, repo, a_path, b_path, a_blob_id, b_blob_id, a_mode,
- b_mode, new_file, deleted_file, rename_from,
- rename_to, diff):
- self.repo = repo
+ def __init__(self, repo, a_path, b_path, a_blob_id, b_blob_id, a_mode,
+ b_mode, new_file, deleted_file, rename_from,
+ rename_to, diff):
+ self.repo = repo
- if not a_blob_id or self.re_is_null_hexsha.search(a_blob_id):
- self.a_blob = None
- else:
- self.a_blob = blob.Blob(repo, id=a_blob_id, mode=a_mode, path=a_path)
- if not b_blob_id or self.re_is_null_hexsha.search(b_blob_id):
- self.b_blob = None
- else:
- self.b_blob = blob.Blob(repo, id=b_blob_id, mode=b_mode, path=b_path)
+ if not a_blob_id or self.re_is_null_hexsha.search(a_blob_id):
+ self.a_blob = None
+ else:
+ self.a_blob = blob.Blob(repo, id=a_blob_id, mode=a_mode, path=a_path)
+ if not b_blob_id or self.re_is_null_hexsha.search(b_blob_id):
+ self.b_blob = None
+ else:
+ self.b_blob = blob.Blob(repo, id=b_blob_id, mode=b_mode, path=b_path)
- self.a_mode = a_mode
- self.b_mode = b_mode
- self.new_file = new_file
- self.deleted_file = deleted_file
- self.rename_from = rename_from
- self.rename_to = rename_to
- self.renamed = rename_from != rename_to
- self.diff = diff
+ self.a_mode = a_mode
+ self.b_mode = b_mode
+ self.new_file = new_file
+ self.deleted_file = deleted_file
+ self.rename_from = rename_from
+ self.rename_to = rename_to
+ self.renamed = rename_from != rename_to
+ self.diff = diff
- @classmethod
- def list_from_string(cls, repo, text):
- """
- Create a new diff object from the given text
- ``repo``
- is the repository we are operating on - it is required
-
- ``text``
- result of 'git diff' between two commits or one commit and the index
-
- Returns
- git.Diff[]
- """
- diffs = []
+ @classmethod
+ def list_from_string(cls, repo, text):
+ """
+ Create a new diff object from the given text
+ ``repo``
+ is the repository we are operating on - it is required
+
+ ``text``
+ result of 'git diff' between two commits or one commit and the index
+
+ Returns
+ git.Diff[]
+ """
+ diffs = []
- diff_header = cls.re_header.match
- for diff in ('\n' + text).split('\ndiff --git')[1:]:
- header = diff_header(diff)
+ diff_header = cls.re_header.match
+ for diff in ('\n' + text).split('\ndiff --git')[1:]:
+ header = diff_header(diff)
- a_path, b_path, similarity_index, rename_from, rename_to, \
- old_mode, new_mode, new_file_mode, deleted_file_mode, \
- a_blob_id, b_blob_id, b_mode = header.groups()
- new_file, deleted_file = bool(new_file_mode), bool(deleted_file_mode)
+ a_path, b_path, similarity_index, rename_from, rename_to, \
+ old_mode, new_mode, new_file_mode, deleted_file_mode, \
+ a_blob_id, b_blob_id, b_mode = header.groups()
+ new_file, deleted_file = bool(new_file_mode), bool(deleted_file_mode)
- diffs.append(Diff(repo, a_path, b_path, a_blob_id, b_blob_id,
- old_mode or deleted_file_mode, new_mode or new_file_mode or b_mode,
- new_file, deleted_file, rename_from, rename_to, diff[header.end():]))
+ diffs.append(Diff(repo, a_path, b_path, a_blob_id, b_blob_id,
+ old_mode or deleted_file_mode, new_mode or new_file_mode or b_mode,
+ new_file, deleted_file, rename_from, rename_to, diff[header.end():]))
- return diffs
+ return diffs
diff --git a/lib/git/errors.py b/lib/git/errors.py
index 45afb590..e9a637c0 100644
--- a/lib/git/errors.py
+++ b/lib/git/errors.py
@@ -8,25 +8,25 @@ Module containing all exceptions thrown througout the git package,
"""
class InvalidGitRepositoryError(Exception):
- """
- Thrown if the given repository appears to have an invalid format.
- """
+ """
+ Thrown if the given repository appears to have an invalid format.
+ """
class NoSuchPathError(OSError):
- """
- Thrown if a path could not be access by the system.
- """
+ """
+ Thrown if a path could not be access by the system.
+ """
class GitCommandError(Exception):
- """
- Thrown if execution of the git command fails with non-zero status code.
- """
- def __init__(self, command, status, stderr=None):
- self.stderr = stderr
- self.status = status
- self.command = command
+ """
+ Thrown if execution of the git command fails with non-zero status code.
+ """
+ def __init__(self, command, status, stderr=None):
+ self.stderr = stderr
+ self.status = status
+ self.command = command
- def __str__(self):
- return repr("%s returned exit status %d" %
- (str(self.command), self.status))
+ def __str__(self):
+ return repr("%s returned exit status %d" %
+ (str(self.command), self.status))
diff --git a/lib/git/head.py b/lib/git/head.py
index 3c3f13ac..f4e94637 100644
--- a/lib/git/head.py
+++ b/lib/git/head.py
@@ -8,56 +8,56 @@ import commit
import base
class Head(base.Ref):
- """
- A Head is a named reference to a Commit. Every Head instance contains a name
- and a Commit object.
-
- Examples::
-
- >>> repo = Repo("/path/to/repo")
- >>> head = repo.heads[0]
-
- >>> head.name
- 'master'
-
- >>> head.commit
- <git.Commit "1c09f116cbc2cb4100fb6935bb162daa4723f455">
-
- >>> head.commit.id
- '1c09f116cbc2cb4100fb6935bb162daa4723f455'
- """
-
- def __init__(self, path, commit):
- """
- Initialize a newly instanced Head
-
- ``path``
- is the path to the head ref, relative to the .git directory, i.e.
- refs/heads/master
-
- `commit`
- is the Commit object that the head points to
- """
- super(Head, self).__init__(name, commit)
-
-
- @property
- def commit(self):
- """
- Returns
- Commit object the head points to
- """
- return self.object
-
- @classmethod
- def find_all(cls, repo, common_path = "refs/heads", **kwargs):
- """
- Returns
- git.Head[]
-
- For more documentation, please refer to git.base.Ref.find_all
- """
- return super(Head,cls).find_all(repo, common_path, **kwargs)
-
- def __repr__(self):
- return '<git.Head "%s">' % self.name
+ """
+ A Head is a named reference to a Commit. Every Head instance contains a name
+ and a Commit object.
+
+ Examples::
+
+ >>> repo = Repo("/path/to/repo")
+ >>> head = repo.heads[0]
+
+ >>> head.name
+ 'master'
+
+ >>> head.commit
+ <git.Commit "1c09f116cbc2cb4100fb6935bb162daa4723f455">
+
+ >>> head.commit.id
+ '1c09f116cbc2cb4100fb6935bb162daa4723f455'
+ """
+
+ def __init__(self, path, commit):
+ """
+ Initialize a newly instanced Head
+
+ ``path``
+ is the path to the head ref, relative to the .git directory, i.e.
+ refs/heads/master
+
+ `commit`
+ is the Commit object that the head points to
+ """
+ super(Head, self).__init__(name, commit)
+
+
+ @property
+ def commit(self):
+ """
+ Returns
+ Commit object the head points to
+ """
+ return self.object
+
+ @classmethod
+ def find_all(cls, repo, common_path = "refs/heads", **kwargs):
+ """
+ Returns
+ git.Head[]
+
+ For more documentation, please refer to git.base.Ref.find_all
+ """
+ return super(Head,cls).find_all(repo, common_path, **kwargs)
+
+ def __repr__(self):
+ return '<git.Head "%s">' % self.name
diff --git a/lib/git/repo.py b/lib/git/repo.py
index 811cf6f0..3c872218 100644
--- a/lib/git/repo.py
+++ b/lib/git/repo.py
@@ -17,496 +17,496 @@ from commit import Commit
from tree import Tree
class Repo(object):
- """
- Represents a git repository and allows you to query references,
- gather commit information, generate diffs, create and clone repositories query
- the log.
- """
- DAEMON_EXPORT_FILE = 'git-daemon-export-ok'
-
- def __init__(self, path=None):
- """
- Create a new Repo instance
-
- ``path``
- is the path to either the root git directory or the bare git repo
-
- Examples::
-
- repo = Repo("/Users/mtrier/Development/git-python")
- repo = Repo("/Users/mtrier/Development/git-python.git")
-
- Raises
- InvalidGitRepositoryError or NoSuchPathError
-
- Returns
- ``git.Repo``
- """
-
- epath = os.path.abspath(os.path.expanduser(path or os.getcwd()))
-
- if not os.path.exists(epath):
- raise NoSuchPathError(epath)
-
- self.path = None
- curpath = epath
- while curpath:
- if is_git_dir(curpath):
- self.bare = True
- self.path = curpath
- self.wd = curpath
- break
- gitpath = os.path.join(curpath, '.git')
- if is_git_dir(gitpath):
- self.bare = False
- self.path = gitpath
- self.wd = curpath
- break
- curpath, dummy = os.path.split(curpath)
- if not dummy:
- break
-
- if self.path is None:
- raise InvalidGitRepositoryError(epath)
-
- self.git = Git(self.wd)
-
- # Description property
- def _get_description(self):
- filename = os.path.join(self.path, 'description')
- return file(filename).read().rstrip()
-
- def _set_description(self, descr):
- filename = os.path.join(self.path, 'description')
- file(filename, 'w').write(descr+'\n')
-
- description = property(_get_description, _set_description,
- doc="the project's description")
- del _get_description
- del _set_description
-
- @property
- def heads(self):
- """
- A list of ``Head`` objects representing the branch heads in
- this repo
-
- Returns
- ``git.Head[]``
- """
- return Head.find_all(self)
-
- # alias heads
- branches = heads
-
- @property
- def tags(self):
- """
- A list of ``Tag`` objects that are available in this repo
-
- Returns
- ``git.Tag[]``
- """
- return Tag.find_all(self)
-
- def commits(self, start='master', path='', max_count=10, skip=0):
- """
- A list of Commit objects representing the history of a given ref/commit
-
- ``start``
- is the branch/commit name (default 'master')
-
- ``path``
- is an optional path to limit the returned commits to
- Commits that do not contain that path will not be returned.
-
- ``max_count``
- is the maximum number of commits to return (default 10)
+ """
+ Represents a git repository and allows you to query references,
+ gather commit information, generate diffs, create and clone repositories query
+ the log.
+ """
+ DAEMON_EXPORT_FILE = 'git-daemon-export-ok'
- ``skip``
- is the number of commits to skip (default 0) which will effectively
- move your commit-window by the given number.
+ def __init__(self, path=None):
+ """
+ Create a new Repo instance
- Returns
- ``git.Commit[]``
- """
- options = {'max_count': max_count,
- 'skip': skip}
+ ``path``
+ is the path to either the root git directory or the bare git repo
- return Commit.find_all(self, start, path, **options)
+ Examples::
- def commits_between(self, frm, to):
- """
- The Commits objects that are reachable via ``to`` but not via ``frm``
- Commits are returned in chronological order.
+ repo = Repo("/Users/mtrier/Development/git-python")
+ repo = Repo("/Users/mtrier/Development/git-python.git")
- ``from``
- is the branch/commit name of the younger item
+ Raises
+ InvalidGitRepositoryError or NoSuchPathError
+
+ Returns
+ ``git.Repo``
+ """
+
+ epath = os.path.abspath(os.path.expanduser(path or os.getcwd()))
+
+ if not os.path.exists(epath):
+ raise NoSuchPathError(epath)
+
+ self.path = None
+ curpath = epath
+ while curpath:
+ if is_git_dir(curpath):
+ self.bare = True
+ self.path = curpath
+ self.wd = curpath
+ break
+ gitpath = os.path.join(curpath, '.git')
+ if is_git_dir(gitpath):
+ self.bare = False
+ self.path = gitpath
+ self.wd = curpath
+ break
+ curpath, dummy = os.path.split(curpath)
+ if not dummy:
+ break
+
+ if self.path is None:
+ raise InvalidGitRepositoryError(epath)
+
+ self.git = Git(self.wd)
+
+ # Description property
+ def _get_description(self):
+ filename = os.path.join(self.path, 'description')
+ return file(filename).read().rstrip()
+
+ def _set_description(self, descr):
+ filename = os.path.join(self.path, 'description')
+ file(filename, 'w').write(descr+'\n')
+
+ description = property(_get_description, _set_description,
+ doc="the project's description")
+ del _get_description
+ del _set_description
+
+ @property
+ def heads(self):
+ """
+ A list of ``Head`` objects representing the branch heads in
+ this repo
+
+ Returns
+ ``git.Head[]``
+ """
+ return Head.find_all(self)
+
+ # alias heads
+ branches = heads
+
+ @property
+ def tags(self):
+ """
+ A list of ``Tag`` objects that are available in this repo
+
+ Returns
+ ``git.Tag[]``
+ """
+ return Tag.find_all(self)
+
+ def commits(self, start='master', path='', max_count=10, skip=0):
+ """
+ A list of Commit objects representing the history of a given ref/commit
+
+ ``start``
+ is the branch/commit name (default 'master')
+
+ ``path``
+ is an optional path to limit the returned commits to
+ Commits that do not contain that path will not be returned.
+
+ ``max_count``
+ is the maximum number of commits to return (default 10)
+
+ ``skip``
+ is the number of commits to skip (default 0) which will effectively
+ move your commit-window by the given number.
+
+ Returns
+ ``git.Commit[]``
+ """
+ options = {'max_count': max_count,
+ 'skip': skip}
+
+ return Commit.find_all(self, start, path, **options)
+
+ def commits_between(self, frm, to):
+ """
+ The Commits objects that are reachable via ``to`` but not via ``frm``
+ Commits are returned in chronological order.
+
+ ``from``
+ is the branch/commit name of the younger item
+
+ ``to``
+ is the branch/commit name of the older item
+
+ Returns
+ ``git.Commit[]``
+ """
+ return reversed(Commit.find_all(self, "%s..%s" % (frm, to)))
+
+ def commits_since(self, start='master', path='', since='1970-01-01'):
+ """
+ The Commits objects that are newer than the specified date.
+ Commits are returned in chronological order.
+
+ ``start``
+ is the branch/commit name (default 'master')
+
+ ``path``
+ is an optinal path to limit the returned commits to.
+
+
+ ``since``
+ is a string represeting a date/time
+
+ Returns
+ ``git.Commit[]``
+ """
+ options = {'since': since}
+
+ return Commit.find_all(self, start, path, **options)
+
+ def commit_count(self, start='master', path=''):
+ """
+ The number of commits reachable by the given branch/commit
+
+ ``start``
+ is the branch/commit name (default 'master')
+
+ ``path``
+ is an optional path
+ Commits that do not contain the path will not contribute to the count.
+
+ Returns
+ ``int``
+ """
+ return Commit.count(self, start, path)
+
+ def commit(self, id, path = ''):
+ """
+ The Commit object for the specified id
- ``to``
- is the branch/commit name of the older item
-
- Returns
- ``git.Commit[]``
- """
- return reversed(Commit.find_all(self, "%s..%s" % (frm, to)))
-
- def commits_since(self, start='master', path='', since='1970-01-01'):
- """
- The Commits objects that are newer than the specified date.
- Commits are returned in chronological order.
+ ``id``
+ is the SHA1 identifier of the commit
- ``start``
- is the branch/commit name (default 'master')
+ ``path``
+ is an optional path, if set the returned commit must contain the path.
- ``path``
- is an optinal path to limit the returned commits to.
-
+ Returns
+ ``git.Commit``
+ """
+ options = {'max_count': 1}
- ``since``
- is a string represeting a date/time
+ commits = Commit.find_all(self, id, path, **options)
- Returns
- ``git.Commit[]``
- """
- options = {'since': since}
+ if not commits:
+ raise ValueError, "Invalid identifier %s, or given path '%s' too restrictive" % ( id, path )
+ return commits[0]
- return Commit.find_all(self, start, path, **options)
-
- def commit_count(self, start='master', path=''):
- """
- The number of commits reachable by the given branch/commit
-
- ``start``
- is the branch/commit name (default 'master')
+ def commit_deltas_from(self, other_repo, ref='master', other_ref='master'):
+ """
+ Returns a list of commits that is in ``other_repo`` but not in self
- ``path``
- is an optional path
- Commits that do not contain the path will not contribute to the count.
-
- Returns
- ``int``
- """
- return Commit.count(self, start, path)
-
- def commit(self, id, path = ''):
- """
- The Commit object for the specified id
-
- ``id``
- is the SHA1 identifier of the commit
-
- ``path``
- is an optional path, if set the returned commit must contain the path.
-
- Returns
- ``git.Commit``
- """
- options = {'max_count': 1}
-
- commits = Commit.find_all(self, id, path, **options)
-
- if not commits:
- raise ValueError, "Invalid identifier %s, or given path '%s' too restrictive" % ( id, path )
- return commits[0]
-
- def commit_deltas_from(self, other_repo, ref='master', other_ref='master'):
- """
- Returns a list of commits that is in ``other_repo`` but not in self
-
- Returns
- git.Commit[]
- """
- repo_refs = self.git.rev_list(ref, '--').strip().splitlines()
- other_repo_refs = other_repo.git.rev_list(other_ref, '--').strip().splitlines()
+ Returns
+ git.Commit[]
+ """
+ repo_refs = self.git.rev_list(ref, '--').strip().splitlines()
+ other_repo_refs = other_repo.git.rev_list(other_ref, '--').strip().splitlines()
- diff_refs = list(set(other_repo_refs) - set(repo_refs))
- return map(lambda ref: Commit.find_all(other_repo, ref, max_count=1)[0], diff_refs)
+ diff_refs = list(set(other_repo_refs) - set(repo_refs))
+ return map(lambda ref: Commit.find_all(other_repo, ref, max_count=1)[0], diff_refs)
- def tree(self, treeish='master'):
- """
- The Tree object for the given treeish reference
+ def tree(self, treeish='master'):
+ """
+ The Tree object for the given treeish reference
- ``treeish``
- is the reference (default 'master')
+ ``treeish``
+ is the reference (default 'master')
- Examples::
+ Examples::
- repo.tree('master')
+ repo.tree('master')
- Returns
- ``git.Tree``
- """
- return Tree(self, id=treeish)
+ Returns
+ ``git.Tree``
+ """
+ return Tree(self, id=treeish)
+
+ def blob(self, id):
+ """
+ The Blob object for the given id
+
+ ``id``
+ is the SHA1 id of the blob
+
+ Returns
+ ``git.Blob``
+ """
+ return Blob(self, id=id)
+
+ def log(self, commit='master', path=None, **kwargs):
+ """
+ The Commit for a treeish, and all commits leading to it.
+
+ ``kwargs``
+ keyword arguments specifying flags to be used in git-log command,
+ i.e.: max_count=1 to limit the amount of commits returned
+
+ Returns
+ ``git.Commit[]``
+ """
+ options = {'pretty': 'raw'}
+ options.update(kwargs)
+ arg = [commit, '--']
+ if path:
+ arg.append(path)
+ commits = self.git.log(*arg, **options)
+ return Commit.list_from_string(self, commits)
+
+ def diff(self, a, b, *paths):
+ """
+ The diff from commit ``a`` to commit ``b``, optionally restricted to the given file(s)
+
+ ``a``
+ is the base commit
+ ``b``
+ is the other commit
+
+ ``paths``
+ is an optional list of file paths on which to restrict the diff
+
+ Returns
+ ``str``
+ """
+ return self.git.diff(a, b, '--', *paths)
+
+ def commit_diff(self, commit):
+ """
+ The commit diff for the given commit
+ ``commit`` is the commit name/id
- def blob(self, id):
- """
- The Blob object for the given id
-
- ``id``
- is the SHA1 id of the blob
-
- Returns
- ``git.Blob``
- """
- return Blob(self, id=id)
-
- def log(self, commit='master', path=None, **kwargs):
- """
- The Commit for a treeish, and all commits leading to it.
-
- ``kwargs``
- keyword arguments specifying flags to be used in git-log command,
- i.e.: max_count=1 to limit the amount of commits returned
+ Returns
+ ``git.Diff[]``
+ """
+ return Commit.diff(self, commit)
- Returns
- ``git.Commit[]``
- """
- options = {'pretty': 'raw'}
- options.update(kwargs)
- arg = [commit, '--']
- if path:
- arg.append(path)
- commits = self.git.log(*arg, **options)
- return Commit.list_from_string(self, commits)
+ @classmethod
+ def init_bare(self, path, mkdir=True, **kwargs):
+ """
+ Initialize a bare git repository at the given path
- def diff(self, a, b, *paths):
- """
- The diff from commit ``a`` to commit ``b``, optionally restricted to the given file(s)
-
- ``a``
- is the base commit
- ``b``
- is the other commit
+ ``path``
+ is the full path to the repo (traditionally ends with /<name>.git)
- ``paths``
- is an optional list of file paths on which to restrict the diff
-
- Returns
- ``str``
- """
- return self.git.diff(a, b, '--', *paths)
+ ``mkdir``
+ if specified will create the repository directory if it doesn't
+ already exists. Creates the directory with a mode=0755.
- def commit_diff(self, commit):
- """
- The commit diff for the given commit
- ``commit`` is the commit name/id
+ ``kwargs``
+ keyword arguments serving as additional options to the git init command
- Returns
- ``git.Diff[]``
- """
- return Commit.diff(self, commit)
+ Examples::
- @classmethod
- def init_bare(self, path, mkdir=True, **kwargs):
- """
- Initialize a bare git repository at the given path
+ git.Repo.init_bare('/var/git/myrepo.git')
- ``path``
- is the full path to the repo (traditionally ends with /<name>.git)
-
- ``mkdir``
- if specified will create the repository directory if it doesn't
- already exists. Creates the directory with a mode=0755.
-
- ``kwargs``
- keyword arguments serving as additional options to the git init command
-
- Examples::
-
- git.Repo.init_bare('/var/git/myrepo.git')
-
- Returns
- ``git.Repo`` (the newly created repo)
- """
-
- if mkdir and not os.path.exists(path):
- os.makedirs(path, 0755)
-
- git = Git(path)
- output = git.init('--bare', **kwargs)
- return Repo(path)
- create = init_bare
-
- def fork_bare(self, path, **kwargs):
- """
- Fork a bare git repository from this repo
-
- ``path``
- is the full path of the new repo (traditionally ends with /<name>.git)
-
- ``kwargs``
- keyword arguments to be given to the git clone command
-
- Returns
- ``git.Repo`` (the newly forked repo)
- """
- options = {'bare': True}
- options.update(kwargs)
- self.git.clone(self.path, path, **options)
- return Repo(path)
-
- def archive_tar(self, treeish='master', prefix=None):
- """
- Archive the given treeish
-
- ``treeish``
- is the treeish name/id (default 'master')
-
- ``prefix``
- is the optional prefix to prepend to each filename in the archive
-
- Examples::
-
- >>> repo.archive_tar
- <String containing tar archive>
-
- >>> repo.archive_tar('a87ff14')
- <String containing tar archive for commit a87ff14>
-
- >>> repo.archive_tar('master', 'myproject/')
- <String containing tar bytes archive, whose files are prefixed with 'myproject/'>
-
- Returns
- str (containing bytes of tar archive)
- """
- options = {}
- if prefix:
- options['prefix'] = prefix
- return self.git.archive(treeish, **options)
-
- def archive_tar_gz(self, treeish='master', prefix=None):
- """
- Archive and gzip the given treeish
-
- ``treeish``
- is the treeish name/id (default 'master')
-
- ``prefix``
- is the optional prefix to prepend to each filename in the archive
-
- Examples::
-
- >>> repo.archive_tar_gz
- <String containing tar.gz archive>
-
- >>> repo.archive_tar_gz('a87ff14')
- <String containing tar.gz archive for commit a87ff14>
-
- >>> repo.archive_tar_gz('master', 'myproject/')
- <String containing tar.gz archive and prefixed with 'myproject/'>
-
- Returns
- str (containing the bytes of tar.gz archive)
- """
- kwargs = {}
- if prefix:
- kwargs['prefix'] = prefix
- resultstr = self.git.archive(treeish, **kwargs)
- sio = StringIO.StringIO()
- gf = gzip.GzipFile(fileobj=sio, mode ='wb')
- gf.write(resultstr)
- gf.close()
- return sio.getvalue()
-
- def _get_daemon_export(self):
- filename = os.path.join(self.path, self.DAEMON_EXPORT_FILE)
- return os.path.exists(filename)
-
- def _set_daemon_export(self, value):
- filename = os.path.join(self.path, self.DAEMON_EXPORT_FILE)
- fileexists = os.path.exists(filename)
- if value and not fileexists:
- touch(filename)
- elif not value and fileexists:
- os.unlink(filename)
-
- daemon_export = property(_get_daemon_export, _set_daemon_export,
- doc="If True, git-daemon may export this repository")
- del _get_daemon_export
- del _set_daemon_export
-
- def _get_alternates(self):
- """
- The list of alternates for this repo from which objects can be retrieved
-
- Returns
- list of strings being pathnames of alternates
- """
- alternates_path = os.path.join(self.path, 'objects', 'info', 'alternates')
-
- if os.path.exists(alternates_path):
- try:
- f = open(alternates_path)
- alts = f.read()
- finally:
- f.close()
- return alts.strip().splitlines()
- else:
- return []
-
- def _set_alternates(self, alts):
- """
- Sets the alternates
-
- ``alts``
- is the array of string paths representing the alternates at which
- git should look for objects, i.e. /home/user/repo/.git/objects
+ Returns
+ ``git.Repo`` (the newly created repo)
+ """
+
+ if mkdir and not os.path.exists(path):
+ os.makedirs(path, 0755)
+
+ git = Git(path)
+ output = git.init('--bare', **kwargs)
+ return Repo(path)
+ create = init_bare
+
+ def fork_bare(self, path, **kwargs):
+ """
+ Fork a bare git repository from this repo
+
+ ``path``
+ is the full path of the new repo (traditionally ends with /<name>.git)
+
+ ``kwargs``
+ keyword arguments to be given to the git clone command
+
+ Returns
+ ``git.Repo`` (the newly forked repo)
+ """
+ options = {'bare': True}
+ options.update(kwargs)
+ self.git.clone(self.path, path, **options)
+ return Repo(path)
+
+ def archive_tar(self, treeish='master', prefix=None):
+ """
+ Archive the given treeish
+
+ ``treeish``
+ is the treeish name/id (default 'master')
+
+ ``prefix``
+ is the optional prefix to prepend to each filename in the archive
+
+ Examples::
+
+ >>> repo.archive_tar
+ <String containing tar archive>
+
+ >>> repo.archive_tar('a87ff14')
+ <String containing tar archive for commit a87ff14>
+
+ >>> repo.archive_tar('master', 'myproject/')
+ <String containing tar bytes archive, whose files are prefixed with 'myproject/'>
+
+ Returns
+ str (containing bytes of tar archive)
+ """
+ options = {}
+ if prefix:
+ options['prefix'] = prefix
+ return self.git.archive(treeish, **options)
+
+ def archive_tar_gz(self, treeish='master', prefix=None):
+ """
+ Archive and gzip the given treeish
+
+ ``treeish``
+ is the treeish name/id (default 'master')
+
+ ``prefix``
+ is the optional prefix to prepend to each filename in the archive
+
+ Examples::
+
+ >>> repo.archive_tar_gz
+ <String containing tar.gz archive>
+
+ >>> repo.archive_tar_gz('a87ff14')
+ <String containing tar.gz archive for commit a87ff14>
+
+ >>> repo.archive_tar_gz('master', 'myproject/')
+ <String containing tar.gz archive and prefixed with 'myproject/'>
+
+ Returns
+ str (containing the bytes of tar.gz archive)
+ """
+ kwargs = {}
+ if prefix:
+ kwargs['prefix'] = prefix
+ resultstr = self.git.archive(treeish, **kwargs)
+ sio = StringIO.StringIO()
+ gf = gzip.GzipFile(fileobj=sio, mode ='wb')
+ gf.write(resultstr)
+ gf.close()
+ return sio.getvalue()
+
+ def _get_daemon_export(self):
+ filename = os.path.join(self.path, self.DAEMON_EXPORT_FILE)
+ return os.path.exists(filename)
+
+ def _set_daemon_export(self, value):
+ filename = os.path.join(self.path, self.DAEMON_EXPORT_FILE)
+ fileexists = os.path.exists(filename)
+ if value and not fileexists:
+ touch(filename)
+ elif not value and fileexists:
+ os.unlink(filename)
+
+ daemon_export = property(_get_daemon_export, _set_daemon_export,
+ doc="If True, git-daemon may export this repository")
+ del _get_daemon_export
+ del _set_daemon_export
+
+ def _get_alternates(self):
+ """
+ The list of alternates for this repo from which objects can be retrieved
+
+ Returns
+ list of strings being pathnames of alternates
+ """
+ alternates_path = os.path.join(self.path, 'objects', 'info', 'alternates')
+
+ if os.path.exists(alternates_path):
+ try:
+ f = open(alternates_path)
+ alts = f.read()
+ finally:
+ f.close()
+ return alts.strip().splitlines()
+ else:
+ return []
+
+ def _set_alternates(self, alts):
+ """
+ Sets the alternates
+
+ ``alts``
+ is the array of string paths representing the alternates at which
+ git should look for objects, i.e. /home/user/repo/.git/objects
Raises
NoSuchPathError
- Returns
- None
- """
- for alt in alts:
- if not os.path.exists(alt):
- raise NoSuchPathError("Could not set alternates. Alternate path %s must exist" % alt)
-
- if not alts:
- os.remove(os.path.join(self.path, 'objects', 'info', 'alternates'))
- else:
- try:
- f = open(os.path.join(self.path, 'objects', 'info', 'alternates'), 'w')
- f.write("\n".join(alts))
- finally:
- f.close()
-
- alternates = property(_get_alternates, _set_alternates, doc="Retrieve a list of alternates paths or set a list paths to be used as alternates")
-
- @property
- def is_dirty(self):
- """
- Return the status of the index.
-
- Returns
- ``True``, if the index has any uncommitted changes,
- otherwise ``False``
+ Returns
+ None
+ """
+ for alt in alts:
+ if not os.path.exists(alt):
+ raise NoSuchPathError("Could not set alternates. Alternate path %s must exist" % alt)
+
+ if not alts:
+ os.remove(os.path.join(self.path, 'objects', 'info', 'alternates'))
+ else:
+ try:
+ f = open(os.path.join(self.path, 'objects', 'info', 'alternates'), 'w')
+ f.write("\n".join(alts))
+ finally:
+ f.close()
+
+ alternates = property(_get_alternates, _set_alternates, doc="Retrieve a list of alternates paths or set a list paths to be used as alternates")
+
+ @property
+ def is_dirty(self):
+ """
+ Return the status of the index.
+
+ Returns
+ ``True``, if the index has any uncommitted changes,
+ otherwise ``False``
NOTE
Working tree changes that have not been staged will not be detected !
- """
- if self.bare:
- # Bare repositories with no associated working directory are
- # always consired to be clean.
- return False
-
- return len(self.git.diff('HEAD', '--').strip()) > 0
-
- @property
- def active_branch(self):
- """
- The name of the currently active branch.
-
- Returns
- str (the branch name)
- """
- branch = self.git.symbolic_ref('HEAD').strip()
- if branch.startswith('refs/heads/'):
- branch = branch[len('refs/heads/'):]
-
- return branch
-
- def __repr__(self):
- return '<git.Repo "%s">' % self.path
+ """
+ if self.bare:
+ # Bare repositories with no associated working directory are
+ # always consired to be clean.
+ return False
+
+ return len(self.git.diff('HEAD', '--').strip()) > 0
+
+ @property
+ def active_branch(self):
+ """
+ The name of the currently active branch.
+
+ Returns
+ str (the branch name)
+ """
+ branch = self.git.symbolic_ref('HEAD').strip()
+ if branch.startswith('refs/heads/'):
+ branch = branch[len('refs/heads/'):]
+
+ return branch
+
+ def __repr__(self):
+ return '<git.Repo "%s">' % self.path
diff --git a/lib/git/stats.py b/lib/git/stats.py
index 307e2f2f..a39d1dab 100644
--- a/lib/git/stats.py
+++ b/lib/git/stats.py
@@ -5,55 +5,55 @@
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
class Stats(object):
- """
- Represents stat information as presented by git at the end of a merge. It is
- created from the output of a diff operation.
-
- ``Example``::
-
- c = Commit( sha1 )
- s = c.stats
- s.total # full-stat-dict
- s.files # dict( filepath : stat-dict )
-
- ``stat-dict``
-
- A dictionary with the following keys and values::
-
- deletions = number of deleted lines as int
- insertions = number of inserted lines as int
- lines = total number of lines changed as int, or deletions + insertions
-
- ``full-stat-dict``
-
- In addition to the items in the stat-dict, it features additional information::
-
- files = number of changed files as int
-
- """
- def __init__(self, repo, total, files):
- self.repo = repo
- self.total = total
- self.files = files
+ """
+ Represents stat information as presented by git at the end of a merge. It is
+ created from the output of a diff operation.
+
+ ``Example``::
+
+ c = Commit( sha1 )
+ s = c.stats
+ s.total # full-stat-dict
+ s.files # dict( filepath : stat-dict )
+
+ ``stat-dict``
+
+ A dictionary with the following keys and values::
+
+ deletions = number of deleted lines as int
+ insertions = number of inserted lines as int
+ lines = total number of lines changed as int, or deletions + insertions
+
+ ``full-stat-dict``
+
+ In addition to the items in the stat-dict, it features additional information::
+
+ files = number of changed files as int
+
+ """
+ def __init__(self, repo, total, files):
+ self.repo = repo
+ self.total = total
+ self.files = files
- @classmethod
- def list_from_string(cls, repo, text):
- """
- Create a Stat object from output retrieved by git-diff.
-
- Returns
- git.Stat
- """
- hsh = {'total': {'insertions': 0, 'deletions': 0, 'lines': 0, 'files': 0}, 'files': {}}
- for line in text.splitlines():
- (raw_insertions, raw_deletions, filename) = line.split("\t")
- insertions = raw_insertions != '-' and int(raw_insertions) or 0
- deletions = raw_deletions != '-' and int(raw_deletions) or 0
- hsh['total']['insertions'] += insertions
- hsh['total']['deletions'] += deletions
- hsh['total']['lines'] += insertions + deletions
- hsh['total']['files'] += 1
- hsh['files'][filename.strip()] = {'insertions': insertions,
- 'deletions': deletions,
- 'lines': insertions + deletions}
- return Stats(repo, hsh['total'], hsh['files'])
+ @classmethod
+ def list_from_string(cls, repo, text):
+ """
+ Create a Stat object from output retrieved by git-diff.
+
+ Returns
+ git.Stat
+ """
+ hsh = {'total': {'insertions': 0, 'deletions': 0, 'lines': 0, 'files': 0}, 'files': {}}
+ for line in text.splitlines():
+ (raw_insertions, raw_deletions, filename) = line.split("\t")
+ insertions = raw_insertions != '-' and int(raw_insertions) or 0
+ deletions = raw_deletions != '-' and int(raw_deletions) or 0
+ hsh['total']['insertions'] += insertions
+ hsh['total']['deletions'] += deletions
+ hsh['total']['lines'] += insertions + deletions
+ hsh['total']['files'] += 1
+ hsh['files'][filename.strip()] = {'insertions': insertions,
+ 'deletions': deletions,
+ 'lines': insertions + deletions}
+ return Stats(repo, hsh['total'], hsh['files'])
diff --git a/lib/git/tag.py b/lib/git/tag.py
index 0c4122ab..4266a7a9 100644
--- a/lib/git/tag.py
+++ b/lib/git/tag.py
@@ -8,121 +8,121 @@ import commit
import base
class TagRef(base.Ref):
- """
- Class representing a lightweight tag reference which either points to a commit
- or to a tag object. In the latter case additional information, like the signature
- or the tag-creator, is available.
-
- This tag object will always point to a commit object, but may carray additional
- information in a tag object::
-
- tagref = TagRef.find_all(repo)[0]
- print tagref.commit.message
- if tagref.tag is not None:
- print tagref.tag.message
- """
-
- __slots__ = "tag"
-
- def __init__(self, path, commit_or_tag):
- """
- Initialize a newly instantiated Tag
+ """
+ Class representing a lightweight tag reference which either points to a commit
+ or to a tag object. In the latter case additional information, like the signature
+ or the tag-creator, is available.
+
+ This tag object will always point to a commit object, but may carray additional
+ information in a tag object::
+
+ tagref = TagRef.find_all(repo)[0]
+ print tagref.commit.message
+ if tagref.tag is not None:
+ print tagref.tag.message
+ """
+
+ __slots__ = "tag"
+
+ def __init__(self, path, commit_or_tag):
+ """
+ Initialize a newly instantiated Tag
- ``path``
- is the full path to the tag
+ ``path``
+ is the full path to the tag
- ``commit_or_tag``
- is the Commit or TagObject that this tag ref points to
- """
- super(TagRef, self).__init__(path, commit_or_tag)
- self.tag = None
-
- if commit_or_tag.type == "tag":
- self.tag = commit_or_tag
- # END tag object handling
-
- @property
- def commit(self):
- """
- Returns
- Commit object the tag ref points to
- """
- if self.object.type == "commit":
- return self.object
- # it is a tag object
- return self.object.object
+ ``commit_or_tag``
+ is the Commit or TagObject that this tag ref points to
+ """
+ super(TagRef, self).__init__(path, commit_or_tag)
+ self.tag = None
+
+ if commit_or_tag.type == "tag":
+ self.tag = commit_or_tag
+ # END tag object handling
+
+ @property
+ def commit(self):
+ """
+ Returns
+ Commit object the tag ref points to
+ """
+ if self.object.type == "commit":
+ return self.object
+ # it is a tag object
+ return self.object.object
- @classmethod
- def find_all(cls, repo, common_path = "refs/tags", **kwargs):
- """
- Returns
- git.Tag[]
-
- For more documentation, please refer to git.base.Ref.find_all
- """
- return super(TagRef,cls).find_all(repo, common_path, **kwargs)
-
-
+ @classmethod
+ def find_all(cls, repo, common_path = "refs/tags", **kwargs):
+ """
+ Returns
+ git.Tag[]
+
+ For more documentation, please refer to git.base.Ref.find_all
+ """
+ return super(TagRef,cls).find_all(repo, common_path, **kwargs)
+
+
# provide an alias
Tag = TagRef
-
+
class TagObject(base.Object):
- """
- Non-Lightweight tag carrying additional information about an object we are pointing
- to.
- """
- type = "tag"
- __slots__ = ( "object", "tag", "tagger", "tagged_date", "message" )
-
- def __init__(self, repo, id, size=None, object=None, tag=None,
- tagger=None, tagged_date=None, message=None):
- """
- Initialize a tag object with additional data
-
- ``repo``
- repository this object is located in
-
- ``id``
- SHA1 or ref suitable for git-rev-parse
-
- ``size``
- Size of the object's data in bytes
-
- ``object``
- Object instance of object we are pointing to
-
- ``tag``
- name of this tag
-
- ``tagger``
- Actor identifying the tagger
-
- ``tagged_date`` : (tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst)
- is the DateTime of the tag creation
- """
- super(TagObject, self).__init__(repo, id , size)
- self.object = object
- self.tag = tag
- self.tagger = tagger
- self.tagged_date = tagged_date
- self.message = message
-
- def __bake__(self):
- super(TagObject, self).__bake__()
-
- output = self.repo.git.cat_file(self.type,self.id)
- lines = output.split("\n")
-
- obj, hexsha = lines[0].split(" ") # object <hexsha>
- type_token, type_name = lines[1].split(" ") # type <type_name>
- self.object = base.Object.get_type_by_name(type_name)(self.repo, hexsha)
-
- self.tag = lines[2][4:] # tag <tag name>
-
- tagger_info = lines[3][7:]# tagger <actor> <date>
- self.tagger, self.tagged_date = commit.Commit._actor(tagger_info)
-
- # line 4 empty - check git source to figure out purpose
- self.message = "\n".join(lines[5:])
-
-
+ """
+ Non-Lightweight tag carrying additional information about an object we are pointing
+ to.
+ """
+ type = "tag"
+ __slots__ = ( "object", "tag", "tagger", "tagged_date", "message" )
+
+ def __init__(self, repo, id, size=None, object=None, tag=None,
+ tagger=None, tagged_date=None, message=None):
+ """
+ Initialize a tag object with additional data
+
+ ``repo``
+ repository this object is located in
+
+ ``id``
+ SHA1 or ref suitable for git-rev-parse
+
+ ``size``
+ Size of the object's data in bytes
+
+ ``object``
+ Object instance of object we are pointing to
+
+ ``tag``
+ name of this tag
+
+ ``tagger``
+ Actor identifying the tagger
+
+ ``tagged_date`` : (tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst)
+ is the DateTime of the tag creation
+ """
+ super(TagObject, self).__init__(repo, id , size)
+ self.object = object
+ self.tag = tag
+ self.tagger = tagger
+ self.tagged_date = tagged_date
+ self.message = message
+
+ def __bake__(self):
+ super(TagObject, self).__bake__()
+
+ output = self.repo.git.cat_file(self.type,self.id)
+ lines = output.split("\n")
+
+ obj, hexsha = lines[0].split(" ") # object <hexsha>
+ type_token, type_name = lines[1].split(" ") # type <type_name>
+ self.object = base.Object.get_type_by_name(type_name)(self.repo, hexsha)
+
+ self.tag = lines[2][4:] # tag <tag name>
+
+ tagger_info = lines[3][7:]# tagger <actor> <date>
+ self.tagger, self.tagged_date = commit.Commit._actor(tagger_info)
+
+ # line 4 empty - check git source to figure out purpose
+ self.message = "\n".join(lines[5:])
+
+
diff --git a/lib/git/tree.py b/lib/git/tree.py
index 6215f875..3d4deb16 100644
--- a/lib/git/tree.py
+++ b/lib/git/tree.py
@@ -9,97 +9,97 @@ import blob
import base
class Tree(base.Object):
-
- type = "tree"
-
- def __init__(self, repo, id, mode=None, path=None):
- super(Tree, self).__init__(repo, id)
- self.mode = mode
- self.path = path
- self._contents = None
-
- def __bake__(self):
- # Read the tree contents.
- super(Tree, self).__bake__()
- self._contents = {}
- for line in self.repo.git.ls_tree(self.id).splitlines():
- obj = self.content_from_string(self.repo, line)
- if obj is not None:
- self._contents[obj.path] = obj
-
- @staticmethod
- def content_from_string(repo, text):
- """
- Parse a content item and create the appropriate object
-
- ``repo``
- is the Repo
-
- ``text``
- is the single line containing the items data in `git ls-tree` format
-
- Returns
- ``git.Blob`` or ``git.Tree``
- """
- try:
- mode, typ, id, path = text.expandtabs(1).split(" ", 3)
- except:
- return None
-
- if typ == "tree":
- return Tree(repo, id=id, mode=mode, path=path)
- elif typ == "blob":
- return blob.Blob(repo, id=id, mode=mode, path=path)
- elif typ == "commit":
- return None
- else:
- raise(TypeError, "Invalid type: %s" % typ)
-
- def __div__(self, file):
- """
- Find the named object in this tree's contents
-
- Examples::
-
- >>> Repo('/path/to/python-git').tree/'lib'
- <git.Tree "6cc23ee138be09ff8c28b07162720018b244e95e">
- >>> Repo('/path/to/python-git').tree/'README.txt'
- <git.Blob "8b1e02c0fb554eed2ce2ef737a68bb369d7527df">
-
- Returns
- ``git.Blob`` or ``git.Tree`` or ``None`` if not found
- """
- return self.get(file)
-
- @property
- def basename(self):
- os.path.basename(self.path)
-
- def __repr__(self):
- return '<git.Tree "%s">' % self.id
-
- # Implement the basics of the dict protocol:
- # directories/trees can be seen as object dicts.
- def __getitem__(self, key):
- return self._contents[key]
-
- def __iter__(self):
- return iter(self._contents)
-
- def __len__(self):
- return len(self._contents)
-
- def __contains__(self, key):
- return key in self._contents
-
- def get(self, key):
- return self._contents.get(key)
-
- def items(self):
- return self._contents.items()
-
- def keys(self):
- return self._contents.keys()
-
- def values(self):
- return self._contents.values()
+
+ type = "tree"
+
+ def __init__(self, repo, id, mode=None, path=None):
+ super(Tree, self).__init__(repo, id)
+ self.mode = mode
+ self.path = path
+ self._contents = None
+
+ def __bake__(self):
+ # Read the tree contents.
+ super(Tree, self).__bake__()
+ self._contents = {}
+ for line in self.repo.git.ls_tree(self.id).splitlines():
+ obj = self.content_from_string(self.repo, line)
+ if obj is not None:
+ self._contents[obj.path] = obj
+
+ @staticmethod
+ def content_from_string(repo, text):
+ """
+ Parse a content item and create the appropriate object
+
+ ``repo``
+ is the Repo
+
+ ``text``
+ is the single line containing the items data in `git ls-tree` format
+
+ Returns
+ ``git.Blob`` or ``git.Tree``
+ """
+ try:
+ mode, typ, id, path = text.expandtabs(1).split(" ", 3)
+ except:
+ return None
+
+ if typ == "tree":
+ return Tree(repo, id=id, mode=mode, path=path)
+ elif typ == "blob":
+ return blob.Blob(repo, id=id, mode=mode, path=path)
+ elif typ == "commit":
+ return None
+ else:
+ raise(TypeError, "Invalid type: %s" % typ)
+
+ def __div__(self, file):
+ """
+ Find the named object in this tree's contents
+
+ Examples::
+
+ >>> Repo('/path/to/python-git').tree/'lib'
+ <git.Tree "6cc23ee138be09ff8c28b07162720018b244e95e">
+ >>> Repo('/path/to/python-git').tree/'README.txt'
+ <git.Blob "8b1e02c0fb554eed2ce2ef737a68bb369d7527df">
+
+ Returns
+ ``git.Blob`` or ``git.Tree`` or ``None`` if not found
+ """
+ return self.get(file)
+
+ @property
+ def basename(self):
+ os.path.basename(self.path)
+
+ def __repr__(self):
+ return '<git.Tree "%s">' % self.id
+
+ # Implement the basics of the dict protocol:
+ # directories/trees can be seen as object dicts.
+ def __getitem__(self, key):
+ return self._contents[key]
+
+ def __iter__(self):
+ return iter(self._contents)
+
+ def __len__(self):
+ return len(self._contents)
+
+ def __contains__(self, key):
+ return key in self._contents
+
+ def get(self, key):
+ return self._contents.get(key)
+
+ def items(self):
+ return self._contents.items()
+
+ def keys(self):
+ return self._contents.keys()
+
+ def values(self):
+ return self._contents.values()
diff --git a/lib/git/utils.py b/lib/git/utils.py
index 5d0ba8ca..c204c432 100644
--- a/lib/git/utils.py
+++ b/lib/git/utils.py
@@ -7,20 +7,20 @@
import os
def dashify(string):
- return string.replace('_', '-')
+ return string.replace('_', '-')
def touch(filename):
- os.utime(filename)
+ os.utime(filename)
def is_git_dir(d):
- """ This is taken from the git setup.c:is_git_directory
- function."""
+ """ This is taken from the git setup.c:is_git_directory
+ function."""
- if os.path.isdir(d) and \
- os.path.isdir(os.path.join(d, 'objects')) and \
- os.path.isdir(os.path.join(d, 'refs')):
- headref = os.path.join(d, 'HEAD')
- return os.path.isfile(headref) or \
- (os.path.islink(headref) and
- os.readlink(headref).startswith('refs'))
- return False
+ if os.path.isdir(d) and \
+ os.path.isdir(os.path.join(d, 'objects')) and \
+ os.path.isdir(os.path.join(d, 'refs')):
+ headref = os.path.join(d, 'HEAD')
+ return os.path.isfile(headref) or \
+ (os.path.islink(headref) and
+ os.readlink(headref).startswith('refs'))
+ return False
diff --git a/setup.py b/setup.py
index 8df94a33..9d483310 100644
--- a/setup.py
+++ b/setup.py
@@ -1,9 +1,9 @@
try:
- from setuptools import setup, find_packages
+ from setuptools import setup, find_packages
except ImportError:
- from ez_setup import use_setuptools
- use_setuptools()
- from setuptools import setup, find_packages
+ from ez_setup import use_setuptools
+ use_setuptools()
+ from setuptools import setup, find_packages
from distutils.command.build_py import build_py as _build_py
from setuptools.command.sdist import sdist as _sdist
@@ -15,52 +15,52 @@ VERSION = v.readline().strip()
v.close()
class build_py(_build_py):
- def run(self):
- init = path.join(self.build_lib, 'git', '__init__.py')
- if path.exists(init):
- os.unlink(init)
- _build_py.run(self)
- _stamp_version(init)
- self.byte_compile([init])
+ def run(self):
+ init = path.join(self.build_lib, 'git', '__init__.py')
+ if path.exists(init):
+ os.unlink(init)
+ _build_py.run(self)
+ _stamp_version(init)
+ self.byte_compile([init])
class sdist(_sdist):
- def make_release_tree (self, base_dir, files):
- _sdist.make_release_tree(self, base_dir, files)
- orig = path.join('lib', 'git', '__init__.py')
- assert path.exists(orig)
- dest = path.join(base_dir, orig)
- if hasattr(os, 'link') and path.exists(dest):
- os.unlink(dest)
- self.copy_file(orig, dest)
- _stamp_version(dest)
+ def make_release_tree (self, base_dir, files):
+ _sdist.make_release_tree(self, base_dir, files)
+ orig = path.join('lib', 'git', '__init__.py')
+ assert path.exists(orig)
+ dest = path.join(base_dir, orig)
+ if hasattr(os, 'link') and path.exists(dest):
+ os.unlink(dest)
+ self.copy_file(orig, dest)
+ _stamp_version(dest)
def _stamp_version(filename):
- found, out = False, []
- f = open(filename, 'r')
- for line in f:
- if '__version__ =' in line:
- line = line.replace("'git'", "'%s'" % VERSION)
- found = True
- out.append(line)
- f.close()
+ found, out = False, []
+ f = open(filename, 'r')
+ for line in f:
+ if '__version__ =' in line:
+ line = line.replace("'git'", "'%s'" % VERSION)
+ found = True
+ out.append(line)
+ f.close()
- if found:
- f = open(filename, 'w')
- f.writelines(out)
- f.close()
+ if found:
+ f = open(filename, 'w')
+ f.writelines(out)
+ f.close()
setup(name = "GitPython",
- cmdclass={'build_py': build_py, 'sdist': sdist},
- version = VERSION,
- description = "Python Git Library",
- author = "Michael Trier",
- author_email = "mtrier@gmail.com",
- url = "http://gitorious.org/projects/git-python/",
- packages = find_packages('lib'),
- package_dir = {'':'lib'},
- license = "BSD License",
- long_description = """\
+ cmdclass={'build_py': build_py, 'sdist': sdist},
+ version = VERSION,
+ description = "Python Git Library",
+ author = "Michael Trier",
+ author_email = "mtrier@gmail.com",
+ url = "http://gitorious.org/projects/git-python/",
+ packages = find_packages('lib'),
+ package_dir = {'':'lib'},
+ license = "BSD License",
+ long_description = """\
GitPython is a python library used to interact with Git repositories.
GitPython provides object model access to your git repository. Once you have
@@ -70,14 +70,14 @@ trees, blobs, etc.
GitPython is a port of the grit library in Ruby created by
Tom Preston-Werner and Chris Wanstrath.
""",
- classifiers = [
- "Development Status :: 3 - Alpha",
- "Intended Audience :: Developers",
- "License :: OSI Approved :: BSD License",
- "Operating System :: OS Independent",
- "Programming Language :: Python",
- "Programming Language :: Python :: 2.5",
- "Programming Language :: Python :: 2.6",
- "Topic :: Software Development :: Libraries :: Python Modules",
- ]
- )
+ classifiers = [
+ "Development Status :: 3 - Alpha",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: BSD License",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 2.5",
+ "Programming Language :: Python :: 2.6",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ ]
+ )
diff --git a/test/git/test_actor.py b/test/git/test_actor.py
index 862010fc..ae4da507 100644
--- a/test/git/test_actor.py
+++ b/test/git/test_actor.py
@@ -9,20 +9,20 @@ from test.testlib import *
from git import *
class TestActor(object):
- def test_from_string_should_separate_name_and_email(self):
- a = Actor.from_string("Michael Trier <mtrier@example.com>")
- assert_equal("Michael Trier", a.name)
- assert_equal("mtrier@example.com", a.email)
+ def test_from_string_should_separate_name_and_email(self):
+ a = Actor.from_string("Michael Trier <mtrier@example.com>")
+ assert_equal("Michael Trier", a.name)
+ assert_equal("mtrier@example.com", a.email)
- def test_from_string_should_handle_just_name(self):
- a = Actor.from_string("Michael Trier")
- assert_equal("Michael Trier", a.name)
- assert_equal(None, a.email)
+ def test_from_string_should_handle_just_name(self):
+ a = Actor.from_string("Michael Trier")
+ assert_equal("Michael Trier", a.name)
+ assert_equal(None, a.email)
- def test_should_display_representation(self):
- a = Actor.from_string("Michael Trier <mtrier@example.com>")
- assert_equal('<git.Actor "Michael Trier <mtrier@example.com>">', repr(a))
+ def test_should_display_representation(self):
+ a = Actor.from_string("Michael Trier <mtrier@example.com>")
+ assert_equal('<git.Actor "Michael Trier <mtrier@example.com>">', repr(a))
- def test_str_should_alias_name(self):
- a = Actor.from_string("Michael Trier <mtrier@example.com>")
- assert_equal(a.name, str(a)) \ No newline at end of file
+ def test_str_should_alias_name(self):
+ a = Actor.from_string("Michael Trier <mtrier@example.com>")
+ assert_equal(a.name, str(a)) \ No newline at end of file
diff --git a/test/git/test_blob.py b/test/git/test_blob.py
index 8741fc1d..e2ac22e1 100644
--- a/test/git/test_blob.py
+++ b/test/git/test_blob.py
@@ -9,89 +9,89 @@ from test.testlib import *
from git import *
class TestBlob(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
-
- @patch_object(Git, '_call_process')
- def test_should_return_blob_contents(self, git):
- git.return_value = fixture('cat_file_blob')
- blob = Blob(self.repo, **{'id': 'abc'})
- assert_equal("Hello world", blob.data)
- assert_true(git.called)
- assert_equal(git.call_args, (('cat_file', 'abc'), {'p': True, 'with_raw_output': True}))
+ def setup(self):
+ self.repo = Repo(GIT_REPO)
+
+ @patch_object(Git, '_call_process')
+ def test_should_return_blob_contents(self, git):
+ git.return_value = fixture('cat_file_blob')
+ blob = Blob(self.repo, **{'id': 'abc'})
+ assert_equal("Hello world", blob.data)
+ assert_true(git.called)
+ assert_equal(git.call_args, (('cat_file', 'abc'), {'p': True, 'with_raw_output': True}))
- @patch_object(Git, '_call_process')
- def test_should_return_blob_contents_with_newline(self, git):
- git.return_value = fixture('cat_file_blob_nl')
- blob = Blob(self.repo, **{'id': 'abc'})
- assert_equal("Hello world\n", blob.data)
- assert_true(git.called)
- assert_equal(git.call_args, (('cat_file', 'abc'), {'p': True, 'with_raw_output': True}))
-
- @patch_object(Git, '_call_process')
- def test_should_cache_data(self, git):
- git.return_value = fixture('cat_file_blob')
- blob = Blob(self.repo, **{'id': 'abc'})
- blob.data
- blob.data
- assert_true(git.called)
- assert_equal(git.call_count, 1)
- assert_equal(git.call_args, (('cat_file', 'abc'), {'p': True, 'with_raw_output': True}))
+ @patch_object(Git, '_call_process')
+ def test_should_return_blob_contents_with_newline(self, git):
+ git.return_value = fixture('cat_file_blob_nl')
+ blob = Blob(self.repo, **{'id': 'abc'})
+ assert_equal("Hello world\n", blob.data)
+ assert_true(git.called)
+ assert_equal(git.call_args, (('cat_file', 'abc'), {'p': True, 'with_raw_output': True}))
+
+ @patch_object(Git, '_call_process')
+ def test_should_cache_data(self, git):
+ git.return_value = fixture('cat_file_blob')
+ blob = Blob(self.repo, **{'id': 'abc'})
+ blob.data
+ blob.data
+ assert_true(git.called)
+ assert_equal(git.call_count, 1)
+ assert_equal(git.call_args, (('cat_file', 'abc'), {'p': True, 'with_raw_output': True}))
- @patch_object(Git, '_call_process')
- def test_should_return_file_size(self, git):
- git.return_value = fixture('cat_file_blob_size')
- blob = Blob(self.repo, **{'id': 'abc'})
- assert_equal(11, blob.size)
- assert_true(git.called)
- assert_equal(git.call_args, (('cat_file', 'abc'), {'s': True}))
+ @patch_object(Git, '_call_process')
+ def test_should_return_file_size(self, git):
+ git.return_value = fixture('cat_file_blob_size')
+ blob = Blob(self.repo, **{'id': 'abc'})
+ assert_equal(11, blob.size)
+ assert_true(git.called)
+ assert_equal(git.call_args, (('cat_file', 'abc'), {'s': True}))
- @patch_object(Git, '_call_process')
- def test_should_cache_file_size(self, git):
- git.return_value = fixture('cat_file_blob_size')
- blob = Blob(self.repo, **{'id': 'abc'})
- assert_equal(11, blob.size)
- assert_equal(11, blob.size)
- assert_true(git.called)
- assert_equal(git.call_count, 1)
- assert_equal(git.call_args, (('cat_file', 'abc'), {'s': True}))
+ @patch_object(Git, '_call_process')
+ def test_should_cache_file_size(self, git):
+ git.return_value = fixture('cat_file_blob_size')
+ blob = Blob(self.repo, **{'id': 'abc'})
+ assert_equal(11, blob.size)
+ assert_equal(11, blob.size)
+ assert_true(git.called)
+ assert_equal(git.call_count, 1)
+ assert_equal(git.call_args, (('cat_file', 'abc'), {'s': True}))
- def test_mime_type_should_return_mime_type_for_known_types(self):
- blob = Blob(self.repo, **{'id': 'abc', 'path': 'foo.png'})
- assert_equal("image/png", blob.mime_type)
+ def test_mime_type_should_return_mime_type_for_known_types(self):
+ blob = Blob(self.repo, **{'id': 'abc', 'path': 'foo.png'})
+ assert_equal("image/png", blob.mime_type)
- def test_mime_type_should_return_text_plain_for_unknown_types(self):
- blob = Blob(self.repo, **{'id': 'abc'})
- assert_equal("text/plain", blob.mime_type)
+ def test_mime_type_should_return_text_plain_for_unknown_types(self):
+ blob = Blob(self.repo, **{'id': 'abc'})
+ assert_equal("text/plain", blob.mime_type)
- @patch_object(Git, '_call_process')
- def test_should_display_blame_information(self, git):
- git.return_value = fixture('blame')
- b = Blob.blame(self.repo, 'master', 'lib/git.py')
- assert_equal(13, len(b))
- assert_equal( 2, len(b[0]) )
- # assert_equal(25, reduce(lambda acc, x: acc + len(x[-1]), b))
- assert_equal(hash(b[0][0]), hash(b[9][0]))
- c = b[0][0]
- assert_true(git.called)
- assert_equal(git.call_args, (('blame', 'master', '--', 'lib/git.py'), {'p': True}))
-
- assert_equal('634396b2f541a9f2d58b00be1a07f0c358b999b3', c.id)
- assert_equal('Tom Preston-Werner', c.author.name)
- assert_equal('tom@mojombo.com', c.author.email)
- assert_equal(time.gmtime(1191997100), c.authored_date)
- assert_equal('Tom Preston-Werner', c.committer.name)
- assert_equal('tom@mojombo.com', c.committer.email)
- assert_equal(time.gmtime(1191997100), c.committed_date)
- assert_equal('initial grit setup', c.message)
-
- # test the 'lines per commit' entries
- tlist = b[0][1]
- assert_true( tlist )
- assert_true( isinstance( tlist[0], basestring ) )
- assert_true( len( tlist ) < sum( len(t) for t in tlist ) ) # test for single-char bug
-
+ @patch_object(Git, '_call_process')
+ def test_should_display_blame_information(self, git):
+ git.return_value = fixture('blame')
+ b = Blob.blame(self.repo, 'master', 'lib/git.py')
+ assert_equal(13, len(b))
+ assert_equal( 2, len(b[0]) )
+ # assert_equal(25, reduce(lambda acc, x: acc + len(x[-1]), b))
+ assert_equal(hash(b[0][0]), hash(b[9][0]))
+ c = b[0][0]
+ assert_true(git.called)
+ assert_equal(git.call_args, (('blame', 'master', '--', 'lib/git.py'), {'p': True}))
+
+ assert_equal('634396b2f541a9f2d58b00be1a07f0c358b999b3', c.id)
+ assert_equal('Tom Preston-Werner', c.author.name)
+ assert_equal('tom@mojombo.com', c.author.email)
+ assert_equal(time.gmtime(1191997100), c.authored_date)
+ assert_equal('Tom Preston-Werner', c.committer.name)
+ assert_equal('tom@mojombo.com', c.committer.email)
+ assert_equal(time.gmtime(1191997100), c.committed_date)
+ assert_equal('initial grit setup', c.message)
+
+ # test the 'lines per commit' entries
+ tlist = b[0][1]
+ assert_true( tlist )
+ assert_true( isinstance( tlist[0], basestring ) )
+ assert_true( len( tlist ) < sum( len(t) for t in tlist ) ) # test for single-char bug
+
- def test_should_return_appropriate_representation(self):
- blob = Blob(self.repo, **{'id': 'abc'})
- assert_equal('<git.Blob "abc">', repr(blob))
+ def test_should_return_appropriate_representation(self):
+ blob = Blob(self.repo, **{'id': 'abc'})
+ assert_equal('<git.Blob "abc">', repr(blob))
diff --git a/test/git/test_commit.py b/test/git/test_commit.py
index fb376b02..e92c13dd 100644
--- a/test/git/test_commit.py
+++ b/test/git/test_commit.py
@@ -8,241 +8,241 @@ from test.testlib import *
from git import *
class TestCommit(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
+ def setup(self):
+ self.repo = Repo(GIT_REPO)
- @patch_object(Git, '_call_process')
- def test_bake(self, git):
- git.return_value = fixture('rev_list_single')
+ @patch_object(Git, '_call_process')
+ def test_bake(self, git):
+ git.return_value = fixture('rev_list_single')
- commit = Commit(self.repo, **{'id': '4c8124ffcf4039d292442eeccabdeca5af5c5017'})
- commit.author # bake
+ commit = Commit(self.repo, **{'id': '4c8124ffcf4039d292442eeccabdeca5af5c5017'})
+ commit.author # bake
- assert_equal("Tom Preston-Werner", commit.author.name)
- assert_equal("tom@mojombo.com", commit.author.email)
+ assert_equal("Tom Preston-Werner", commit.author.name)
+ assert_equal("tom@mojombo.com", commit.author.email)
- assert_true(git.called)
- assert_equal(git.call_args, (('rev_list', '4c8124ffcf4039d292442eeccabdeca5af5c5017', '--', ''), {'pretty': 'raw', 'max_count': 1}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('rev_list', '4c8124ffcf4039d292442eeccabdeca5af5c5017', '--', ''), {'pretty': 'raw', 'max_count': 1}))
- @patch_object(Git, '_call_process')
- def test_id_abbrev(self, git):
- git.return_value = fixture('rev_list_commit_idabbrev')
- assert_equal('80f136f', self.repo.commit('80f136f500dfdb8c3e8abf4ae716f875f0a1b57f').id_abbrev)
+ @patch_object(Git, '_call_process')
+ def test_id_abbrev(self, git):
+ git.return_value = fixture('rev_list_commit_idabbrev')
+ assert_equal('80f136f', self.repo.commit('80f136f500dfdb8c3e8abf4ae716f875f0a1b57f').id_abbrev)
- @patch_object(Git, '_call_process')
- def test_diff(self, git):
- git.return_value = fixture('diff_p')
+ @patch_object(Git, '_call_process')
+ def test_diff(self, git):
+ git.return_value = fixture('diff_p')
- diffs = Commit.diff(self.repo, 'master')
+ diffs = Commit.diff(self.repo, 'master')
- assert_equal(15, len(diffs))
+ assert_equal(15, len(diffs))
- assert_equal('.gitignore', diffs[0].a_blob.path)
- assert_equal('.gitignore', diffs[0].b_blob.path)
- assert_equal('4ebc8aea50e0a67e000ba29a30809d0a7b9b2666', diffs[0].a_blob.id)
- assert_equal('2dd02534615434d88c51307beb0f0092f21fd103', diffs[0].b_blob.id)
- assert_equal('100644', diffs[0].b_blob.mode)
- assert_equal(False, diffs[0].new_file)
- assert_equal(False, diffs[0].deleted_file)
- assert_equal("--- a/.gitignore\n+++ b/.gitignore\n@@ -1 +1,2 @@\n coverage\n+pkg", diffs[0].diff)
+ assert_equal('.gitignore', diffs[0].a_blob.path)
+ assert_equal('.gitignore', diffs[0].b_blob.path)
+ assert_equal('4ebc8aea50e0a67e000ba29a30809d0a7b9b2666', diffs[0].a_blob.id)
+ assert_equal('2dd02534615434d88c51307beb0f0092f21fd103', diffs[0].b_blob.id)
+ assert_equal('100644', diffs[0].b_blob.mode)
+ assert_equal(False, diffs[0].new_file)
+ assert_equal(False, diffs[0].deleted_file)
+ assert_equal("--- a/.gitignore\n+++ b/.gitignore\n@@ -1 +1,2 @@\n coverage\n+pkg", diffs[0].diff)
- assert_equal('lib/grit/actor.rb', diffs[5].b_blob.path)
- assert_equal(None, diffs[5].a_blob)
- assert_equal('f733bce6b57c0e5e353206e692b0e3105c2527f4', diffs[5].b_blob.id)
- assert_equal( None, diffs[5].a_mode )
- assert_equal(True, diffs[5].new_file)
+ assert_equal('lib/grit/actor.rb', diffs[5].b_blob.path)
+ assert_equal(None, diffs[5].a_blob)
+ assert_equal('f733bce6b57c0e5e353206e692b0e3105c2527f4', diffs[5].b_blob.id)
+ assert_equal( None, diffs[5].a_mode )
+ assert_equal(True, diffs[5].new_file)
- assert_true(git.called)
- assert_equal(git.call_args, (('diff', '-M', 'master'), {'full_index': True}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('diff', '-M', 'master'), {'full_index': True}))
- @patch_object(Git, '_call_process')
- def test_diff_with_rename(self, git):
- git.return_value = fixture('diff_rename')
+ @patch_object(Git, '_call_process')
+ def test_diff_with_rename(self, git):
+ git.return_value = fixture('diff_rename')
- diffs = Commit.diff(self.repo, 'rename')
+ diffs = Commit.diff(self.repo, 'rename')
- assert_equal(1, len(diffs))
+ assert_equal(1, len(diffs))
- diff = diffs[0]
- assert_true(diff.renamed)
- assert_equal(diff.rename_from, 'AUTHORS')
- assert_equal(diff.rename_to, 'CONTRIBUTORS')
+ diff = diffs[0]
+ assert_true(diff.renamed)
+ assert_equal(diff.rename_from, 'AUTHORS')
+ assert_equal(diff.rename_to, 'CONTRIBUTORS')
- assert_true(git.called)
- assert_equal(git.call_args, (('diff', '-M', 'rename'), {'full_index': True}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('diff', '-M', 'rename'), {'full_index': True}))
- @patch_object(Git, '_call_process')
- def test_diff_with_two_commits(self, git):
- git.return_value = fixture('diff_2')
+ @patch_object(Git, '_call_process')
+ def test_diff_with_two_commits(self, git):
+ git.return_value = fixture('diff_2')
- diffs = Commit.diff(self.repo, '59ddc32', '13d27d5')
+ diffs = Commit.diff(self.repo, '59ddc32', '13d27d5')
- assert_equal(3, len(diffs))
+ assert_equal(3, len(diffs))
- assert_true(git.called)
- assert_equal(git.call_args, (('diff', '-M', '59ddc32', '13d27d5'), {'full_index': True}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('diff', '-M', '59ddc32', '13d27d5'), {'full_index': True}))
- @patch_object(Git, '_call_process')
- def test_diff_with_files(self, git):
- git.return_value = fixture('diff_f')
+ @patch_object(Git, '_call_process')
+ def test_diff_with_files(self, git):
+ git.return_value = fixture('diff_f')
- diffs = Commit.diff(self.repo, '59ddc32', ['lib'])
+ diffs = Commit.diff(self.repo, '59ddc32', ['lib'])
- assert_equal(1, len(diffs))
- assert_equal('lib/grit/diff.rb', diffs[0].a_blob.path)
+ assert_equal(1, len(diffs))
+ assert_equal('lib/grit/diff.rb', diffs[0].a_blob.path)
- assert_true(git.called)
- assert_equal(git.call_args, (('diff', '-M', '59ddc32', '--', 'lib'), {'full_index': True}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('diff', '-M', '59ddc32', '--', 'lib'), {'full_index': True}))
- @patch_object(Git, '_call_process')
- def test_diff_with_two_commits_and_files(self, git):
- git.return_value = fixture('diff_2f')
+ @patch_object(Git, '_call_process')
+ def test_diff_with_two_commits_and_files(self, git):
+ git.return_value = fixture('diff_2f')
- diffs = Commit.diff(self.repo, '59ddc32', '13d27d5', ['lib'])
+ diffs = Commit.diff(self.repo, '59ddc32', '13d27d5', ['lib'])
- assert_equal(1, len(diffs))
- assert_equal('lib/grit/commit.rb', diffs[0].a_blob.path)
+ assert_equal(1, len(diffs))
+ assert_equal('lib/grit/commit.rb', diffs[0].a_blob.path)
- assert_true(git.called)
- assert_equal(git.call_args, (('diff', '-M', '59ddc32', '13d27d5', '--', 'lib'), {'full_index': True}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('diff', '-M', '59ddc32', '13d27d5', '--', 'lib'), {'full_index': True}))
- @patch_object(Git, '_call_process')
- def test_diffs(self, git):
- git.return_value = fixture('diff_p')
+ @patch_object(Git, '_call_process')
+ def test_diffs(self, git):
+ git.return_value = fixture('diff_p')
- commit = Commit(self.repo, id='91169e1f5fa4de2eaea3f176461f5dc784796769', parents=['038af8c329ef7c1bae4568b98bd5c58510465493'])
- diffs = commit.diffs
+ commit = Commit(self.repo, id='91169e1f5fa4de2eaea3f176461f5dc784796769', parents=['038af8c329ef7c1bae4568b98bd5c58510465493'])
+ diffs = commit.diffs
- assert_equal(15, len(diffs))
+ assert_equal(15, len(diffs))
- assert_equal('.gitignore', diffs[0].a_blob.path)
- assert_equal('.gitignore', diffs[0].b_blob.path)
- assert_equal('4ebc8aea50e0a67e000ba29a30809d0a7b9b2666', diffs[0].a_blob.id)
- assert_equal('2dd02534615434d88c51307beb0f0092f21fd103', diffs[0].b_blob.id)
- assert_equal('100644', diffs[0].b_blob.mode)
- assert_equal(False, diffs[0].new_file)
- assert_equal(False, diffs[0].deleted_file)
- assert_equal("--- a/.gitignore\n+++ b/.gitignore\n@@ -1 +1,2 @@\n coverage\n+pkg", diffs[0].diff)
+ assert_equal('.gitignore', diffs[0].a_blob.path)
+ assert_equal('.gitignore', diffs[0].b_blob.path)
+ assert_equal('4ebc8aea50e0a67e000ba29a30809d0a7b9b2666', diffs[0].a_blob.id)
+ assert_equal('2dd02534615434d88c51307beb0f0092f21fd103', diffs[0].b_blob.id)
+ assert_equal('100644', diffs[0].b_blob.mode)
+ assert_equal(False, diffs[0].new_file)
+ assert_equal(False, diffs[0].deleted_file)
+ assert_equal("--- a/.gitignore\n+++ b/.gitignore\n@@ -1 +1,2 @@\n coverage\n+pkg", diffs[0].diff)
- assert_equal('lib/grit/actor.rb', diffs[5].b_blob.path)
- assert_equal(None, diffs[5].a_blob)
- assert_equal('f733bce6b57c0e5e353206e692b0e3105c2527f4', diffs[5].b_blob.id)
- assert_equal(True, diffs[5].new_file)
+ assert_equal('lib/grit/actor.rb', diffs[5].b_blob.path)
+ assert_equal(None, diffs[5].a_blob)
+ assert_equal('f733bce6b57c0e5e353206e692b0e3105c2527f4', diffs[5].b_blob.id)
+ assert_equal(True, diffs[5].new_file)
- assert_true(git.called)
- assert_equal(git.call_args, (('diff', '-M',
- '038af8c329ef7c1bae4568b98bd5c58510465493',
- '91169e1f5fa4de2eaea3f176461f5dc784796769',
- ), {'full_index': True}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('diff', '-M',
+ '038af8c329ef7c1bae4568b98bd5c58510465493',
+ '91169e1f5fa4de2eaea3f176461f5dc784796769',
+ ), {'full_index': True}))
- @patch_object(Git, '_call_process')
- def test_diffs_on_initial_import(self, git):
- git.return_value = fixture('diff_i')
-
- commit = Commit(self.repo, id='634396b2f541a9f2d58b00be1a07f0c358b999b3')
- commit.__bake_it__()
- diffs = commit.diffs
+ @patch_object(Git, '_call_process')
+ def test_diffs_on_initial_import(self, git):
+ git.return_value = fixture('diff_i')
+
+ commit = Commit(self.repo, id='634396b2f541a9f2d58b00be1a07f0c358b999b3')
+ commit.__bake_it__()
+ diffs = commit.diffs
- assert_equal(10, len(diffs))
+ assert_equal(10, len(diffs))
- assert_equal('History.txt', diffs[0].b_blob.path)
- assert_equal(None, diffs[0].a_blob)
- assert_equal('100644', diffs[0].b_blob.mode)
- assert_equal('81d2c27608b352814cbe979a6acd678d30219678', diffs[0].b_blob.id)
- assert_equal(True, diffs[0].new_file)
- assert_equal(False, diffs[0].deleted_file)
- assert_equal("--- /dev/null\n+++ b/History.txt\n@@ -0,0 +1,5 @@\n+== 1.0.0 / 2007-10-09\n+\n+* 1 major enhancement\n+ * Birthday!\n+", diffs[0].diff)
+ assert_equal('History.txt', diffs[0].b_blob.path)
+ assert_equal(None, diffs[0].a_blob)
+ assert_equal('100644', diffs[0].b_blob.mode)
+ assert_equal('81d2c27608b352814cbe979a6acd678d30219678', diffs[0].b_blob.id)
+ assert_equal(True, diffs[0].new_file)
+ assert_equal(False, diffs[0].deleted_file)
+ assert_equal("--- /dev/null\n+++ b/History.txt\n@@ -0,0 +1,5 @@\n+== 1.0.0 / 2007-10-09\n+\n+* 1 major enhancement\n+ * Birthday!\n+", diffs[0].diff)
- assert_equal('lib/grit.rb', diffs[5].b_blob.path)
- assert_equal(None, diffs[5].a_blob)
- assert_equal('32cec87d1e78946a827ddf6a8776be4d81dcf1d1', diffs[5].b_blob.id)
- assert_equal(True, diffs[5].new_file)
+ assert_equal('lib/grit.rb', diffs[5].b_blob.path)
+ assert_equal(None, diffs[5].a_blob)
+ assert_equal('32cec87d1e78946a827ddf6a8776be4d81dcf1d1', diffs[5].b_blob.id)
+ assert_equal(True, diffs[5].new_file)
- assert_true(git.called)
- assert_equal(git.call_args, (('show', '634396b2f541a9f2d58b00be1a07f0c358b999b3', '-M'), {'full_index': True, 'pretty': 'raw'}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('show', '634396b2f541a9f2d58b00be1a07f0c358b999b3', '-M'), {'full_index': True, 'pretty': 'raw'}))
- @patch_object(Git, '_call_process')
- def test_diffs_on_initial_import_with_empty_commit(self, git):
- git.return_value = fixture('show_empty_commit')
-
- commit = Commit(self.repo, id='634396b2f541a9f2d58b00be1a07f0c358b999b3')
- diffs = commit.diffs
+ @patch_object(Git, '_call_process')
+ def test_diffs_on_initial_import_with_empty_commit(self, git):
+ git.return_value = fixture('show_empty_commit')
+
+ commit = Commit(self.repo, id='634396b2f541a9f2d58b00be1a07f0c358b999b3')
+ diffs = commit.diffs
- assert_equal([], diffs)
-
- assert_true(git.called)
- assert_equal(git.call_args, (('show', '634396b2f541a9f2d58b00be1a07f0c358b999b3', '-M'), {'full_index': True, 'pretty': 'raw'}))
-
- @patch_object(Git, '_call_process')
- def test_diffs_with_mode_only_change(self, git):
- git.return_value = fixture('diff_mode_only')
-
- commit = Commit(self.repo, id='91169e1f5fa4de2eaea3f176461f5dc784796769')
- commit.__bake_it__()
- diffs = commit.diffs
-
- # in case of mode-only changes, there is no blob
- assert_equal(23, len(diffs))
- assert_equal(None, diffs[0].a_blob)
- assert_equal(None, diffs[0].b_blob)
- assert_equal('100644', diffs[0].a_mode)
- assert_equal('100755', diffs[0].b_mode)
-
- assert_true(git.called)
- assert_equal(git.call_args, (('show', '91169e1f5fa4de2eaea3f176461f5dc784796769', '-M'), {'full_index': True, 'pretty': 'raw'}))
-
- @patch_object(Git, '_call_process')
- def test_stats(self, git):
- git.return_value = fixture('diff_tree_numstat_root')
-
- commit = Commit(self.repo, id='634396b2f541a9f2d58b00be1a07f0c358b999b3')
- commit.__bake_it__()
- stats = commit.stats
-
- keys = stats.files.keys()
- keys.sort()
- assert_equal(["a.txt", "b.txt"], keys)
-
- assert_true(git.called)
- assert_equal(git.call_args, (('diff_tree', '634396b2f541a9f2d58b00be1a07f0c358b999b3', '--'), {'numstat': True, 'root': True }))
-
- @patch_object(Git, '_call_process')
- def test_rev_list_bisect_all(self, git):
- """
- 'git rev-list --bisect-all' returns additional information
- in the commit header. This test ensures that we properly parse it.
- """
-
- git.return_value = fixture('rev_list_bisect_all')
-
- revs = self.repo.git.rev_list('HEAD',
- pretty='raw',
- first_parent=True,
- bisect_all=True)
- assert_true(git.called)
-
- commits = Commit.list_from_string(self.repo, revs)
- expected_ids = (
- 'cf37099ea8d1d8c7fbf9b6d12d7ec0249d3acb8b',
- '33ebe7acec14b25c5f84f35a664803fcab2f7781',
- 'a6604a00a652e754cb8b6b0b9f194f839fc38d7c',
- '8df638c22c75ddc9a43ecdde90c0c9939f5009e7',
- 'c231551328faa864848bde6ff8127f59c9566e90',
- )
- for sha1, commit in zip(expected_ids, commits):
- assert_equal(sha1, commit.id)
-
- def test_str(self):
- commit = Commit(self.repo, id='abc')
- assert_equal ("abc", str(commit))
-
- def test_repr(self):
- commit = Commit(self.repo, id='abc')
- assert_equal('<git.Commit "abc">', repr(commit))
-
- def test_equality(self):
- commit1 = Commit(self.repo, id='abc')
- commit2 = Commit(self.repo, id='abc')
- commit3 = Commit(self.repo, id='zyx')
- assert_equal(commit1, commit2)
- assert_not_equal(commit2, commit3)
+ assert_equal([], diffs)
+
+ assert_true(git.called)
+ assert_equal(git.call_args, (('show', '634396b2f541a9f2d58b00be1a07f0c358b999b3', '-M'), {'full_index': True, 'pretty': 'raw'}))
+
+ @patch_object(Git, '_call_process')
+ def test_diffs_with_mode_only_change(self, git):
+ git.return_value = fixture('diff_mode_only')
+
+ commit = Commit(self.repo, id='91169e1f5fa4de2eaea3f176461f5dc784796769')
+ commit.__bake_it__()
+ diffs = commit.diffs
+
+ # in case of mode-only changes, there is no blob
+ assert_equal(23, len(diffs))
+ assert_equal(None, diffs[0].a_blob)
+ assert_equal(None, diffs[0].b_blob)
+ assert_equal('100644', diffs[0].a_mode)
+ assert_equal('100755', diffs[0].b_mode)
+
+ assert_true(git.called)
+ assert_equal(git.call_args, (('show', '91169e1f5fa4de2eaea3f176461f5dc784796769', '-M'), {'full_index': True, 'pretty': 'raw'}))
+
+ @patch_object(Git, '_call_process')
+ def test_stats(self, git):
+ git.return_value = fixture('diff_tree_numstat_root')
+
+ commit = Commit(self.repo, id='634396b2f541a9f2d58b00be1a07f0c358b999b3')
+ commit.__bake_it__()
+ stats = commit.stats
+
+ keys = stats.files.keys()
+ keys.sort()
+ assert_equal(["a.txt", "b.txt"], keys)
+
+ assert_true(git.called)
+ assert_equal(git.call_args, (('diff_tree', '634396b2f541a9f2d58b00be1a07f0c358b999b3', '--'), {'numstat': True, 'root': True }))
+
+ @patch_object(Git, '_call_process')
+ def test_rev_list_bisect_all(self, git):
+ """
+ 'git rev-list --bisect-all' returns additional information
+ in the commit header. This test ensures that we properly parse it.
+ """
+
+ git.return_value = fixture('rev_list_bisect_all')
+
+ revs = self.repo.git.rev_list('HEAD',
+ pretty='raw',
+ first_parent=True,
+ bisect_all=True)
+ assert_true(git.called)
+
+ commits = Commit.list_from_string(self.repo, revs)
+ expected_ids = (
+ 'cf37099ea8d1d8c7fbf9b6d12d7ec0249d3acb8b',
+ '33ebe7acec14b25c5f84f35a664803fcab2f7781',
+ 'a6604a00a652e754cb8b6b0b9f194f839fc38d7c',
+ '8df638c22c75ddc9a43ecdde90c0c9939f5009e7',
+ 'c231551328faa864848bde6ff8127f59c9566e90',
+ )
+ for sha1, commit in zip(expected_ids, commits):
+ assert_equal(sha1, commit.id)
+
+ def test_str(self):
+ commit = Commit(self.repo, id='abc')
+ assert_equal ("abc", str(commit))
+
+ def test_repr(self):
+ commit = Commit(self.repo, id='abc')
+ assert_equal('<git.Commit "abc">', repr(commit))
+
+ def test_equality(self):
+ commit1 = Commit(self.repo, id='abc')
+ commit2 = Commit(self.repo, id='abc')
+ commit3 = Commit(self.repo, id='zyx')
+ assert_equal(commit1, commit2)
+ assert_not_equal(commit2, commit3)
diff --git a/test/git/test_diff.py b/test/git/test_diff.py
index 65a27e98..b9834879 100644
--- a/test/git/test_diff.py
+++ b/test/git/test_diff.py
@@ -8,23 +8,23 @@ from test.testlib import *
from git import *
class TestDiff(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
+ def setup(self):
+ self.repo = Repo(GIT_REPO)
- def test_list_from_string_new_mode(self):
- output = fixture('diff_new_mode')
- diffs = Diff.list_from_string(self.repo, output)
- assert_equal(1, len(diffs))
- assert_equal(10, len(diffs[0].diff.splitlines()))
+ def test_list_from_string_new_mode(self):
+ output = fixture('diff_new_mode')
+ diffs = Diff.list_from_string(self.repo, output)
+ assert_equal(1, len(diffs))
+ assert_equal(10, len(diffs[0].diff.splitlines()))
- def test_diff_with_rename(self):
- output = fixture('diff_rename')
- diffs = Diff.list_from_string(self.repo, output)
+ def test_diff_with_rename(self):
+ output = fixture('diff_rename')
+ diffs = Diff.list_from_string(self.repo, output)
- assert_equal(1, len(diffs))
+ assert_equal(1, len(diffs))
- diff = diffs[0]
- assert_true(diff.renamed)
- assert_equal(diff.rename_from, 'AUTHORS')
- assert_equal(diff.rename_to, 'CONTRIBUTORS')
+ diff = diffs[0]
+ assert_true(diff.renamed)
+ assert_equal(diff.rename_from, 'AUTHORS')
+ assert_equal(diff.rename_to, 'CONTRIBUTORS')
diff --git a/test/git/test_git.py b/test/git/test_git.py
index 6e28f4c0..c9f399cc 100644
--- a/test/git/test_git.py
+++ b/test/git/test_git.py
@@ -9,50 +9,50 @@ from test.testlib import *
from git import Git, GitCommandError
class TestGit(object):
- def setup(self):
- base = os.path.join(os.path.dirname(__file__), "../..")
- self.git = Git(base)
-
- @patch_object(Git, 'execute')
- def test_call_process_calls_execute(self, git):
- git.return_value = ''
- self.git.version()
- assert_true(git.called)
- assert_equal(git.call_args, ((['git', 'version'],), {}))
-
- @raises(GitCommandError)
- def test_it_raises_errors(self):
- self.git.this_does_not_exist()
-
-
- def test_it_transforms_kwargs_into_git_command_arguments(self):
- assert_equal(["-s"], self.git.transform_kwargs(**{'s': True}))
- assert_equal(["-s5"], self.git.transform_kwargs(**{'s': 5}))
-
- assert_equal(["--max-count"], self.git.transform_kwargs(**{'max_count': True}))
- assert_equal(["--max-count=5"], self.git.transform_kwargs(**{'max_count': 5}))
-
- assert_equal(["-s", "-t"], self.git.transform_kwargs(**{'s': True, 't': True}))
-
- def test_it_executes_git_to_shell_and_returns_result(self):
- assert_match('^git version [\d\.]{2}.*$', self.git.execute(["git","version"]))
-
- def test_it_accepts_stdin(self):
- filename = fixture_path("cat_file_blob")
- fh = open(filename, 'r')
- assert_equal("70c379b63ffa0795fdbfbc128e5a2818397b7ef8",
- self.git.hash_object(istream=fh, stdin=True))
- fh.close()
-
- def test_it_handles_large_input(self):
- if sys.platform == 'win32':
- output = self.git.execute(["type", "C:\WINDOWS\system32\cmd.exe"])
- else:
- output = self.git.execute(["cat", "/bin/bash"])
- assert_true(len(output) > 4096) # at least 4k
-
- @patch_object(Git, 'execute')
- def test_it_ignores_false_kwargs(self, git):
- # this_should_not_be_ignored=False implies it *should* be ignored
- output = self.git.version(pass_this_kwarg=False)
- assert_true("pass_this_kwarg" not in git.call_args[1])
+ def setup(self):
+ base = os.path.join(os.path.dirname(__file__), "../..")
+ self.git = Git(base)
+
+ @patch_object(Git, 'execute')
+ def test_call_process_calls_execute(self, git):
+ git.return_value = ''
+ self.git.version()
+ assert_true(git.called)
+ assert_equal(git.call_args, ((['git', 'version'],), {}))
+
+ @raises(GitCommandError)
+ def test_it_raises_errors(self):
+ self.git.this_does_not_exist()
+
+
+ def test_it_transforms_kwargs_into_git_command_arguments(self):
+ assert_equal(["-s"], self.git.transform_kwargs(**{'s': True}))
+ assert_equal(["-s5"], self.git.transform_kwargs(**{'s': 5}))
+
+ assert_equal(["--max-count"], self.git.transform_kwargs(**{'max_count': True}))
+ assert_equal(["--max-count=5"], self.git.transform_kwargs(**{'max_count': 5}))
+
+ assert_equal(["-s", "-t"], self.git.transform_kwargs(**{'s': True, 't': True}))
+
+ def test_it_executes_git_to_shell_and_returns_result(self):
+ assert_match('^git version [\d\.]{2}.*$', self.git.execute(["git","version"]))
+
+ def test_it_accepts_stdin(self):
+ filename = fixture_path("cat_file_blob")
+ fh = open(filename, 'r')
+ assert_equal("70c379b63ffa0795fdbfbc128e5a2818397b7ef8",
+ self.git.hash_object(istream=fh, stdin=True))
+ fh.close()
+
+ def test_it_handles_large_input(self):
+ if sys.platform == 'win32':
+ output = self.git.execute(["type", "C:\WINDOWS\system32\cmd.exe"])
+ else:
+ output = self.git.execute(["cat", "/bin/bash"])
+ assert_true(len(output) > 4096) # at least 4k
+
+ @patch_object(Git, 'execute')
+ def test_it_ignores_false_kwargs(self, git):
+ # this_should_not_be_ignored=False implies it *should* be ignored
+ output = self.git.version(pass_this_kwarg=False)
+ assert_true("pass_this_kwarg" not in git.call_args[1])
diff --git a/test/git/test_head.py b/test/git/test_head.py
index e3408974..8338552f 100644
--- a/test/git/test_head.py
+++ b/test/git/test_head.py
@@ -8,25 +8,25 @@ from test.testlib import *
from git import *
class TestHead(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
+ def setup(self):
+ self.repo = Repo(GIT_REPO)
- @patch_object(Git, '_call_process')
- def test_repr(self, git):
- git.return_value = fixture('for_each_ref')
-
- head = self.repo.heads[0]
-
- assert_equal('<git.Head "%s">' % head.name, repr(head))
-
- assert_true(git.called)
- assert_equal(git.call_args, (('for_each_ref', 'refs/heads'), {'sort': 'committerdate', 'format': '%(refname)%00%(objectname)'}))
+ @patch_object(Git, '_call_process')
+ def test_repr(self, git):
+ git.return_value = fixture('for_each_ref')
+
+ head = self.repo.heads[0]
+
+ assert_equal('<git.Head "%s">' % head.name, repr(head))
+
+ assert_true(git.called)
+ assert_equal(git.call_args, (('for_each_ref', 'refs/heads'), {'sort': 'committerdate', 'format': '%(refname)%00%(objectname)'}))
- @patch_object(Git, '_call_process')
- def test_ref_with_path_component(self, git):
- git.return_value = fixture('for_each_ref_with_path_component')
- head = self.repo.heads[0]
+ @patch_object(Git, '_call_process')
+ def test_ref_with_path_component(self, git):
+ git.return_value = fixture('for_each_ref_with_path_component')
+ head = self.repo.heads[0]
- assert_equal('refactoring/feature1', head.name)
- assert_true(git.called)
- assert_equal(git.call_args, (('for_each_ref', 'refs/heads'), {'sort': 'committerdate', 'format': '%(refname)%00%(objectname)'}))
+ assert_equal('refactoring/feature1', head.name)
+ assert_true(git.called)
+ assert_equal(git.call_args, (('for_each_ref', 'refs/heads'), {'sort': 'committerdate', 'format': '%(refname)%00%(objectname)'}))
diff --git a/test/git/test_repo.py b/test/git/test_repo.py
index a9d3beaf..e232b065 100644
--- a/test/git/test_repo.py
+++ b/test/git/test_repo.py
@@ -10,255 +10,255 @@ from test.testlib import *
from git import *
class TestRepo(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
-
- @raises(InvalidGitRepositoryError)
- def test_new_should_raise_on_invalid_repo_location(self):
- if sys.platform == "win32":
- Repo("C:\\WINDOWS\\Temp")
- else:
- Repo("/tmp")
+ def setup(self):
+ self.repo = Repo(GIT_REPO)
+
+ @raises(InvalidGitRepositoryError)
+ def test_new_should_raise_on_invalid_repo_location(self):
+ if sys.platform == "win32":
+ Repo("C:\\WINDOWS\\Temp")
+ else:
+ Repo("/tmp")
- @raises(NoSuchPathError)
- def test_new_should_raise_on_non_existant_path(self):
- Repo("repos/foobar")
+ @raises(NoSuchPathError)
+ def test_new_should_raise_on_non_existant_path(self):
+ Repo("repos/foobar")
- def test_description(self):
- txt = "Test repository"
- self.repo.description = txt
- assert_equal(self.repo.description, txt)
+ def test_description(self):
+ txt = "Test repository"
+ self.repo.description = txt
+ assert_equal(self.repo.description, txt)
- def test_heads_should_return_array_of_head_objects(self):
- for head in self.repo.heads:
- assert_equal(Head, head.__class__)
+ def test_heads_should_return_array_of_head_objects(self):
+ for head in self.repo.heads:
+ assert_equal(Head, head.__class__)
- @patch_object(Git, '_call_process')
- def test_heads_should_populate_head_data(self, git):
- git.return_value = fixture('for_each_ref')
+ @patch_object(Git, '_call_process')
+ def test_heads_should_populate_head_data(self, git):
+ git.return_value = fixture('for_each_ref')
- head = self.repo.heads[0]
- assert_equal('master', head.name)
- assert_equal('634396b2f541a9f2d58b00be1a07f0c358b999b3', head.commit.id)
+ head = self.repo.heads[0]
+ assert_equal('master', head.name)
+ assert_equal('634396b2f541a9f2d58b00be1a07f0c358b999b3', head.commit.id)
- assert_true(git.called)
- assert_equal(git.call_args, (('for_each_ref', 'refs/heads'), {'sort': 'committerdate', 'format': '%(refname)%00%(objectname)'}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('for_each_ref', 'refs/heads'), {'sort': 'committerdate', 'format': '%(refname)%00%(objectname)'}))
- @patch_object(Git, '_call_process')
- def test_commits(self, git):
- git.return_value = fixture('rev_list')
+ @patch_object(Git, '_call_process')
+ def test_commits(self, git):
+ git.return_value = fixture('rev_list')
- commits = self.repo.commits('master', max_count=10)
+ commits = self.repo.commits('master', max_count=10)
- c = commits[0]
- assert_equal('4c8124ffcf4039d292442eeccabdeca5af5c5017', c.id)
- assert_equal(["634396b2f541a9f2d58b00be1a07f0c358b999b3"], [p.id for p in c.parents])
- assert_equal("672eca9b7f9e09c22dcb128c283e8c3c8d7697a4", c.tree.id)
- assert_equal("Tom Preston-Werner", c.author.name)
- assert_equal("tom@mojombo.com", c.author.email)
- assert_equal(time.gmtime(1191999972), c.authored_date)
- assert_equal("Tom Preston-Werner", c.committer.name)
- assert_equal("tom@mojombo.com", c.committer.email)
- assert_equal(time.gmtime(1191999972), c.committed_date)
- assert_equal("implement Grit#heads", c.message)
+ c = commits[0]
+ assert_equal('4c8124ffcf4039d292442eeccabdeca5af5c5017', c.id)
+ assert_equal(["634396b2f541a9f2d58b00be1a07f0c358b999b3"], [p.id for p in c.parents])
+ assert_equal("672eca9b7f9e09c22dcb128c283e8c3c8d7697a4", c.tree.id)
+ assert_equal("Tom Preston-Werner", c.author.name)
+ assert_equal("tom@mojombo.com", c.author.email)
+ assert_equal(time.gmtime(1191999972), c.authored_date)
+ assert_equal("Tom Preston-Werner", c.committer.name)
+ assert_equal("tom@mojombo.com", c.committer.email)
+ assert_equal(time.gmtime(1191999972), c.committed_date)
+ assert_equal("implement Grit#heads", c.message)
- c = commits[1]
- assert_equal([], c.parents)
+ c = commits[1]
+ assert_equal([], c.parents)
- c = commits[2]
- assert_equal(["6e64c55896aabb9a7d8e9f8f296f426d21a78c2c", "7f874954efb9ba35210445be456c74e037ba6af2"], map(lambda p: p.id, c.parents))
- assert_equal("Merge branch 'site'", c.summary)
+ c = commits[2]
+ assert_equal(["6e64c55896aabb9a7d8e9f8f296f426d21a78c2c", "7f874954efb9ba35210445be456c74e037ba6af2"], map(lambda p: p.id, c.parents))
+ assert_equal("Merge branch 'site'", c.summary)
- assert_true(git.called)
- assert_equal(git.call_args, (('rev_list', 'master', '--', ''), {'skip': 0, 'pretty': 'raw', 'max_count': 10}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('rev_list', 'master', '--', ''), {'skip': 0, 'pretty': 'raw', 'max_count': 10}))
- @patch_object(Git, '_call_process')
- def test_commit_count(self, git):
- git.return_value = fixture('rev_list_count')
+ @patch_object(Git, '_call_process')
+ def test_commit_count(self, git):
+ git.return_value = fixture('rev_list_count')
- assert_equal(655, self.repo.commit_count('master'))
+ assert_equal(655, self.repo.commit_count('master'))
- assert_true(git.called)
- assert_equal(git.call_args, (('rev_list', 'master', '--', ''), {}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('rev_list', 'master', '--', ''), {}))
- @patch_object(Git, '_call_process')
- def test_commit(self, git):
- git.return_value = fixture('rev_list_single')
+ @patch_object(Git, '_call_process')
+ def test_commit(self, git):
+ git.return_value = fixture('rev_list_single')
- commit = self.repo.commit('4c8124ffcf4039d292442eeccabdeca5af5c5017')
+ commit = self.repo.commit('4c8124ffcf4039d292442eeccabdeca5af5c5017')
- assert_equal("4c8124ffcf4039d292442eeccabdeca5af5c5017", commit.id)
+ assert_equal("4c8124ffcf4039d292442eeccabdeca5af5c5017", commit.id)
- assert_true(git.called)
- assert_equal(git.call_args, (('rev_list', '4c8124ffcf4039d292442eeccabdeca5af5c5017', '--', ''), {'pretty': 'raw', 'max_count': 1}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('rev_list', '4c8124ffcf4039d292442eeccabdeca5af5c5017', '--', ''), {'pretty': 'raw', 'max_count': 1}))
- @patch_object(Git, '_call_process')
- def test_tree(self, git):
- git.return_value = fixture('ls_tree_a')
+ @patch_object(Git, '_call_process')
+ def test_tree(self, git):
+ git.return_value = fixture('ls_tree_a')
- tree = self.repo.tree('master')
+ tree = self.repo.tree('master')
- assert_equal(4, len([c for c in tree.values() if isinstance(c, Blob)]))
- assert_equal(3, len([c for c in tree.values() if isinstance(c, Tree)]))
+ assert_equal(4, len([c for c in tree.values() if isinstance(c, Blob)]))
+ assert_equal(3, len([c for c in tree.values() if isinstance(c, Tree)]))
- assert_true(git.called)
- assert_equal(git.call_args, (('ls_tree', 'master'), {}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('ls_tree', 'master'), {}))
- @patch_object(Git, '_call_process')
- def test_blob(self, git):
- git.return_value = fixture('cat_file_blob')
+ @patch_object(Git, '_call_process')
+ def test_blob(self, git):
+ git.return_value = fixture('cat_file_blob')
- blob = self.repo.blob("abc")
- assert_equal("Hello world", blob.data)
+ blob = self.repo.blob("abc")
+ assert_equal("Hello world", blob.data)
- assert_true(git.called)
- assert_equal(git.call_args, (('cat_file', 'abc'), {'p': True, 'with_raw_output': True}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('cat_file', 'abc'), {'p': True, 'with_raw_output': True}))
- @patch_object(Repo, '__init__')
- @patch_object(Git, '_call_process')
- def test_init_bare(self, git, repo):
- git.return_value = True
- repo.return_value = None
+ @patch_object(Repo, '__init__')
+ @patch_object(Git, '_call_process')
+ def test_init_bare(self, git, repo):
+ git.return_value = True
+ repo.return_value = None
- Repo.init_bare("repos/foo/bar.git")
+ Repo.init_bare("repos/foo/bar.git")
- assert_true(git.called)
- assert_equal(git.call_args, (('init', '--bare'), {}))
- assert_true(repo.called)
- assert_equal(repo.call_args, (('repos/foo/bar.git',), {}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('init', '--bare'), {}))
+ assert_true(repo.called)
+ assert_equal(repo.call_args, (('repos/foo/bar.git',), {}))
- @patch_object(Repo, '__init__')
- @patch_object(Git, '_call_process')
- def test_init_bare_with_options(self, git, repo):
- git.return_value = True
- repo.return_value = None
+ @patch_object(Repo, '__init__')
+ @patch_object(Git, '_call_process')
+ def test_init_bare_with_options(self, git, repo):
+ git.return_value = True
+ repo.return_value = None
- Repo.init_bare("repos/foo/bar.git", **{'template': "/baz/sweet"})
+ Repo.init_bare("repos/foo/bar.git", **{'template': "/baz/sweet"})
- assert_true(git.called)
- assert_equal(git.call_args, (('init', '--bare'), {'template': '/baz/sweet'}))
- assert_true(repo.called)
- assert_equal(repo.call_args, (('repos/foo/bar.git',), {}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('init', '--bare'), {'template': '/baz/sweet'}))
+ assert_true(repo.called)
+ assert_equal(repo.call_args, (('repos/foo/bar.git',), {}))
- @patch_object(Repo, '__init__')
- @patch_object(Git, '_call_process')
- def test_fork_bare(self, git, repo):
- git.return_value = None
- repo.return_value = None
+ @patch_object(Repo, '__init__')
+ @patch_object(Git, '_call_process')
+ def test_fork_bare(self, git, repo):
+ git.return_value = None
+ repo.return_value = None
- self.repo.fork_bare("repos/foo/bar.git")
+ self.repo.fork_bare("repos/foo/bar.git")
- assert_true(git.called)
- path = os.path.join(absolute_project_path(), '.git')
- assert_equal(git.call_args, (('clone', path, 'repos/foo/bar.git'), {'bare': True}))
- assert_true(repo.called)
+ assert_true(git.called)
+ path = os.path.join(absolute_project_path(), '.git')
+ assert_equal(git.call_args, (('clone', path, 'repos/foo/bar.git'), {'bare': True}))
+ assert_true(repo.called)
- @patch_object(Repo, '__init__')
- @patch_object(Git, '_call_process')
- def test_fork_bare_with_options(self, git, repo):
- git.return_value = None
- repo.return_value = None
+ @patch_object(Repo, '__init__')
+ @patch_object(Git, '_call_process')
+ def test_fork_bare_with_options(self, git, repo):
+ git.return_value = None
+ repo.return_value = None
- self.repo.fork_bare("repos/foo/bar.git", **{'template': '/awesome'})
+ self.repo.fork_bare("repos/foo/bar.git", **{'template': '/awesome'})
- assert_true(git.called)
- path = os.path.join(absolute_project_path(), '.git')
- assert_equal(git.call_args, (('clone', path, 'repos/foo/bar.git'),
- {'bare': True, 'template': '/awesome'}))
- assert_true(repo.called)
+ assert_true(git.called)
+ path = os.path.join(absolute_project_path(), '.git')
+ assert_equal(git.call_args, (('clone', path, 'repos/foo/bar.git'),
+ {'bare': True, 'template': '/awesome'}))
+ assert_true(repo.called)
- @patch_object(Git, '_call_process')
- def test_diff(self, git):
- self.repo.diff('master^', 'master')
+ @patch_object(Git, '_call_process')
+ def test_diff(self, git):
+ self.repo.diff('master^', 'master')
- assert_true(git.called)
- assert_equal(git.call_args, (('diff', 'master^', 'master', '--'), {}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('diff', 'master^', 'master', '--'), {}))
- self.repo.diff('master^', 'master', 'foo/bar')
+ self.repo.diff('master^', 'master', 'foo/bar')
- assert_true(git.called)
- assert_equal(git.call_args, (('diff', 'master^', 'master', '--', 'foo/bar'), {}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('diff', 'master^', 'master', '--', 'foo/bar'), {}))
- self.repo.diff('master^', 'master', 'foo/bar', 'foo/baz')
+ self.repo.diff('master^', 'master', 'foo/bar', 'foo/baz')
- assert_true(git.called)
- assert_equal(git.call_args, (('diff', 'master^', 'master', '--', 'foo/bar', 'foo/baz'), {}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('diff', 'master^', 'master', '--', 'foo/bar', 'foo/baz'), {}))
- @patch_object(Git, '_call_process')
- def test_diff_with_parents(self, git):
- git.return_value = fixture('diff_p')
+ @patch_object(Git, '_call_process')
+ def test_diff_with_parents(self, git):
+ git.return_value = fixture('diff_p')
- diffs = self.repo.commit_diff('master')
- assert_equal(15, len(diffs))
- assert_true(git.called)
+ diffs = self.repo.commit_diff('master')
+ assert_equal(15, len(diffs))
+ assert_true(git.called)
- def test_archive_tar(self):
- assert self.repo.archive_tar()
+ def test_archive_tar(self):
+ assert self.repo.archive_tar()
- def test_archive_tar_gz(self):
- assert self.repo.archive_tar_gz()
+ def test_archive_tar_gz(self):
+ assert self.repo.archive_tar_gz()
- @patch('git.utils.touch')
- def test_enable_daemon_serve(self, touch):
- self.repo.daemon_serve = False
- assert_false(self.repo.daemon_serve)
+ @patch('git.utils.touch')
+ def test_enable_daemon_serve(self, touch):
+ self.repo.daemon_serve = False
+ assert_false(self.repo.daemon_serve)
- def test_disable_daemon_serve(self):
- self.repo.daemon_serve = True
- assert_true(self.repo.daemon_serve)
+ def test_disable_daemon_serve(self):
+ self.repo.daemon_serve = True
+ assert_true(self.repo.daemon_serve)
- @patch_object(os.path, 'exists')
- def test_alternates_no_file(self, os):
- os.return_value = False
- assert_equal([], self.repo.alternates)
-
- assert_true(os.called)
-
- @patch_object(os, 'remove')
- def test_alternates_setter_empty(self, os):
- self.repo.alternates = []
- assert_true(os.called)
-
- def test_repr(self):
- path = os.path.join(os.path.abspath(GIT_REPO), '.git')
- assert_equal('<git.Repo "%s">' % path, repr(self.repo))
-
- @patch_object(Git, '_call_process')
- def test_log(self, git):
- git.return_value = fixture('rev_list')
- assert_equal('4c8124ffcf4039d292442eeccabdeca5af5c5017', self.repo.log()[0].id)
- assert_equal('ab25fd8483882c3bda8a458ad2965d2248654335', self.repo.log()[-1].id)
- assert_true(git.called)
- assert_equal(git.call_count, 2)
- assert_equal(git.call_args, (('log', 'master', '--'), {'pretty': 'raw'}))
-
- @patch_object(Git, '_call_process')
- def test_log_with_path_and_options(self, git):
- git.return_value = fixture('rev_list')
- self.repo.log('master', 'file.rb', **{'max_count': 1})
- assert_true(git.called)
- assert_equal(git.call_args, (('log', 'master', '--', 'file.rb'), {'pretty': 'raw', 'max_count': 1}))
-
- def test_is_dirty_with_bare_repository(self):
- self.repo.bare = True
- assert_false(self.repo.is_dirty)
-
- @patch_object(Git, '_call_process')
- def test_is_dirty_with_clean_working_dir(self, git):
- self.repo.bare = False
- git.return_value = ''
- assert_false(self.repo.is_dirty)
- assert_equal(git.call_args, (('diff', 'HEAD', '--'), {}))
-
- @patch_object(Git, '_call_process')
- def test_is_dirty_with_dirty_working_dir(self, git):
- self.repo.bare = False
- git.return_value = '''-aaa\n+bbb'''
- assert_true(self.repo.is_dirty)
- assert_equal(git.call_args, (('diff', 'HEAD', '--'), {}))
-
- @patch_object(Git, '_call_process')
- def test_active_branch(self, git):
- git.return_value = 'refs/heads/major-refactoring'
- assert_equal(self.repo.active_branch, 'major-refactoring')
- assert_equal(git.call_args, (('symbolic_ref', 'HEAD'), {}))
+ @patch_object(os.path, 'exists')
+ def test_alternates_no_file(self, os):
+ os.return_value = False
+ assert_equal([], self.repo.alternates)
+
+ assert_true(os.called)
+
+ @patch_object(os, 'remove')
+ def test_alternates_setter_empty(self, os):
+ self.repo.alternates = []
+ assert_true(os.called)
+
+ def test_repr(self):
+ path = os.path.join(os.path.abspath(GIT_REPO), '.git')
+ assert_equal('<git.Repo "%s">' % path, repr(self.repo))
+
+ @patch_object(Git, '_call_process')
+ def test_log(self, git):
+ git.return_value = fixture('rev_list')
+ assert_equal('4c8124ffcf4039d292442eeccabdeca5af5c5017', self.repo.log()[0].id)
+ assert_equal('ab25fd8483882c3bda8a458ad2965d2248654335', self.repo.log()[-1].id)
+ assert_true(git.called)
+ assert_equal(git.call_count, 2)
+ assert_equal(git.call_args, (('log', 'master', '--'), {'pretty': 'raw'}))
+
+ @patch_object(Git, '_call_process')
+ def test_log_with_path_and_options(self, git):
+ git.return_value = fixture('rev_list')
+ self.repo.log('master', 'file.rb', **{'max_count': 1})
+ assert_true(git.called)
+ assert_equal(git.call_args, (('log', 'master', '--', 'file.rb'), {'pretty': 'raw', 'max_count': 1}))
+
+ def test_is_dirty_with_bare_repository(self):
+ self.repo.bare = True
+ assert_false(self.repo.is_dirty)
+
+ @patch_object(Git, '_call_process')
+ def test_is_dirty_with_clean_working_dir(self, git):
+ self.repo.bare = False
+ git.return_value = ''
+ assert_false(self.repo.is_dirty)
+ assert_equal(git.call_args, (('diff', 'HEAD', '--'), {}))
+
+ @patch_object(Git, '_call_process')
+ def test_is_dirty_with_dirty_working_dir(self, git):
+ self.repo.bare = False
+ git.return_value = '''-aaa\n+bbb'''
+ assert_true(self.repo.is_dirty)
+ assert_equal(git.call_args, (('diff', 'HEAD', '--'), {}))
+
+ @patch_object(Git, '_call_process')
+ def test_active_branch(self, git):
+ git.return_value = 'refs/heads/major-refactoring'
+ assert_equal(self.repo.active_branch, 'major-refactoring')
+ assert_equal(git.call_args, (('symbolic_ref', 'HEAD'), {}))
diff --git a/test/git/test_stats.py b/test/git/test_stats.py
index b6f1b60e..0063bb2d 100644
--- a/test/git/test_stats.py
+++ b/test/git/test_stats.py
@@ -8,20 +8,20 @@ from test.testlib import *
from git import *
class TestStats(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
-
- def test_list_from_string(self):
- output = fixture('diff_numstat')
- stats = Stats.list_from_string(self.repo, output)
-
- assert_equal(2, stats.total['files'])
- assert_equal(52, stats.total['lines'])
- assert_equal(29, stats.total['insertions'])
- assert_equal(23, stats.total['deletions'])
-
- assert_equal(29, stats.files["a.txt"]['insertions'])
- assert_equal(18, stats.files["a.txt"]['deletions'])
-
- assert_equal(0, stats.files["b.txt"]['insertions'])
- assert_equal(5, stats.files["b.txt"]['deletions'])
+ def setup(self):
+ self.repo = Repo(GIT_REPO)
+
+ def test_list_from_string(self):
+ output = fixture('diff_numstat')
+ stats = Stats.list_from_string(self.repo, output)
+
+ assert_equal(2, stats.total['files'])
+ assert_equal(52, stats.total['lines'])
+ assert_equal(29, stats.total['insertions'])
+ assert_equal(23, stats.total['deletions'])
+
+ assert_equal(29, stats.files["a.txt"]['insertions'])
+ assert_equal(18, stats.files["a.txt"]['deletions'])
+
+ assert_equal(0, stats.files["b.txt"]['insertions'])
+ assert_equal(5, stats.files["b.txt"]['deletions'])
diff --git a/test/git/test_tree.py b/test/git/test_tree.py
index 3946a33c..d52a8e0a 100644
--- a/test/git/test_tree.py
+++ b/test/git/test_tree.py
@@ -8,142 +8,142 @@ from test.testlib import *
from git import *
class TestTree(object):
- def setup(self):
- self.repo = Repo(GIT_REPO)
-
- @patch_object(Git, '_call_process')
- def test_contents_should_cache(self, git):
- git.return_value = fixture('ls_tree_a') + fixture('ls_tree_b')
-
- tree = self.repo.tree('master')
-
- child = tree['grit']
- child.items()
- child.items()
-
- assert_true(git.called)
- assert_equal(2, git.call_count)
- assert_equal(git.call_args, (('ls_tree', '34868e6e7384cb5ee51c543a8187fdff2675b5a7'), {}))
+ def setup(self):
+ self.repo = Repo(GIT_REPO)
+
+ @patch_object(Git, '_call_process')
+ def test_contents_should_cache(self, git):
+ git.return_value = fixture('ls_tree_a') + fixture('ls_tree_b')
+
+ tree = self.repo.tree('master')
+
+ child = tree['grit']
+ child.items()
+ child.items()
+
+ assert_true(git.called)
+ assert_equal(2, git.call_count)
+ assert_equal(git.call_args, (('ls_tree', '34868e6e7384cb5ee51c543a8187fdff2675b5a7'), {}))
- def test_content_from_string_tree_should_return_tree(self):
- text = fixture('ls_tree_a').splitlines()[-1]
- tree = Tree.content_from_string(None, text)
-
- assert_equal(Tree, tree.__class__)
- assert_equal("650fa3f0c17f1edb4ae53d8dcca4ac59d86e6c44", tree.id)
- assert_equal("040000", tree.mode)
- assert_equal("test", tree.path)
+ def test_content_from_string_tree_should_return_tree(self):
+ text = fixture('ls_tree_a').splitlines()[-1]
+ tree = Tree.content_from_string(None, text)
+
+ assert_equal(Tree, tree.__class__)
+ assert_equal("650fa3f0c17f1edb4ae53d8dcca4ac59d86e6c44", tree.id)
+ assert_equal("040000", tree.mode)
+ assert_equal("test", tree.path)
- def test_content_from_string_tree_should_return_blob(self):
- text = fixture('ls_tree_b').split("\n")[0]
-
- tree = Tree.content_from_string(None, text)
-
- assert_equal(Blob, tree.__class__)
- assert_equal("aa94e396335d2957ca92606f909e53e7beaf3fbb", tree.id)
- assert_equal("100644", tree.mode)
- assert_equal("grit.rb", tree.path)
+ def test_content_from_string_tree_should_return_blob(self):
+ text = fixture('ls_tree_b').split("\n")[0]
+
+ tree = Tree.content_from_string(None, text)
+
+ assert_equal(Blob, tree.__class__)
+ assert_equal("aa94e396335d2957ca92606f909e53e7beaf3fbb", tree.id)
+ assert_equal("100644", tree.mode)
+ assert_equal("grit.rb", tree.path)
- def test_content_from_string_tree_should_return_commit(self):
- text = fixture('ls_tree_commit').split("\n")[1]
-
- tree = Tree.content_from_string(None, text)
- assert_none(tree)
-
- @raises(TypeError)
- def test_content_from_string_invalid_type_should_raise(self):
- Tree.content_from_string(None, "040000 bogus 650fa3f0c17f1edb4ae53d8dcca4ac59d86e6c44 test")
-
- @patch_object(Blob, 'size')
- @patch_object(Git, '_call_process')
- def test_slash(self, git, blob):
- git.return_value = fixture('ls_tree_a')
- blob.return_value = 1
-
- tree = self.repo.tree('master')
-
- assert_equal('aa06ba24b4e3f463b3c4a85469d0fb9e5b421cf8', (tree/'lib').id)
- assert_equal('8b1e02c0fb554eed2ce2ef737a68bb369d7527df', (tree/'README.txt').id)
-
- assert_true(git.called)
- assert_equal(git.call_args, (('ls_tree', 'master'), {}))
+ def test_content_from_string_tree_should_return_commit(self):
+ text = fixture('ls_tree_commit').split("\n")[1]
+
+ tree = Tree.content_from_string(None, text)
+ assert_none(tree)
+
+ @raises(TypeError)
+ def test_content_from_string_invalid_type_should_raise(self):
+ Tree.content_from_string(None, "040000 bogus 650fa3f0c17f1edb4ae53d8dcca4ac59d86e6c44 test")
+
+ @patch_object(Blob, 'size')
+ @patch_object(Git, '_call_process')
+ def test_slash(self, git, blob):
+ git.return_value = fixture('ls_tree_a')
+ blob.return_value = 1
+
+ tree = self.repo.tree('master')
+
+ assert_equal('aa06ba24b4e3f463b3c4a85469d0fb9e5b421cf8', (tree/'lib').id)
+ assert_equal('8b1e02c0fb554eed2ce2ef737a68bb369d7527df', (tree/'README.txt').id)
+
+ assert_true(git.called)
+ assert_equal(git.call_args, (('ls_tree', 'master'), {}))
- @patch_object(Blob, 'size')
- @patch_object(Git, '_call_process')
- def test_slash_with_zero_length_file(self, git, blob):
- git.return_value = fixture('ls_tree_a')
- blob.return_value = 0
-
- tree = self.repo.tree('master')
-
- assert_not_none(tree/'README.txt')
- assert_equal('8b1e02c0fb554eed2ce2ef737a68bb369d7527df', (tree/'README.txt').id)
-
- assert_true(git.called)
- assert_equal(git.call_args, (('ls_tree', 'master'), {}))
+ @patch_object(Blob, 'size')
+ @patch_object(Git, '_call_process')
+ def test_slash_with_zero_length_file(self, git, blob):
+ git.return_value = fixture('ls_tree_a')
+ blob.return_value = 0
+
+ tree = self.repo.tree('master')
+
+ assert_not_none(tree/'README.txt')
+ assert_equal('8b1e02c0fb554eed2ce2ef737a68bb369d7527df', (tree/'README.txt').id)
+
+ assert_true(git.called)
+ assert_equal(git.call_args, (('ls_tree', 'master'), {}))
- @patch_object(Git, '_call_process')
- def test_slash_with_commits(self, git):
- git.return_value = fixture('ls_tree_commit')
+ @patch_object(Git, '_call_process')
+ def test_slash_with_commits(self, git):
+ git.return_value = fixture('ls_tree_commit')
- tree = self.repo.tree('master')
-
- assert_none(tree/'bar')
- assert_equal('2afb47bcedf21663580d5e6d2f406f08f3f65f19', (tree/'foo').id)
- assert_equal('f623ee576a09ca491c4a27e48c0dfe04be5f4a2e', (tree/'baz').id)
+ tree = self.repo.tree('master')
+
+ assert_none(tree/'bar')
+ assert_equal('2afb47bcedf21663580d5e6d2f406f08f3f65f19', (tree/'foo').id)
+ assert_equal('f623ee576a09ca491c4a27e48c0dfe04be5f4a2e', (tree/'baz').id)
- assert_true(git.called)
- assert_equal(git.call_args, (('ls_tree', 'master'), {}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('ls_tree', 'master'), {}))
- @patch_object(Blob, 'size')
- @patch_object(Git, '_call_process')
- def test_dict(self, git, blob):
- git.return_value = fixture('ls_tree_a')
- blob.return_value = 1
+ @patch_object(Blob, 'size')
+ @patch_object(Git, '_call_process')
+ def test_dict(self, git, blob):
+ git.return_value = fixture('ls_tree_a')
+ blob.return_value = 1
- tree = self.repo.tree('master')
+ tree = self.repo.tree('master')
- assert_equal('aa06ba24b4e3f463b3c4a85469d0fb9e5b421cf8', tree['lib'].id)
- assert_equal('8b1e02c0fb554eed2ce2ef737a68bb369d7527df', tree['README.txt'].id)
+ assert_equal('aa06ba24b4e3f463b3c4a85469d0fb9e5b421cf8', tree['lib'].id)
+ assert_equal('8b1e02c0fb554eed2ce2ef737a68bb369d7527df', tree['README.txt'].id)
- assert_true(git.called)
- assert_equal(git.call_args, (('ls_tree', 'master'), {}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('ls_tree', 'master'), {}))
- @patch_object(Blob, 'size')
- @patch_object(Git, '_call_process')
- def test_dict_with_zero_length_file(self, git, blob):
- git.return_value = fixture('ls_tree_a')
- blob.return_value = 0
+ @patch_object(Blob, 'size')
+ @patch_object(Git, '_call_process')
+ def test_dict_with_zero_length_file(self, git, blob):
+ git.return_value = fixture('ls_tree_a')
+ blob.return_value = 0
- tree = self.repo.tree('master')
+ tree = self.repo.tree('master')
- assert_not_none(tree['README.txt'])
- assert_equal('8b1e02c0fb554eed2ce2ef737a68bb369d7527df', tree['README.txt'].id)
+ assert_not_none(tree['README.txt'])
+ assert_equal('8b1e02c0fb554eed2ce2ef737a68bb369d7527df', tree['README.txt'].id)
- assert_true(git.called)
- assert_equal(git.call_args, (('ls_tree', 'master'), {}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('ls_tree', 'master'), {}))
- @patch_object(Git, '_call_process')
- def test_dict_with_commits(self, git):
- git.return_value = fixture('ls_tree_commit')
+ @patch_object(Git, '_call_process')
+ def test_dict_with_commits(self, git):
+ git.return_value = fixture('ls_tree_commit')
- tree = self.repo.tree('master')
+ tree = self.repo.tree('master')
- assert_none(tree.get('bar'))
- assert_equal('2afb47bcedf21663580d5e6d2f406f08f3f65f19', tree['foo'].id)
- assert_equal('f623ee576a09ca491c4a27e48c0dfe04be5f4a2e', tree['baz'].id)
+ assert_none(tree.get('bar'))
+ assert_equal('2afb47bcedf21663580d5e6d2f406f08f3f65f19', tree['foo'].id)
+ assert_equal('f623ee576a09ca491c4a27e48c0dfe04be5f4a2e', tree['baz'].id)
- assert_true(git.called)
- assert_equal(git.call_args, (('ls_tree', 'master'), {}))
+ assert_true(git.called)
+ assert_equal(git.call_args, (('ls_tree', 'master'), {}))
- @patch_object(Git, '_call_process')
- @raises(KeyError)
- def test_dict_with_non_existant_file(self, git):
- git.return_value = fixture('ls_tree_commit')
+ @patch_object(Git, '_call_process')
+ @raises(KeyError)
+ def test_dict_with_non_existant_file(self, git):
+ git.return_value = fixture('ls_tree_commit')
- tree = self.repo.tree('master')
- tree['bar']
+ tree = self.repo.tree('master')
+ tree['bar']
- def test_repr(self):
- tree = Tree(self.repo, id='abc')
- assert_equal('<git.Tree "abc">', repr(tree))
+ def test_repr(self):
+ tree = Tree(self.repo, id='abc')
+ assert_equal('<git.Tree "abc">', repr(tree))
diff --git a/test/git/test_utils.py b/test/git/test_utils.py
index 327a07ed..2983a14a 100644
--- a/test/git/test_utils.py
+++ b/test/git/test_utils.py
@@ -9,13 +9,13 @@ from test.testlib import *
from git import *
class TestUtils(object):
- def setup(self):
- self.testdict = {
- "string": "42",
- "int": 42,
- "array": [ 42 ],
- }
+ def setup(self):
+ self.testdict = {
+ "string": "42",
+ "int": 42,
+ "array": [ 42 ],
+ }
- def test_it_should_dashify(self):
- assert_equal('this-is-my-argument', dashify('this_is_my_argument'))
- assert_equal('foo', dashify('foo'))
+ def test_it_should_dashify(self):
+ assert_equal('this-is-my-argument', dashify('this_is_my_argument'))
+ assert_equal('foo', dashify('foo'))
diff --git a/test/testlib/__init__.py b/test/testlib/__init__.py
index 77512794..2133eb8c 100644
--- a/test/testlib/__init__.py
+++ b/test/testlib/__init__.py
@@ -10,4 +10,4 @@ from asserts import *
from helper import *
__all__ = [ name for name, obj in locals().items()
- if not (name.startswith('_') or inspect.ismodule(obj)) ]
+ if not (name.startswith('_') or inspect.ismodule(obj)) ]
diff --git a/test/testlib/asserts.py b/test/testlib/asserts.py
index f66af122..8f2acdc9 100644
--- a/test/testlib/asserts.py
+++ b/test/testlib/asserts.py
@@ -10,29 +10,29 @@ from nose import tools
from nose.tools import *
__all__ = ['assert_instance_of', 'assert_not_instance_of',
- 'assert_none', 'assert_not_none',
- 'assert_match', 'assert_not_match'] + tools.__all__
+ 'assert_none', 'assert_not_none',
+ 'assert_match', 'assert_not_match'] + tools.__all__
def assert_instance_of(expected, actual, msg=None):
- """Verify that object is an instance of expected """
- assert isinstance(actual, expected), msg
+ """Verify that object is an instance of expected """
+ assert isinstance(actual, expected), msg
def assert_not_instance_of(expected, actual, msg=None):
- """Verify that object is not an instance of expected """
- assert not isinstance(actual, expected, msg)
-
+ """Verify that object is not an instance of expected """
+ assert not isinstance(actual, expected, msg)
+
def assert_none(actual, msg=None):
- """verify that item is None"""
- assert_equal(None, actual, msg)
+ """verify that item is None"""
+ assert_equal(None, actual, msg)
def assert_not_none(actual, msg=None):
- """verify that item is None"""
- assert_not_equal(None, actual, msg)
+ """verify that item is None"""
+ assert_not_equal(None, actual, msg)
def assert_match(pattern, string, msg=None):
- """verify that the pattern matches the string"""
- assert_not_none(re.search(pattern, string), msg)
+ """verify that the pattern matches the string"""
+ assert_not_none(re.search(pattern, string), msg)
def assert_not_match(pattern, string, msg=None):
- """verify that the pattern does not match the string"""
- assert_none(re.search(pattern, string), msg) \ No newline at end of file
+ """verify that the pattern does not match the string"""
+ assert_none(re.search(pattern, string), msg) \ No newline at end of file
diff --git a/test/testlib/helper.py b/test/testlib/helper.py
index ca262ee4..74f48447 100644
--- a/test/testlib/helper.py
+++ b/test/testlib/helper.py
@@ -9,11 +9,11 @@ import os
GIT_REPO = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
def fixture_path(name):
- test_dir = os.path.dirname(os.path.dirname(__file__))
- return os.path.join(test_dir, "fixtures", name)
+ test_dir = os.path.dirname(os.path.dirname(__file__))
+ return os.path.join(test_dir, "fixtures", name)
def fixture(name):
- return open(fixture_path(name)).read()
+ return open(fixture_path(name)).read()
def absolute_project_path():
- return os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
+ return os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))