Commit 4f08bab6 authored by Michal Čihař's avatar Michal Čihař

Merge branch 'master' into bootstrap

Conflicts:
	weblate/html/git-commit-info.html
	weblate/html/js/git-status.html
parents 7f6cfa0b ff4661b5
......@@ -14,8 +14,6 @@ Django (>= 1.6)
https://www.djangoproject.com/
Translate-toolkit (>= 1.9.0, 1.10.0 or newer strongly recommended)
http://toolkit.translatehouse.org/
GitPython (>= 0.3.2)
https://github.com/gitpython-developers/GitPython
Git (>= 1.7.2)
http://git-scm.com/
python-social-auth (>= 0.1.17, < 0.1.24)
......@@ -47,7 +45,7 @@ you can use apt-get:
.. code-block:: sh
apt-get install python-django translate-toolkit python-git \
apt-get install python-django translate-toolkit \
python-whoosh python-pil python-django-south python-libravatar \
python-pyicu python-babel
......@@ -77,7 +75,7 @@ All requirements are available either directly in openSUSE or in
.. code-block:: sh
zypper install python-Django python-icu translate-toolkit python-GitPython \
zypper install python-Django python-icu translate-toolkit \
python-Whoosh python-Pillow python-South python-python-social-auth \
python-babel
......
......@@ -15,7 +15,6 @@ Requires: cron
Requires: python-django >= 1.5
Requires: python-python-social-auth >= 0.1.17
Requires: translate-toolkit >= 1.10.0
Requires: python-GitPython >= 0.3.2
Requires: python-whoosh >= 2.5.2
Requires: python-Pillow
Requires: python-South >= 1.0
......
......@@ -23,6 +23,7 @@ import logging
from weblate.requirements import (
check_requirements, get_versions, get_optional_versions
)
from weblate.trans.vcs import GitRepository, RepositoryException
logger = logging.getLogger('weblate')
......@@ -39,7 +40,7 @@ def is_running_git():
'''
Checks whether we're running inside Git checkout.
'''
return os.path.exists(os.path.join(get_root_dir(), '.git'))
return os.path.exists(os.path.join(get_root_dir(), '.git', 'config'))
# Weblate version
VERSION = '2.0'
......@@ -58,9 +59,8 @@ GIT_VERSION = VERSION
# Grab some information from git
if RUNNING_GIT:
try:
import git
# Describe current checkout
GIT_VERSION = git.Repo(get_root_dir()).git.describe(always=True)
GIT_VERSION = GitRepository(get_root_dir()).describe()
# Check if we're close to release tag
parts = GIT_VERSION.split('-')
......@@ -70,7 +70,7 @@ if RUNNING_GIT:
# Mark version as devel if it is
if not GIT_RELEASE:
VERSION += '-dev'
except (ImportError, git.exc.GitCommandError):
except RepositoryException:
# Import failed or git has troubles reading
# repo (eg. swallow clone)
RUNNING_GIT = False
......
......@@ -17,7 +17,7 @@
<p>{% blocktrans with sp.repo as repo and sp.linked_subproject.get_full_slug as slug %}Not showing status of linked repository. Check <a href="#{{ slug }}">{{ repo }}</a> instead.{% endblocktrans %}</p>
{% else %}
<pre>
{{ sp.git_repo.git.status }}
{{ sp.repository.status }}
</pre>
{% endif %}
{% endfor %}
......
{% load i18n %}{% load translations %}
{% load i18n %}
<code class="git-commit" data-toggle="tooltip" data-placement="bottom" data-title="
{% blocktrans with commit.hexsha as hash %}Commit {{ hash }}{% endblocktrans %}<br />
{% blocktrans with commit.author.name as author and commit.authored_date|gitdate as date %}Authored by {{ author }} on {{ date }}{% endblocktrans %}
{% blocktrans with commit.author.name as author and commit.authored_date|date:"DATETIME_FORMAT" as date %}Authored by {{ author }} on {{ date }}{% endblocktrans %}
">{{ commit.hexsha|slice:":8" }}</code>
......@@ -64,12 +64,12 @@
{% for sp in object.subproject_set.all %}
<h4>{{ sp }}</h3>
<pre>
{{ sp.git_repo.git.status }}
{{ sp.repository.status }}
</pre>
{% endfor %}
{% else %}
<pre>
{{ object.git_repo.git.status }}
{{ object.repository.status }}
</pre>
{% endif %}
</div>
......
......@@ -130,26 +130,6 @@ def get_versions():
'2.5',
))
name = 'GitPython'
url = 'https://github.com/gitpython-developers/GitPython'
mod = get_version_module('git', name, url)
result.append((
name,
url,
mod.__version__,
'0.3.2',
))
name = 'gitdb'
url = 'https://github.com/gitpython-developers/gitdb'
mod = get_version_module('gitdb', name, url)
result.append((
name,
url,
mod.__version__,
'0.5.4',
))
result.append((
'Git',
'http://git-scm.com/',
......
......@@ -30,4 +30,4 @@ class Command(WeblateCommand):
'''
for subproject in self.get_subprojects(*args, **options):
print '%s:' % subproject
print subproject.git_repo.git.status()
print subproject.repository.status()
......@@ -24,10 +24,10 @@ from django.utils.text import slugify
from weblate.trans.models import SubProject, Project
from weblate.trans.formats import FILE_FORMATS
from weblate.trans.util import is_repo_link
from weblate.trans.vcs import GitRepository
from glob import glob
from optparse import make_option
import tempfile
import git
import os
import re
import shutil
......@@ -109,16 +109,10 @@ class Command(BaseCommand):
os.chmod(workdir, 0755)
# Initialize git repository
self.logger.info('Initializing git repository...')
gitrepo = git.Repo.init(workdir)
gitrepo.git.remote('add', 'origin', repo)
self.logger.info('Fetching remote git repository...')
gitrepo.git.remote('update', 'origin')
gitrepo.git.branch('--track', branch, 'origin/%s' % branch)
self.logger.info('Cloning git repository...')
gitrepo = GitRepository.clone(repo, workdir)
self.logger.info('Updating working copy in git repository...')
gitrepo.git.checkout(branch)
gitrepo.configure_branch(branch)
return workdir
......
This diff is collapsed.
......@@ -29,9 +29,7 @@ from django.utils import timezone
from django.core.urlresolvers import reverse
import os
import subprocess
import git
import traceback
import ConfigParser
from translate.storage import poheader
from datetime import datetime, timedelta
......@@ -45,6 +43,7 @@ from weblate.trans.models.unitdata import Check, Suggestion, Comment
from weblate.trans.util import (
get_site_url, sleep_while_git_locked, translation_percent, split_plural,
)
from weblate.trans.vcs import RepositoryException
from weblate.accounts.avatar import get_user_display
from weblate.trans.mixins import URLMixin, PercentMixin
from weblate.trans.boolean_sum import BooleanSum
......@@ -611,8 +610,8 @@ class Translation(models.Model, URLMixin, PercentMixin):
notify_new_string(self)
@property
def git_repo(self):
return self.subproject.git_repo
def repository(self):
return self.subproject.repository
def get_last_remote_commit(self):
return self.subproject.get_last_remote_commit()
......@@ -633,24 +632,11 @@ class Translation(models.Model, URLMixin, PercentMixin):
'''
Returns current Git blob hash for file.
'''
tree = self.git_repo.tree()
try:
ret = tree[self.filename].hexsha
except KeyError:
# Try to resolve symlinks
real_path = os.path.realpath(self.get_filename())
project_path = os.path.realpath(self.subproject.get_path())
if not real_path.startswith(project_path):
raise ValueError('Too many symlinks or link outside tree')
real_path = real_path[len(project_path):].lstrip('/')
ret = tree[real_path].hexsha
ret = self.repository.get_object_hash(self.get_filename())
if self.subproject.has_template():
ret += ','
ret += tree[self.subproject.template].hexsha
ret += self.repository.get_object_hash(self.subproject.template)
return ret
def update_stats(self):
......@@ -801,50 +787,10 @@ class Translation(models.Model, URLMixin, PercentMixin):
return msg
def __configure_git(self, gitrepo, section, key, expected):
'''
Adjusts git config to ensure that section.key is set to expected.
'''
cnf = gitrepo.config_writer()
try:
# Get value and if it matches we're done
value = cnf.get(section, key)
if value == expected:
return
except ConfigParser.Error:
pass
# Add section if it does not exist
if not cnf.has_section(section):
cnf.add_section(section)
# Update config
cnf.set(section, key, expected)
def __configure_committer(self, gitrepo):
'''
Wrapper for setting proper committer. As this can not be done by
passing parameter, we need to check config on every commit.
'''
self.__configure_git(
gitrepo,
'user',
'name',
self.subproject.project.committer_name
)
self.__configure_git(
gitrepo,
'user',
'email',
self.subproject.project.committer_email
)
def __git_commit(self, gitrepo, author, timestamp, sync=False):
def __git_commit(self, author, timestamp, sync=False):
'''
Commits translation to git.
'''
# Check git config
self.__configure_committer(gitrepo)
# Format commit message
msg = self.get_commit_message()
......@@ -867,7 +813,7 @@ class Translation(models.Model, URLMixin, PercentMixin):
)
# Create list of files to commit
gitrepo.git.add(self.filename)
files = [self.filename]
if self.subproject.extra_commit_file != '':
extra_file = self.subproject.extra_commit_file % {
'language': self.language_code,
......@@ -877,13 +823,11 @@ class Translation(models.Model, URLMixin, PercentMixin):
extra_file
)
if os.path.exists(full_path_extra):
gitrepo.git.add(extra_file)
files.append(extra_file)
# Do actual commit
gitrepo.git.commit(
author=author.encode('utf-8'),
date=timestamp.isoformat(),
m=msg.encode('utf-8'),
self.repository.commit(
msg, author, timestamp, files
)
# Optionally store updated hash
......@@ -894,11 +838,7 @@ class Translation(models.Model, URLMixin, PercentMixin):
'''
Checks whether there are some not committed changes.
'''
status = self.git_repo.git.status('--porcelain', '--', self.filename)
if status == '':
# No changes to commit
return False
return True
return self.repository.needs_commit(self.filename)
def git_needs_merge(self):
return self.subproject.git_needs_merge()
......@@ -916,8 +856,6 @@ class Translation(models.Model, URLMixin, PercentMixin):
sync updates git hash stored within the translation (otherwise
translation rescan will be needed)
'''
gitrepo = self.git_repo
# Is there something for commit?
if not self.git_needs_commit():
return False
......@@ -941,12 +879,12 @@ class Translation(models.Model, URLMixin, PercentMixin):
)
with self.subproject.git_lock:
try:
self.__git_commit(gitrepo, author, timestamp, sync)
except git.GitCommandError:
self.__git_commit(author, timestamp, sync)
except RepositoryException:
# There might be another attempt on commit in same time
# so we will sleep a bit an retry
sleep_while_git_locked()
self.__git_commit(gitrepo, author, timestamp, sync)
self.__git_commit(author, timestamp, sync)
# Push if we should
if (self.subproject.project.push_on_commit
......
......@@ -23,13 +23,12 @@ from django.contrib.admin.templatetags.admin_static import static
from django.utils.safestring import mark_safe
from django.utils.encoding import force_unicode
from django.utils.translation import ugettext as _, ungettext, ugettext_lazy
from django.utils.formats import date_format
from django.utils import timezone
from django import template
import re
from datetime import date, datetime
from datetime import date
import weblate
......@@ -252,17 +251,6 @@ def show_checks(checks, user):
}
@register.filter
def gitdate(value):
'''
Formats timestamp as returned byt GitPython.
'''
return date_format(
datetime.fromtimestamp(value),
'DATETIME_FORMAT'
)
def naturaltime_past(value, now):
"""
Handling of past dates for naturaltime.
......
......@@ -29,11 +29,11 @@ from django.contrib.auth.models import Permission, User
from django.core.exceptions import ValidationError
import shutil
import os
import git
from weblate.trans.models import Project, SubProject, Unit, WhiteboardMessage
from weblate.trans.models.source import Source
from weblate import appsettings
from weblate.trans.tests.test_util import get_test_file
from weblate.trans.vcs import GitRepository
REPOWEB_URL = \
'https://github.com/nijel/weblate-test/blob/master/%(file)s#L%(line)s'
......@@ -61,15 +61,12 @@ class RepoTestCase(TestCase):
'test-repo.git'
)
# Git command wrapper
cmd = git.Git()
# Clone repo for testing
if not os.path.exists(self.base_repo_path):
cmd.clone(
'--bare',
GitRepository.clone(
GIT_URL,
self.base_repo_path
self.base_repo_path,
bare=True
)
# Remove possibly existing directory
......
......@@ -19,10 +19,12 @@
#
from weblate.trans.tests.test_models import RepoTestCase
from weblate.trans.vcs import GitRepository
from weblate.trans.vcs import GitRepository, RepositoryException
import tempfile
import shutil
import os.path
import datetime
class VCSGitTest(RepoTestCase):
......@@ -31,51 +33,49 @@ class VCSGitTest(RepoTestCase):
def setUp(self):
super(VCSGitTest, self).setUp()
self._tempdir = tempfile.mkdtemp()
self.repo = GitRepository.clone(self.repo_path, self._tempdir)
def tearDown(self):
if self._tempdir is not None:
shutil.rmtree(self._tempdir)
def test_clone(self):
GitRepository.clone(self.repo_path, self._tempdir)
self.assertTrue(os.path.exists(os.path.join(self._tempdir, '.git')))
def test_revision(self):
repo = GitRepository.clone(self.repo_path, self._tempdir)
self.assertEquals(
repo.last_revision,
repo.last_remote_revision
self.repo.last_revision,
self.repo.last_remote_revision
)
def test_update_remote(self):
repo = GitRepository.clone(self.repo_path, self._tempdir)
repo.update_remote()
self.repo.update_remote()
def test_push(self):
repo = GitRepository.clone(self.repo_path, self._tempdir)
repo.push('master')
self.repo.push('master')
def test_reset(self):
repo = GitRepository.clone(self.repo_path, self._tempdir)
repo.reset('master')
self.repo.reset('master')
def test_merge(self):
repo = GitRepository.clone(self.repo_path, self._tempdir)
repo.merge('master')
self.repo.merge('master')
def test_rebase(self):
repo = GitRepository.clone(self.repo_path, self._tempdir)
repo.rebase('master')
self.repo.rebase('master')
def test_status(self):
repo = GitRepository.clone(self.repo_path, self._tempdir)
status = repo.status()
status = self.repo.status()
self.assertTrue(
"Your branch is up-to-date with 'origin/master'." in status
)
def test_needs_commit(self):
repo = GitRepository.clone(self.repo_path, self._tempdir)
self.assertFalse(repo.needs_commit())
self.assertFalse(self.repo.needs_commit())
with open(os.path.join(self._tempdir, 'README.md'), 'a') as handle:
handle.write('CHANGE')
self.assertTrue(self.repo.needs_commit())
self.assertTrue(self.repo.needs_commit('README.md'))
self.assertFalse(self.repo.needs_commit('dummy'))
def check_valid_info(self, info):
self.assertTrue('summary' in info)
......@@ -85,14 +85,12 @@ class VCSGitTest(RepoTestCase):
self.assertTrue('commitdate' in info)
def test_revision_info(self):
repo = GitRepository.clone(self.repo_path, self._tempdir)
# Latest commit
info = repo.get_revision_info(repo.last_revision)
info = self.repo.get_revision_info(self.repo.last_revision)
self.check_valid_info(info)
# GPG signed commit
info = repo.get_revision_info(
info = self.repo.get_revision_info(
'd6179e46c8255f1d5029f06c49468caf57b13b61'
)
self.check_valid_info(info)
......@@ -102,15 +100,89 @@ class VCSGitTest(RepoTestCase):
)
# Normal commit
info = repo.get_revision_info(
info = self.repo.get_revision_info(
'2ae1998450a693f0a7962d69a1eec4cb2213d595'
)
self.check_valid_info(info)
def test_needs_merge(self):
repo = GitRepository.clone(self.repo_path, self._tempdir)
self.assertFalse(repo.needs_merge('master'))
self.assertFalse(repo.needs_push('master'))
self.assertFalse(self.repo.needs_merge('master'))
self.assertFalse(self.repo.needs_push('master'))
def test_get_version(self):
self.assertTrue(GitRepository.get_version() != '')
def test_set_committer(self):
self.repo.set_committer('Foo Bar', 'foo@example.net')
self.assertEquals(
self.repo.get_config('user.name'), 'Foo Bar'
)
self.assertEquals(
self.repo.get_config('user.email'), 'foo@example.net'
)
def test_commit(self):
self.repo.set_committer('Foo Bar', 'foo@example.net')
# Create test file
with open(os.path.join(self._tempdir, 'testfile'), 'w') as handle:
handle.write('TEST FILE\n')
oldrev = self.repo.last_revision
# Commit it
self.repo.commit(
'Test commit',
'Foo Bar <foo@bar.com>',
datetime.datetime.now(),
['testfile']
)
# Check we have new revision
self.assertNotEquals(
oldrev,
self.repo.last_revision
)
info = self.repo.get_revision_info(self.repo.last_revision)
self.assertEquals(
info['author'],
'Foo Bar <foo@bar.com>',
)
# Check file hash
self.assertEquals(
self.repo.get_object_hash('testfile'),
'fafd745150eb1f20fc3719778942a96e2106d25b'
)
def test_object_hash(self):
obj_hash = self.repo.get_object_hash('README.md')
self.assertEquals(
len(obj_hash),
40
)
def test_configure_remote(self):
self.repo.configure_remote('pullurl', 'pushurl', 'branch')
self.assertEquals(
self.repo.get_config('remote.origin.url'),
'pullurl',
)
self.assertEquals(
self.repo.get_config('remote.origin.pushURL'),
'pushurl',
)
# Test that we handle not set fetching
self.repo.execute(['config', '--unset', 'remote.origin.fetch'])
self.repo.configure_remote('pullurl', 'pushurl', 'branch')
self.assertEquals(
self.repo.get_config('remote.origin.fetch'),
'+refs/heads/branch:refs/remotes/origin/branch',
)
def test_configure_branch(self):
# Existing branch
self.repo.configure_branch('master')
self.assertRaises(
RepositoryException,
self.repo.configure_branch,
('branch')
)
......@@ -154,4 +154,5 @@ def get_clean_env():
return {
'HOME': os.environ['HOME'],
'PATH': os.environ['PATH'],
'LANG': os.environ['LANG'],
}
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment