Browse Source

Added_symbolic_ref function into porcelain module.

This implements `git symbolic-ref` command via Dulwich porcelain.

Signed-off-by: Jelmer Vernooij <jelmer@samba.org>
Marcin Kuzminski 11 years ago
parent
commit
776d9d8964
3 changed files with 67 additions and 0 deletions
  1. 11 0
      bin/dulwich
  2. 15 0
      dulwich/porcelain.py
  3. 41 0
      dulwich/tests/test_porcelain.py

+ 11 - 0
bin/dulwich

@@ -184,6 +184,16 @@ def cmd_update_server_info(args):
     porcelain.update_server_info(".")
 
 
+def cmd_symbolic_ref(args):
+    opts, args = getopt(args, "", ["ref-name", "force"])
+    if not args:
+        print "Usage: dulwich symbolic-ref REF_NAME [--force]"
+        sys.exit(1)
+
+    ref_name = args.pop(0)
+    porcelain.symbolic_ref(".", ref_name=ref_name, force='--force' in args)
+
+
 def cmd_show(args):
     opts, args = getopt(args, "", [])
     porcelain.show(".")
@@ -200,6 +210,7 @@ commands = {
     "clone": cmd_clone,
     "archive": cmd_archive,
     "update-server-info": cmd_update_server_info,
+    "symbolic-ref": cmd_symbolic_ref,
     "diff": cmd_diff,
     "add": cmd_add,
     "rm": cmd_rm,

+ 15 - 0
dulwich/porcelain.py

@@ -34,6 +34,7 @@ Currently implemented:
  * init
  * remove
  * update-server-info
+ * symbolic-ref
 
 These functions are meant to behave similarly to the git subcommands.
 Differences in behaviour are considered bugs.
@@ -74,6 +75,20 @@ def update_server_info(repo="."):
     server_update_server_info(r)
 
 
+def symbolic_ref(repo, ref_name, force=False):
+    """Set git symbolic ref into HEAD.
+
+    :param repo: path to the repository
+    :param ref_name: short name of the new ref
+    :param force: force settings without checking if it exists in refs/heads
+    """
+    repo_obj = open_repo(repo)
+    ref_path = 'refs/heads/%s' % ref_name
+    if not force and ref_path not in repo_obj.refs.keys():
+        raise ValueError('fatal: ref `%s` is not a ref' % ref_name)
+    repo_obj.refs.set_symbolic_ref('HEAD', ref_path)
+
+
 def commit(repo=".", message=None, author=None, committer=None):
     """Create a new commit.
 

+ 41 - 0
dulwich/tests/test_porcelain.py

@@ -160,3 +160,44 @@ class ShowTests(PorcelainTestCase):
         outstream = StringIO()
         porcelain.show(self.repo.path, committish=c3.id, outstream=outstream)
         self.assertTrue(outstream.getvalue().startswith("-" * 50))
+
+
+class SymbolicRefTests(PorcelainTestCase):
+
+    def test_set_wrong_symbolic_ref(self):
+        c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
+            [3, 1, 2]])
+        self.repo.refs["HEAD"] = c3.id
+
+        outstream = StringIO()
+        self.assertRaises(ValueError, porcelain.symbolic_ref, self.repo.path, 'foobar')
+
+    def test_set_force_wrong_symbolic_ref(self):
+        c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
+            [3, 1, 2]])
+        self.repo.refs["HEAD"] = c3.id
+
+        porcelain.symbolic_ref(self.repo.path, 'force_foobar', force=True)
+
+        #test if we actually changed the file
+        new_ref = self.repo.get_named_file('HEAD').read()
+        self.assertEqual(new_ref, 'ref: refs/heads/force_foobar\n')
+
+    def test_set_symbolic_ref(self):
+        c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
+            [3, 1, 2]])
+        self.repo.refs["HEAD"] = c3.id
+
+        porcelain.symbolic_ref(self.repo.path, 'master')
+
+    def test_set_symbolic_ref_other_than_master(self):
+        c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
+            [3, 1, 2]], attrs=dict(refs='develop'))
+        self.repo.refs["HEAD"] = c3.id
+        self.repo.refs["refs/heads/develop"] = c3.id
+
+        porcelain.symbolic_ref(self.repo.path, 'develop')
+
+        #test if we actually changed the file
+        new_ref = self.repo.get_named_file('HEAD').read()
+        self.assertEqual(new_ref, 'ref: refs/heads/develop\n')