Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/filter/opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,22 @@ fn iterate(filter: Filter) -> Filter {
filter
}

fn is_prefix(op: Op) -> bool {
match op {
Op::Prefix(_) => true,
_ => false,
}
}

fn prefix_of(op: Op) -> Filter {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the name here... This gets the last of a chain, if it is a prefix?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe last_prefix?

let last = to_op(last_chain(to_filter(Op::Nop), to_filter(op.clone())).1);
to_filter(if is_prefix(last.clone()) {
last
} else {
Op::Nop
})
}

/*
* Attempt to apply one optimization rule to a filter. If no rule applies the input
* is returned.
Expand Down Expand Up @@ -335,6 +351,8 @@ fn step(filter: Filter) -> Filter {
}
Op::Chain(a, b) => match (to_op(a), to_op(b)) {
(Op::Chain(x, y), b) => Op::Chain(x, to_filter(Op::Chain(y, to_filter(b)))),
(Op::Prefix(a), Op::Subdir(b)) if a == b => Op::Nop,
(Op::Prefix(a), Op::Subdir(b)) if a != b => Op::Empty,
(Op::Nop, b) => b,
(a, Op::Nop) => a,
(Op::Empty, _) => Op::Empty,
Expand All @@ -347,10 +365,22 @@ fn step(filter: Filter) -> Filter {
Op::Subtract(a, b) if a == b => Op::Empty,
Op::Subtract(af, bf) => match (to_op(af), to_op(bf)) {
(Op::Empty, _) => Op::Empty,
(_, Op::Nop) => Op::Empty,
(a, Op::Empty) => a,
(Op::Chain(a, b), Op::Chain(c, d)) if a == c => {
Op::Chain(a, to_filter(Op::Subtract(b, d)))
}
(_, b) if prefix_of(b.clone()) != to_filter(Op::Nop) => {
Op::Subtract(af, last_chain(to_filter(Op::Nop), to_filter(b.clone())).0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here you are redoing the same operation as in prefix_of. Might be optimizable?

}
(a, _) if prefix_of(a.clone()) != to_filter(Op::Nop) => Op::Chain(
to_filter(Op::Subtract(
last_chain(to_filter(Op::Nop), to_filter(a.clone())).0,
bf,
)),
prefix_of(a),
),
(_, b) if is_prefix(b.clone()) => Op::Subtract(af, to_filter(Op::Nop)),
_ if common_post(&vec![af, bf]).is_some() => {
let (cp, rest) = common_post(&vec![af, bf]).unwrap();
Op::Chain(to_filter(Op::Subtract(rest[0], rest[1])), cp)
Expand Down
21 changes: 15 additions & 6 deletions tests/filter/pretty_print.t
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@
:/b
]

$ josh-filter -p :subtract[a=:[::x/,::y/,::z/],b=:[::x/,::y/]]
a/z = :/z
$ josh-filter -p :subtract[a=:[::x/,::y/,::z/],a=:[::x/,::y/]]
a/z = :/z
$ josh-filter -p :subtract[a=:[::x/,::y/],a=:[::x/,::y/]]
:empty
$ josh-filter -p :subtract[a=:[::x/,::y/],b=:[::x/,::y/]]
:empty

$ cat > f <<EOF
> a/b = :/a/b
> a/j = :/a/j
Expand Down Expand Up @@ -71,9 +80,9 @@
> ]]
> EOF
$ josh-filter -p --file f
:subtract[
::b/
::c/
b = :subtract[
:/b
:/c
]

$ cat > f <<EOF
Expand Down Expand Up @@ -173,9 +182,9 @@
> EOF

$ josh-filter -p --file f
:subtract[
x/g = :/a/x/g
p/au/bs/i1 = :/m/bs/m2/i/tc/i1
x/g = :subtract[
:/a/x/g
:/m/bs/m2/i/tc/i1
]

$ cat > f <<EOF
Expand Down
69 changes: 11 additions & 58 deletions tests/proxy/workspace_modify_chain_prefix_subtree.t
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,19 @@

nothing to commit (create/copy files and use "git add" to track)

$ git checkout -b master
Switched to a new branch 'master'
$ git checkout -q -b master


$ echo content1 > file1 1> /dev/null
$ git add .
$ git commit -m "initial" 1> /dev/null

$ git checkout -b new1
Switched to a new branch 'new1'
$ git checkout -q -b new1
$ echo content > newfile1 1> /dev/null
$ git add .
$ git commit -m "add newfile1" 1> /dev/null

$ git checkout master 1> /dev/null
Switched to branch 'master'
$ git checkout -q master 1> /dev/null
$ echo content > newfile_master 1> /dev/null
$ git add .
$ git commit -m "newfile master" 1> /dev/null
Expand Down Expand Up @@ -116,25 +113,7 @@
* add file2
* add file1

$ git checkout HEAD~1 1> /dev/null
Note: switching to 'HEAD~1'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

git switch -c <new-branch-name>

Or undo this operation with:

git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at a4b6822 add workspace
$ git checkout -q HEAD~1 1> /dev/null
$ tree
.
|-- a
Expand All @@ -147,9 +126,7 @@

4 directories, 3 files

$ git checkout HEAD~1 1> /dev/null
Previous HEAD position was a4b6822 add workspace
HEAD is now at 2a03ad0 add file2
$ git checkout -q HEAD~1 1> /dev/null
$ tree
.
|-- a
Expand All @@ -161,9 +138,7 @@

4 directories, 2 files

$ git checkout master 1> /dev/null
Previous HEAD position was 2a03ad0 add file2
Switched to branch 'master'
$ git checkout -q master 1> /dev/null

$ echo newfile_1_contents > c/subsub/newfile_1
$ git rm c/subsub/file1
Expand Down Expand Up @@ -282,25 +257,7 @@ Note that ws/d/ is now present in the ws
cat: sub1/subsub/file1: No such file or directory
[1]

$ git checkout HEAD~1 1> /dev/null
Note: switching to 'HEAD~1'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

git switch -c <new-branch-name>

Or undo this operation with:

git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at edefd7d add in filter
$ git checkout -q HEAD~1 1> /dev/null
$ git clean -ffdx 1> /dev/null
$ tree
.
Expand All @@ -321,9 +278,7 @@ Note that ws/d/ is now present in the ws

5 directories, 9 files

$ git checkout HEAD~1 1> /dev/null
Previous HEAD position was edefd7d add in filter
HEAD is now at aaec05d mod workspace
$ git checkout -q HEAD~1 1> /dev/null
$ git clean -ffdx 1> /dev/null
$ tree
.
Expand Down Expand Up @@ -370,13 +325,11 @@ Note that ws/d/ is now present in the ws
| | | `-- HEAD
| | |-- %3A%2Fws%2Fd
| | | `-- HEAD
| | |-- %3Aworkspace=ws
| | | `-- HEAD
| | `-- %3Aworkspace=ws%3Aprefix=pre%3A%2Fpre
| | `-- %3Aworkspace=ws
| | `-- HEAD
| |-- rewrites
| | `-- real_repo.git
| | `-- 010e03f34d3497fc1e309e7c8bd06a95e399677b
| | `-- 7bd92d97e96693ea7fd7eb5757b3580002889948
| | |-- r_44edc62d506b9805a3edfc74db15b1cc0bfc6871
| | `-- r_9d72b88b11aed97d3313f0a6d80894ee2ffdf3e9
| `-- upstream
Expand All @@ -388,6 +341,6 @@ Note that ws/d/ is now present in the ws
|-- namespaces
`-- tags

21 directories, 12 files
20 directories, 11 files

$ cat ${TESTTMP}/josh-proxy.out | grep VIEW