diff options
Diffstat (limited to 'src/lib/git')
| -rw-r--r-- | src/lib/git/mod.rs | 133 |
1 files changed, 129 insertions, 4 deletions
diff --git a/src/lib/git/mod.rs b/src/lib/git/mod.rs index 641349c..0001ca1 100644 --- a/src/lib/git/mod.rs +++ b/src/lib/git/mod.rs | |||
| @@ -105,10 +105,9 @@ pub trait RepoActions { | |||
| 105 | 105 | ||
| 106 | impl RepoActions for Repo { | 106 | impl RepoActions for Repo { |
| 107 | fn get_path(&self) -> Result<&Path> { | 107 | fn get_path(&self) -> Result<&Path> { |
| 108 | self.git_repo | 108 | self.git_repo.workdir().context( |
| 109 | .path() | 109 | "failed to find repository working directory (bare repositories are not supported)", |
| 110 | .parent() | 110 | ) |
| 111 | .context("failed to find repositiory path as .git has no parent") | ||
| 112 | } | 111 | } |
| 113 | 112 | ||
| 114 | fn get_origin_url(&self) -> Result<String> { | 113 | fn get_origin_url(&self) -> Result<String> { |
| @@ -2848,4 +2847,130 @@ index ce01362..a21e91c 100644\n\ | |||
| 2848 | } | 2847 | } |
| 2849 | } | 2848 | } |
| 2850 | 2849 | ||
| 2850 | mod worktree { | ||
| 2851 | use super::*; | ||
| 2852 | |||
| 2853 | #[test] | ||
| 2854 | fn get_path_returns_worktree_working_dir() -> Result<()> { | ||
| 2855 | let test_repo = GitTestRepo::default(); | ||
| 2856 | test_repo.populate()?; | ||
| 2857 | |||
| 2858 | let worktree_repo = test_repo.create_worktree("wt-branch")?; | ||
| 2859 | let git_repo = Repo::from_path(&worktree_repo.dir)?; | ||
| 2860 | |||
| 2861 | let path = git_repo.get_path()?; | ||
| 2862 | // get_path() should return the worktree's working directory, not | ||
| 2863 | // somewhere inside the main repo's .git/worktrees/ | ||
| 2864 | assert_eq!(path.canonicalize()?, worktree_repo.dir.canonicalize()?,); | ||
| 2865 | Ok(()) | ||
| 2866 | } | ||
| 2867 | |||
| 2868 | #[test] | ||
| 2869 | fn get_path_returns_normal_repo_working_dir() -> Result<()> { | ||
| 2870 | let test_repo = GitTestRepo::default(); | ||
| 2871 | test_repo.populate()?; | ||
| 2872 | |||
| 2873 | let git_repo = Repo::from_path(&test_repo.dir)?; | ||
| 2874 | let path = git_repo.get_path()?; | ||
| 2875 | assert_eq!(path.canonicalize()?, test_repo.dir.canonicalize()?,); | ||
| 2876 | Ok(()) | ||
| 2877 | } | ||
| 2878 | |||
| 2879 | #[test] | ||
| 2880 | fn from_path_works_with_worktree_dir() -> Result<()> { | ||
| 2881 | let test_repo = GitTestRepo::default(); | ||
| 2882 | test_repo.populate()?; | ||
| 2883 | |||
| 2884 | let worktree_repo = test_repo.create_worktree("wt-open")?; | ||
| 2885 | // Opening from the worktree's working directory should succeed | ||
| 2886 | let git_repo = Repo::from_path(&worktree_repo.dir)?; | ||
| 2887 | // And get_path() should return the worktree dir | ||
| 2888 | assert_eq!( | ||
| 2889 | git_repo.get_path()?.canonicalize()?, | ||
| 2890 | worktree_repo.dir.canonicalize()?, | ||
| 2891 | ); | ||
| 2892 | Ok(()) | ||
| 2893 | } | ||
| 2894 | |||
| 2895 | #[test] | ||
| 2896 | fn worktree_can_read_branches() -> Result<()> { | ||
| 2897 | let test_repo = GitTestRepo::default(); | ||
| 2898 | test_repo.populate()?; | ||
| 2899 | |||
| 2900 | let worktree_repo = test_repo.create_worktree("wt-branches")?; | ||
| 2901 | let git_repo = Repo::from_path(&worktree_repo.dir)?; | ||
| 2902 | |||
| 2903 | let branches = git_repo.get_local_branch_names()?; | ||
| 2904 | assert!(branches.contains(&"main".to_string())); | ||
| 2905 | assert!(branches.contains(&"wt-branches".to_string())); | ||
| 2906 | Ok(()) | ||
| 2907 | } | ||
| 2908 | |||
| 2909 | #[test] | ||
| 2910 | fn worktree_can_read_git_config() -> Result<()> { | ||
| 2911 | let test_repo = GitTestRepo::default(); | ||
| 2912 | test_repo.populate()?; | ||
| 2913 | |||
| 2914 | let worktree_repo = test_repo.create_worktree("wt-config")?; | ||
| 2915 | let git_repo = Repo::from_path(&worktree_repo.dir)?; | ||
| 2916 | |||
| 2917 | // nostr.repo is set by GitTestRepo::default() on the main repo | ||
| 2918 | // and should be readable from the worktree since config is shared | ||
| 2919 | let nostr_repo = git_repo.get_git_config_item("nostr.repo", None)?; | ||
| 2920 | assert!(nostr_repo.is_some()); | ||
| 2921 | Ok(()) | ||
| 2922 | } | ||
| 2923 | |||
| 2924 | #[test] | ||
| 2925 | fn worktree_get_head_commit_works() -> Result<()> { | ||
| 2926 | let test_repo = GitTestRepo::default(); | ||
| 2927 | test_repo.populate()?; | ||
| 2928 | |||
| 2929 | let worktree_repo = test_repo.create_worktree("wt-head")?; | ||
| 2930 | let git_repo = Repo::from_path(&worktree_repo.dir)?; | ||
| 2931 | |||
| 2932 | // Should not error - worktree has its own HEAD | ||
| 2933 | let _head = git_repo.get_head_commit()?; | ||
| 2934 | Ok(()) | ||
| 2935 | } | ||
| 2936 | |||
| 2937 | #[test] | ||
| 2938 | fn worktree_files_accessible_from_get_path() -> Result<()> { | ||
| 2939 | let test_repo = GitTestRepo::default(); | ||
| 2940 | test_repo.populate()?; | ||
| 2941 | |||
| 2942 | let worktree_repo = test_repo.create_worktree("wt-files")?; | ||
| 2943 | let git_repo = Repo::from_path(&worktree_repo.dir)?; | ||
| 2944 | |||
| 2945 | // Create a file in the worktree | ||
| 2946 | let test_file = worktree_repo.dir.join("worktree-test.txt"); | ||
| 2947 | fs::write(&test_file, "hello from worktree")?; | ||
| 2948 | |||
| 2949 | // get_path() should point to the worktree dir where the file lives | ||
| 2950 | let path = git_repo.get_path()?; | ||
| 2951 | assert!(path.join("worktree-test.txt").exists()); | ||
| 2952 | Ok(()) | ||
| 2953 | } | ||
| 2954 | |||
| 2955 | #[test] | ||
| 2956 | fn worktree_opened_via_git_dir_env_works() -> Result<()> { | ||
| 2957 | let test_repo = GitTestRepo::default(); | ||
| 2958 | test_repo.populate()?; | ||
| 2959 | |||
| 2960 | let worktree_repo = test_repo.create_worktree("wt-gitdir")?; | ||
| 2961 | |||
| 2962 | // In a worktree, GIT_DIR points to the worktree-specific git dir | ||
| 2963 | // (e.g., .git/worktrees/<name>). Simulate what git does when | ||
| 2964 | // calling a remote helper. | ||
| 2965 | let git_dir = worktree_repo.git_repo.path().to_path_buf(); | ||
| 2966 | let git_repo = Repo::from_path(&git_dir)?; | ||
| 2967 | |||
| 2968 | // get_path() should still return the worktree working directory | ||
| 2969 | assert_eq!( | ||
| 2970 | git_repo.get_path()?.canonicalize()?, | ||
| 2971 | worktree_repo.dir.canonicalize()?, | ||
| 2972 | ); | ||
| 2973 | Ok(()) | ||
| 2974 | } | ||
| 2975 | } | ||
| 2851 | } | 2976 | } |