mirror of
https://github.com/rust-lang/cargo
synced 2024-10-13 11:12:25 +00:00
Reduce calls to fs::metadata in list_git_files
When walking over entries in the index of a git repository the file type can be known without a syscall (in the form of a libc constant), but walking over untracked files still requires a syscall to determine if it's a directory.
This commit is contained in:
parent
e595e87762
commit
046a6c59e9
|
@ -4,8 +4,9 @@ use std::fs;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use glob::Pattern;
|
|
||||||
use git2;
|
use git2;
|
||||||
|
use glob::Pattern;
|
||||||
|
use libc;
|
||||||
|
|
||||||
use core::{Package, PackageId, Summary, SourceId, Source, Dependency, Registry};
|
use core::{Package, PackageId, Summary, SourceId, Source, Dependency, Registry};
|
||||||
use ops;
|
use ops;
|
||||||
|
@ -146,15 +147,19 @@ impl<'cfg> PathSource<'cfg> {
|
||||||
// Here we're also careful to look at both tracked an untracked files as
|
// Here we're also careful to look at both tracked an untracked files as
|
||||||
// the untracked files are often part of a build and may become relevant
|
// the untracked files are often part of a build and may become relevant
|
||||||
// as part of a future commit.
|
// as part of a future commit.
|
||||||
let index_files = index.iter().map(|entry| join(&root, &entry.path));
|
let index_files = index.iter().map(|entry| {
|
||||||
|
let is_dir = entry.mode & (libc::S_IFMT as u32) ==
|
||||||
|
(libc::S_IFDIR as u32);
|
||||||
|
(join(&root, &entry.path), Some(is_dir))
|
||||||
|
});
|
||||||
let mut opts = git2::StatusOptions::new();
|
let mut opts = git2::StatusOptions::new();
|
||||||
opts.include_untracked(true);
|
opts.include_untracked(true);
|
||||||
let statuses = try!(repo.statuses(Some(&mut opts)));
|
let statuses = try!(repo.statuses(Some(&mut opts)));
|
||||||
let untracked = statuses.iter().map(|entry| {
|
let untracked = statuses.iter().map(|entry| {
|
||||||
join(&root, entry.path_bytes())
|
(join(&root, entry.path_bytes()), None)
|
||||||
});
|
});
|
||||||
|
|
||||||
'outer: for file_path in index_files.chain(untracked) {
|
'outer: for (file_path, is_dir) in index_files.chain(untracked) {
|
||||||
let file_path = try!(file_path);
|
let file_path = try!(file_path);
|
||||||
|
|
||||||
// Filter out files outside this package.
|
// Filter out files outside this package.
|
||||||
|
@ -176,9 +181,10 @@ impl<'cfg> PathSource<'cfg> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: the `entry` has a mode we should be able to look at instead
|
let is_dir = is_dir.or_else(|| {
|
||||||
// of just calling stat() again
|
fs::metadata(&file_path).ok().map(|m| m.is_dir())
|
||||||
if fs::metadata(&file_path).map(|m| m.is_dir()).unwrap_or(false) {
|
}).unwrap_or(false);
|
||||||
|
if is_dir {
|
||||||
warn!(" found submodule {}", file_path.display());
|
warn!(" found submodule {}", file_path.display());
|
||||||
let rel = util::without_prefix(&file_path, &root).unwrap();
|
let rel = util::without_prefix(&file_path, &root).unwrap();
|
||||||
let rel = try!(rel.to_str().chain_error(|| {
|
let rel = try!(rel.to_str().chain_error(|| {
|
||||||
|
|
Loading…
Reference in a new issue