Skip to content

Commit dba851d

Browse files
committed
Auto merge of #14036 - weihanglo:gix-list, r=hi-rustin
fix: remove `__CARGO_GITOXIDE_DISABLE_LIST_FILES` env var ### What does this PR try to resolve? `__CARGO_GITOXIDE_DISABLE_LIST_FILES` is temporary and supposed to remove before 1.79 is out. However nobody remembers this. See #13696 ### How should we test and review this PR? The test suite should have covered it. ### Additional information <!-- homu-ignore:end -->
2 parents b3425d8 + 911a10f commit dba851d

File tree

1 file changed

+3
-220
lines changed

1 file changed

+3
-220
lines changed

src/cargo/sources/path.rs

+3-220
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::collections::HashSet;
21
use std::fmt::{self, Debug, Formatter};
32
use std::path::{Path, PathBuf};
43
use std::task::Poll;
@@ -422,16 +421,7 @@ fn _list_files(pkg: &Package, gctx: &GlobalContext) -> CargoResult<Vec<PathBuf>>
422421
let root = pkg.root();
423422
let no_include_option = pkg.manifest().include().is_empty();
424423
let git_repo = if no_include_option {
425-
if gctx
426-
.get_env("__CARGO_GITOXIDE_DISABLE_LIST_FILES")
427-
.ok()
428-
.as_deref()
429-
== Some("1")
430-
{
431-
discover_git_repo(root)?.map(Git2OrGixRepository::Git2)
432-
} else {
433-
discover_gix_repo(root)?.map(Git2OrGixRepository::Gix)
434-
}
424+
discover_gix_repo(root)?
435425
} else {
436426
None
437427
};
@@ -489,61 +479,12 @@ fn _list_files(pkg: &Package, gctx: &GlobalContext) -> CargoResult<Vec<PathBuf>>
489479
// Attempt Git-prepopulate only if no `include` (see rust-lang/cargo#4135).
490480
if no_include_option {
491481
if let Some(repo) = git_repo {
492-
return match repo {
493-
Git2OrGixRepository::Git2(repo) => list_files_git(pkg, &repo, &filter, gctx),
494-
Git2OrGixRepository::Gix(repo) => list_files_gix(pkg, &repo, &filter, gctx),
495-
};
482+
return list_files_gix(pkg, &repo, &filter, gctx);
496483
}
497484
}
498485
list_files_walk(pkg, &filter, gctx)
499486
}
500487

501-
enum Git2OrGixRepository {
502-
Git2(git2::Repository),
503-
Gix(gix::Repository),
504-
}
505-
506-
/// Returns `Some(git2::Repository)` if found sibling `Cargo.toml` and `.git`
507-
/// directory; otherwise, caller should fall back on full file list.
508-
fn discover_git_repo(root: &Path) -> CargoResult<Option<git2::Repository>> {
509-
let repo = match git2::Repository::discover(root) {
510-
Ok(repo) => repo,
511-
Err(e) => {
512-
tracing::debug!(
513-
"could not discover git repo at or above {}: {}",
514-
root.display(),
515-
e
516-
);
517-
return Ok(None);
518-
}
519-
};
520-
let index = repo
521-
.index()
522-
.with_context(|| format!("failed to open git index at {}", repo.path().display()))?;
523-
let repo_root = repo.workdir().ok_or_else(|| {
524-
anyhow::format_err!(
525-
"did not expect repo at {} to be bare",
526-
repo.path().display()
527-
)
528-
})?;
529-
let repo_relative_path = match paths::strip_prefix_canonical(root, repo_root) {
530-
Ok(p) => p,
531-
Err(e) => {
532-
warn!(
533-
"cannot determine if path `{:?}` is in git repo `{:?}`: {:?}",
534-
root, repo_root, e
535-
);
536-
return Ok(None);
537-
}
538-
};
539-
let manifest_path = repo_relative_path.join("Cargo.toml");
540-
if index.get_path(&manifest_path, 0).is_some() {
541-
return Ok(Some(repo));
542-
}
543-
// Package Cargo.toml is not in git, don't use git to guide our selection.
544-
Ok(None)
545-
}
546-
547488
/// Returns [`Some(gix::Repository)`](gix::Repository) if the discovered repository
548489
/// (searched upwards from `root`) contains a tracked `<root>/Cargo.toml`.
549490
/// Otherwise, the caller should fall back on full file list.
@@ -589,164 +530,6 @@ fn discover_gix_repo(root: &Path) -> CargoResult<Option<gix::Repository>> {
589530
Ok(None)
590531
}
591532

592-
/// Lists files relevant to building this package inside this source by
593-
/// consulting both Git index (tracked) or status (untracked) under
594-
/// a given Git repository.
595-
///
596-
/// This looks into Git submodules as well.
597-
fn list_files_git(
598-
pkg: &Package,
599-
repo: &git2::Repository,
600-
filter: &dyn Fn(&Path, bool) -> bool,
601-
gctx: &GlobalContext,
602-
) -> CargoResult<Vec<PathBuf>> {
603-
debug!("list_files_git {}", pkg.package_id());
604-
let index = repo.index()?;
605-
let root = repo
606-
.workdir()
607-
.ok_or_else(|| anyhow::format_err!("can't list files on a bare repository"))?;
608-
let pkg_path = pkg.root();
609-
610-
let mut ret = Vec::<PathBuf>::new();
611-
612-
// We use information from the Git repository to guide us in traversing
613-
// its tree. The primary purpose of this is to take advantage of the
614-
// `.gitignore` and auto-ignore files that don't matter.
615-
//
616-
// Here we're also careful to look at both tracked and untracked files as
617-
// the untracked files are often part of a build and may become relevant
618-
// as part of a future commit.
619-
let index_files = index.iter().map(|entry| {
620-
use libgit2_sys::{GIT_FILEMODE_COMMIT, GIT_FILEMODE_LINK};
621-
// ``is_dir`` is an optimization to avoid calling
622-
// ``fs::metadata`` on every file.
623-
let is_dir = if entry.mode == GIT_FILEMODE_LINK as u32 {
624-
// Let the code below figure out if this symbolic link points
625-
// to a directory or not.
626-
None
627-
} else {
628-
Some(entry.mode == GIT_FILEMODE_COMMIT as u32)
629-
};
630-
(join(root, &entry.path), is_dir)
631-
});
632-
let mut opts = git2::StatusOptions::new();
633-
opts.include_untracked(true);
634-
if let Ok(suffix) = pkg_path.strip_prefix(root) {
635-
opts.pathspec(suffix);
636-
}
637-
let statuses = repo.statuses(Some(&mut opts))?;
638-
let mut skip_paths = HashSet::new();
639-
let untracked: Vec<_> = statuses
640-
.iter()
641-
.filter_map(|entry| {
642-
match entry.status() {
643-
// Don't include Cargo.lock if it is untracked. Packaging will
644-
// generate a new one as needed.
645-
git2::Status::WT_NEW if entry.path() != Some("Cargo.lock") => {
646-
Some(Ok((join(root, entry.path_bytes()), None)))
647-
}
648-
git2::Status::WT_DELETED => {
649-
let path = match join(root, entry.path_bytes()) {
650-
Ok(p) => p,
651-
Err(e) => return Some(Err(e)),
652-
};
653-
skip_paths.insert(path);
654-
None
655-
}
656-
_ => None,
657-
}
658-
})
659-
.collect::<CargoResult<_>>()?;
660-
661-
let mut subpackages_found = Vec::new();
662-
663-
for (file_path, is_dir) in index_files.chain(untracked) {
664-
let file_path = file_path?;
665-
if skip_paths.contains(&file_path) {
666-
continue;
667-
}
668-
669-
// Filter out files blatantly outside this package. This is helped a
670-
// bit above via the `pathspec` function call, but we need to filter
671-
// the entries in the index as well.
672-
if !file_path.starts_with(pkg_path) {
673-
continue;
674-
}
675-
676-
match file_path.file_name().and_then(|s| s.to_str()) {
677-
// The `target` directory is never included.
678-
Some("target") => {
679-
// Only filter out target if its in the package root.
680-
if file_path.parent().unwrap() == pkg_path {
681-
continue;
682-
}
683-
}
684-
685-
// Keep track of all sub-packages found and also strip out all
686-
// matches we've found so far. Note, though, that if we find
687-
// our own `Cargo.toml`, we keep going.
688-
Some("Cargo.toml") => {
689-
let path = file_path.parent().unwrap();
690-
if path != pkg_path {
691-
debug!("subpackage found: {}", path.display());
692-
ret.retain(|p| !p.starts_with(path));
693-
subpackages_found.push(path.to_path_buf());
694-
continue;
695-
}
696-
}
697-
698-
_ => {}
699-
}
700-
701-
// If this file is part of any other sub-package we've found so far,
702-
// skip it.
703-
if subpackages_found.iter().any(|p| file_path.starts_with(p)) {
704-
continue;
705-
}
706-
707-
// `is_dir` is None for symlinks. The `unwrap` checks if the
708-
// symlink points to a directory.
709-
let is_dir = is_dir.unwrap_or_else(|| file_path.is_dir());
710-
if is_dir {
711-
trace!(" found directory {}", file_path.display());
712-
match git2::Repository::open(&file_path) {
713-
Ok(repo) => {
714-
let files = list_files_git(pkg, &repo, filter, gctx)?;
715-
ret.extend(files.into_iter());
716-
}
717-
Err(..) => {
718-
walk(&file_path, &mut ret, false, filter, gctx)?;
719-
}
720-
}
721-
} else if filter(&file_path, is_dir) {
722-
assert!(!is_dir);
723-
// We found a file!
724-
trace!(" found {}", file_path.display());
725-
ret.push(file_path);
726-
}
727-
}
728-
return Ok(ret);
729-
730-
#[cfg(unix)]
731-
fn join(path: &Path, data: &[u8]) -> CargoResult<PathBuf> {
732-
use std::ffi::OsStr;
733-
use std::os::unix::prelude::*;
734-
Ok(path.join(<OsStr as OsStrExt>::from_bytes(data)))
735-
}
736-
#[cfg(windows)]
737-
fn join(path: &Path, data: &[u8]) -> CargoResult<PathBuf> {
738-
use std::str;
739-
match str::from_utf8(data) {
740-
Ok(s) => Ok(path.join(s)),
741-
Err(e) => Err(anyhow::format_err!(
742-
"cannot process path in git with a non utf8 filename: {}\n{:?}",
743-
e,
744-
data
745-
)),
746-
}
747-
}
748-
}
749-
750533
/// Lists files relevant to building this package inside this source by
751534
/// traversing the git working tree, while avoiding ignored files.
752535
///
@@ -886,7 +669,7 @@ fn list_files_gix(
886669
/// Lists files relevant to building this package inside this source by
887670
/// walking the filesystem from the package root path.
888671
///
889-
/// This is a fallback for [`list_files_git`] when the package
672+
/// This is a fallback for [`list_files_gix`] when the package
890673
/// is not tracked under a Git repository.
891674
fn list_files_walk(
892675
pkg: &Package,

0 commit comments

Comments
 (0)