Fix the gitdir path in a submodule .git file if it uses an absolute path.
(
&self,
git_file: &Path,
repo_path: &Path,
)
| 785 | |
| 786 | /// Fix the gitdir path in a submodule .git file if it uses an absolute path. |
| 787 | async fn fix_submodule_gitdir_path( |
| 788 | &self, |
| 789 | git_file: &Path, |
| 790 | repo_path: &Path, |
| 791 | ) -> Result<(), String> { |
| 792 | let content = tokio::fs::read_to_string(git_file) |
| 793 | .await |
| 794 | .map_err(|e| format!("Failed to read {}: {}", git_file.display(), e))?; |
| 795 | |
| 796 | let gitdir_line = content.trim(); |
| 797 | if !gitdir_line.starts_with("gitdir: ") { |
| 798 | return Err(format!("Invalid .git file format: {}", git_file.display())); |
| 799 | } |
| 800 | |
| 801 | let gitdir_path = gitdir_line.strip_prefix("gitdir: ").unwrap_or("").trim(); |
| 802 | |
| 803 | // Check if it's an absolute path (starts with / or contains : for Windows) |
| 804 | if gitdir_path.starts_with('/') || gitdir_path.contains(':') { |
| 805 | // Absolute path needs rewriting |
| 806 | // Extract the module path from the absolute path |
| 807 | if let Some(modules_pos) = gitdir_path.find("/.git/modules/") { |
| 808 | let module_path = &gitdir_path[modules_pos + "/.git/modules/".len()..]; |
| 809 | let submodule_dir = git_file |
| 810 | .parent() |
| 811 | .ok_or_else(|| "No parent directory".to_string())?; |
| 812 | let depth = submodule_dir |
| 813 | .strip_prefix(repo_path) |
| 814 | .map_err(|_| "Path not under repo".to_string())? |
| 815 | .components() |
| 816 | .count(); |
| 817 | |
| 818 | let prefix = if depth > 0 { |
| 819 | "../".repeat(depth) |
| 820 | } else { |
| 821 | "./".to_string() |
| 822 | }; |
| 823 | let new_gitdir = format!("{}.git/modules/{}", prefix, module_path); |
| 824 | |
| 825 | tokio::fs::write(git_file, format!("gitdir: {}\n", new_gitdir)) |
| 826 | .await |
| 827 | .map_err(|e| format!("Failed to write {}: {}", git_file.display(), e))?; |
| 828 | } else { |
| 829 | return Err(format!( |
| 830 | "Could not extract module path from absolute gitdir: {}", |
| 831 | gitdir_path |
| 832 | )); |
| 833 | } |
| 834 | } |
| 835 | // Relative paths should work as-is since the structure is preserved |
| 836 | |
| 837 | Ok(()) |
| 838 | } |
| 839 | |
| 840 | /// Fix worktree paths in .git/modules/*/config files if they use absolute paths. |
| 841 | /// Returns any warnings encountered during the fix. |