Struct git_worktree::fs::cache::Platform
source · pub struct Platform<'a, 'paths> { /* private fields */ }
Implementations§
source§impl<'a, 'paths> Platform<'a, 'paths>
impl<'a, 'paths> Platform<'a, 'paths>
sourcepub fn path(&self) -> &'a Path
pub fn path(&self) -> &'a Path
The full path to relative
will be returned for use on the file system.
Examples found in repository?
More examples
src/index/entry.rs (line 40)
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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
pub fn checkout<Find, E>(
entry: &mut Entry,
entry_path: &BStr,
Context { find, path_cache, buf }: Context<'_, '_, Find>,
index::checkout::Options {
fs: fs::Capabilities {
symlink,
executable_bit,
..
},
destination_is_initially_empty,
overwrite_existing,
..
}: index::checkout::Options,
) -> Result<usize, index::checkout::Error<E>>
where
Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Result<git_object::BlobRef<'a>, E>,
E: std::error::Error + Send + Sync + 'static,
{
let dest_relative = git_path::try_from_bstr(entry_path).map_err(|_| index::checkout::Error::IllformedUtf8 {
path: entry_path.to_owned(),
})?;
let is_dir = Some(entry.mode == git_index::entry::Mode::COMMIT || entry.mode == git_index::entry::Mode::DIR);
let dest = path_cache.at_path(dest_relative, is_dir, &mut *find)?.path();
let object_size = match entry.mode {
git_index::entry::Mode::FILE | git_index::entry::Mode::FILE_EXECUTABLE => {
let obj = find(&entry.id, buf).map_err(|err| index::checkout::Error::Find {
err,
oid: entry.id,
path: dest.to_path_buf(),
})?;
#[cfg_attr(not(unix), allow(unused_mut))]
let mut options = open_options(dest, destination_is_initially_empty, overwrite_existing);
let needs_executable_bit = executable_bit && entry.mode == git_index::entry::Mode::FILE_EXECUTABLE;
#[cfg(unix)]
if needs_executable_bit && destination_is_initially_empty {
use std::os::unix::fs::OpenOptionsExt;
// Note that these only work if the file was newly created, but won't if it's already
// existing, possibly without the executable bit set. Thus we do this only if the file is new.
options.mode(0o777);
}
let mut file = try_write_or_unlink(dest, overwrite_existing, |p| options.open(p))?;
file.write_all(obj.data)?;
// For possibly existing, overwritten files, we must change the file mode explicitly.
#[cfg(unix)]
if needs_executable_bit && !destination_is_initially_empty {
use std::os::unix::fs::PermissionsExt;
let mut perm = std::fs::symlink_metadata(dest)?.permissions();
perm.set_mode(0o777);
std::fs::set_permissions(dest, perm)?;
}
// NOTE: we don't call `file.sync_all()` here knowing that some filesystems don't handle this well.
// revisit this once there is a bug to fix.
update_fstat(entry, file.metadata()?)?;
file.close()?;
obj.data.len()
}
git_index::entry::Mode::SYMLINK => {
let obj = find(&entry.id, buf).map_err(|err| index::checkout::Error::Find {
err,
oid: entry.id,
path: dest.to_path_buf(),
})?;
let symlink_destination = git_path::try_from_byte_slice(obj.data)
.map_err(|_| index::checkout::Error::IllformedUtf8 { path: obj.data.into() })?;
if symlink {
try_write_or_unlink(dest, overwrite_existing, |p| os::create_symlink(symlink_destination, p))?;
} else {
let mut file = try_write_or_unlink(dest, overwrite_existing, |p| {
open_options(p, destination_is_initially_empty, overwrite_existing).open(dest)
})?;
file.write_all(obj.data)?;
file.close()?;
}
update_fstat(entry, std::fs::symlink_metadata(dest)?)?;
obj.data.len()
}
git_index::entry::Mode::DIR => todo!(),
git_index::entry::Mode::COMMIT => todo!(),
_ => unreachable!(),
};
Ok(object_size)
}
sourcepub fn is_excluded(&self) -> bool
pub fn is_excluded(&self) -> bool
See if the currently set entry is excluded as per exclude and git-ignore files.
Panics
If the cache was configured without exclude patterns.