Skip to content

Commit 4997cf4

Browse files
Fix generated merge commit on workspace redirect (#1306)
The :workspace filter compares the workspace mapping between commits and creates a merge commit with the history of newly mapped paths. This did not work correctly in case the parents workspace mapping was a redirect, in which case it considered all paths as newly mapped even though they are already part of the history. Now the redirect is taken into account when parting the parents workspace definition and we get correct history. Change: fix-redirect-merge
1 parent 007fd70 commit 4997cf4

File tree

2 files changed

+74
-24
lines changed

2 files changed

+74
-24
lines changed

josh-core/src/filter/mod.rs

+22-13
Original file line numberDiff line numberDiff line change
@@ -384,14 +384,17 @@ fn resolve_workspace_redirect<'a>(
384384
repo: &'a git2::Repository,
385385
tree: &'a git2::Tree<'a>,
386386
path: &Path,
387-
) -> Option<Filter> {
387+
) -> Option<(Filter, std::path::PathBuf)> {
388388
let f = parse::parse(&tree::get_blob(repo, tree, &path.join("workspace.josh")))
389389
.unwrap_or_else(|_| to_filter(Op::Empty));
390390

391-
if let Op::Workspace(_) = to_op(f) {
392-
Some(chain(
393-
to_filter(Op::Exclude(to_filter(Op::File(path.to_owned())))),
394-
f,
391+
if let Op::Workspace(p) = to_op(f) {
392+
Some((
393+
chain(
394+
to_filter(Op::Exclude(to_filter(Op::File(path.to_owned())))),
395+
f,
396+
),
397+
p,
395398
))
396399
} else {
397400
None
@@ -570,7 +573,8 @@ fn apply_to_commit2(
570573
.map(|parent| transaction.get(filter, parent))
571574
.collect::<Option<Vec<git2::Oid>>>();
572575

573-
if let Some(redirect) = resolve_workspace_redirect(repo, &commit.tree()?, ws_path) {
576+
if let Some((redirect, _)) = resolve_workspace_redirect(repo, &commit.tree()?, ws_path)
577+
{
574578
if let Some(r) = apply_to_commit2(&to_op(redirect), &commit, transaction)? {
575579
transaction.insert(filter, commit.id(), r, true);
576580
return Ok(Some(r));
@@ -588,17 +592,22 @@ fn apply_to_commit2(
588592
.map(|parent| {
589593
rs_tracing::trace_scoped!("parent", "id": parent.id().to_string());
590594

595+
let p = if let Some((_, p)) =
596+
resolve_workspace_redirect(repo, &parent.tree()?, ws_path)
597+
{
598+
p
599+
} else {
600+
ws_path.clone()
601+
};
602+
591603
let pcw = get_workspace(
592604
repo,
593605
&parent.tree().unwrap_or_else(|_| tree::empty(repo)),
594-
ws_path,
606+
&p,
595607
);
608+
let f = opt::optimize(to_filter(Op::Subtract(cw, pcw)));
596609

597-
apply_to_commit2(
598-
&to_op(opt::optimize(to_filter(Op::Subtract(cw, pcw)))),
599-
&parent,
600-
transaction,
601-
)
610+
apply_to_commit2(&to_op(f), &parent, transaction)
602611
})
603612
.collect::<JoshResult<Option<Vec<_>>>>()?;
604613

@@ -764,7 +773,7 @@ fn apply2<'a>(
764773
let base = to_filter(Op::Subdir(path.to_owned()));
765774
let wsj_file = chain(base, wsj_file);
766775

767-
if let Some(redirect) = resolve_workspace_redirect(repo, &tree, path) {
776+
if let Some((redirect, _)) = resolve_workspace_redirect(repo, &tree, path) {
768777
return apply(transaction, redirect, tree);
769778
}
770779

tests/filter/workspace_redirect.t

+52-11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@
2424
$ git add ws
2525
$ git commit -m "add ws" 1> /dev/null
2626

27+
$ mkdir sub3
28+
$ echo contents3 > sub3/file4
29+
$ git add sub3
30+
$ git commit -m "add file4" 1> /dev/null
31+
32+
$ cat > ws/workspace.josh <<EOF
33+
> ::sub2/subsub/
34+
> a = :/sub1
35+
> b = :/sub3
36+
> EOF
37+
$ git add ws
38+
$ git commit -m "edit ws" 1> /dev/null
39+
2740
$ mkdir ws_new
2841
$ echo "foobar" > ws_new/extra_file_new
2942
$ cat > ws_new/workspace.josh <<EOF
@@ -33,25 +46,35 @@
3346
$ git commit -m "add ws_new" 1> /dev/null
3447

3548
$ josh-filter -s :workspace=ws master --update refs/heads/filtered
49+
[1] :prefix=b
50+
[2] :/sub3
3651
[2] :[
3752
a = :/sub1
3853
::sub2/subsub/
3954
]
40-
[2] :workspace=ws
55+
[3] :workspace=ws
4156
$ josh-filter -s :workspace=ws_new master --update refs/heads/filtered_new
57+
[1] :prefix=b
4258
[1] :workspace=ws_new
59+
[2] :/sub3
4360
[2] :[
4461
a = :/sub1
4562
::sub2/subsub/
4663
]
47-
[2] :workspace=ws
48-
[3] :exclude[::ws_new]
64+
[3] :workspace=ws
65+
[5] :exclude[::ws_new]
4966

5067
$ git log --graph --pretty=%s refs/heads/filtered
68+
* edit ws
69+
|\
70+
| * add file4
5171
* add ws
5272
* add file2
5373
* add file1
5474
$ git log --graph --pretty=%s refs/heads/filtered_new
75+
* edit ws
76+
|\
77+
| * add file4
5578
* add ws
5679
* add file2
5780
* add file1
@@ -71,6 +94,13 @@
7194
+++ b/a/file4
7295
@@ -0,0 +1 @@
7396
+contents4
97+
diff --git a/b/file4 b/b/file4
98+
new file mode 100644
99+
index 0000000..1cb5d64
100+
--- /dev/null
101+
+++ b/b/file4
102+
@@ -0,0 +1 @@
103+
+contents3
74104
diff --git a/extra_file b/extra_file
75105
new file mode 100644
76106
index 0000000..323fae0
@@ -87,12 +117,13 @@
87117
+contents1
88118
diff --git a/workspace.josh b/workspace.josh
89119
new file mode 100644
90-
index 0000000..68bf391
120+
index 0000000..795cb6d
91121
--- /dev/null
92122
+++ b/workspace.josh
93-
@@ -0,0 +1,2 @@
123+
@@ -0,0 +1,3 @@
94124
+::sub2/subsub/
95125
+a = :/sub1
126+
+b = :/sub3
96127
$ git diff ${EMPTY_TREE}..refs/heads/filtered_new
97128
diff --git a/a/file1 b/a/file1
98129
new file mode 100644
@@ -108,6 +139,13 @@
108139
+++ b/a/file4
109140
@@ -0,0 +1 @@
110141
+contents4
142+
diff --git a/b/file4 b/b/file4
143+
new file mode 100644
144+
index 0000000..1cb5d64
145+
--- /dev/null
146+
+++ b/b/file4
147+
@@ -0,0 +1 @@
148+
+contents3
111149
diff --git a/extra_file b/extra_file
112150
new file mode 100644
113151
index 0000000..323fae0
@@ -124,12 +162,13 @@
124162
+contents1
125163
diff --git a/workspace.josh b/workspace.josh
126164
new file mode 100644
127-
index 0000000..68bf391
165+
index 0000000..795cb6d
128166
--- /dev/null
129167
+++ b/workspace.josh
130-
@@ -0,0 +1,2 @@
168+
@@ -0,0 +1,3 @@
131169
+::sub2/subsub/
132170
+a = :/sub1
171+
+b = :/sub3
133172

134173

135174
$ cat > ws/workspace.josh <<EOF
@@ -139,11 +178,13 @@
139178
$ git commit -m "add ws recursion" 1> /dev/null
140179

141180
$ josh-filter -s :workspace=ws master --update refs/heads/filtered
181+
[1] :prefix=b
182+
[2] :/sub3
142183
[2] :[
143184
a = :/sub1
144185
::sub2/subsub/
145186
]
146-
[2] :workspace=ws_new
147-
[3] :exclude[::ws]
148-
[3] :exclude[::ws_new]
149-
[3] :workspace=ws
187+
[3] :workspace=ws_new
188+
[4] :exclude[::ws]
189+
[4] :workspace=ws
190+
[6] :exclude[::ws_new]

0 commit comments

Comments
 (0)