@@ -2005,6 +2005,148 @@ def test_notes_merge(git_repo: GitSync) -> None:
20052005 )
20062006
20072007
2008+ class NoteCustomRefFixture (t .NamedTuple ):
2009+ """Fixture for testing GitNoteCmd ref propagation from GitNotesManager."""
2010+
2011+ test_id : str
2012+ ref : str
2013+ message : str
2014+
2015+
2016+ NOTE_CUSTOM_REF_FIXTURES : list [NoteCustomRefFixture ] = [
2017+ NoteCustomRefFixture (
2018+ test_id = "custom-ref-basic" ,
2019+ ref = "custom-notes" ,
2020+ message = "Note in custom ref" ,
2021+ ),
2022+ NoteCustomRefFixture (
2023+ test_id = "custom-ref-review" ,
2024+ ref = "review" ,
2025+ message = "Code review note" ,
2026+ ),
2027+ ]
2028+
2029+
2030+ @pytest .mark .parametrize (
2031+ list (NoteCustomRefFixture ._fields ),
2032+ NOTE_CUSTOM_REF_FIXTURES ,
2033+ ids = [test .test_id for test in NOTE_CUSTOM_REF_FIXTURES ],
2034+ )
2035+ def test_notes_custom_ref_propagation (
2036+ git_repo : GitSync ,
2037+ test_id : str ,
2038+ ref : str ,
2039+ message : str ,
2040+ ) -> None :
2041+ """Test that GitNoteCmd objects from ls() inherit the manager's custom ref.
2042+
2043+ This verifies commit eda818c which fixed GitNoteCmd to receive the ref
2044+ from GitNotesManager, allowing show/remove operations to work on
2045+ custom note refs instead of always targeting refs/notes/commits.
2046+ """
2047+ # Create a manager with custom ref
2048+ custom_notes = git_repo .cmd .notes .__class__ (
2049+ path = git_repo .path ,
2050+ cmd = git_repo .cmd ,
2051+ ref = ref ,
2052+ )
2053+
2054+ # Add a note to the custom ref
2055+ custom_notes .add (message = message , force = True )
2056+
2057+ # List notes from the custom ref manager
2058+ notes = custom_notes .ls ()
2059+ assert len (notes ) > 0 , "Expected at least one note in custom ref"
2060+
2061+ # Key assertion: The GitNoteCmd should have the ref attribute set
2062+ note = notes [0 ]
2063+ assert note .ref == ref , f"Expected note.ref={ ref !r} , got { note .ref !r} "
2064+
2065+ # Verify show() works with the custom ref (uses --ref flag internally)
2066+ content = note .show ()
2067+ assert message in content , f"Expected { message !r} in note content"
2068+
2069+ # Verify isolation: note should NOT appear in default ref
2070+ default_notes = git_repo .cmd .notes .ls ()
2071+ default_object_shas = [n .object_sha for n in default_notes ]
2072+ assert note .object_sha not in default_object_shas , (
2073+ "Note should not appear in default ref"
2074+ )
2075+
2076+
2077+ class RemoteUrlSpaceFixture (t .NamedTuple ):
2078+ """Fixture for testing GitRemoteManager.ls() with URLs containing spaces."""
2079+
2080+ test_id : str
2081+ remote_name : str
2082+ path_suffix : str
2083+
2084+
2085+ REMOTE_URL_SPACE_FIXTURES : list [RemoteUrlSpaceFixture ] = [
2086+ RemoteUrlSpaceFixture (
2087+ test_id = "single-space" ,
2088+ remote_name = "spacey" ,
2089+ path_suffix = "path with space" ,
2090+ ),
2091+ RemoteUrlSpaceFixture (
2092+ test_id = "multiple-spaces" ,
2093+ remote_name = "spacier" ,
2094+ path_suffix = "foo bar baz" ,
2095+ ),
2096+ ]
2097+
2098+
2099+ @pytest .mark .parametrize (
2100+ list (RemoteUrlSpaceFixture ._fields ),
2101+ REMOTE_URL_SPACE_FIXTURES ,
2102+ ids = [test .test_id for test in REMOTE_URL_SPACE_FIXTURES ],
2103+ )
2104+ def test_remote_url_with_spaces (
2105+ git_repo : GitSync ,
2106+ tmp_path : pathlib .Path ,
2107+ test_id : str ,
2108+ remote_name : str ,
2109+ path_suffix : str ,
2110+ ) -> None :
2111+ r"""Test that GitRemoteManager.ls() correctly parses URLs containing spaces.
2112+
2113+ This verifies commit cb42d4a which fixed the regex pattern to handle
2114+ paths with spaces instead of silently dropping them.
2115+
2116+ Git outputs remotes as: <name>\t<url> (fetch|push)
2117+ where the URL is printed literally without escaping spaces.
2118+ """
2119+ # Create a remote repo path with spaces
2120+ remote_path = tmp_path / path_suffix
2121+ remote_path .mkdir (parents = True )
2122+
2123+ # Initialize a bare git repo at that path
2124+ git .Git (path = remote_path ).init (bare = True )
2125+
2126+ # Add remote with the space-containing path
2127+ git_repo .cmd .remotes .add (name = remote_name , url = str (remote_path ))
2128+
2129+ # List remotes
2130+ remotes = git_repo .cmd .remotes .ls ()
2131+
2132+ # Find our remote by name
2133+ matching = [r for r in remotes if r .remote_name == remote_name ]
2134+ assert len (matching ) == 1 , f"Expected to find remote { remote_name !r} "
2135+
2136+ remote = matching [0 ]
2137+
2138+ # Key assertions: URL should contain the space and match the full path
2139+ assert remote .fetch_url is not None , "Expected fetch_url to be set"
2140+ assert remote .push_url is not None , "Expected push_url to be set"
2141+ assert " " in remote .fetch_url , "Expected space in fetch_url"
2142+ assert remote .fetch_url == str (remote_path ), (
2143+ f"Expected fetch_url={ str (remote_path )!r} , got { remote .fetch_url !r} "
2144+ )
2145+ assert remote .push_url == str (remote_path ), (
2146+ f"Expected push_url={ str (remote_path )!r} , got { remote .push_url !r} "
2147+ )
2148+
2149+
20082150# GitReflog tests
20092151
20102152
0 commit comments