Unified · Split
| @@ -16,6 +16,8 @@ mod error { · 15 unmodified lines | |||
| 16 | MissingUrl { direction: remote::Direction }, | 16 | MissingUrl { direction: remote::Direction }, |
| 17 | #[error("Protocol named {given:?} is not a valid protocol. Choose between 1 and 2")] | 17 | #[error("Protocol named {given:?} is not a valid protocol. Choose between 1 and 2")] |
| 18 | UnknownProtocol { given: BString }, | 18 | UnknownProtocol { given: BString }, |
| 19 | #[error("Could not verify that file:// url is a valid git directory before attempting to use it")] | ||
| 20 | FileUrl(#[from] git_discover::is_git::Error), | ||
| 19 | } | 21 | } |
| 20 | } | 22 | } |
| 21 | pub use error::Error; | 23 | pub use error::Error; |
| @@ -70,7 +72,17 @@ impl<'repo> Remote<'repo> { · 48 unmodified lines | |||
| 70 | }) | 72 | }) |
| 71 | })?; | 73 | })?; |
| 72 | 74 | ||
| 73 | let url = self.url(direction).ok_or(Error::MissingUrl { direction })?.to_owned(); | 75 | let mut url = self.url(direction).ok_or(Error::MissingUrl { direction })?.to_owned(); |
| 76 | if url.scheme == git_url::Scheme::File { | ||
| 77 | let mut dir = git_path::from_bstr(url.path.as_ref()); | ||
| 78 | let kind = git_discover::is_git(dir.as_ref()).or_else(|_| { | ||
| 79 | dir.to_mut().push(git_discover::DOT_GIT_DIR); | ||
| 80 | git_discover::is_git(dir.as_ref()) | ||
| 81 | })?; | ||
| 82 | let (git_dir, _work_dir) = git_discover::repository::Path::from_dot_git_dir(dir.into_owned(), kind) | ||
| 83 | .into_repository_and_work_tree_directories(); | ||
| 84 | url.path = git_path::into_bstr(git_dir).into_owned(); | ||
| 85 | } | ||
| 74 | let transport = git_protocol::transport::connect(url, protocol).await?; | 86 | let transport = git_protocol::transport::connect(url, protocol).await?; |
| 75 | Ok(self.to_connection_with_transport(transport, progress)) | 87 | Ok(self.to_connection_with_transport(transport, progress)) |
| 76 | } | 88 | } |
| @@ -1,4 +1,6 @@ | |||
| 1 | use crate::remote::connection::State; | ||
| 1 | use crate::remote::{Connection, Direction}; | 2 | use crate::remote::{Connection, Direction}; |
| 3 | use git_features::progress::Progress; | ||
| 2 | use git_protocol::transport::client::Transport; | 4 | use git_protocol::transport::client::Transport; |
| 3 | 5 | ||
| 4 | mod error { | 6 | mod error { |
| @@ -10,9 +12,7 @@ mod error { · 5 unmodified lines | |||
| 10 | ListRefs(#[from] git_protocol::fetch::refs::Error), | 12 | ListRefs(#[from] git_protocol::fetch::refs::Error), |
| 11 | } | 13 | } |
| 12 | } | 14 | } |
| 13 | use crate::remote::connection::State; | ||
| 14 | pub use error::Error; | 15 | pub use error::Error; |
| 15 | use git_features::progress::Progress; | ||
| 16 | 16 | ||
| 17 | impl<'a, 'repo, T, P> Connection<'a, 'repo, T, P> | 17 | impl<'a, 'repo, T, P> Connection<'a, 'repo, T, P> |
| 18 | where | 18 | where |
| @@ -10,24 +10,39 @@ pub(crate) enum State { · 9 unmodified lines | |||
| 10 | }, | 10 | }, |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | pub struct Connection<'a, 'repo, T, P> { | 13 | pub struct Connection<'a, 'repo, T, P> |
| 14 | where | ||
| 15 | T: git_protocol::transport::client::Transport, | ||
| 16 | { | ||
| 14 | pub(crate) remote: &'a Remote<'repo>, | 17 | pub(crate) remote: &'a Remote<'repo>, |
| 15 | pub(crate) transport: T, | 18 | pub(crate) transport: T, |
| 16 | pub(crate) progress: P, | 19 | pub(crate) progress: P, |
| 17 | pub(crate) state: State, | 20 | pub(crate) state: State, |
| 18 | } | 21 | } |
| 19 | 22 | ||
| 23 | mod impls { | ||
| 24 | use crate::remote::Connection; | ||
| 25 | use git_protocol::transport::client::Transport; | ||
| 26 | |||
| 27 | impl<'a, 'repo, T, P> Drop for Connection<'a, 'repo, T, P> | ||
| 28 | where | ||
| 29 | T: Transport, | ||
| 30 | { | ||
| 31 | fn drop(&mut self) { | ||
| 32 | git_protocol::fetch::indicate_end_of_interaction(&mut self.transport).ok(); | ||
| 33 | } | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 20 | mod access { | 37 | mod access { |
| 21 | use crate::remote::Connection; | 38 | use crate::remote::Connection; |
| 22 | use crate::Remote; | 39 | use crate::Remote; |
| 23 | 40 | ||
| 24 | /// Access and conversion | 41 | /// Access and conversion |
| 25 | impl<'a, 'repo, T, P> Connection<'a, 'repo, T, P> { | 42 | impl<'a, 'repo, T, P> Connection<'a, 'repo, T, P> |
| 26 | /// Obtain the transport from this instance. | 43 | where |
| 27 | pub fn into_transport(self) -> T { | 44 | T: git_protocol::transport::client::Transport, |
| 28 | self.transport | 45 | { |
| 29 | } | ||
| 30 | |||
| 31 | /// Drop the transport and additional state to regain the original remote. | 46 | /// Drop the transport and additional state to regain the original remote. |
| 32 | pub fn remote(&self) -> &Remote<'repo> { | 47 | pub fn remote(&self) -> &Remote<'repo> { |
| 33 | self.remote | 48 | self.remote |
| @@ -5,11 +5,11 @@ mod blocking_io { · 4 unmodified lines | |||
| 5 | use git_repository::remote::Direction::Fetch; | 5 | use git_repository::remote::Direction::Fetch; |
| 6 | 6 | ||
| 7 | #[test] | 7 | #[test] |
| 8 | #[ignore] | ||
| 9 | fn all() { | 8 | fn all() { |
| 10 | let repo = remote::repo("clone"); | 9 | let repo = remote::repo("clone"); |
| 11 | let remote = repo.find_remote("origin").unwrap(); | 10 | let remote = repo.find_remote("origin").unwrap(); |
| 12 | let mut connection = remote.connect(Fetch, progress::Discard).unwrap(); | 11 | let mut connection = remote.connect(Fetch, progress::Discard).unwrap(); |
| 13 | let _refs = connection.list_refs().unwrap(); | 12 | let refs = connection.list_refs().unwrap(); |
| 13 | assert_eq!(refs.len(), 14, "it gets all remote refs, independently of the refspec."); | ||
| 14 | } | 14 | } |
| 15 | } | 15 | } |