Skip to content

Commit

Permalink
Improve: Add basic diff between commits
Browse files Browse the repository at this point in the history
  • Loading branch information
Aaron O'Mullan committed Feb 7, 2013
1 parent bbc3395 commit 5014d8b
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 5 deletions.
75 changes: 70 additions & 5 deletions gittle/gittle.py
Expand Up @@ -4,12 +4,14 @@
# Python imports
import os
import copy
import logging
from hashlib import sha1
from shutil import rmtree
from functools import partial
import logging
from functools import partial, wraps
from StringIO import StringIO

# Dulwich imports
from dulwich import patch
from dulwich.repo import Repo as DulwichRepo
from dulwich.client import get_transport_and_path
from dulwich.index import build_index_from_tree, changes_from_tree
Expand All @@ -24,7 +26,28 @@
__all__ = ('Gittle',)


# Useful decorators
# A better way to do this in the future would maybe to use Mixins
def working_only(method):
@wraps(method)
def f(self, *args, **kwargs):
if self.is_working:
return method(*args, **kwargs)
raise NotImplemented("%s can not be called on a bare repository")
return f


def bare_only(method):
@wraps(method)
def f(self, *args, **kwargs):
if self.is_bare:
return method(*args, **kwargs)
raise NotImplemented("%s can not be called on a working repository")
return f


class Gittle(object):
DEFAULT_COMMIT = 'HEAD'
DEFAULT_BRANCH = 'master'
DEFAULT_MESSAGE = '**No Message**'
DEFAULT_USER_INFO = {
Expand Down Expand Up @@ -85,6 +108,21 @@ def _format_userinfo(self, userinfo):
return self._format_author(name, email)
return None

@property
def is_bare(self):
"""Bare repositories have no working directories or indexes
"""
return self.repo.bare

@property
def is_working(self):
return not(self.is_bare)

def has_index(self):
"""Opposite of is_bare
"""
return self.repo.has_index()

@property
def has_commits(self):
"""
Expand Down Expand Up @@ -227,13 +265,16 @@ def fetch(self, origin_uri=None):
return self.checkout_all()

@classmethod
def clone(cls, origin_uri, local_path, auth=None, mkdir=True, **kwargs):
def clone(cls, origin_uri, local_path, auth=None, mkdir=True, bare=False, **kwargs):
"""Clone a remote repository"""
if mkdir and not(os.path.exists(local_path)):
os.makedirs(local_path)

# Initialize the local repository
local_repo = DulwichRepo.init(local_path)
if bare:
local_repo = cls.init_bare(local_path)
else:
local_repo = cls.init(local_path)

repo = cls(local_repo, origin_uri=origin_uri, auth=auth)

Expand All @@ -254,7 +295,8 @@ def _commit(self, committer=None, author=None, message=None, *args, **kwargs):
return self.repo.do_commit(
message=message,
author=author_msg,
committer=committer_msg)
committer=committer_msg,
encoding='UTF-8')

# Like: git commmit -a
def commit(self, name=None, email=None, message=None):
Expand Down Expand Up @@ -479,6 +521,29 @@ def _parse_reference(self, ref_string):
return self._get_commits_nth_parent(commit, count)
return self.repo[ref_string]

def _commit_tree(self, commit_sha):
"""Return the tree object for a given commit
"""
return self.repo[commit_sha].tree

def diff_between(self, old_commit_sha, new_commit_sha):
"""Get the diff between two commits
"""
old_tree = self._commit_tree(old_commit_sha)
new_tree = self._commit_tree(new_commit_sha)

output = StringIO()

# Write to output (our string)
patch.write_tree_diff(
output,
self.repo.object_store,
old_tree,
new_tree
)

return output.getvalue()

def __hash__(self):
"""
This is required otherwise the memoize function
Expand Down
2 changes: 2 additions & 0 deletions sitecustomize.py
@@ -0,0 +1,2 @@
import sys
sys.setdefaultencoding('latin-1')
30 changes: 30 additions & 0 deletions tests/commit.py
@@ -0,0 +1,30 @@
# -*- coding: utf8 -*-

import os
from gittle import Gittle
from tempfile import mkdtemp

path = mkdtemp()
fn = 'test.txt'
filename = os.path.join(path, fn)

name = 'Samy Pessé'
email = 'samypesse@gmail.com'
message = "C'est beau là bas"


def create_file():
fd = open(filename, 'w+')
fd.write('blabla\n BOOM BOOM\n à la montagne')
fd.close()

repo = Gittle.init(path)
create_file()

repo.stage(fn)
repo.commit(name=name, email=email, message=message)


print('COMMIT_INFO =', repo.commit_info())

print('PATH =', path)
10 changes: 10 additions & 0 deletions tests/diff.py
@@ -0,0 +1,10 @@
from gittle import Gittle

repo = Gittle('.')

lastest = [
info['sha']
for info in repo.commit_info()[:2]
]

print(repo.diff_between(*lastest))

0 comments on commit 5014d8b

Please sign in to comment.