Skip to content

Commit bc3c05e

Browse files
committed
Assure main-worktree is also resolved in the main worktree (#301)
1 parent 199583a commit bc3c05e

File tree

4 files changed

+67
-28
lines changed

4 files changed

+67
-28
lines changed

git-ref/src/store/file/find.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -163,17 +163,15 @@ impl file::Store {
163163

164164
impl file::Store {
165165
fn base_dir_and_rela_path_for_name<'a>(&self, name: FullNameRef<'a>) -> (&Path, Cow<'a, Path>) {
166-
let (base, relative_path) = self
167-
.common_dir
168-
.as_deref()
169-
.and_then(|commondir| {
170-
name.category_and_short_name().and_then(|(c, sn)| {
171-
use crate::Category::*;
172-
Some(match c {
173-
Tag | LocalBranch | RemoteBranch | Note => (commondir, name.as_bstr()),
174-
MainRef | MainPseudoRef | LinkedRef | LinkedPseudoRef => (commondir, sn),
175-
PseudoRef | Bisect | Rewritten | WorktreePrivate => return None,
176-
})
166+
let commondir = self.common_dir_resolved();
167+
let (base, relative_path) = name
168+
.category_and_short_name()
169+
.and_then(|(c, sn)| {
170+
use crate::Category::*;
171+
Some(match c {
172+
Tag | LocalBranch | RemoteBranch | Note => (commondir, name.as_bstr()),
173+
MainRef | MainPseudoRef | LinkedRef | LinkedPseudoRef => (commondir, sn),
174+
PseudoRef | Bisect | Rewritten | WorktreePrivate => return None,
177175
})
178176
})
179177
.unwrap_or((self.git_dir.as_path(), name.as_bstr()));

git-ref/src/store/file/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,11 @@ mod access {
5353
self.common_dir.as_deref()
5454
}
5555

56-
/// The directory in which the packed references file would be placed.
57-
pub fn packed_refs_dir(&self) -> &Path {
56+
/// Similar to [`common_dir()`][file::Store::common_dir()], but it will produce either the common-dir, or the git-dir if the former
57+
/// isn't present.
58+
///
59+
/// This is also the directory in which the packed references file would be placed.
60+
pub fn common_dir_resolved(&self) -> &Path {
5861
self.common_dir.as_deref().unwrap_or(&self.git_dir)
5962
}
6063
}

git-ref/src/store/file/packed.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl file::Store {
4242

4343
/// Return the path at which packed-refs would usually be stored
4444
pub fn packed_refs_path(&self) -> PathBuf {
45-
self.packed_refs_dir().join("packed-refs")
45+
self.common_dir_resolved().join("packed-refs")
4646
}
4747
}
4848

git-ref/tests/file/worktree.rs

+52-14
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,78 @@
1+
use git_odb::Find;
2+
use git_ref::file::ReferenceExt;
13
use std::path::PathBuf;
24

3-
fn dir(packed: bool) -> PathBuf {
5+
fn dir(packed: bool) -> crate::Result<PathBuf> {
46
let name = "make_worktree_repo.sh";
57
if packed {
68
git_testtools::scripted_fixture_repo_read_only_with_args(name, Some("packed"))
79
} else {
810
git_testtools::scripted_fixture_repo_read_only(name)
911
}
10-
.unwrap()
1112
}
1213

13-
fn main_store(packed: bool) -> git_ref::file::Store {
14-
let dir = dir(packed);
15-
git_ref::file::Store::at(dir.join("repo").join(".git"), Default::default(), Default::default())
14+
fn main_store(packed: bool) -> crate::Result<(git_ref::file::Store, git_odb::Handle)> {
15+
let dir = dir(packed)?;
16+
let git_dir = dir.join("repo").join(".git");
17+
Ok((
18+
git_ref::file::Store::at(&git_dir, Default::default(), Default::default()),
19+
git_odb::at(git_dir.join("objects"))?,
20+
))
1621
}
1722

18-
fn worktree_store(packed: bool) -> git_ref::file::Store {
19-
let dir = dir(packed);
20-
let (git_dir, _work_tree) = git_discover::upwards(dir.join("w1"))
21-
.unwrap()
23+
fn worktree_store(packed: bool) -> crate::Result<(git_ref::file::Store, git_odb::Handle)> {
24+
let dir = dir(packed)?;
25+
let (git_dir, _work_tree) = git_discover::upwards(dir.join("w1"))?
2226
.0
2327
.into_repository_and_work_tree_directories();
2428
let common_dir = git_dir.join("../..");
25-
git_ref::file::Store::for_linked_worktree(git_dir, common_dir, Default::default(), Default::default())
29+
Ok((
30+
git_ref::file::Store::for_linked_worktree(git_dir, &common_dir, Default::default(), Default::default()),
31+
git_odb::at(common_dir.join("objects"))?,
32+
))
33+
}
34+
35+
fn into_peel(
36+
store: &git_ref::file::Store,
37+
odb: git_odb::Handle,
38+
) -> impl Fn(git_ref::Reference) -> git_hash::ObjectId + '_ {
39+
move |mut r: git_ref::Reference| {
40+
r.peel_to_id_in_place(
41+
store,
42+
|id, buf| -> Result<Option<(git_object::Kind, &[u8])>, git_odb::store::find::Error> {
43+
let data = odb.try_find(id, buf)?;
44+
Ok(data.map(|d| (d.kind, d.data)))
45+
},
46+
)
47+
.unwrap()
48+
}
2649
}
2750

2851
#[test]
29-
fn with_common_dir() {
52+
fn linked() {
3053
for packed in [false, true] {
31-
let _store = worktree_store(packed);
54+
let (store, odb) = worktree_store(packed).unwrap();
55+
let peel = into_peel(&store, odb);
56+
assert_ne!(
57+
peel(store.find("HEAD").unwrap()),
58+
peel(store.find("main-worktree/HEAD").unwrap())
59+
);
3260
}
3361
}
3462

3563
#[test]
36-
fn with_git_dir() {
64+
fn main() {
3765
for packed in [false, true] {
38-
let _store = main_store(packed);
66+
let (store, odb) = main_store(packed).unwrap();
67+
let peel = into_peel(&store, odb);
68+
69+
assert_eq!(
70+
peel(store.find("HEAD").unwrap()),
71+
peel(store.find("main-worktree/HEAD").unwrap())
72+
);
73+
assert_eq!(
74+
peel(store.find("main").unwrap()),
75+
peel(store.find("main-worktree/refs/heads/main").unwrap())
76+
);
3977
}
4078
}

0 commit comments

Comments
 (0)