RP7YRM5QOINW7FB5BGNZEXVQN7TXB7LLLHXZPPAI6DGFGRP7JPFQC
5DUMO2ICSN2WFFYHREJUHA3VNRX7QAXZVQAQI2O7ZMXYXOC5SUGAC
3SJ3DJNFDA665FS5RLD3HA5S2RKMB5GTA56MBF77YSOPCOHTFMYAC
UC5C5REV3W3KPY45FFZWSZYLP7BCGK54Z5N74RSF26ZTC3HAC2QQC
XFYALEYNPVBGT6ET2LT2QKBM4C5MFTIQKABOU3VQJLAYEWMJM22QC
SFY4U6XENPS67BWNMTZI472WBORGVL7B4FZDIHGHEJQR5VYRYCVAC
YVA72CP2DB5XDKML3HR6NLB2GNPN5PXCGZD6DVXZGLAUEB3W4TGAC
SXEYMYF7P4RZMZ46WPL4IZUTSQ2ATBWYZX7QNVMS3SGOYXYOHAGQC
SNZ3OAMCPUGFYON5SZHQQQK46ZZMVMJECJYEUCMG657UVLY2PNBQC
GUL4M5FIE7JYXJHR7MCTQS3543HIQXGPLBWZKASBAWWEA4SZ75CAC
5SLOJYHGPMZVCOE3IS7ICNMJJYX3RBT6CDG5MAV6T4CJIOW7YZ6QC
EUZFFJSOWV4PXDFFPDAFBHFUUMOFEU6ST7JH57YYRRR2SEOXLN6QC
LOJL4HMYG7EOVZ5MSMCORDLDSRHWO2JPHMOTLMLQA7GPJNSVDXOQC
V435QOJRFHNKW3NKJHMVMFOGO3KGAZVSURLSGFUHVKOMHMF4Q2ZQC
YGPEHOTED5UG3IUK263PIX566VEHM3KYHPYIXZHPJ4ICHXWZEUJAC
ZHABNS3S6FSINO74FOI5KHYXYDTBPO4FQTTYTUS7NNKEVVNLYC4AC
ZDK3GNDBWXJ2OXFDYB72ZCEBGLBF4MKE5K3PVHDZATHJ7HJIDPRQC
OJZWJUF2TCGZ7RFVY6FPKBS5P3C4BGHZDPVH775OHVNVFMJICKNQC
46XERN6R4LPZLWEPUBSTGCKPOBGMCMHPVUKRUC55OWLBVJCUVNUQC
R3H7D42UZ446V5TO2574BMAQQAYYJPEIMSZVDPAGVIYU2COJSWBAC
LCERQSWMA2YKOPAPNZUSOQ7FLBGDHBZR33OHLYX7T4KTKULRMJDQC
let reset_was_useful = Rc::new(RefCell::new(false));
let mut builder = git2::build::CheckoutBuilder::new();
let repo_path = repo.repo.path.clone();
let reset_was_useful_ = reset_was_useful.clone();
builder
.force()
.remove_untracked(true)
.remove_ignored(true)
.progress(move |file, a, b| {
debug!("Git progress: {:?} {:?} {:?}", file, a, b);
if let Some(file) = file {
let file = repo_path.join(file);
if let Ok(meta) = std::fs::metadata(&file) {
if !meta.file_type().is_symlink() {
*reset_was_useful_.borrow_mut() = true
}
} else {
*reset_was_useful_.borrow_mut() = true
}
}
});
builder.notify(|notif, file, _, _, _| {
info!("Git reset: {:?} {:?}", notif, file);
true
});
git.reset(&object, git2::ResetType::Hard, Some(&mut builder))?;
impl<'a> libpijul::working_copy::WorkingCopyRead for Commit<'a> {
type Error = git2::Error;
fn file_metadata(&self, file: &str) -> Result<InodeMetadata, Self::Error> {
debug!("metadata {:?}", file);
let entry = self.c.tree()?.get_path(Path::new(file))?;
let is_dir = entry.kind() == Some(git2::ObjectType::Tree);
if is_dir {
Ok(InodeMetadata::new(0o100, true))
} else {
let permissions = entry.filemode();
debug!(
"permissions = {:o} {:o} {:?}",
permissions,
permissions & 0o100,
is_dir
);
Ok(InodeMetadata::new(permissions as usize & 0o100, false))
}
}
fn read_file(&self, file: &str, buffer: &mut Vec<u8>) -> Result<(), Self::Error> {
debug!("read file {:?}", file);
let entry = self.c.tree()?.get_path(Path::new(file))?;
if let Ok(b) = entry.to_object(self.r)?.peel_to_blob() {
buffer.extend(b.content());
}
debug!("entry {:?}", entry.kind());
Ok(())
}
fn modified_time(&self, _: &str) -> Result<std::time::SystemTime, Self::Error> {
Ok(std::time::SystemTime::now())
}
}
for p in prefixes.iter() {
if let Ok(m) = std::fs::metadata(&p) {
use path_slash::PathExt;
let p = p.to_slash_lossy();
if m.is_dir() {
txn_.add_dir(&p, 0).map(|_| ()).unwrap_or(());
let mut prefixes_ = BTreeMap::new();
for (mut p, is_dir) in prefixes {
use path_slash::PathExt;
loop {
debug!("p = {:?}", p);
if prefixes_.contains_key(&p) {
break;
}
let p_ = p.to_slash_lossy();
debug!("adding prefix {:?}", p_);
let (tracked, pos) = libpijul::fs::get_vertex(&*txn_, &p_)?;
if !tracked {
debug!("not tracked");
if is_dir {
txn_.add_dir(&p_, 0).map(|_| ()).unwrap_or(());
} else {
txn_.add_file(&p_, 0).map(|_| ()).unwrap_or(());
}
}
debug!("pos = {:?}", pos);
if pos.is_none() || !is_dir {
if !p.pop() {
prefixes_.insert(PathBuf::new(), true);
break;
}
let num_cpus = num_cpus::get();
for p in prefixes.iter() {
use libpijul::working_copy::filesystem::*;
match working_copy.record_prefix(
txn.clone(),
channel.clone(),
changes,
&mut state,
repo_path.clone(),
p,
false,
num_cpus,
0,
) {
Ok(_) => {}
Err(Error::Add(AddError::Fs(FsError::NotFound(_)))) => {}
Err(Error::Add(AddError::Fs(FsError::AlreadyInRepo(_)))) => {}
Err(Error::Add(AddError::Io(e))) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => {
error!("While adding {:?}: {:?}", p, e);
let mut last = None;
for (p, _) in prefixes.iter() {
if let Some(last) = last {
if p.starts_with(&last) {
continue;
use libpijul::working_copy::filesystem::*;
match working_copy.record_prefix(
txn.clone(),
channel.clone(),
changes,
&mut state,
repo_path.clone(),
Path::new(""),
false,
num_cpus,
0,
) {
Ok(_) => {}
Err(Error::Add(AddError::Fs(FsError::NotFound(_)))) => {}
Err(Error::Add(AddError::Fs(FsError::AlreadyInRepo(_)))) => {}
Err(Error::Add(AddError::Io(e))) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => {
error!("While adding {:?}: {:?}", prefixes, e);
}
}
state
.record_single_thread(
txn.clone(),
libpijul::Algorithm::default(),
false,
&libpijul::DEFAULT_SEPARATOR,
channel.clone(),
working_copy,
changes,
"",
)
.unwrap();
/// Returns whether a path is registered in the working copy.
pub fn get_vertex<T: TreeTxnT>(
txn: &T,
path: &str,
) -> Result<(bool, Option<Position<ChangeId>>), TreeErr<T::TreeError>> {
debug!("is_tracked {:?}", path);
let (inode, mut remaining_path_components) = closest_in_repo_ancestor(txn, path)?;
debug!("/is_tracked {:?}", path);
if remaining_path_components.next().is_none() {
Ok((true, txn.get_inodes(&inode, None)?.cloned()))
} else {
Ok((false, None))
}
}