Skip to content

Commit 878abe9

Browse files
committed
Add a way to clone using gitoxide without removing git2 just yet.
1 parent 900ae56 commit 878abe9

File tree

3 files changed

+91
-2
lines changed

3 files changed

+91
-2
lines changed

src/index/diff/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ impl Index {
186186
.replace_refspecs(Some(spec.as_str()), git::remote::Direction::Fetch)
187187
.expect("valid statically known refspec");
188188
}
189-
let res: git::remote::fetch::Outcome<'_> = remote
189+
let res: git::remote::fetch::Outcome = remote
190190
.connect(git::remote::Direction::Fetch, progress)?
191191
.prepare_fetch(Default::default())?
192192
.receive(should_interrupt)?;

src/index/init.rs

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
use crate::index::{CloneOptions, LAST_SEEN_REFNAME};
1+
use crate::index::{CloneOptions, CloneOptions2, LAST_SEEN_REFNAME};
22
use crate::Index;
33
use git_repository as git;
44
use std::path::Path;
5+
use std::sync::atomic::AtomicBool;
56

67
/// The error returned by various initialization methods.
78
#[derive(Debug, thiserror::Error)]
@@ -13,6 +14,18 @@ pub enum Error {
1314
Open(#[from] git::open::Error),
1415
}
1516

17+
/// The error returned by various initialization methods.
18+
#[derive(Debug, thiserror::Error)]
19+
#[allow(missing_docs)]
20+
pub enum Error2 {
21+
#[error(transparent)]
22+
PrepareClone(#[from] git::clone::prepare::Error),
23+
#[error(transparent)]
24+
Fetch(#[from] git::clone::fetch::Error),
25+
#[error(transparent)]
26+
Open(#[from] git::open::Error),
27+
}
28+
1629
/// Initialization
1730
impl Index {
1831
/// Return a new `Index` instance from the given `path`, which should contain a bare or non-bare
@@ -94,6 +107,68 @@ impl Index {
94107
})
95108
}
96109

110+
/// Return a new `Index` instance from the given `path`, which should contain a bare clone of the `crates.io` index.
111+
/// If the directory does not contain the repository or does not exist, it will be cloned from
112+
/// the official location automatically (with complete history).
113+
///
114+
/// An error will occour if the repository exists and the remote URL does not match the given repository URL.
115+
///
116+
/// # Examples
117+
///
118+
/// ```no_run
119+
/// use std::sync::atomic::AtomicBool;
120+
/// use crates_index_diff::{Index, index, git};
121+
///
122+
/// # let path = tempdir::TempDir::new("index").unwrap();
123+
/// // Note that credentials are automatically picked up from the standard git configuration.
124+
/// let mut options = index::CloneOptions2 {
125+
/// url: "https://github.com/rust-lang/staging.crates.io-index".into(),
126+
/// };
127+
///
128+
///
129+
/// let index = Index::from_path_or_cloned_with_options2(path, git::progress::Discard, &AtomicBool::default(), options)?;
130+
/// # Ok::<(), crates_index_diff::index::init::Error2>(())
131+
/// ```
132+
pub fn from_path_or_cloned_with_options2(
133+
path: impl AsRef<Path>,
134+
progress: impl git::Progress,
135+
should_interrupt: &AtomicBool,
136+
CloneOptions2 { url }: CloneOptions2,
137+
) -> Result<Index, Error2> {
138+
let path = path.as_ref();
139+
let mut repo = match git::open(path) {
140+
Ok(repo) => repo,
141+
Err(git::open::Error::NotARepository(_)) => {
142+
let (repo, _out) =
143+
git::prepare_clone_bare(url, path)?.fetch_only(progress, should_interrupt)?;
144+
repo
145+
}
146+
Err(err) => return Err(err.into()),
147+
}
148+
.apply_environment();
149+
150+
repo.object_cache_size_if_unset(4 * 1024 * 1024);
151+
Ok(Index {
152+
repo,
153+
remote_name: Some("origin"),
154+
branch_name: "master",
155+
seen_ref_name: LAST_SEEN_REFNAME,
156+
})
157+
}
158+
159+
/// Return a new `Index` instance from the given `path`, which should contain a bare or non-bare
160+
/// clone of the `crates.io` index.
161+
/// If the directory does not contain the repository or does not exist, it will be cloned from
162+
/// the official location automatically (with complete history).
163+
pub fn from_path_or_cloned2(path: impl AsRef<Path>) -> Result<Index, Error2> {
164+
Index::from_path_or_cloned_with_options2(
165+
path,
166+
git::progress::Discard,
167+
&AtomicBool::default(),
168+
CloneOptions2::default(),
169+
)
170+
}
171+
97172
/// Return a new `Index` instance from the given `path`, which should contain a bare or non-bare
98173
/// clone of the `crates.io` index.
99174
/// If the directory does not contain the repository or does not exist, it will be cloned from

src/index/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,20 @@ impl<'a> Default for CloneOptions<'a> {
2222
}
2323
}
2424

25+
/// Options for cloning the crates-io index.
26+
pub struct CloneOptions2 {
27+
/// The url to clone the crates-index repository from.
28+
pub url: String,
29+
}
30+
31+
impl Default for CloneOptions2 {
32+
fn default() -> Self {
33+
CloneOptions2 {
34+
url: INDEX_GIT_URL.into(),
35+
}
36+
}
37+
}
38+
2539
/// Access
2640
impl Index {
2741
/// Return the crates.io repository.

0 commit comments

Comments
 (0)