From 6dde3ebfbc77d657c47cfc04838414524e21c506 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 24 Apr 2020 08:10:19 -0700 Subject: [PATCH] Fix more Windows paths. (#557) --- src/build.rs | 2 ++ src/config.rs | 2 ++ src/diff.rs | 2 +- src/index.rs | 23 ++++++++--------------- src/pathspec.rs | 5 +++-- src/repo.rs | 19 ++++++++++++++----- 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/build.rs b/src/build.rs index 6aaa6991dd..f86b89ca93 100644 --- a/src/build.rs +++ b/src/build.rs @@ -267,6 +267,7 @@ impl<'cb> RepoBuilder<'cb> { } let url = CString::new(url)?; + // Normal file path OK (does not need Windows conversion). let into = into.into_c_string()?; let mut raw = ptr::null_mut(); unsafe { @@ -511,6 +512,7 @@ impl<'cb> CheckoutBuilder<'cb> { /// Set the directory to check out to pub fn target_dir(&mut self, dst: &Path) -> &mut CheckoutBuilder<'cb> { + // Normal file path OK (does not need Windows conversion). self.target_dir = Some(dst.into_c_string().unwrap()); self } diff --git a/src/config.rs b/src/config.rs index ddda1d4fe2..8c2768ae58 100644 --- a/src/config.rs +++ b/src/config.rs @@ -46,6 +46,7 @@ impl Config { pub fn open(path: &Path) -> Result { crate::init(); let mut raw = ptr::null_mut(); + // Normal file path OK (does not need Windows conversion). let path = path.into_c_string()?; unsafe { try_call!(raw::git_config_open_ondisk(&mut raw, path)); @@ -122,6 +123,7 @@ impl Config { /// file instances in order (instances with a higher priority level will be /// accessed first). pub fn add_file(&mut self, path: &Path, level: ConfigLevel, force: bool) -> Result<(), Error> { + // Normal file path OK (does not need Windows conversion). let path = path.into_c_string()?; unsafe { try_call!(raw::git_config_add_file_ondisk( diff --git a/src/diff.rs b/src/diff.rs index 02764e4ff1..08a9f4e751 100644 --- a/src/diff.rs +++ b/src/diff.rs @@ -828,7 +828,7 @@ impl DiffOptions { /// Add to the array of paths/fnmatch patterns to constrain the diff. pub fn pathspec(&mut self, pathspec: T) -> &mut DiffOptions { - let s = pathspec.into_c_string().unwrap(); + let s = util::cstring_to_repo_path(pathspec).unwrap(); self.pathspec_ptrs.push(s.as_ptr()); self.pathspec.push(s); self diff --git a/src/index.rs b/src/index.rs index 6c27db143b..2ab48b8200 100644 --- a/src/index.rs +++ b/src/index.rs @@ -1,4 +1,4 @@ -use std::ffi::{CStr, CString, OsString}; +use std::ffi::{CStr, CString}; use std::marker; use std::ops::Range; use std::path::Path; @@ -7,7 +7,7 @@ use std::slice; use libc::{c_char, c_int, c_uint, c_void, size_t}; -use crate::util::{self, Binding}; +use crate::util::{self, path_to_repo_path, Binding}; use crate::IntoCString; use crate::{panic, raw, Error, IndexAddOption, IndexTime, Oid, Repository, Tree}; @@ -94,6 +94,7 @@ impl Index { pub fn open(index_path: &Path) -> Result { crate::init(); let mut raw = ptr::null_mut(); + // Normal file path OK (does not need Windows conversion). let index_path = index_path.into_c_string()?; unsafe { try_call!(raw::git_index_open(&mut raw, index_path)); @@ -220,15 +221,7 @@ impl Index { /// no longer be marked as conflicting. The data about the conflict will be /// moved to the "resolve undo" (REUC) section. pub fn add_path(&mut self, path: &Path) -> Result<(), Error> { - // Git apparently expects '/' to be separators for paths - let mut posix_path = OsString::new(); - for (i, comp) in path.components().enumerate() { - if i != 0 { - posix_path.push("/"); - } - posix_path.push(comp.as_os_str()); - } - let posix_path = posix_path.into_c_string()?; + let posix_path = path_to_repo_path(path)?; unsafe { try_call!(raw::git_index_add_bypath(self.raw, posix_path)); Ok(()) @@ -364,7 +357,7 @@ impl Index { /// Get one of the entries in the index by its path. pub fn get_path(&self, path: &Path, stage: i32) -> Option { - let path = path.into_c_string().unwrap(); + let path = path_to_repo_path(path).unwrap(); unsafe { let ptr = call!(raw::git_index_get_bypath(self.raw, path, stage as c_int)); if ptr.is_null() { @@ -419,7 +412,7 @@ impl Index { /// Remove an entry from the index pub fn remove(&mut self, path: &Path, stage: i32) -> Result<(), Error> { - let path = path.into_c_string()?; + let path = path_to_repo_path(path)?; unsafe { try_call!(raw::git_index_remove(self.raw, path, stage as c_int)); } @@ -435,7 +428,7 @@ impl Index { /// no longer be marked as conflicting. The data about the conflict will be /// moved to the "resolve undo" (REUC) section. pub fn remove_path(&mut self, path: &Path) -> Result<(), Error> { - let path = path.into_c_string()?; + let path = path_to_repo_path(path)?; unsafe { try_call!(raw::git_index_remove_bypath(self.raw, path)); } @@ -444,7 +437,7 @@ impl Index { /// Remove all entries from the index under a given directory. pub fn remove_dir(&mut self, path: &Path, stage: i32) -> Result<(), Error> { - let path = path.into_c_string()?; + let path = path_to_repo_path(path)?; unsafe { try_call!(raw::git_index_remove_directory( self.raw, diff --git a/src/pathspec.rs b/src/pathspec.rs index 6d842a55eb..e5fa0493d6 100644 --- a/src/pathspec.rs +++ b/src/pathspec.rs @@ -5,7 +5,7 @@ use std::ops::Range; use std::path::Path; use std::ptr; -use crate::util::Binding; +use crate::util::{path_to_repo_path, Binding}; use crate::{raw, Diff, DiffDelta, Error, Index, IntoCString, PathspecFlags, Repository, Tree}; /// Structure representing a compiled pathspec used for matching against various @@ -45,6 +45,7 @@ impl Pathspec { T: IntoCString, I: IntoIterator, { + crate::init(); let (_a, _b, arr) = crate::util::iter2cstrs_paths(specs)?; unsafe { let mut ret = ptr::null_mut(); @@ -158,7 +159,7 @@ impl Pathspec { /// explicitly pass flags to control case sensitivity or else this will fall /// back on being case sensitive. pub fn matches_path(&self, path: &Path, flags: PathspecFlags) -> bool { - let path = path.into_c_string().unwrap(); + let path = path_to_repo_path(path).unwrap(); unsafe { raw::git_pathspec_matches_path(&*self.raw, flags.bits(), path.as_ptr()) == 1 } } } diff --git a/src/repo.rs b/src/repo.rs index 14f88760dc..88d5f8c044 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -64,6 +64,7 @@ impl Repository { /// The path can point to either a normal or bare repository. pub fn open>(path: P) -> Result { init(); + // Normal file path OK (does not need Windows conversion). let path = path.as_ref().into_c_string()?; let mut ret = ptr::null_mut(); unsafe { @@ -77,6 +78,7 @@ impl Repository { /// The path can point to only a bare repository. pub fn open_bare>(path: P) -> Result { init(); + // Normal file path OK (does not need Windows conversion). let path = path.as_ref().into_c_string()?; let mut ret = ptr::null_mut(); unsafe { @@ -142,6 +144,7 @@ impl Repository { I: IntoIterator, { init(); + // Normal file path OK (does not need Windows conversion). let path = path.as_ref().into_c_string()?; let ceiling_dirs_os = env::join_paths(ceiling_dirs)?; let ceiling_dirs = ceiling_dirs_os.into_c_string()?; @@ -165,6 +168,7 @@ impl Repository { // TODO: this diverges significantly from the libgit2 API init(); let buf = Buf::new(); + // Normal file path OK (does not need Windows conversion). let path = path.as_ref().into_c_string()?; unsafe { try_call!(raw::git_repository_discover( @@ -201,6 +205,7 @@ impl Repository { opts: &RepositoryInitOptions, ) -> Result { init(); + // Normal file path OK (does not need Windows conversion). let path = path.as_ref().into_c_string()?; let mut ret = ptr::null_mut(); unsafe { @@ -393,6 +398,7 @@ impl Repository { /// and set config "core.worktree" (if workdir is not the parent of the .git /// directory). pub fn set_workdir(&self, path: &Path, update_gitlink: bool) -> Result<(), Error> { + // Normal file path OK (does not need Windows conversion). let path = path.into_c_string()?; unsafe { try_call!(raw::git_repository_set_workdir( @@ -856,7 +862,7 @@ impl Repository { /// directory containing the file, would it be added or not? pub fn status_should_ignore(&self, path: &Path) -> Result { let mut ret = 0 as c_int; - let path = path.into_c_string()?; + let path = util::cstring_to_repo_path(path)?; unsafe { try_call!(raw::git_status_should_ignore(&mut ret, self.raw, path)); } @@ -950,7 +956,7 @@ impl Repository { flags: AttrCheckFlags, ) -> Result, Error> { let mut ret = ptr::null(); - let path = path.into_c_string()?; + let path = util::cstring_to_repo_path(path)?; let name = CString::new(name)?; unsafe { try_call!(raw::git_attr_get( @@ -991,6 +997,7 @@ impl Repository { /// The Oid returned can in turn be passed to `find_blob` to get a handle to /// the blob. pub fn blob_path(&self, path: &Path) -> Result { + // Normal file path OK (does not need Windows conversion). let path = path.into_c_string()?; let mut raw = raw::git_oid { id: [0; raw::GIT_OID_RAWSZ], @@ -1545,7 +1552,7 @@ impl Repository { use_gitlink: bool, ) -> Result, Error> { let url = CString::new(url)?; - let path = path.into_c_string()?; + let path = path_to_repo_path(path)?; let mut raw = ptr::null_mut(); unsafe { try_call!(raw::git_submodule_add_setup( @@ -2069,7 +2076,7 @@ impl Repository { path: &Path, opts: Option<&mut BlameOptions>, ) -> Result, Error> { - let path = path.into_c_string()?; + let path = path_to_repo_path(path)?; let mut raw = ptr::null_mut(); unsafe { @@ -2800,12 +2807,13 @@ impl RepositoryInitOptions { self } - /// The path do the working directory. + /// The path to the working directory. /// /// If this is a relative path it will be evaulated relative to the repo /// path. If this is not the "natural" working directory, a .git gitlink /// file will be created here linking to the repo path. pub fn workdir_path(&mut self, path: &Path) -> &mut RepositoryInitOptions { + // Normal file path OK (does not need Windows conversion). self.workdir_path = Some(path.into_c_string().unwrap()); self } @@ -2823,6 +2831,7 @@ impl RepositoryInitOptions { /// If this is not configured, then the default locations will be searched /// instead. pub fn template_path(&mut self, path: &Path) -> &mut RepositoryInitOptions { + // Normal file path OK (does not need Windows conversion). self.template_path = Some(path.into_c_string().unwrap()); self }