diff --git a/packages/tauri/src/git/diff.rs b/packages/tauri/src/git/diff.rs index b3d14fa23..fa42910f2 100644 --- a/packages/tauri/src/git/diff.rs +++ b/packages/tauri/src/git/diff.rs @@ -43,6 +43,7 @@ pub fn workdir( .include_untracked(true) .show_binary(true) .show_untracked_content(true) + .ignore_submodules(true) .context_lines(opts.context_lines); let diff = repository.diff_tree_to_workdir(Some(&tree), Some(&mut diff_opts))?; @@ -60,6 +61,7 @@ pub fn trees( .recurse_untracked_dirs(true) .include_untracked(true) .show_binary(true) + .ignore_submodules(true) .show_untracked_content(true); let diff = diff --git a/packages/tauri/src/git/repository.rs b/packages/tauri/src/git/repository.rs index e59f5e908..64f82aa43 100644 --- a/packages/tauri/src/git/repository.rs +++ b/packages/tauri/src/git/repository.rs @@ -1,10 +1,12 @@ use std::{path, str}; +use git2::Submodule; + use crate::keys; use super::{ AnnotatedCommit, Blob, Branch, BranchName, Commit, Config, Index, Oid, Reference, Remote, - Result, Signature, Tree, TreeBuilder, + Result, Signature, Tree, TreeBuilder, Url, }; // wrapper around git2::Repository to get control over how it's used. @@ -52,6 +54,12 @@ impl Repository { Ok(()) } + pub fn add_submodule(&self, url: &Url, path: &path::Path) -> Result> { + self.0 + .submodule(&url.to_string(), path, false) + .map_err(Into::into) + } + pub fn find_annotated_commit(&self, id: Oid) -> Result> { self.0 .find_annotated_commit(id.into()) diff --git a/packages/tauri/src/virtual_branches/virtual.rs b/packages/tauri/src/virtual_branches/virtual.rs index bcf9083f6..9f85fd9fc 100644 --- a/packages/tauri/src/virtual_branches/virtual.rs +++ b/packages/tauri/src/virtual_branches/virtual.rs @@ -1558,7 +1558,7 @@ fn get_applied_status( &default_target.sha, &diff::Options::default(), ) - .context("failed to diff")?; + .context("failed to diff workdir")?; // sort by order, so that the default branch is first (left in the ui) virtual_branches.sort_by(|a, b| a.order.cmp(&b.order)); diff --git a/packages/tauri/tests/common.rs b/packages/tauri/tests/common.rs index ff02f2c0a..6c64296a0 100644 --- a/packages/tauri/tests/common.rs +++ b/packages/tauri/tests/common.rs @@ -1,3 +1,5 @@ +use std::path; + use gblib::git; pub fn temp_dir() -> std::path::PathBuf { @@ -193,4 +195,21 @@ impl TestProject { .collect::, _>>() .expect("failed to read references") } + + pub fn add_submodule(&self, url: &git::Url, path: &path::Path) { + let mut submodule = self.local_repository.add_submodule(url, path).unwrap(); + let repo = submodule.open().unwrap(); + + // checkout submodule's master head + repo.find_remote("origin") + .unwrap() + .fetch(&["+refs/heads/*:refs/heads/*"], None, None) + .unwrap(); + let reference = repo.find_reference("refs/heads/master").unwrap(); + let reference_head = repo.find_commit(reference.target().unwrap()).unwrap(); + repo.checkout_tree(reference_head.tree().unwrap().as_object(), None) + .unwrap(); + + submodule.add_finalize().unwrap(); + } } diff --git a/packages/tauri/tests/gb_repository/mod.rs b/packages/tauri/tests/gb_repository/mod.rs index 3b9059f29..5ab4aacc2 100644 --- a/packages/tauri/tests/gb_repository/mod.rs +++ b/packages/tauri/tests/gb_repository/mod.rs @@ -1,4 +1,6 @@ -use gblib::{gb_repository, project_repository, projects}; +use std::path; + +use gblib::{gb_repository, git, project_repository, projects}; use crate::{common::TestProject, paths}; @@ -120,4 +122,31 @@ mod flush { gb_repo.flush(&project_repository, None).unwrap(); } + + #[test] + fn handle_submodules() { + let test_project = TestProject::default(); + + let data_dir = paths::data_dir(); + let projects = projects::Controller::from(&data_dir); + + let project = projects + .add(test_project.path()) + .expect("failed to add project"); + + let project_repository = project_repository::Repository::open(&project).unwrap(); + + let gb_repo = + gb_repository::Repository::open(&data_dir, &project_repository, None).unwrap(); + + let submodule_url: git::Url = TestProject::default() + .path() + .display() + .to_string() + .parse() + .unwrap(); + test_project.add_submodule(&submodule_url, path::Path::new("submodule")); + + gb_repo.flush(&project_repository, None).unwrap(); + } } diff --git a/packages/tauri/tests/virtual_branches/mod.rs b/packages/tauri/tests/virtual_branches/mod.rs index 1d73dd4dc..1225a24d2 100644 --- a/packages/tauri/tests/virtual_branches/mod.rs +++ b/packages/tauri/tests/virtual_branches/mod.rs @@ -4,7 +4,7 @@ clippy::rest_pat_in_fully_bound_structs )] -use std::{fs, str::FromStr}; +use std::{fs, path, str::FromStr}; use gblib::{ error::Error, @@ -2012,6 +2012,36 @@ mod amend { mod init { use super::*; + #[tokio::test] + async fn submodule() { + let Test { + repository, + project_id, + controller, + .. + } = Test::default(); + + let submodule_url: git::Url = TestProject::default() + .path() + .display() + .to_string() + .parse() + .unwrap(); + repository.add_submodule(&submodule_url, path::Path::new("submodule")); + + controller + .set_base_branch( + &project_id, + &git::RemoteBranchName::from_str("refs/remotes/origin/master").unwrap(), + ) + .unwrap(); + + let branches = controller.list_virtual_branches(&project_id).await.unwrap(); + assert_eq!(branches.len(), 1); + assert_eq!(branches[0].files.len(), 1); + assert_eq!(branches[0].files[0].hunks.len(), 1); + } + #[tokio::test] async fn dirty() { let Test {