MCPcopy Create free account
hub / github.com/dtormoen/tsk-tsk / copy_repo

Method copy_repo

src/git.rs:108–432  ·  view source on GitHub ↗

Copy repository for a task using the task ID and repository root Creates a task repository by cloning the source repository and overlaying all non-ignored files from the working directory including: - Tracked files with their current working directory content (including unstaged changes) - Staged files (newly added files in the index) - Untracked files (not ignored) - The .tsk directory for proje

(
        &self,
        task_id: &str,
        repo_root: &Path,
        source_commit: Option<&str>,
        branch_name: &str,
        copy_mode: CopyMode,
    )

Source from the content-addressed store, hash-verified

106 ///
107 /// Returns a [`CopyResult`] with the path and any non-fatal warnings.
108 pub async fn copy_repo(
109 &self,
110 task_id: &str,
111 repo_root: &Path,
112 source_commit: Option<&str>,
113 branch_name: &str,
114 copy_mode: CopyMode,
115 ) -> Result<CopyResult, String> {
116 // Use the task ID directly for the directory name
117 let task_dir_name = task_id;
118 let branch_name = branch_name.to_string();
119 let mut warnings = Vec::new();
120
121 // Create the task directory structure in centralized location
122 let task_dir = self.ctx.tsk_env().task_dir(task_dir_name);
123 let repo_path = task_dir.join("repo");
124
125 // Create directories if they don't exist
126 crate::file_system::create_dir(&task_dir)
127 .await
128 .map_err(|e| format!("Failed to create task directory: {e}"))?;
129
130 // Check if the provided path is in a git repository
131 if !git_operations::is_git_repository(repo_root).await? {
132 return Err("Not in a git repository".to_string());
133 }
134
135 // Use the provided repository root
136 let current_dir = repo_root.to_path_buf();
137
138 // Get list of all files that should be copied (only needed for WorkingTree mode):
139 // 1. All tracked files (from working directory, including unstaged changes)
140 // 2. All staged files (including newly added files in the index)
141 // 3. All untracked files (not ignored)
142 let all_files_to_copy = if matches!(copy_mode, CopyMode::WorkingTree) {
143 git_operations::get_all_non_ignored_files(&current_dir).await?
144 } else {
145 Vec::new()
146 };
147
148 // Clone repository with optimized pack files (no hardlinks)
149 // This creates an efficient repository copy with 1-2 pack files instead of
150 // preserving fragmented pack structure from the source repository
151 git_operations::clone_local(&current_dir, &repo_path)
152 .await
153 .map_err(|e| format!("Failed to clone repository: {e}"))?;
154
155 // Copy .git/modules from source to preserve submodule git data
156 // This must happen BEFORE branch creation and file overlay so that
157 // submodule .git files have valid targets to point to
158 let src_git_common = crate::repo_utils::resolve_git_common_dir(&current_dir)
159 .unwrap_or_else(|_| current_dir.join(".git"));
160 let src_modules = src_git_common.join("modules");
161 let dst_modules = repo_path.join(".git/modules");
162
163 if crate::file_system::exists(&src_modules)
164 .await
165 .unwrap_or(false)

Calls 15

create_dirFunction · 0.85
is_git_repositoryFunction · 0.85
clone_localFunction · 0.85
resolve_git_common_dirFunction · 0.85
existsFunction · 0.85
copy_dirFunction · 0.85
create_branchFunction · 0.85
init_submodulesFunction · 0.85
remove_fileFunction · 0.85
copy_fileFunction · 0.85