-
Notifications
You must be signed in to change notification settings - Fork 562
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Integrate new hunk dependency algorithm
- behind a project level feature flag
- Loading branch information
Showing
7 changed files
with
244 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
crates/gitbutler-branch-actions/tests/virtual_branches/locking.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
use super::*; | ||
use gitbutler_branch::BranchCreateRequest; | ||
use gitbutler_branch_actions::{ | ||
create_commit, create_virtual_branch, list_virtual_branches, set_base_branch, | ||
}; | ||
|
||
// This test ensures hunk lock detection works when a lines are shifted. | ||
// | ||
// The idea is you introduce change A, then you shift it down in a a different | ||
// (default) branch with commit B, so that new line numbers no longer intersect | ||
// with those applied to the isolated branch. | ||
#[tokio::test] | ||
async fn hunk_locking_confused_by_line_number_shift() -> anyhow::Result<()> { | ||
let Test { | ||
repository, | ||
project, | ||
.. | ||
} = &Test::default(); | ||
let mut lines = repository.gen_file("file.txt", 9); | ||
repository.commit_all("initial commit"); | ||
repository.push(); | ||
|
||
set_base_branch(project, &"refs/remotes/origin/master".parse().unwrap()).unwrap(); | ||
|
||
// Introduce a change that should lock the last change to the first branch. | ||
lines[8] = "modification 1 to line 8".to_string(); | ||
repository.write_file("file.txt", &lines); | ||
|
||
// We're forced to call this before making a second commit. | ||
let (branches, _) = list_virtual_branches(project).unwrap(); | ||
create_commit(project, branches[0].id, "first commit", None, false)?; | ||
|
||
let (branches, _) = list_virtual_branches(project).unwrap(); | ||
assert_eq!(branches[0].files.len(), 0); | ||
assert_eq!(branches[0].commits.len(), 1); | ||
|
||
// Commit some changes to the second branch that will push the first | ||
// changes down when diffing workspace head against the default target. | ||
create_virtual_branch( | ||
project, | ||
&BranchCreateRequest { | ||
selected_for_changes: Some(true), | ||
..Default::default() | ||
}, | ||
) | ||
.unwrap(); | ||
|
||
let new_lines: Vec<_> = (0_i32..5_i32) | ||
.map(|i| format!("inserted line {}", i)) | ||
.collect(); | ||
lines.splice(0..0, new_lines); | ||
repository.write_file("file.txt", &lines); | ||
|
||
// We're forced to call this before making a second commit. | ||
let (branches, _) = list_virtual_branches(project).unwrap(); | ||
create_commit(project, branches[1].id, "second commit", None, false)?; | ||
|
||
// At this point we expect no uncommitted files, and one commit per branch. | ||
let (branches, _) = list_virtual_branches(project).unwrap(); | ||
assert_eq!(branches[0].commits.len(), 1); | ||
assert_eq!(branches[0].files.len(), 0); | ||
assert_eq!(branches[1].commits.len(), 1); | ||
assert_eq!(branches[1].files.len(), 0); | ||
|
||
// Now we change line we already changed in the first commit. | ||
lines[13] = "modification 2 to original line 8".to_string(); | ||
repository.write_file("file.txt", &lines); | ||
|
||
// And ensure that the new change is assigned to the first branch, despite the second | ||
// branch being default for new changes. | ||
let (branches, _) = list_virtual_branches(project).unwrap(); | ||
assert_eq!(branches[0].files.len(), 1); | ||
|
||
// For good measure, let's ensure the hunk lock points to the right branch. | ||
let branch = &branches[0]; | ||
let file = &branch.files[0]; | ||
let hunk_locks = file.hunks[0].locked_to.clone().unwrap(); | ||
assert_eq!(hunk_locks[0].branch_id, branch.id); | ||
Ok(()) | ||
} | ||
|
||
// This test ensures hunk lock detection works when a lines are shifted. | ||
// | ||
// The idea is you introduce change A, then you shift it down in a a different | ||
// (default) branch with commit B, so that new line numbers no longer intersect | ||
// with those applied to the isolated branch. | ||
#[tokio::test] | ||
async fn hunk_locking_with_deleted_lines_only() -> anyhow::Result<()> { | ||
let Test { | ||
repository, | ||
project, | ||
.. | ||
} = &Test::default(); | ||
repository.gen_file("file.txt", 3); | ||
repository.commit_all("initial commit"); | ||
repository.push(); | ||
|
||
set_base_branch(project, &"refs/remotes/origin/master".parse().unwrap()).unwrap(); | ||
|
||
// Introduce a change that should lock the last change to the first branch. | ||
let mut lines = repository.gen_file("file.txt", 2); | ||
lines[1] = "line 2".to_string(); | ||
repository.write_file("file.txt", &lines); | ||
|
||
// We have to do this before creating a commit. | ||
let (branches, _) = list_virtual_branches(project).unwrap(); | ||
create_commit(project, branches[0].id, "first commit", None, false)?; | ||
|
||
let (branches, _) = list_virtual_branches(project).unwrap(); | ||
assert_eq!(branches[0].commits.len(), 1); | ||
assert_eq!(branches[0].files.len(), 0); | ||
|
||
// Commit some changes to the second branch that will push the first changes | ||
// down when diffing workspace head against the default target. | ||
create_virtual_branch( | ||
project, | ||
&BranchCreateRequest { | ||
selected_for_changes: Some(true), | ||
..Default::default() | ||
}, | ||
) | ||
.unwrap(); | ||
|
||
lines[1] = "modified line 2".to_string(); | ||
repository.write_file("file.txt", &lines); | ||
|
||
let (branches, _) = list_virtual_branches(project)?; | ||
assert_eq!(branches[0].files.len(), 1); | ||
assert_eq!(branches[1].files.len(), 0); | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters