mirror of
https://github.com/martinvonz/jj.git
synced 2024-12-24 12:48:55 +00:00
cli: respect Git's core.excludesFile config (#87)
It probably doesn't make sense to respect Git's `core.excludesFile` config when not running in a Git-backed repo, but we also already respect `.gitignore` files in the working copy regardless of backend, so at least it's consistent with that. We can revisit it when the native backend becomes a reasonable choice. Closes #87.
This commit is contained in:
parent
8336c489fa
commit
326654952e
3 changed files with 51 additions and 13 deletions
|
@ -15,9 +15,11 @@ The following list describes which Git features Jujutsu is compatible with. For
|
|||
a comparison with Git, including how workflows are different, see the
|
||||
[Git-comparison doc](git-comparison.md).
|
||||
|
||||
* **Configuration: No.** The only configuration from Git (e.g. in
|
||||
`~/.gitconfig`) that's respected is the configuration of remotes. Feel free
|
||||
to file a bug if you miss any particular configuration options.
|
||||
* **Configuration: Partial.** The only configuration from Git (e.g. in
|
||||
`~/.gitconfig`) that's respected is the following. Feel free to file a bug if
|
||||
you miss any particular configuration options.
|
||||
* The configuration of remotes (`[remote "<name>"]`).
|
||||
* `core.exludesFile`
|
||||
* **Authentication: Partial.** Only `ssh-agent` or a password-less key file at
|
||||
`~/.ssh/id_rsa` (and only at exactly that path).
|
||||
* **Branches: Yes.** You can read more about
|
||||
|
|
|
@ -382,13 +382,23 @@ impl WorkspaceCommandHelper {
|
|||
self.working_copy_shared_with_git
|
||||
}
|
||||
|
||||
fn git_config(&self) -> Result<git2::Config, git2::Error> {
|
||||
if let Some(git_repo) = self.repo.store().git_repo() {
|
||||
git_repo.config()
|
||||
} else {
|
||||
git2::Config::open_default()
|
||||
}
|
||||
}
|
||||
|
||||
fn base_ignores(&self) -> Arc<GitIgnoreFile> {
|
||||
let mut git_ignores = GitIgnoreFile::empty();
|
||||
if let Ok(home_dir) = std::env::var("HOME") {
|
||||
let home_dir_path = PathBuf::from(home_dir);
|
||||
// TODO: Look up the name of the file in the core.excludesFile config instead of
|
||||
// hard-coding its name like this.
|
||||
git_ignores = git_ignores.chain_with_file("", home_dir_path.join(".gitignore"));
|
||||
if let Ok(excludes_file_str) = self
|
||||
.git_config()
|
||||
.and_then(|git_config| git_config.get_string("core.excludesFile"))
|
||||
{
|
||||
let excludes_file_path =
|
||||
std::fs::canonicalize(PathBuf::from(excludes_file_str)).unwrap();
|
||||
git_ignores = git_ignores.chain_with_file("", excludes_file_path);
|
||||
}
|
||||
if let Some(git_repo) = self.repo.store().git_repo() {
|
||||
git_ignores =
|
||||
|
|
|
@ -26,21 +26,47 @@ fn test_gitignores() {
|
|||
.assert()
|
||||
.success();
|
||||
|
||||
// Say in .git/info/exclude that we don't want file1 and file2
|
||||
// Say in core.excludesFiles that we don't want file1, file2, or file3
|
||||
let mut file = std::fs::OpenOptions::new()
|
||||
.append(true)
|
||||
.open(workspace_root.join(".git").join("config"))
|
||||
.unwrap();
|
||||
let excludes_file_path = test_env
|
||||
.env_root()
|
||||
.join("my-ignores")
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string();
|
||||
file.write_all(
|
||||
format!(
|
||||
"[core]\nexcludesFile=\"{}\"",
|
||||
excludes_file_path
|
||||
.replace('\\', "\\\\")
|
||||
.replace('\"', "\\\"")
|
||||
)
|
||||
.as_bytes(),
|
||||
)
|
||||
.unwrap();
|
||||
drop(file);
|
||||
std::fs::write(excludes_file_path, "file1\nfile2\nfile3").unwrap();
|
||||
|
||||
// Say in .git/info/exclude that we actually do want file2 and file3
|
||||
let mut file = std::fs::OpenOptions::new()
|
||||
.append(true)
|
||||
.open(workspace_root.join(".git").join("info").join("exclude"))
|
||||
.unwrap();
|
||||
file.write_all(b"file1\nfile2").unwrap();
|
||||
file.write_all(b"!file2\n!file3").unwrap();
|
||||
drop(file);
|
||||
|
||||
// Say in .gitignore (in the working copy) that we actually do want file2
|
||||
std::fs::write(workspace_root.join(".gitignore"), "!file2").unwrap();
|
||||
// Say in .gitignore (in the working copy) that we actually do not want file2
|
||||
// (again)
|
||||
std::fs::write(workspace_root.join(".gitignore"), "file2").unwrap();
|
||||
|
||||
// Writes some files to the working copy
|
||||
std::fs::write(workspace_root.join("file0"), "contents").unwrap();
|
||||
std::fs::write(workspace_root.join("file1"), "contents").unwrap();
|
||||
std::fs::write(workspace_root.join("file2"), "contents").unwrap();
|
||||
std::fs::write(workspace_root.join("file3"), "contents").unwrap();
|
||||
|
||||
let assert = test_env
|
||||
.jj_cmd(&workspace_root, &["diff", "-s"])
|
||||
|
@ -49,6 +75,6 @@ fn test_gitignores() {
|
|||
insta::assert_snapshot!(get_stdout_string(&assert), @r###"
|
||||
A .gitignore
|
||||
A file0
|
||||
A file2
|
||||
A file3
|
||||
"###);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue