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
3 changes: 3 additions & 0 deletions .github/workflows/deployment-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- ".github/workflows/deploy-apt-repo.yml"
- ".github/workflows/release-manual-main.yml"
- "scripts/update-aur.sh"
- "scripts/cargo-flatten-dupes.sh"
- "scripts/package-macos.sh"
- "scripts/macos-cargo-config.sh"
- "scripts/generate-homebrew-formula.sh"
Expand All @@ -25,6 +26,7 @@ on:
- ".github/workflows/deploy-apt-repo.yml"
- ".github/workflows/release-manual-main.yml"
- "scripts/update-aur.sh"
- "scripts/cargo-flatten-dupes.sh"
- "scripts/package-macos.sh"
- "scripts/macos-cargo-config.sh"
- "scripts/generate-homebrew-formula.sh"
Expand All @@ -49,6 +51,7 @@ jobs:

- name: Validate shell scripts syntax
run: |
bash -n scripts/cargo-flatten-dupes.sh
bash -n scripts/update-aur.sh
bash -n scripts/package-macos.sh
bash -n scripts/notarize-macos.sh
Expand Down
107 changes: 17 additions & 90 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 46 additions & 4 deletions crates/gitcomet-core/src/merge_extraction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
//! into production code so it can be reused outside ad-hoc test harnesses.

use crate::merge::{MergeOptions, merge_file};
use crate::process::configure_background_command;
use crate::process::git_command;
use rustc_hash::FxHashSet as HashSet;
use std::collections::BTreeSet;
use std::fmt;
use std::io;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};
#[cfg(test)]
use std::process::Command;
use std::process::Output;

fn bytes_to_text_preserving_utf8(bytes: &[u8]) -> String {
use std::fmt::Write as _;
Expand Down Expand Up @@ -526,8 +528,7 @@ fn read_blob_bytes_optional(
}

fn run_git(repo: &Path, args: &[&str]) -> Result<Output, MergeExtractionError> {
let mut command = Command::new("git");
configure_background_command(&mut command);
let mut command = git_command();
command
.args(args)
.current_dir(repo)
Expand Down Expand Up @@ -597,9 +598,38 @@ fn sanitize_fixture_component(path: &str) -> String {
#[cfg(test)]
mod tests {
use super::*;
use crate::process::{
GitExecutablePreference, current_git_executable_preference,
install_git_executable_preference, lock_git_runtime_test,
};
#[cfg(windows)]
use std::sync::OnceLock;

// Keep merge-extraction tests isolated from process::tests, which mutate
// the shared git executable preference under this same mutex.
struct SystemGitRuntimeGuard {
_lock: std::sync::MutexGuard<'static, ()>,
original: GitExecutablePreference,
}

impl SystemGitRuntimeGuard {
fn new() -> Self {
let lock = lock_git_runtime_test();
let original = current_git_executable_preference();
let _ = install_git_executable_preference(GitExecutablePreference::SystemPath);
Self {
_lock: lock,
original,
}
}
}

impl Drop for SystemGitRuntimeGuard {
fn drop(&mut self) {
let _ = install_git_executable_preference(self.original.clone());
}
}

#[cfg(windows)]
fn is_git_shell_startup_failure(text: &str) -> bool {
text.contains("sh.exe: *** fatal error -")
Expand Down Expand Up @@ -760,6 +790,7 @@ mod tests {

#[test]
fn discovers_merge_commits_with_two_parents() {
let _git_runtime = SystemGitRuntimeGuard::new();
let repo = create_conflicting_merge_repo();
let merges = discover_merge_commits(repo.path(), 10).expect("discover merges");
assert_eq!(merges.len(), 1, "expected one merge commit");
Expand All @@ -772,6 +803,7 @@ mod tests {

#[test]
fn discovers_merge_commits_from_repo_subdirectory() {
let _git_runtime = SystemGitRuntimeGuard::new();
let repo = create_conflicting_merge_repo();
let subdir = repo.path().join("nested").join("dir");
std::fs::create_dir_all(&subdir).expect("create nested subdirectory");
Expand All @@ -786,6 +818,7 @@ mod tests {

#[test]
fn discover_merge_commits_zero_max_merges_errors() {
let _git_runtime = SystemGitRuntimeGuard::new();
let repo = create_conflicting_merge_repo();
let error =
discover_merge_commits(repo.path(), 0).expect_err("expected invalid argument error");
Expand All @@ -801,6 +834,7 @@ mod tests {

#[test]
fn discover_merge_commits_reports_not_git_repository_stderr() {
let _git_runtime = SystemGitRuntimeGuard::new();
let tmp = tempfile::tempdir().expect("create temp dir");
let repo = tmp.path();
let error =
Expand All @@ -820,6 +854,7 @@ mod tests {

#[test]
fn discovers_merge_commits_after_recent_octopus_merges() {
let _git_runtime = SystemGitRuntimeGuard::new();
if !require_git_shell_for_octopus_merge_tests() {
return;
}
Expand Down Expand Up @@ -911,6 +946,7 @@ mod tests {

#[test]
fn extracts_sorted_text_cases_and_skips_binary() {
let _git_runtime = SystemGitRuntimeGuard::new();
let repo = create_conflicting_merge_repo();
let merges = discover_merge_commits(repo.path(), 10).expect("discover merges");
let cases = extract_merge_cases(repo.path(), &merges[0], 10).expect("extract cases");
Expand All @@ -933,6 +969,7 @@ mod tests {
#[test]
#[cfg(not(windows))]
fn changed_files_handles_paths_with_newlines() {
let _git_runtime = SystemGitRuntimeGuard::new();
let tmp = tempfile::tempdir().expect("create temp dir");
let repo = tmp.path();

Expand Down Expand Up @@ -965,6 +1002,7 @@ mod tests {

#[test]
fn extracts_cases_with_missing_base_or_parent_as_empty_text() {
let _git_runtime = SystemGitRuntimeGuard::new();
let repo = create_missing_side_conflict_merge_repo();
let merges = discover_merge_commits(repo.path(), 10).expect("discover merges");
assert_eq!(merges.len(), 1, "expected one merge commit");
Expand Down Expand Up @@ -1023,6 +1061,7 @@ mod tests {

#[test]
fn git_show_missing_path_is_treated_as_absent_side() {
let _git_runtime = SystemGitRuntimeGuard::new();
let repo = create_conflicting_merge_repo();
let missing = read_blob_bytes_optional(repo.path(), "HEAD", "this-file-does-not-exist")
.expect("missing path should not error");
Expand All @@ -1034,6 +1073,7 @@ mod tests {

#[test]
fn git_show_non_missing_errors_are_propagated() {
let _git_runtime = SystemGitRuntimeGuard::new();
let repo = create_conflicting_merge_repo();
let err = read_blob_bytes_optional(repo.path(), "definitely-not-a-ref", "a.txt")
.expect_err("invalid ref should surface as git command failure");
Expand All @@ -1055,6 +1095,7 @@ mod tests {

#[test]
fn read_blob_bytes_optional_reads_existing_blob_content() {
let _git_runtime = SystemGitRuntimeGuard::new();
let repo = create_conflicting_merge_repo();
let content =
read_blob_bytes_optional(repo.path(), "HEAD", "a.txt").expect("read existing path");
Expand All @@ -1065,6 +1106,7 @@ mod tests {

#[test]
fn extracts_merge_cases_from_repo_subdirectory() {
let _git_runtime = SystemGitRuntimeGuard::new();
let repo = create_conflicting_merge_repo();
let subdir = repo.path().join("nested").join("dir");
std::fs::create_dir_all(&subdir).expect("create nested subdirectory");
Expand Down
Loading
Loading