mirror of
https://github.com/MrBeanCpp/MIT.git
synced 2026-02-03 18:33:46 +08:00
处理Windows下绝对路径转换产生的"\\\\?\\"前缀
This commit is contained in:
@@ -47,7 +47,7 @@ pub fn add(files: Vec<String>, all: bool, mut update: bool) {
|
||||
}
|
||||
|
||||
fn add_a_file(file: &Path, index: &mut Index) {
|
||||
println!("add a file: {}", get_relative_path(file, get_working_dir().unwrap()).display());
|
||||
println!("add a file: {}", get_relative_path(file, &*get_working_dir().unwrap()).display());
|
||||
if !file.exists() { //文件被删除
|
||||
index.remove(file);
|
||||
} else { //文件存在
|
||||
|
||||
@@ -17,7 +17,7 @@ pub struct Blob {
|
||||
impl Blob {
|
||||
/// 从源文件新建blob对象,并直接保存到/objects/中
|
||||
pub fn new(file: &Path) -> Blob {
|
||||
let data = fs::read_to_string(file).unwrap();
|
||||
let data = fs::read_to_string(file).expect("无法读取文件");
|
||||
let hash = calc_hash(&data);
|
||||
let blob = Blob { hash, data };
|
||||
blob.save();
|
||||
|
||||
@@ -6,6 +6,7 @@ use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::SystemTime;
|
||||
use crate::utils::util::get_relative_path;
|
||||
|
||||
// 文件元数据结构
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
@@ -116,9 +117,16 @@ impl Index {
|
||||
}
|
||||
|
||||
/// 二进制序列化
|
||||
pub fn save(&self) {
|
||||
pub fn save(&mut self) {
|
||||
//要先转化为相对路径
|
||||
let ser = serde_json::to_string_pretty(&self).unwrap();
|
||||
let relative_index: HashMap<PathBuf, FileMetaData> = self.entries.iter()
|
||||
.map(|(path, value)| {
|
||||
println!("path: {:?}", path);
|
||||
let relative_path = get_relative_path(path, &self.working_dir);
|
||||
(relative_path, value.clone())
|
||||
})
|
||||
.collect();
|
||||
let ser = serde_json::to_string_pretty(&relative_index).unwrap();
|
||||
println!("{}", ser);
|
||||
}
|
||||
|
||||
@@ -153,8 +161,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_save() {
|
||||
util::setup_test_with_clean_mit();
|
||||
|
||||
let mut index = Index::new();
|
||||
let metadata = fs::metadata("../.gitignore").unwrap();
|
||||
let metadata = fs::metadata(".mit/HEAD").unwrap();
|
||||
let file_meta_data = FileMetaData {
|
||||
hash: "123".to_string(),
|
||||
size: metadata.len(),
|
||||
@@ -162,12 +171,13 @@ mod tests {
|
||||
modified_time: metadata.modified().unwrap(),
|
||||
mode: "100644".to_string(),
|
||||
};
|
||||
index.add(PathBuf::from(".gitignore"), file_meta_data);
|
||||
index.add(PathBuf::from(".mit/HEAD"), file_meta_data);
|
||||
let path = PathBuf::from("../mit_test_storage/中文路径测试.txt");
|
||||
index.add(
|
||||
PathBuf::from("../src/models/index.rs"),
|
||||
path.clone(),
|
||||
FileMetaData::new(
|
||||
&Blob::new(Path::new("../src/models/index.rs")),
|
||||
Path::new("../src/models/index.rs"),
|
||||
&Blob::new(&path),
|
||||
Path::new(&path),
|
||||
),
|
||||
);
|
||||
index.save();
|
||||
|
||||
@@ -115,7 +115,13 @@ pub fn list_files(path: &Path) -> io::Result<Vec<PathBuf>> {
|
||||
Ok(files)
|
||||
}
|
||||
|
||||
pub fn get_relative_path(path: &Path, dir: PathBuf) -> PathBuf {
|
||||
/// 获取相对于dir的相对路径
|
||||
pub fn get_relative_path(path: &Path, dir: &Path) -> PathBuf {
|
||||
let path = if path.is_relative() {
|
||||
get_absolute_path(path)
|
||||
} else {
|
||||
path.to_path_buf()
|
||||
};
|
||||
let relative_path = path.strip_prefix(dir).unwrap();
|
||||
relative_path.to_path_buf()
|
||||
}
|
||||
@@ -147,6 +153,35 @@ pub fn get_file_mode(path: &Path) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// 清除Windows下的绝对路径前缀"\\\\?\\"
|
||||
/// <a href="https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation">Windows 系统中的文件路径格式</a>
|
||||
pub fn clean_win_abs_path_pre(path: PathBuf) -> PathBuf {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
const DOS_PREFIX: &str = "\\\\?\\";
|
||||
let path_str = path.to_string_lossy();
|
||||
if path_str.starts_with(DOS_PREFIX) {
|
||||
PathBuf::from(&path_str[DOS_PREFIX.len()..])
|
||||
} else {
|
||||
path
|
||||
}
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取绝对路径(相对于当前current_dir)
|
||||
pub fn get_absolute_path(path: &Path) -> PathBuf {
|
||||
if path.is_absolute() {
|
||||
path.to_path_buf()
|
||||
} else {
|
||||
let abs_path = path.canonicalize().unwrap();
|
||||
clean_win_abs_path_pre(abs_path)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use sha1::{Sha1, Digest};
|
||||
use std::fs::File;
|
||||
use std::io::{Write, BufReader, BufRead, Error};
|
||||
use mit::utils::util;
|
||||
|
||||
#[test]
|
||||
fn test_hash() {
|
||||
@@ -8,11 +9,12 @@ fn test_hash() {
|
||||
hasher.update(String::from("hello world"));
|
||||
let result = format!("{:x}", hasher.finalize());
|
||||
println!("{}", result);
|
||||
println!("{}", mit::utils::util::calc_hash(&String::from("hello world")));
|
||||
println!("{}", util::calc_hash(&String::from("hello world")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write() -> Result<(), Error> {
|
||||
util::setup_test_with_mit();
|
||||
let path = "lines.txt";
|
||||
//create会截断文件
|
||||
let mut output = File::create(path)?; // ? 用于传播错误
|
||||
@@ -22,6 +24,7 @@ fn test_write() -> Result<(), Error> {
|
||||
|
||||
#[test]
|
||||
fn test_read() -> Result<(), Error> {
|
||||
util::setup_test_with_mit();
|
||||
let path = "lines.txt";
|
||||
let input = File::open(path)?;
|
||||
let buffered = BufReader::new(input);
|
||||
|
||||
Reference in New Issue
Block a user