:raise ValueError: If the range can not be parsed
"""
committish = to_bytes(committish)
- return repo[committish] # For now..
+ try:
+ return repo[committish]
+ except KeyError:
+ pass
+ try:
+ return repo[parse_ref(repo, committish)]
+ except KeyError:
+ pass
+ raise KeyError(committish)
# TODO: parse_path_in_tree(), which handles e.g. v1.0:Documentation
* add
* branch{_create,_delete,_list}
* check-ignore
+ * checkout
* clone
* commit
* commit-tree
pretty_format_tree_entry,
)
from dulwich.objectspec import (
+ parse_commit,
parse_object,
+ parse_ref,
parse_reftuples,
parse_tree,
)
continue
if ignore_manager.is_ignored(path):
yield path
+
+
+def update_head(repo, target, detached=False, new_branch=None):
+ """Update HEAD to point at a new branch/commit.
+
+ Note that this does not actually update the working tree.
+
+ :param repo: Path to the repository
+ :param detach: Create a detached head
+ :param target: Branch or committish to switch to
+ :param new_branch: New branch to create
+ """
+ with open_repo_closing(repo) as r:
+ if new_branch is not None:
+ to_set = b"refs/heads/" + new_branch.encode(DEFAULT_ENCODING)
+ else:
+ to_set = b"HEAD"
+ if detached:
+ # TODO(jelmer): Provide some way so that the actual ref gets
+ # updated rather than what it points to, so the delete isn't necessary.
+ del r.refs[to_set]
+ r.refs[to_set] = parse_commit(r, target).id
+ else:
+ r.refs.set_symbolic_ref(to_set, parse_ref(r, target))
+ if new_branch is not None:
+ r.refs.set_symbolic_ref(b"HEAD", to_set)
self.assertEqual(
['foo'],
list(porcelain.check_ignore(self.repo, ['foo'], no_index=True)))
+
+
+class UpdateHeadTests(PorcelainTestCase):
+
+ def test_set_to_branch(self):
+ [c1] = build_commit_graph(self.repo.object_store, [[1]])
+ self.repo.refs[b"refs/heads/blah"] = c1.id
+ porcelain.update_head(self.repo, "blah")
+ self.assertEqual(c1.id, self.repo.head())
+ self.assertEqual(b'ref: refs/heads/blah',
+ self.repo.refs.read_ref('HEAD'))
+
+ def test_set_to_branch_detached(self):
+ [c1] = build_commit_graph(self.repo.object_store, [[1]])
+ self.repo.refs[b"refs/heads/blah"] = c1.id
+ porcelain.update_head(self.repo, "blah", detached=True)
+ self.assertEqual(c1.id, self.repo.head())
+ self.assertEqual(c1.id, self.repo.refs.read_ref(b'HEAD'))
+
+ def test_set_to_commit_detached(self):
+ [c1] = build_commit_graph(self.repo.object_store, [[1]])
+ self.repo.refs[b"refs/heads/blah"] = c1.id
+ porcelain.update_head(self.repo, c1.id, detached=True)
+ self.assertEqual(c1.id, self.repo.head())
+ self.assertEqual(c1.id, self.repo.refs.read_ref(b'HEAD'))
+
+ def test_set_new_branch(self):
+ [c1] = build_commit_graph(self.repo.object_store, [[1]])
+ self.repo.refs[b"refs/heads/blah"] = c1.id
+ porcelain.update_head(self.repo, "blah", new_branch="bar")
+ self.assertEqual(c1.id, self.repo.head())
+ self.assertEqual(b'ref: refs/heads/bar',
+ self.repo.refs.read_ref(b'HEAD'))