forked from argotorg/fe
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit.rs
More file actions
68 lines (58 loc) · 2.15 KB
/
Copy pathgit.rs
File metadata and controls
68 lines (58 loc) · 2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#[cfg(not(target_arch = "wasm32"))]
use git2::{FetchOptions, Oid, Repository};
use std::error::Error;
#[cfg(not(target_arch = "wasm32"))]
use std::path::Path;
/// Fetch and checkout the specified refspec from the remote repository without
/// fetching any additional history.
#[cfg(not(target_arch = "wasm32"))]
pub fn fetch_and_checkout<P: AsRef<Path>>(
remote: &str,
target_directory: P,
refspec: &str,
) -> Result<(), Box<dyn Error>> {
// We initialize the repo here so that we can be sure that we created a directory that
// needs to be clean up in case of an error. If the init fails, there won't be anything
// to clean up.
let repo = Repository::init(&target_directory)?;
let res = _fetch_and_checkout(remote, repo, refspec);
if res.is_err() {
std::fs::remove_dir_all(target_directory).expect("Failed to clean up directory");
}
res
}
#[cfg(not(target_arch = "wasm32"))]
fn _fetch_and_checkout(
remote: &str,
repo: Repository,
refspec: &str,
) -> Result<(), Box<dyn Error>> {
let mut remote = repo.remote("origin", remote)?;
let mut fetch_options = FetchOptions::new();
fetch_options.depth(1);
// Fetch the specified SHA1 with depth 1
if let Err(e) = remote.fetch(&[refspec], Some(&mut fetch_options), None) {
if let (git2::ErrorClass::Net, git2::ErrorCode::GenericError) = (e.class(), e.code()) {
// That's a pretty cryptic error for the common case of the refspec not existing.
// We keep the cryptic error (because it might have other causes) but add a hint.
return Err(format!("{}\nMake sure revision {} exists in remote", e, refspec).into());
} else {
return Err(e.into());
}
}
// Find the fetched commit by SHA1
let oid = Oid::from_str(refspec)?;
let commit = repo.find_commit(oid)?;
// Checkout the commit
repo.checkout_tree(commit.as_object(), None)?;
repo.set_head_detached(oid)?;
Ok(())
}
#[cfg(target_arch = "wasm32")]
pub fn fetch_and_checkout(
_remote: &str,
_target_directory: &str,
_refspec: &str,
) -> Result<(), Box<dyn Error>> {
Err("Not supported on WASM".into())
}