Skip to content

Commit 96dd43a

Browse files
committed
temp-index
1 parent c0d974b commit 96dd43a

File tree

2 files changed

+57
-20
lines changed

2 files changed

+57
-20
lines changed

src/stupid/mod.rs

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mod command;
1010
pub(crate) mod diff;
1111
mod oid;
1212
pub(crate) mod status;
13+
mod tempindex;
1314
mod version;
1415

1516
use std::{
@@ -41,7 +42,7 @@ impl<'repo, 'index> Stupid<'repo, 'index> for gix::Repository {
4142
StupidContext {
4243
git_dir: Some(self.git_dir()),
4344
work_dir: self.work_dir(),
44-
index_path: None,
45+
index_filename: None,
4546
git_version: RefCell::new(None::<StupidVersion>),
4647
}
4748
}
@@ -52,7 +53,7 @@ impl<'repo, 'index> Stupid<'repo, 'index> for gix::Repository {
5253
pub(crate) struct StupidContext<'repo, 'index> {
5354
git_dir: Option<&'repo Path>,
5455
work_dir: Option<&'repo Path>,
55-
index_path: Option<&'index Path>,
56+
index_filename: Option<&'index Path>,
5657
git_version: RefCell<Option<StupidVersion>>,
5758
}
5859

@@ -64,21 +65,14 @@ impl<'repo, 'index> StupidContext<'repo, 'index> {
6465
where
6566
F: FnOnce(&StupidContext) -> Result<T>,
6667
{
67-
let temp_index_root = if let Some(git_dir) = self.git_dir {
68-
git_dir
69-
} else {
70-
self.index_path
71-
.expect("StupidContext has either a git_dir or an index_path")
72-
.parent()
73-
.expect("git index path has parent")
74-
};
75-
let index_tempfile = tempfile::Builder::new()
76-
.prefix("index-temp-stg")
77-
.tempfile_in(temp_index_root)?;
68+
let git_dir = self
69+
.git_dir
70+
.expect("git_dir required to use with_temp_index");
71+
let temp_index = tempindex::TempIndex::new(git_dir)?;
7872
let stupid_temp = StupidContext {
7973
git_dir: self.git_dir,
8074
work_dir: self.work_dir,
81-
index_path: Some(index_tempfile.path()),
75+
index_filename: Some(temp_index.filename()),
8276
git_version: RefCell::new(None),
8377
};
8478

@@ -101,21 +95,28 @@ impl<'repo, 'index> StupidContext<'repo, 'index> {
10195
let realpath =
10296
|path| gix::path::realpath_opts(path, cwd.as_path(), gix::path::realpath::MAX_SYMLINKS);
10397
if let Some(git_dir) = self.git_dir {
104-
command.env("GIT_DIR", realpath(git_dir)?);
98+
let git_dir = realpath(git_dir)?;
99+
if let Some(index_filename) = self.index_filename {
100+
command.env("GIT_INDEX_FILE", git_dir.join(index_filename));
101+
}
102+
command.env("GIT_DIR", git_dir);
105103
}
106104
command.env("GIT_WORK_TREE", ".");
107-
if let Some(index_path) = self.index_path {
108-
command.env("GIT_INDEX_FILE", realpath(index_path)?);
109-
}
110105
Ok(command)
111106
}
112107

113108
fn setup_git_env(&self, command: &mut Command) {
114109
self.git_dir.map(|git_dir| command.env("GIT_DIR", git_dir));
115110
self.work_dir
116111
.map(|work_dir| command.env("GIT_WORK_TREE", work_dir));
117-
self.index_path
118-
.map(|index_path| command.env("GIT_INDEX_FILE", index_path));
112+
self.index_filename.map(|filename| {
113+
command.env(
114+
"GIT_INDEX_FILE",
115+
self.git_dir
116+
.expect("git_dir must be set when index_filename is used")
117+
.join(filename),
118+
)
119+
});
119120
}
120121

121122
fn at_least_version(&self, version: &StupidVersion) -> Result<bool> {

src/stupid/tempindex.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use std::path::{Path, PathBuf};
2+
3+
use anyhow::Result;
4+
5+
pub(crate) struct TempIndex<'repo> {
6+
git_dir: &'repo Path,
7+
filename: PathBuf,
8+
}
9+
10+
impl<'repo> TempIndex<'repo> {
11+
pub(crate) fn new(git_dir: &'repo Path) -> Result<Self> {
12+
let pid = std::process::id();
13+
let filename = PathBuf::from(format!("index-temp-stg-{pid}"));
14+
let index_path = git_dir.join(&filename);
15+
std::fs::OpenOptions::new()
16+
.create_new(true)
17+
.write(true)
18+
.open(index_path)?;
19+
20+
Ok(Self { git_dir, filename })
21+
}
22+
23+
pub(crate) fn filename(&self) -> &Path {
24+
self.filename.as_ref()
25+
}
26+
}
27+
28+
impl<'repo> Drop for TempIndex<'repo> {
29+
fn drop(&mut self) {
30+
let index_path = self.git_dir.join(self.filename());
31+
assert!(index_path.is_file());
32+
if let Err(e) = std::fs::remove_file(&index_path) {
33+
panic!("failed to remove temp index {index_path:?}: {e}");
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)