-
Notifications
You must be signed in to change notification settings - Fork 70
Add :linear filter #741
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add :linear filter #741
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,8 +61,9 @@ enum Op { | |
| Nop, | ||
| Empty, | ||
| Fold, | ||
| Squash, | ||
| Paths, | ||
| Squash, | ||
| Linear, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alphabetical order? |
||
|
|
||
| #[cfg(feature = "search")] | ||
| Index, | ||
|
|
@@ -185,6 +186,7 @@ fn spec2(op: &Op) -> String { | |
| Op::Index => ":INDEX".to_string(), | ||
| Op::Fold => ":FOLD".to_string(), | ||
| Op::Squash => ":SQUASH".to_string(), | ||
| Op::Linear => ":linear".to_string(), | ||
| Op::Subdir(path) => format!(":/{}", path.to_string_lossy()), | ||
| Op::File(path) => format!("::{}", path.to_string_lossy()), | ||
| Op::Prefix(path) => format!(":prefix={}", path.to_string_lossy()), | ||
|
|
@@ -274,6 +276,24 @@ fn apply_to_commit2( | |
| Op::Squash => { | ||
| return Some(history::rewrite_commit(repo, commit, &[], &commit.tree()?)).transpose() | ||
| } | ||
| Op::Linear => { | ||
| let p: Vec<_> = commit.parents().collect(); | ||
| if p.len() == 0 { | ||
| return Ok(Some(commit.id())); | ||
| } | ||
| let parent = some_or!(apply_to_commit2(op, &p[0], transaction)?, { | ||
| return Ok(None); | ||
| }); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dont understand this case
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Returning |
||
|
|
||
| let parent_commit = repo.find_commit(parent)?; | ||
| return Some(history::rewrite_commit( | ||
| repo, | ||
| commit, | ||
| &[&parent_commit], | ||
| &commit.tree()?, | ||
| )) | ||
| .transpose(); | ||
| } | ||
| _ => { | ||
| if let Some(oid) = transaction.get(filter, commit.id()) { | ||
| return Ok(Some(oid)); | ||
|
|
@@ -457,6 +477,7 @@ fn apply2<'a>( | |
| Op::Empty => return Ok(tree::empty(repo)), | ||
| Op::Fold => Ok(tree), | ||
| Op::Squash => Ok(tree), | ||
| Op::Linear => Ok(tree), | ||
|
|
||
| Op::Glob(pattern) => { | ||
| let pattern = glob::Pattern::new(pattern)?; | ||
|
|
@@ -555,6 +576,7 @@ fn unapply2<'a>( | |
| ) -> JoshResult<git2::Tree<'a>> { | ||
| return match op { | ||
| Op::Nop => Ok(tree), | ||
| Op::Linear => Ok(tree), | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can see that it works, but I don't understand why. How does it find the parents after this?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Magic 🪄 Just like with any other filter: When we need to find the original commits we search them by traversing the commit graph until we find Many filters drop commits, how exactly does not matter for the algorithm to work.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense. Thinking about it more, this didn't confuse me on other filters, but for some reason I got stuck on this one :) |
||
| Op::Empty => Ok(parent_tree), | ||
|
|
||
| Op::Chain(a, b) => { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| $ git init -q 1> /dev/null | ||
|
|
||
| $ echo contents1 > file1 | ||
| $ git add . | ||
| $ git commit -m "add file1" 1> /dev/null | ||
|
|
||
| $ git log --graph --pretty=%s | ||
| * add file1 | ||
|
|
||
| $ git checkout -b branch2 | ||
| Switched to a new branch 'branch2' | ||
|
|
||
| $ echo contents2 > file1 | ||
| $ git add . | ||
| $ git commit -m "mod file1" 1> /dev/null | ||
|
|
||
| $ git checkout master | ||
| Switched to branch 'master' | ||
|
|
||
| $ echo contents3 > file2 | ||
| $ git add . | ||
| $ git commit -m "add file2" 1> /dev/null | ||
|
|
||
| $ git merge -q branch2 --no-ff | ||
|
|
||
| $ git log --graph --pretty=%s | ||
| * Merge branch 'branch2' | ||
| |\ | ||
| | * mod file1 | ||
| * | add file2 | ||
| |/ | ||
| * add file1 | ||
|
|
||
| $ josh-filter -s :linear refs/heads/master --update refs/heads/filtered | ||
|
|
||
| $ git log --graph --pretty=%s refs/heads/filtered | ||
| * Merge branch 'branch2' | ||
| * add file2 | ||
| * add file1 | ||
|
|
||
| $ git ls-tree --name-only -r refs/heads/filtered | ||
| file1 | ||
| file2 | ||
|
|
||
| $ git checkout filtered | ||
| Switched to branch 'filtered' | ||
|
|
||
| $ echo contents4 > file2 | ||
| $ git add . | ||
| $ git commit -m "mod file2" 1> /dev/null | ||
|
|
||
| $ git log --graph --pretty=%s refs/heads/filtered | ||
| * mod file2 | ||
| * Merge branch 'branch2' | ||
| * add file2 | ||
| * add file1 | ||
|
|
||
| $ josh-filter -s :linear refs/heads/master --update refs/heads/filtered --reverse | ||
|
|
||
| $ git log --graph --pretty=%s refs/heads/master | ||
| * mod file2 | ||
| * Merge branch 'branch2' | ||
| |\ | ||
| | * mod file1 | ||
| * | add file2 | ||
| |/ | ||
| * add file1 | ||
|
|
||
| $ git log --graph --pretty=%s refs/heads/filtered | ||
| * mod file2 | ||
| * Merge branch 'branch2' | ||
| * add file2 | ||
| * add file1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe a few words on a typical use case?