Index parsing and gitignore files
This commit is contained in:
+60
-31
@@ -1,62 +1,91 @@
|
||||
use anyhow::{Result, bail};
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{
|
||||
self, prelude::*, BufRead
|
||||
}, path::Path, result
|
||||
io::{self, BufRead, prelude::*},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use crate::GIT_DIR;
|
||||
|
||||
pub mod gitignore;
|
||||
pub mod head;
|
||||
pub mod index;
|
||||
pub mod object;
|
||||
|
||||
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
|
||||
where P: AsRef<Path> {
|
||||
fn read_lines<P>(filename: P) -> Result<io::Lines<io::BufReader<File>>>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let file = File::open(filename)?;
|
||||
Ok(io::BufReader::new(file).lines())
|
||||
}
|
||||
|
||||
pub fn normalize_path_in_worktree(path: &Path) -> Result<PathBuf> {
|
||||
let wt_root = get_worktree_root()?;
|
||||
let canon = path.canonicalize()?;
|
||||
let mut canon_it = canon.components();
|
||||
|
||||
for wt_c in wt_root.components() {
|
||||
if let Some(c) = canon_it.next()
|
||||
&& wt_c == c
|
||||
{
|
||||
continue;
|
||||
} else {
|
||||
bail!(
|
||||
"'{}' is outside repository at '{}'",
|
||||
path.display(),
|
||||
wt_root.display()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(canon_it.as_path().to_path_buf())
|
||||
}
|
||||
|
||||
pub fn get_worktree_root() -> Result<PathBuf> {
|
||||
let canon = Path::new(".").canonicalize()?;
|
||||
for ancestor in canon.ancestors() {
|
||||
let potential = ancestor.join(GIT_DIR);
|
||||
if potential.is_dir() {
|
||||
return Ok(ancestor.to_path_buf());
|
||||
}
|
||||
}
|
||||
bail!("not a git repository (or any parent up to mount point)")
|
||||
}
|
||||
|
||||
pub fn get_git_root() -> Result<PathBuf> {
|
||||
Ok(get_worktree_root()?.join(GIT_DIR))
|
||||
}
|
||||
|
||||
pub struct Ref {
|
||||
ref_name: String,
|
||||
commit_hash: String,
|
||||
}
|
||||
|
||||
impl Ref {
|
||||
pub fn load(name: String) -> result::Result<Self, ()> {
|
||||
let path = Path::new(GIT_DIR).join(&name);
|
||||
pub fn load(name: String) -> Result<Self> {
|
||||
let path = get_git_root()?.join(&name);
|
||||
|
||||
let mut lines = match read_lines(path) {
|
||||
Ok(lines) => lines,
|
||||
Err(_) => return Err(()),
|
||||
};
|
||||
let mut lines = read_lines(path)?;
|
||||
|
||||
let content = match lines.next() {
|
||||
Some(Ok(line)) => line,
|
||||
_ => return Err(()),
|
||||
Some(line) => line?,
|
||||
_ => bail!(""),
|
||||
};
|
||||
|
||||
Ok(
|
||||
Ref {
|
||||
ref_name: name,
|
||||
commit_hash: content
|
||||
}
|
||||
)
|
||||
Ok(Ref {
|
||||
ref_name: name,
|
||||
commit_hash: content,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn save(&self) -> result::Result<(), ()> {
|
||||
let path = Path::new(GIT_DIR)
|
||||
.join("refs")
|
||||
.join(&self.ref_name);
|
||||
pub fn save(&self) -> Result<()> {
|
||||
let path = get_git_root()?.join("refs").join(&self.ref_name);
|
||||
|
||||
let mut file = match File::create(&path) {
|
||||
Err(_) => return Err(()),
|
||||
Ok(file) => file,
|
||||
};
|
||||
let mut file = File::create(&path)?;
|
||||
|
||||
match file.write(self.commit_hash.as_bytes()) {
|
||||
Err(_) => Err(()),
|
||||
Ok(_) => Ok(()),
|
||||
}
|
||||
file.write_all(self.commit_hash.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user