@@ -147,6 +147,8 @@ pub struct GitManager {
147147 config : Config ,
148148 /// Path to the configuration file
149149 config_path : PathBuf ,
150+ /// Whether to print verbose output
151+ verbose : bool ,
150152}
151153
152154impl GitManager {
@@ -296,7 +298,8 @@ impl GitManager {
296298 Ok ( ( ) )
297299 }
298300
299- /// Creates a new `GitManager` by loading configuration from the given path.
301+ /// Creates a new `GitManager` by loading configuration from the given path
302+ /// with default (non-verbose) output.
300303 ///
301304 /// # Arguments
302305 ///
@@ -306,9 +309,15 @@ impl GitManager {
306309 ///
307310 /// Returns `SubmoduleError::RepositoryError` if the repository cannot be discovered,
308311 /// or `SubmoduleError::ConfigError` if the configuration fails to load.
312+ #[ allow( dead_code) ]
309313 pub fn new ( config_path : PathBuf ) -> Result < Self , SubmoduleError > {
314+ Self :: with_verbose ( config_path, false )
315+ }
316+
317+ /// Creates a new `GitManager` with the specified verbosity level.
318+ pub fn with_verbose ( config_path : PathBuf , verbose : bool ) -> Result < Self , SubmoduleError > {
310319 // Use GitOpsManager for repository detection and operations
311- let git_ops = GitOpsManager :: new ( Some ( Path :: new ( "." ) ) )
320+ let git_ops = GitOpsManager :: new ( Some ( Path :: new ( "." ) ) , verbose )
312321 . map_err ( |_| SubmoduleError :: RepositoryError ) ?;
313322
314323 let config = Config :: default ( )
@@ -319,6 +328,7 @@ impl GitManager {
319328 git_ops,
320329 config,
321330 config_path,
331+ verbose,
322332 } )
323333 }
324334
@@ -628,7 +638,9 @@ impl GitManager {
628638 SubmoduleError :: GitoxideError ( format ! ( "GitOpsManager update failed: {e}" ) )
629639 } ) ?;
630640
631- println ! ( "✅ Updated {name} successfully" ) ;
641+ if self . verbose {
642+ println ! ( "✅ Updated {name} successfully" ) ;
643+ }
632644 Ok ( ( ) )
633645 }
634646
@@ -694,7 +706,9 @@ impl GitManager {
694706 let submodule_path = Path :: new ( path_str) ;
695707
696708 if submodule_path. exists ( ) && submodule_path. join ( ".git" ) . exists ( ) {
697- println ! ( "✅ {name} already initialized" ) ;
709+ if self . verbose {
710+ println ! ( "✅ {name} already initialized" ) ;
711+ }
698712 // Even if already initialized, check if we need to configure sparse checkout
699713 let sparse_paths_opt = self
700714 . config
@@ -707,7 +721,9 @@ impl GitManager {
707721 return Ok ( ( ) ) ;
708722 }
709723
710- println ! ( "🔄 Initializing {name}..." ) ;
724+ if self . verbose {
725+ println ! ( "🔄 Initializing {name}..." ) ;
726+ }
711727
712728 let workdir = std:: path:: Path :: new ( "." ) ;
713729
@@ -748,7 +764,9 @@ impl GitManager {
748764 . map_err ( Self :: map_git_ops_error) ?;
749765 }
750766
751- println ! ( " ✅ Initialized using git submodule commands: {path_str}" ) ;
767+ if self . verbose {
768+ println ! ( " ✅ Initialized using git submodule commands: {path_str}" ) ;
769+ }
752770
753771 // Configure sparse checkout if specified
754772 if let Some ( sparse_checkouts) = submodules. sparse_checkouts ( ) {
@@ -757,85 +775,110 @@ impl GitManager {
757775 }
758776 }
759777
760- println ! ( "✅ {name} initialized" ) ;
778+ if self . verbose {
779+ println ! ( "✅ {name} initialized" ) ;
780+ }
761781 Ok ( ( ) )
762782 }
763783
764784 /// Check all submodules using gitoxide APIs where possible
765785 pub fn check_all_submodules ( & self ) -> Result < ( ) , SubmoduleError > {
766- println ! ( "Checking submodule configurations..." ) ;
786+ if self . verbose {
787+ println ! ( "Checking submodule configurations..." ) ;
788+ }
767789
768790 for ( submodule_name, submodule) in self . config . get_submodules ( ) {
769- println ! ( "\n 📁 {submodule_name}" ) ;
770-
771791 // Handle missing path gracefully - report but don't fail
772792 let path_str = if let Some ( path) = submodule. path . as_ref ( ) {
773793 path
774794 } else {
775- println ! ( " ❌ Configuration error: No path configured" ) ;
795+ // Always show errors regardless of verbosity
796+ println ! ( " ❌ {submodule_name}: No path configured" ) ;
776797 continue ;
777798 } ;
778799
779800 // Handle missing URL gracefully - report but don't fail
780801 if submodule. url . is_none ( ) {
781- println ! ( " ❌ Configuration error : No URL configured" ) ;
802+ println ! ( " ❌ {submodule_name} : No URL configured" ) ;
782803 continue ;
783804 }
784805
785806 let submodule_path = Path :: new ( path_str) ;
786807 let git_path = submodule_path. join ( ".git" ) ;
787808
788809 if !submodule_path. exists ( ) {
789- println ! ( " ❌ Folder missing: {path_str}" ) ;
810+ println ! ( " ❌ {submodule_name}: Folder missing ( {path_str}) " ) ;
790811 continue ;
791812 }
792813
793814 if !git_path. exists ( ) {
794- println ! ( " ❌ Not a git repository" ) ;
815+ println ! ( " ❌ {submodule_name}: Not a git repository" ) ;
795816 continue ;
796817 }
797818
798819 // GITOXIDE API: Use gix::open and status check
799820 match self . check_submodule_repository_status ( path_str, submodule_name) {
800821 Ok ( status) => {
801- println ! ( " ✅ Git repository exists" ) ;
822+ if self . verbose {
823+ println ! ( "\n 📁 {submodule_name}" ) ;
824+ println ! ( " ✅ Git repository exists" ) ;
825+
826+ if status. is_clean {
827+ println ! ( " ✅ Working tree is clean" ) ;
828+ } else {
829+ println ! ( " ⚠️ Working tree has changes" ) ;
830+ }
802831
803- if status. is_clean {
804- println ! ( " ��� Working tree is clean" ) ;
805- } else {
806- println ! ( " ⚠️ Working tree has changes" ) ;
807- }
832+ if let Some ( commit) = & status. current_commit {
833+ println ! ( " ✅ Current commit: {}" , & commit[ ..8 ] ) ;
834+ }
808835
809- if let Some ( commit) = & status. current_commit {
810- println ! ( " ✅ Current commit: {}" , & commit[ ..8 ] ) ;
811- }
836+ if status. has_remotes {
837+ println ! ( " ✅ Has remotes configured" ) ;
838+ } else {
839+ println ! ( " ⚠️ No remotes configured" ) ;
840+ }
812841
813- if status. has_remotes {
814- println ! ( " ✅ Has remotes configured" ) ;
815- } else {
816- println ! ( " ⚠️ No remotes configured" ) ;
817- }
842+ match & status. sparse_status {
843+ SparseStatus :: NotEnabled => { }
844+ SparseStatus :: NotConfigured => {
845+ println ! ( " ❌ Sparse checkout not configured" ) ;
846+ }
847+ SparseStatus :: Correct => {
848+ println ! ( " ✅ Sparse checkout configured correctly" ) ;
849+ }
850+ SparseStatus :: Mismatch { expected, actual } => {
851+ println ! ( " ❌ Sparse checkout mismatch" ) ;
852+ println ! ( " Expected: {expected:?}" ) ;
853+ println ! ( " Current: {actual:?}" ) ;
854+ }
855+ }
818856
819- match status. sparse_status {
820- SparseStatus :: NotEnabled => { }
821- SparseStatus :: NotConfigured => {
822- println ! ( " ❌ Sparse checkout not configured" ) ;
857+ // Show effective settings
858+ self . show_effective_settings ( submodule_name, submodule) ;
859+ } else {
860+ // Non-verbose: only print warnings/problems
861+ if !status. is_clean {
862+ println ! ( " ⚠️ {submodule_name}: Working tree has changes" ) ;
823863 }
824- SparseStatus :: Correct => {
825- println ! ( " ✅ Sparse checkout configured correctly " ) ;
864+ if !status . has_remotes {
865+ println ! ( " ⚠️ {submodule_name}: No remotes configured " ) ;
826866 }
827- SparseStatus :: Mismatch { expected, actual } => {
828- println ! ( " ❌ Sparse checkout mismatch" ) ;
829- println ! ( " Expected: {expected:?}" ) ;
830- println ! ( " Current: {actual:?}" ) ;
867+ match & status. sparse_status {
868+ SparseStatus :: NotEnabled | SparseStatus :: Correct => { }
869+ SparseStatus :: NotConfigured => {
870+ println ! ( " ❌ {submodule_name}: Sparse checkout not configured" ) ;
871+ }
872+ SparseStatus :: Mismatch { expected, actual } => {
873+ println ! ( " ❌ {submodule_name}: Sparse checkout mismatch" ) ;
874+ println ! ( " Expected: {expected:?}" ) ;
875+ println ! ( " Current: {actual:?}" ) ;
876+ }
831877 }
832878 }
833-
834- // Show effective settings
835- self . show_effective_settings ( submodule_name, submodule) ;
836879 }
837880 Err ( e) => {
838- println ! ( " ❌ Cannot analyze repository: {e}" ) ;
881+ println ! ( " ❌ {submodule_name}: Cannot analyze repository: {e}" ) ;
839882 }
840883 }
841884 }
@@ -847,13 +890,13 @@ impl GitManager {
847890 println ! ( " 📋 Effective settings:" ) ;
848891
849892 if let Some ( ignore) = & config. ignore {
850- println ! ( " ignore = {:?}" , ignore ) ;
893+ println ! ( " ignore = {ignore :?}" ) ;
851894 }
852895 if let Some ( update) = & config. update {
853- println ! ( " update = {:?}" , update ) ;
896+ println ! ( " update = {update :?}" ) ;
854897 }
855898 if let Some ( branch) = & config. branch {
856- println ! ( " branch = {:?}" , branch ) ;
899+ println ! ( " branch = {branch :?}" ) ;
857900 }
858901 }
859902 /// Get reference to the underlying config
@@ -1648,8 +1691,9 @@ impl GitManager {
16481691
16491692 if from_setup {
16501693 // Read .gitmodules from the repo and convert to our config format
1651- let git_ops = crate :: git_ops:: GitOpsManager :: new ( Some ( std:: path:: Path :: new ( "." ) ) )
1652- . map_err ( |_| SubmoduleError :: RepositoryError ) ?;
1694+ let git_ops =
1695+ crate :: git_ops:: GitOpsManager :: new ( Some ( std:: path:: Path :: new ( "." ) ) , false )
1696+ . map_err ( |_| SubmoduleError :: RepositoryError ) ?;
16531697 let entries = git_ops. read_gitmodules ( ) . map_err ( |e| {
16541698 SubmoduleError :: ConfigError ( format ! ( "Failed to read .gitmodules: {e}" ) )
16551699 } ) ?;
@@ -1662,6 +1706,7 @@ impl GitManager {
16621706 git_ops,
16631707 config,
16641708 config_path : output. to_path_buf ( ) ,
1709+ verbose : false ,
16651710 } ;
16661711 tmp_manager. write_full_config ( ) ?;
16671712 println ! (
0 commit comments