ソースを参照

Add porcelain for branch delete/list/create.

Jelmer Vernooij 10 年 前
コミット
220ec30ca6
4 ファイル変更101 行追加0 行削除
  1. 3 0
      NEWS
  2. 51 0
      dulwich/porcelain.py
  3. 4 0
      dulwich/refs.py
  4. 43 0
      dulwich/tests/test_porcelain.py

+ 3 - 0
NEWS

@@ -18,6 +18,9 @@
 
   * Add 'status' support to bin/dulwich. (Jelmer Vernooij)
 
+  * Add 'branch_create', 'branch_list', 'branch_delete' porcelain.
+    (Jelmer Vernooij)
+
  CHANGES
 
   * dul-web is now available as 'dulwich web-daemon'.

+ 51 - 0
dulwich/porcelain.py

@@ -21,6 +21,7 @@
 Currently implemented:
  * archive
  * add
+ * branch{_create,_delete,_list}
  * clone
  * commit
  * commit-tree
@@ -624,3 +625,53 @@ def receive_pack(path=".", inf=sys.stdin, outf=sys.stdout):
     # FIXME: Catch exceptions and write a single-line summary to outf.
     handler.handle()
     return 0
+
+
+def branch_delete(repo, name):
+    """Delete a branch.
+
+    :param repo: Path to the repository
+    :param name: Name of the branch
+    """
+    r = open_repo(repo)
+    if isinstance(name, str):
+        names = [name]
+    elif isinstance(name, list):
+        names = name
+    else:
+        raise TypeError("Unexpected branch name type %r" % name)
+    for name in names:
+        del r.refs["refs/heads/" + name]
+
+
+def branch_create(repo, name, objectish=None, force=False):
+    """Create a branch.
+
+    :param repo: Path to the repository
+    :param name: Name of the new branch
+    :param objectish: Target object to point new branch at (defaults to HEAD)
+    :param force: Force creation of branch, even if it already exists
+    """
+    r = open_repo(repo)
+    if isinstance(name, str):
+        names = [name]
+    elif isinstance(name, list):
+        names = name
+    else:
+        raise TypeError("Unexpected branch name type %r" % name)
+    if objectish is None:
+        objectish = "HEAD"
+    object = parse_object(r, objectish)
+    refname = "refs/heads/" + name
+    if refname in r.refs and not force:
+        raise KeyError("Branch with name %s already exists." % name)
+    r.refs[refname] = object.id
+
+
+def branch_list(repo):
+    """List all branches.
+
+    :param repo: Path to the repository
+    """
+    r = open_repo(repo)
+    return r.refs.keys(base="refs/heads/")

+ 4 - 0
dulwich/refs.py

@@ -38,6 +38,7 @@ from dulwich.file import (
 
 
 SYMREF = 'ref: '
+LOCAL_BRANCH_PREFIX = 'refs/heads/'
 
 
 def check_ref_format(refname):
@@ -752,3 +753,6 @@ def write_info_refs(refs, store):
         yield '%s\t%s\n' % (o.id, name)
         if o.id != peeled.id:
             yield '%s\t%s^{}\n' % (peeled.id, name)
+
+
+is_local_branch = lambda x: x.startswith("refs/heads/")

+ 43 - 0
dulwich/tests/test_porcelain.py

@@ -621,3 +621,46 @@ class ReceivePackTests(PorcelainTestCase):
             '003f9e65bdcf4a22cdd4f3700604a275cd2aaf146b23 refs/heads/master',
             '0000'], outlines)
         self.assertEqual(0, exitcode)
+
+
+class BranchListTests(PorcelainTestCase):
+
+    def test_standard(self):
+        self.assertEquals(set([]), set(porcelain.branch_list(self.repo)))
+
+    def test_new_branch(self):
+        [c1] = build_commit_graph(self.repo.object_store, [[1]])
+        self.repo["HEAD"] = c1.id
+        porcelain.branch_create(self.repo, "foo")
+        self.assertEquals(
+            set(["master", "foo"]),
+            set(porcelain.branch_list(self.repo)))
+
+
+class BranchCreateTests(PorcelainTestCase):
+
+    def test_branch_exists(self):
+        [c1] = build_commit_graph(self.repo.object_store, [[1]])
+        self.repo["HEAD"] = c1.id
+        porcelain.branch_create(self.repo, "foo")
+        self.assertRaises(KeyError, porcelain.branch_create, self.repo, "foo")
+        porcelain.branch_create(self.repo, "foo", force=True)
+
+    def test_new_branch(self):
+        [c1] = build_commit_graph(self.repo.object_store, [[1]])
+        self.repo["HEAD"] = c1.id
+        porcelain.branch_create(self.repo, "foo")
+        self.assertEquals(
+            set(["master", "foo"]),
+            set(porcelain.branch_list(self.repo)))
+
+
+class BranchDeleteTests(PorcelainTestCase):
+
+    def test_simple(self):
+        [c1] = build_commit_graph(self.repo.object_store, [[1]])
+        self.repo["HEAD"] = c1.id
+        porcelain.branch_create(self.repo, 'foo')
+        self.assertTrue("foo" in porcelain.branch_list(self.repo))
+        porcelain.branch_delete(self.repo, 'foo')
+        self.assertFalse("foo" in porcelain.branch_list(self.repo))