# HG changeset patch # User Andrew Shadura # Date 2016-07-24 18:12:14 # Node ID e54ddaa52fee0b56d8d089aba2d3f00775bfb8b3 # Parent bcb8073057313cf4151ede244b7f0b6cc0092432 hooks: parse incoming git refs correctly Hooks receive a line of the following format on standard input: SP SP LF where is the old object name stored in the ref, is the new object name to be stored in the ref and is the full name of the ref. This means, we have to strip at least the LF in order to have a correct version of the ref name after the split. Also, when parsing the ref name itself, use all components but first instead of just second, as a ref name may have slashes in it. Previously, failure to parse ref name correctly would lead to the following behaviour. A newly created repository with no commits pushed has HEAD set to refs/heads/master by default, even though there's no such ref in the repository yet. Upon first push, Kallithea rewrites this symbolic reference with a reference to a real branch. However, due to a bug in ref name parsing, if a ref name had a slash, Kallithea would update HEAD to an invalid reference: git push origin feature/branch would rewrite HEAD to refs/heads/feature. All future attempts to work with this repository would fail because dulwich would complain it can't read HEAD as it is a directory. diff --git a/kallithea/lib/hooks.py b/kallithea/lib/hooks.py --- a/kallithea/lib/hooks.py +++ b/kallithea/lib/hooks.py @@ -424,14 +424,14 @@ def handle_git_receive(repo_path, revs, elif hook_type == 'post' and _hooks.get(Ui.HOOK_PUSH): rev_data = [] for l in revs: - old_rev, new_rev, ref = l.split(' ') + old_rev, new_rev, ref = l.strip().split(' ') _ref_data = ref.split('/') if _ref_data[1] in ['tags', 'heads']: rev_data.append({'old_rev': old_rev, 'new_rev': new_rev, 'ref': ref, 'type': _ref_data[1], - 'name': _ref_data[2].strip()}) + 'name': '/'.join(_ref_data[2:])}) git_revs = []