-
Notifications
You must be signed in to change notification settings - Fork 570
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
250 additions
and
76 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
26 changes: 26 additions & 0 deletions
26
crates/but-workspace/tests/fixtures/scenario/two-signed-commits-with-line-offset.sh
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,26 @@ | ||
#!/usr/bin/env bash | ||
|
||
### Description | ||
# A single branch with two signed commits. The first commit has 10 lines, the second adds | ||
# another 10 lines to the top of the file. | ||
# Large numbers are used make fuzzy-patch application harder. | ||
set -eu -o pipefail | ||
|
||
ssh-keygen -t rsa -b 2048 -C "[email protected]" -N "" -f signature.key | ||
|
||
git init | ||
git config gpg.format ssh | ||
git config user.signingKey "$PWD/signature.key" | ||
git config GitButler.signCommits true | ||
|
||
export "GIT_CONFIG_COUNT=2" | ||
export "GIT_CONFIG_KEY_0=commit.gpgsign" | ||
export "GIT_CONFIG_VALUE_0=true" | ||
export "GIT_CONFIG_KEY_1=init.defaultBranch" | ||
export "GIT_CONFIG_VALUE_1=main" | ||
|
||
seq 10 20 >file | ||
git add file && git commit -m init && git tag first-commit | ||
|
||
seq 20 >file && git commit -am "insert 10 lines to the top" | ||
|
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 |
---|---|---|
@@ -1,15 +1,13 @@ | ||
use crate::commit_engine::utils::{ | ||
commit_whole_files_and_all_hunks_from_workspace, read_only_in_memory_scenario, stable_env, | ||
visualize_tree, | ||
assure_stable_env, commit_from_outcome, commit_whole_files_and_all_hunks_from_workspace, | ||
read_only_in_memory_scenario, visualize_tree, writable_scenario, writable_scenario_execute, | ||
write_sequence, | ||
}; | ||
use but_workspace::commit_engine::Destination; | ||
use gix::prelude::ObjectIdExt; | ||
use serial_test::serial; | ||
|
||
#[test] | ||
#[serial] | ||
fn all_changes_and_renames_to_topmost_commit_no_parent() -> anyhow::Result<()> { | ||
let _env = stable_env(); | ||
assure_stable_env(); | ||
|
||
let repo = read_only_in_memory_scenario("all-file-types-renamed-and-modified")?; | ||
let head_commit = repo.rev_parse_single("HEAD")?; | ||
|
@@ -69,29 +67,111 @@ fn all_changes_and_renames_to_topmost_commit_no_parent() -> anyhow::Result<()> { | |
} | ||
|
||
#[test] | ||
#[serial] | ||
#[ignore = "TBD"] | ||
fn all_aspects_of_amended_commit_are_copied_including_extra_headers() -> anyhow::Result<()> { | ||
fn all_aspects_of_amended_commit_are_copied() -> anyhow::Result<()> { | ||
assure_stable_env(); | ||
|
||
let (repo, _tmp) = writable_scenario("merge-with-two-branches-line-offset"); | ||
// Rewrite the entire file, which is fine as we rewrite/amend the base-commit itself. | ||
write_sequence(&repo, "file", [(40, 70)])?; | ||
let outcome = commit_whole_files_and_all_hunks_from_workspace( | ||
&repo, | ||
Destination::AmendCommit(repo.rev_parse_single("merge")?.detach()), | ||
)?; | ||
let tree = visualize_tree(&repo, &outcome)?; | ||
insta::assert_snapshot!(tree, @r#" | ||
5bbee6d | ||
└── file:100644:1c9325b "40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59\n60\n61\n62\n63\n64\n65\n66\n67\n68\n69\n70\n" | ||
"#); | ||
insta::assert_debug_snapshot!(commit_from_outcome(&repo, &outcome)?, @r#" | ||
Commit { | ||
tree: Sha1(5bbee6d0219923e795f7b0818dda2f33f16278b4), | ||
parents: [ | ||
Sha1(91ef6f6fc0a8b97fb456886c1cc3b2a3536ea2eb), | ||
Sha1(7f389eda1b366f3d56ecc1300b3835727c3309b6), | ||
], | ||
author: Signature { | ||
name: "author", | ||
email: "[email protected]", | ||
time: Time { | ||
seconds: 946684800, | ||
offset: 0, | ||
sign: Plus, | ||
}, | ||
}, | ||
committer: Signature { | ||
name: "committer", | ||
email: "[email protected]", | ||
time: Time { | ||
seconds: 946771200, | ||
offset: 0, | ||
sign: Plus, | ||
}, | ||
}, | ||
encoding: None, | ||
message: "Merge branch \'A\' into merge\n", | ||
extra_headers: [], | ||
} | ||
"#); | ||
Ok(()) | ||
} | ||
|
||
#[test] | ||
#[serial] | ||
#[ignore = "TBD"] | ||
fn signatures_are_redone() -> anyhow::Result<()> { | ||
assure_stable_env(); | ||
|
||
let (mut repo, _tmp) = writable_scenario_execute("two-signed-commits-with-line-offset"); | ||
|
||
let head_id = repo.head_id()?; | ||
let head_commit = head_id.object()?.into_commit().decode()?.to_owned(); | ||
let head_id = head_id.detach(); | ||
let previous_signature = head_commit | ||
.extra_headers() | ||
.pgp_signature() | ||
.expect("it's signed by default"); | ||
|
||
// Rewrite everything for amending on top. | ||
write_sequence(&repo, "file", [(40, 60)])?; | ||
let outcome = | ||
commit_whole_files_and_all_hunks_from_workspace(&repo, Destination::AmendCommit(head_id))?; | ||
|
||
let new_commit = commit_from_outcome(&repo, &outcome)?; | ||
let new_signature = new_commit | ||
.extra_headers() | ||
.pgp_signature() | ||
.expect("signing config is respected"); | ||
assert_ne!( | ||
previous_signature, new_signature, | ||
"signatures are recreated as the commit is changed" | ||
); | ||
assert_eq!( | ||
new_commit | ||
.extra_headers() | ||
.find_all(gix::objs::commit::SIGNATURE_FIELD_NAME) | ||
.count(), | ||
1, | ||
"it doesn't leave outdated signatures on top of the updated one" | ||
); | ||
|
||
repo.config_snapshot_mut() | ||
.set_raw_value(&"gitbutler.signCommits", "false")?; | ||
write_local_config(&repo)?; | ||
let outcome = | ||
commit_whole_files_and_all_hunks_from_workspace(&repo, Destination::AmendCommit(head_id))?; | ||
let new_commit = commit_from_outcome(&repo, &outcome)?; | ||
assert!( | ||
new_commit.extra_headers().pgp_signature().is_none(), | ||
"If signing commits is disabled, \ | ||
it will drop the signature (instead of leaving an invalid one)" | ||
); | ||
Ok(()) | ||
} | ||
|
||
fn commit_from_outcome( | ||
repo: &gix::Repository, | ||
outcome: &but_workspace::commit_engine::CreateCommitOutcome, | ||
) -> anyhow::Result<gix::objs::Commit> { | ||
Ok(outcome | ||
.new_commit | ||
.expect("the amended commit was created") | ||
.attach(repo) | ||
.object()? | ||
.peel_to_commit()? | ||
.decode()? | ||
.into()) | ||
// In-memory config changes aren't enough as we still only have snapshots, without the ability to keep | ||
// the entire configuration fresh. | ||
fn write_local_config(repo: &gix::Repository) -> anyhow::Result<()> { | ||
repo.config_snapshot().write_to_filter( | ||
&mut std::fs::File::create(repo.path().join("config"))?, | ||
|section| section.meta().source == gix::config::Source::Local, | ||
)?; | ||
Ok(()) | ||
} |
Oops, something went wrong.