Skip to content

Commit 73e34dd

Browse files
Introduce syntax for :squash(...) filter (#1097)
Previously this filter could only be created programatically, now it can be specified in the filter language. Change: squash-syntax
1 parent 34ccdc3 commit 73e34dd

File tree

7 files changed

+114
-36
lines changed

7 files changed

+114
-36
lines changed

src/bin/josh-filter.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -152,19 +152,6 @@ fn run_filter(args: Vec<String>) -> josh::JoshResult<i32> {
152152

153153
let mut filterobj = josh::filter::parse(&specstr)?;
154154

155-
if args.get_flag("print-filter") {
156-
let filterobj = if args.get_flag("reverse") {
157-
josh::filter::invert(filterobj)?
158-
} else {
159-
filterobj
160-
};
161-
println!(
162-
"{}",
163-
josh::filter::pretty(filterobj, if args.contains_id("file") { 0 } else { 4 })
164-
);
165-
return Ok(0);
166-
}
167-
168155
let repo = git2::Repository::open_from_env()?;
169156
if !args.get_flag("no-cache") {
170157
josh::cache::load(repo.path())?;
@@ -197,6 +184,19 @@ fn run_filter(args: Vec<String>) -> josh::JoshResult<i32> {
197184
filterobj = josh::filter::chain(josh::filter::squash(Some(&ids)), filterobj);
198185
};
199186

187+
if args.get_flag("print-filter") {
188+
let filterobj = if args.get_flag("reverse") {
189+
josh::filter::invert(filterobj)?
190+
} else {
191+
filterobj
192+
};
193+
println!(
194+
"{}",
195+
josh::filter::pretty(filterobj, if args.contains_id("file") { 0 } else { 4 })
196+
);
197+
return Ok(0);
198+
}
199+
200200
let odb = repo.odb()?;
201201
let mp = if args.get_flag("pack") {
202202
let mempack = odb.add_new_mempack_backend(1000)?;

src/filter/grammar.pest

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ filter_spec = { (
2020
filter_group
2121
| filter_rev
2222
| filter_replace
23+
| filter_squash
2324
| filter_presub
2425
| filter_subdir
2526
| filter_nop
@@ -52,6 +53,15 @@ filter_replace = {
5253
~ ")"
5354
}
5455

56+
filter_squash = {
57+
CMD_START ~ "squash" ~ "("
58+
~ NEWLINE*
59+
~ (argument ~ ":" ~ string)?
60+
~ (CMD_SEP+ ~ (argument ~ ":" ~ string))*
61+
~ NEWLINE*
62+
~ ")"
63+
}
64+
5565
argument = { string | PATH }
5666

5767
cmd = { ALNUM+ }

src/filter/mod.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,21 @@ fn pretty2(op: &Op, indent: usize, compose: bool) -> String {
193193
.collect::<Vec<_>>();
194194
format!(":replace(\n{}\n)", v.join("\n"))
195195
}
196+
Op::Squash(Some(ids)) => {
197+
let mut v = ids
198+
.iter()
199+
.map(|(oid, msg)| {
200+
format!(
201+
"{}{}:{}",
202+
" ".repeat(indent),
203+
&oid.to_string(),
204+
parse::quote(msg)
205+
)
206+
})
207+
.collect::<Vec<_>>();
208+
v.sort();
209+
format!(":squash(\n{}\n)", v.join("\n"))
210+
}
196211
_ => spec2(op),
197212
}
198213
}
@@ -279,16 +294,13 @@ fn spec2(op: &Op) -> String {
279294
Op::Index => ":INDEX".to_string(),
280295
Op::Fold => ":FOLD".to_string(),
281296
Op::Squash(None) => ":SQUASH".to_string(),
282-
Op::Squash(Some(hs)) => {
283-
let mut v = hs
297+
Op::Squash(Some(ids)) => {
298+
let mut v = ids
284299
.iter()
285-
.map(|(x, y)| format!("{}:{}", x, y))
286-
.collect::<Vec<String>>();
300+
.map(|(oid, msg)| format!("{}:{}", oid, parse::quote(msg)))
301+
.collect::<Vec<_>>();
287302
v.sort();
288-
let s = v.join(",");
289-
let s = git2::Oid::hash_object(git2::ObjectType::Blob, s.as_bytes())
290-
.expect("hash_object filter");
291-
format!(":SQUASH={}", s)
303+
format!(":squash({})", v.join(","))
292304
}
293305
Op::Linear => ":linear".to_string(),
294306
Op::Unsign => ":unsign".to_string(),

src/filter/parse.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,20 @@ fn parse_item(pair: pest::iterators::Pair<Rule>) -> JoshResult<Op> {
124124

125125
Ok(Op::RegexReplace(replacements))
126126
}
127+
Rule::filter_squash => {
128+
let ids = pair
129+
.into_inner()
130+
.tuples()
131+
.map(|(oid, message)| {
132+
Ok((
133+
git2::Oid::from_str(oid.as_str())?,
134+
unquote(message.as_str()),
135+
))
136+
})
137+
.collect::<JoshResult<_>>()?;
138+
139+
Ok(Op::Squash(Some(ids)))
140+
}
127141

128142
_ => Err(josh_error("parse_item: no match")),
129143
}

tests/filter/pretty_print.t

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
$ export TESTTMP=${PWD}
22

3+
$ git init -q
4+
$ git commit -q --allow-empty -m "empty"
5+
36
$ josh-filter -p :/a
47
:/a
58
$ josh-filter -p :/"a"

tests/filter/squash.t

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030

3131
$ josh-filter -s --squash "refs/tags/*" --author "New Author" --email "new@e.mail" --update refs/heads/filtered
3232
Warning: reference refs/heads/filtered wasn't updated
33-
[1] :SQUASH=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
33+
[1] :squash(
34+
35+
)
3436

3537
$ git log --graph --decorate --pretty=oneline refs/heads/filtered
3638
fatal: ambiguous argument 'refs/heads/filtered': unknown revision or path not in the working tree.
@@ -39,9 +41,13 @@
3941
[128]
4042
$ git tag tag_a 1d69b7d
4143
$ josh-filter -s --squash "refs/tags/*" :author=\"New\ Author\"\;\"new@e.mail\" --update refs/heads/filtered
42-
[1] :SQUASH=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
4344
[1] :author="New Author";"new@e.mail"
44-
[2] :SQUASH=10d465cdf297e8062eed54204414414faa63671e
45+
[1] :squash(
46+
47+
)
48+
[2] :squash(
49+
1d69b7d2651f744be3416f2ad526aeccefb99310:"refs/tags/tag_a"
50+
)
4551
4652
$ git log --graph --decorate --pretty=oneline refs/heads/filtered
4753
* d8aa5a9937f4f0bd645dbc0b591bae5cd6b6d91b (tag: filtered/tag_a, filtered) refs/tags/tag_a
@@ -58,9 +64,17 @@
5864
* 0b4cf6c9efbbda1eada39fa9c1d21d2525b027bb (tag: tag_b) add file1
5965
6066
$ josh-filter -s --squash "refs/tags/*" :author=\"New\ Author\"\;\"new@e.mail\" --update refs/heads/filtered
61-
[1] :SQUASH=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
62-
[2] :SQUASH=10d465cdf297e8062eed54204414414faa63671e
63-
[3] :SQUASH=dd8bdf1d78a6cb9ffc9e2a0644a8bf41de56ad36
67+
[1] :squash(
68+
69+
)
70+
[2] :squash(
71+
1d69b7d2651f744be3416f2ad526aeccefb99310:"refs/tags/tag_a"
72+
)
73+
[3] :squash(
74+
0b4cf6c9efbbda1eada39fa9c1d21d2525b027bb:"refs/tags/tag_b"
75+
1d69b7d2651f744be3416f2ad526aeccefb99310:"refs/tags/tag_a"
76+
d8aa5a9937f4f0bd645dbc0b591bae5cd6b6d91b:"refs/tags/filtered/tag_a"
77+
)
6478
[4] :author="New Author";"new@e.mail"
6579
6680
$ git log --graph --decorate --pretty=oneline refs/heads/filtered
@@ -83,17 +97,42 @@
8397
8498
$ git tag tag_c 975d4c4
8599
86-
$ josh-filter -s --squash "refs/tags/*" :author=\"New\ Author\"\;\"new@e.mail\" --update refs/heads/filtered
87-
[1] :SQUASH=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
88-
[2] :SQUASH=10d465cdf297e8062eed54204414414faa63671e
89-
[3] :SQUASH=dd8bdf1d78a6cb9ffc9e2a0644a8bf41de56ad36
90-
[6] :SQUASH=b2a9a51df03600d3b5858fa7fca044741f88e521
91-
[9] :author="New Author";"new@e.mail"
100+
$ josh-filter -s --squash "refs/tags/*" :author=\"New\ Author\"\;\"new@e.mail\" --update refs/heads/filtered -p > filter.josh
101+
$ cat filter.josh
102+
:squash(
103+
0b4cf6c9efbbda1eada39fa9c1d21d2525b027bb:"refs/tags/tag_b"
104+
1d69b7d2651f744be3416f2ad526aeccefb99310:"refs/tags/tag_a"
105+
5b1a753860ca124024f6dfb4fd018fe7df8beae4:"refs/tags/filtered/tag_a"
106+
68dc45079334d83e5b61d2ceeda035b96da4c838:"refs/tags/filtered/filtered/tag_a"
107+
96a731a4d64a8928e6af7abb2d425df3812b4197:"refs/tags/filtered/tag_b"
108+
975d4c4975912729482cc864d321c5196a969271:"refs/tags/tag_c"
109+
):author="New Author";"new@e.mail"
110+
$ josh-filter -s --file filter.josh --update refs/heads/filtered
111+
[1] :squash(
112+
113+
)
114+
[2] :squash(
115+
1d69b7d2651f744be3416f2ad526aeccefb99310:"refs/tags/tag_a"
116+
)
117+
[3] :squash(
118+
0b4cf6c9efbbda1eada39fa9c1d21d2525b027bb:"refs/tags/tag_b"
119+
1d69b7d2651f744be3416f2ad526aeccefb99310:"refs/tags/tag_a"
120+
5b1a753860ca124024f6dfb4fd018fe7df8beae4:"refs/tags/filtered/tag_a"
121+
68dc45079334d83e5b61d2ceeda035b96da4c838:"refs/tags/filtered/filtered/tag_a"
122+
96a731a4d64a8928e6af7abb2d425df3812b4197:"refs/tags/filtered/tag_b"
123+
975d4c4975912729482cc864d321c5196a969271:"refs/tags/tag_c"
124+
)
125+
[3] :squash(
126+
0b4cf6c9efbbda1eada39fa9c1d21d2525b027bb:"refs/tags/tag_b"
127+
1d69b7d2651f744be3416f2ad526aeccefb99310:"refs/tags/tag_a"
128+
d8aa5a9937f4f0bd645dbc0b591bae5cd6b6d91b:"refs/tags/filtered/tag_a"
129+
)
130+
[6] :author="New Author";"new@e.mail"
92131
93132
$ git log --graph --decorate --pretty=oneline refs/heads/filtered
94-
* 9fe45cb2bead844630852ab338ecd8e073f8ba50 (tag: filtered/tag_a, filtered) refs/tags/tag_a
133+
* 9fe45cb2bead844630852ab338ecd8e073f8ba50 (filtered) refs/tags/tag_a
95134
|\
96-
| * d6b88d4c1cc566b7f4d9b51353ec6f3204a93b81 (tag: filtered/tag_c) refs/tags/tag_c
135+
| * d6b88d4c1cc566b7f4d9b51353ec6f3204a93b81 refs/tags/tag_c
97136
|/
98137
* 96a731a4d64a8928e6af7abb2d425df3812b4197 (tag: filtered/tag_b) refs/tags/tag_b
99138

tests/proxy/workspace_errors.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Error in filter
104104
remote: 1 | a/b = :b/sub2
105105
remote: | ^---
106106
remote: |
107-
remote: = expected EOI, filter_group, filter_subdir, filter_nop, filter_presub, filter, filter_noarg, filter_rev, or filter_replace
107+
remote: = expected EOI, filter_group, filter_subdir, filter_nop, filter_presub, filter, filter_noarg, filter_rev, filter_replace, or filter_squash
108108
remote:
109109
remote: a/b = :b/sub2
110110
remote: c = :/sub1

0 commit comments

Comments
 (0)