# HG changeset patch # User Marcin Kuzminski # Date 2012-04-17 21:00:36 # Node ID 31ebf7010566489f7897983d4b738e1be2a2c98b # Parent 9784a54a0f5b8eb05afb8d9d89929d617702a43d various fixes for git and mercurial with InMemoryCommit backend and non-ascii files - hg use tolocal for unicode objects - git use core.quotepath=false for commands diff --git a/rhodecode/controllers/files.py b/rhodecode/controllers/files.py --- a/rhodecode/controllers/files.py +++ b/rhodecode/controllers/files.py @@ -306,10 +306,10 @@ class FilesController(BaseRepoController try: self.scm_model.create_node(repo=c.rhodecode_repo, - repo_name=repo_name, cs=c.cs, - user=self.rhodecode_user, - author=author, message=message, - content=content, f_path=node_path) + repo_name=repo_name, cs=c.cs, + user=self.rhodecode_user, + author=author, message=message, + content=content, f_path=node_path) h.flash(_('Successfully committed to %s' % node_path), category='success') except NodeAlreadyExistsError, e: diff --git a/rhodecode/lib/vcs/backends/git/changeset.py b/rhodecode/lib/vcs/backends/git/changeset.py --- a/rhodecode/lib/vcs/backends/git/changeset.py +++ b/rhodecode/lib/vcs/backends/git/changeset.py @@ -73,7 +73,6 @@ class GitChangeset(BaseChangeset): if ref: return safe_unicode(ref) - def _fix_path(self, path): """ Paths are stored without trailing slash so we need to get rid off it if @@ -131,7 +130,6 @@ class GitChangeset(BaseChangeset): name = item self._paths[name] = id self._stat_modes[name] = stat - if not path in self._paths: raise NodeDoesNotExistError("There is no file nor directory " "at the given path %r at revision %r" @@ -393,7 +391,7 @@ class GitChangeset(BaseChangeset): def _diff_name_status(self): output = [] for parent in self.parents: - cmd = 'diff --name-status %s %s' % (parent.raw_id, self.raw_id) + cmd = 'diff --name-status %s %s --encoding=utf8' % (parent.raw_id, self.raw_id) so, se = self.repository.run_git_command(cmd) output.append(so.strip()) return '\n'.join(output) @@ -409,13 +407,16 @@ class GitChangeset(BaseChangeset): for line in self._diff_name_status.splitlines(): if not line: continue + if line.startswith(char): - splitted = line.split(char,1) + splitted = line.split(char, 1) if not len(splitted) == 2: raise VCSError("Couldn't parse diff result:\n%s\n\n and " "particularly that line: %s" % (self._diff_name_status, line)) - paths.add(splitted[1].strip()) + _path = splitted[1].strip() + paths.add(_path) + return sorted(paths) @LazyProperty diff --git a/rhodecode/lib/vcs/backends/git/inmemory.py b/rhodecode/lib/vcs/backends/git/inmemory.py --- a/rhodecode/lib/vcs/backends/git/inmemory.py +++ b/rhodecode/lib/vcs/backends/git/inmemory.py @@ -5,12 +5,13 @@ from dulwich import objects from dulwich.repo import Repo from rhodecode.lib.vcs.backends.base import BaseInMemoryChangeset from rhodecode.lib.vcs.exceptions import RepositoryError +from rhodecode.lib.vcs.utils import safe_str class GitInMemoryChangeset(BaseInMemoryChangeset): def commit(self, message, author, parents=None, branch=None, date=None, - **kwargs): + **kwargs): """ Performs in-memory commit (doesn't check workdir in any way) and returns newly created ``Changeset``. Updates repository's @@ -120,9 +121,9 @@ class GitInMemoryChangeset(BaseInMemoryC commit = objects.Commit() commit.tree = commit_tree.id commit.parents = [p._commit.id for p in self.parents if p] - commit.author = commit.committer = author + commit.author = commit.committer = safe_str(author) commit.encoding = ENCODING - commit.message = message + ' ' + commit.message = safe_str(message) + ' ' # Compute date if date is None: diff --git a/rhodecode/lib/vcs/backends/git/repository.py b/rhodecode/lib/vcs/backends/git/repository.py --- a/rhodecode/lib/vcs/backends/git/repository.py +++ b/rhodecode/lib/vcs/backends/git/repository.py @@ -79,11 +79,13 @@ class GitRepository(BaseRepository): :param cmd: git command to be executed """ - #cmd = '(cd %s && git %s)' % (self.path, cmd) + _copts = ['-c', 'core.quotepath=false', ] + if isinstance(cmd, basestring): - cmd = 'GIT_CONFIG_NOGLOBAL=1 git %s' % cmd - else: - cmd = ['GIT_CONFIG_NOGLOBAL=1', 'git'] + cmd + cmd = [cmd] + + cmd = ['GIT_CONFIG_NOGLOBAL=1', 'git'] + _copts + cmd + try: opts = dict( shell=isinstance(cmd, basestring), diff --git a/rhodecode/lib/vcs/backends/hg/inmemory.py b/rhodecode/lib/vcs/backends/hg/inmemory.py --- a/rhodecode/lib/vcs/backends/hg/inmemory.py +++ b/rhodecode/lib/vcs/backends/hg/inmemory.py @@ -4,7 +4,7 @@ import errno from rhodecode.lib.vcs.backends.base import BaseInMemoryChangeset from rhodecode.lib.vcs.exceptions import RepositoryError -from ...utils.hgcompat import memfilectx, memctx, hex +from ...utils.hgcompat import memfilectx, memctx, hex, tolocal class MercurialInMemoryChangeset(BaseInMemoryChangeset): @@ -30,9 +30,9 @@ class MercurialInMemoryChangeset(BaseInM self.check_integrity(parents) from .repository import MercurialRepository - if not isinstance(message, str) or not isinstance(author, str): + if not isinstance(message, unicode) or not isinstance(author, unicode): raise RepositoryError('Given message and author needs to be ' - 'an instance') + 'an instance') if branch is None: branch = MercurialRepository.DEFAULT_BRANCH_NAME @@ -70,7 +70,7 @@ class MercurialInMemoryChangeset(BaseInM copied=False) raise RepositoryError("Given path haven't been marked as added," - "changed or removed (%s)" % path) + "changed or removed (%s)" % path) parents = [None, None] for i, parent in enumerate(self.parents): @@ -89,9 +89,11 @@ class MercurialInMemoryChangeset(BaseInM date=date, extra=kwargs) + loc = lambda u: tolocal(u.encode('utf-8')) + # injecting given _repo params - commit_ctx._text = message - commit_ctx._user = author + commit_ctx._text = loc(message) + commit_ctx._user = loc(author) commit_ctx._date = date # TODO: Catch exceptions! diff --git a/rhodecode/lib/vcs/nodes.py b/rhodecode/lib/vcs/nodes.py --- a/rhodecode/lib/vcs/nodes.py +++ b/rhodecode/lib/vcs/nodes.py @@ -120,6 +120,10 @@ class Node(object): return None @LazyProperty + def unicode_path(self): + return safe_unicode(self.path) + + @LazyProperty def name(self): """ Returns name of the node so if its path diff --git a/rhodecode/lib/vcs/utils/hgcompat.py b/rhodecode/lib/vcs/utils/hgcompat.py --- a/rhodecode/lib/vcs/utils/hgcompat.py +++ b/rhodecode/lib/vcs/utils/hgcompat.py @@ -1,6 +1,7 @@ -"""Mercurial libs compatibility +""" +Mercurial libs compatibility +""" -""" from mercurial import archival, merge as hg_merge, patch, ui from mercurial.commands import clone, nullid, pull from mercurial.context import memctx, memfilectx @@ -10,3 +11,4 @@ from mercurial.localrepo import localrep from mercurial.match import match from mercurial.mdiff import diffopts from mercurial.node import hex +from mercurial.encoding import tolocal \ No newline at end of file diff --git a/rhodecode/model/scm.py b/rhodecode/model/scm.py --- a/rhodecode/model/scm.py +++ b/rhodecode/model/scm.py @@ -35,7 +35,7 @@ from rhodecode.lib.vcs.nodes import File from rhodecode import BACKENDS from rhodecode.lib import helpers as h -from rhodecode.lib.utils2 import safe_str +from rhodecode.lib.utils2 import safe_str, safe_unicode from rhodecode.lib.auth import HasRepoPermissionAny, HasReposGroupPermissionAny from rhodecode.lib.utils import get_repos as get_filesystem_repos, make_ui, \ action_logger, EmptyChangeset, REMOVED_REPO_PAT @@ -369,14 +369,16 @@ class ScmModel(BaseModel): # decoding here will force that we have proper encoded values # in any other case this will throw exceptions and deny commit content = safe_str(content) - message = safe_str(message) path = safe_str(f_path) - author = safe_str(author) + # message and author needs to be unicode + # proper backend should then translate that into required type + message = safe_unicode(message) + author = safe_unicode(author) m = IMC(repo) m.change(FileNode(path, content)) tip = m.commit(message=message, - author=author, - parents=[cs], branch=cs.branch) + author=author, + parents=[cs], branch=cs.branch) new_cs = tip.short_id action = 'push_local:%s' % new_cs @@ -403,21 +405,21 @@ class ScmModel(BaseModel): type(content) )) - message = safe_str(message) + message = safe_unicode(message) + author = safe_unicode(author) path = safe_str(f_path) - author = safe_str(author) m = IMC(repo) if isinstance(cs, EmptyChangeset): - # Emptychangeset means we we're editing empty repository + # EmptyChangeset means we we're editing empty repository parents = None else: parents = [cs] m.add(FileNode(path, content=content)) tip = m.commit(message=message, - author=author, - parents=parents, branch=cs.branch) + author=author, + parents=parents, branch=cs.branch) new_cs = tip.short_id action = 'push_local:%s' % new_cs diff --git a/rhodecode/templates/files/files_edit.html b/rhodecode/templates/files/files_edit.html --- a/rhodecode/templates/files/files_edit.html +++ b/rhodecode/templates/files/files_edit.html @@ -56,7 +56,7 @@ % endif -
${_('Editing file')}: ${c.file.path}
+
${_('Editing file')}: ${c.file.unicode_path}