]> git.proxmox.com Git - cargo.git/blobdiff - vendor/git2/src/remote.rs
New upstream version 0.52.0
[cargo.git] / vendor / git2 / src / remote.rs
index d2ea83fa016e190393468ea56ffa06af97b66fde..042a3caa452936779a1f6a78303e82e57aeab1ff 100644 (file)
@@ -29,7 +29,7 @@ pub struct Refspecs<'remote> {
     remote: &'remote Remote<'remote>,
 }
 
-/// Description of a reference advertised bya remote server, given out on calls
+/// Description of a reference advertised by a remote server, given out on calls
 /// to `list`.
 pub struct RemoteHead<'remote> {
     raw: *const raw::git_remote_head,
@@ -73,6 +73,22 @@ impl<'repo> Remote<'repo> {
         unsafe { raw::git_remote_is_valid_name(remote_name.as_ptr()) == 1 }
     }
 
+    /// Create a detached remote
+    ///
+    /// Create a remote with the given url in-memory. You can use this
+    /// when you have a URL instead of a remote's name.
+    /// Contrasted with an anonymous remote, a detached remote will not
+    /// consider any repo configuration values.
+    pub fn create_detached(url: &str) -> Result<Remote<'_>, Error> {
+        crate::init();
+        let mut ret = ptr::null_mut();
+        let url = CString::new(url)?;
+        unsafe {
+            try_call!(raw::git_remote_create_detached(&mut ret, url));
+            Ok(Binding::from_raw(ret))
+        }
+    }
+
     /// Get the remote's name.
     ///
     /// Returns `None` if this remote has not yet been named or if the name is
@@ -205,6 +221,17 @@ impl<'repo> Remote<'repo> {
         Ok(())
     }
 
+    /// Cancel the operation
+    ///
+    /// At certain points in its operation, the network code checks whether the
+    /// operation has been cancelled and if so stops the operation.
+    pub fn stop(&mut self) -> Result<(), Error> {
+        unsafe {
+            try_call!(raw::git_remote_stop(self.raw));
+        }
+        Ok(())
+    }
+
     /// Get the number of refspecs for a remote
     pub fn refspecs(&self) -> Refspecs<'_> {
         let cnt = unsafe { raw::git_remote_refspec_count(&*self.raw) as usize };
@@ -231,15 +258,15 @@ impl<'repo> Remote<'repo> {
     ///
     /// # Examples
     ///
-    /// Example of functionality similar to `git fetch origin/master`:
+    /// Example of functionality similar to `git fetch origin/main`:
     ///
     /// ```no_run
-    /// fn fetch_origin_master(repo: git2::Repository) -> Result<(), git2::Error> {
-    ///     repo.find_remote("origin")?.fetch(&["master"], None, None)
+    /// fn fetch_origin_main(repo: git2::Repository) -> Result<(), git2::Error> {
+    ///     repo.find_remote("origin")?.fetch(&["main"], None, None)
     /// }
     ///
     /// let repo = git2::Repository::discover("rust").unwrap();
-    /// fetch_origin_master(repo).unwrap();
+    /// fetch_origin_main(repo).unwrap();
     /// ```
     pub fn fetch<Str: AsRef<str> + crate::IntoCString + Clone>(
         &mut self,
@@ -329,6 +356,15 @@ impl<'repo> Remote<'repo> {
         }
     }
 
+    /// Prune tracking refs that are no longer present on remote
+    pub fn prune(&mut self, callbacks: Option<RemoteCallbacks<'_>>) -> Result<(), Error> {
+        let cbs = Box::new(callbacks.unwrap_or_else(RemoteCallbacks::new));
+        unsafe {
+            try_call!(raw::git_remote_prune(self.raw, &cbs.raw()));
+        }
+        Ok(())
+    }
+
     /// Get the remote's list of fetch refspecs
     pub fn fetch_refspecs(&self) -> Result<StringArray, Error> {
         unsafe {
@@ -598,6 +634,11 @@ impl<'repo, 'connection, 'cb> RemoteConnection<'repo, 'connection, 'cb> {
     pub fn default_branch(&self) -> Result<Buf, Error> {
         self.remote.default_branch()
     }
+
+    /// access remote bound to this connection
+    pub fn remote(&mut self) -> &mut Remote<'repo> {
+        self.remote
+    }
 }
 
 impl<'repo, 'connection, 'cb> Drop for RemoteConnection<'repo, 'connection, 'cb> {
@@ -620,7 +661,7 @@ mod tests {
         drop(repo);
 
         let repo = t!(Repository::init(td.path()));
-        let origin = t!(repo.find_remote("origin"));
+        let mut origin = t!(repo.find_remote("origin"));
         assert_eq!(origin.name(), Some("origin"));
         assert_eq!(origin.url(), Some("/path/to/nowhere"));
         assert_eq!(origin.pushurl(), None);
@@ -630,6 +671,8 @@ mod tests {
 
         let stats = origin.stats();
         assert_eq!(stats.total_objects(), 0);
+
+        t!(origin.stop());
     }
 
     #[test]
@@ -757,7 +800,7 @@ mod tests {
             assert_eq!(list.len(), 2);
             assert_eq!(list[0].name(), "HEAD");
             assert!(!list[0].is_local());
-            assert_eq!(list[1].name(), "refs/heads/master");
+            assert_eq!(list[1].name(), "refs/heads/main");
             assert!(!list[1].is_local());
         }
         assert!(progress_hit.get());
@@ -790,7 +833,7 @@ mod tests {
             assert_eq!(list.len(), 2);
             assert_eq!(list[0].name(), "HEAD");
             assert!(!list[0].is_local());
-            assert_eq!(list[1].name(), "refs/heads/master");
+            assert_eq!(list[1].name(), "refs/heads/main");
             assert!(!list[1].is_local());
         }
         assert!(!origin.connected());
@@ -803,7 +846,10 @@ mod tests {
         let td3 = TempDir::new().unwrap();
         let url = crate::test::path2url(&td2.path());
 
-        Repository::init_bare(td2.path()).unwrap();
+        let mut opts = crate::RepositoryInitOptions::new();
+        opts.bare(true);
+        opts.initial_head("main");
+        Repository::init_opts(td2.path(), &opts).unwrap();
         // git push
         let mut remote = repo.remote("origin", &url).unwrap();
         let mut updated = false;
@@ -811,14 +857,14 @@ mod tests {
             let mut callbacks = RemoteCallbacks::new();
             callbacks.push_update_reference(|refname, status| {
                 updated = true;
-                assert_eq!(refname, "refs/heads/master");
+                assert_eq!(refname, "refs/heads/main");
                 assert_eq!(status, None);
                 Ok(())
             });
             let mut options = PushOptions::new();
             options.remote_callbacks(callbacks);
             remote
-                .push(&["refs/heads/master"], Some(&mut options))
+                .push(&["refs/heads/main"], Some(&mut options))
                 .unwrap();
         }
         assert!(updated);
@@ -828,4 +874,46 @@ mod tests {
         let commit = repo.find_commit(commit).unwrap();
         assert_eq!(commit.message(), Some("initial"));
     }
+
+    #[test]
+    fn prune() {
+        let (td, remote_repo) = crate::test::repo_init();
+        let oid = remote_repo.head().unwrap().target().unwrap();
+        let commit = remote_repo.find_commit(oid).unwrap();
+        remote_repo.branch("stale", &commit, true).unwrap();
+
+        let td2 = TempDir::new().unwrap();
+        let url = crate::test::path2url(&td.path());
+        let repo = Repository::clone(&url, &td2).unwrap();
+
+        fn assert_branch_count(repo: &Repository, count: usize) {
+            assert_eq!(
+                repo.branches(Some(crate::BranchType::Remote))
+                    .unwrap()
+                    .filter(|b| b.as_ref().unwrap().0.name().unwrap() == Some("origin/stale"))
+                    .count(),
+                count,
+            );
+        }
+
+        assert_branch_count(&repo, 1);
+
+        // delete `stale` branch on remote repo
+        let mut stale_branch = remote_repo
+            .find_branch("stale", crate::BranchType::Local)
+            .unwrap();
+        stale_branch.delete().unwrap();
+
+        // prune
+        let mut remote = repo.find_remote("origin").unwrap();
+        remote.connect(Direction::Push).unwrap();
+        let mut callbacks = RemoteCallbacks::new();
+        callbacks.update_tips(|refname, _a, b| {
+            assert_eq!(refname, "refs/remotes/origin/stale");
+            assert!(b.is_zero());
+            true
+        });
+        remote.prune(Some(callbacks)).unwrap();
+        assert_branch_count(&repo, 0);
+    }
 }