Browse Source

Add porcelain 'pull'.

Ryan Faulkner 11 năm trước cách đây
mục cha
commit
a0f01709a4
3 tập tin đã thay đổi với 60 bổ sung0 xóa
  1. 2 0
      NEWS
  2. 25 0
      dulwich/porcelain.py
  3. 33 0
      dulwich/tests/test_porcelain.py

+ 2 - 0
NEWS

@@ -4,6 +4,8 @@
 
  * Add porcelain 'push'. (Ryan Faulkner)
 
+ * Add porcelain 'pull'. (Ryan Faulkner)
+
 0.9.5	2014-02-23
 
  IMPROVEMENTS

+ 25 - 0
dulwich/porcelain.py

@@ -46,6 +46,7 @@ Currently implemented:
  * commit-tree
  * diff-tree
  * init
+ * pull
  * push
  * remove
  * reset
@@ -420,3 +421,27 @@ def push(repo, remote_location, refs_path,
     except (UpdateRefsError, SendPackError) as e:
         outstream.write("Push to %s failed.\n" % remote_location)
         errstream.write("Push to %s failed -> '%s'\n" % e.message)
+
+
+def pull(repo, remote_location, refs_path,
+         outstream=sys.stdout, errstream=sys.stderr):
+    """ Pull from remote via dulwich.client
+
+    :param repo: Path to repository
+    :param remote_location: Location of the remote
+    :param refs_path: relative path to the fetched refs
+    :param outstream: A stream file to write to output
+    :param errstream: A stream file to write to errors
+    """
+
+    # Open the repo
+    r = open_repo(repo)
+
+    client, path = get_transport_and_path(remote_location)
+    remote_refs = client.fetch(path, r, progress=errstream.write)
+    r['HEAD'] = remote_refs[refs_path]
+
+    # Perform 'git checkout .' - syncs staged changes
+    indexfile = r.index_path()
+    tree = r["HEAD"].tree
+    index.build_index_from_tree(r.path, indexfile, r.object_store, tree)

+ 33 - 0
dulwich/tests/test_porcelain.py

@@ -417,3 +417,36 @@ class PushTests(PorcelainTestCase):
 
         self.assertEquals(r_clone['HEAD'].id, self.repo[refs_path].id)
         self.assertEquals(os.path.basename(fullpath), change.new.path)
+
+
+class PullTests(PorcelainTestCase):
+
+    def test_simple(self):
+        outstream = StringIO()
+        errstream = StringIO()
+
+        # create a file for initial commit
+        handle, fullpath = tempfile.mkstemp(dir=self.repo.path)
+        filename = os.path.basename(fullpath)
+        porcelain.add(repo=self.repo.path, paths=filename)
+        porcelain.commit(repo=self.repo.path, message='test',
+                         author='test', committer='test')
+
+        # Setup target repo
+        target_path = tempfile.mkdtemp()
+        porcelain.clone(self.repo.path, target=target_path, outstream=outstream)
+
+        # create a second file to be pushed
+        handle, fullpath = tempfile.mkstemp(dir=self.repo.path)
+        filename = os.path.basename(fullpath)
+        porcelain.add(repo=self.repo.path, paths=filename)
+        porcelain.commit(repo=self.repo.path, message='test2',
+            author='test2', committer='test2')
+
+        # Pull changes into the cloned repo
+        porcelain.pull(target_path, self.repo.path, 'refs/heads/master',
+            outstream=outstream, errstream=errstream)
+
+        # Check the target repo for pushed changes
+        r = Repo(target_path)
+        self.assertEquals(r['HEAD'].id, self.repo['HEAD'].id)