upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/lib/git
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/git')
-rw-r--r--src/lib/git/mod.rs133
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
106impl RepoActions for Repo { 106impl 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}