@@ -143,6 +143,44 @@ def test_multi_line_config(self):
143143 )
144144 self .assertEqual (len (config .sections ()), 23 )
145145
146+ def test_backslash_line_continuation (self ):
147+ """An unquoted value ending in a backslash continues on the next line,
148+ exactly as git config parses it: the final backslash and the newline
149+ are removed before the complete logical value is parsed."""
150+ cases = [
151+ (b"[a]\n \t k = line1\\ \n line2\n " , "line1 line2" ),
152+ (b"[a]\n \t k = one\\ \n two\\ \n three\n " , "one two three" ),
153+ (b"[a]\n \t k = one\\ \n two \n " , "one two" ),
154+ (b"[a]\n \t k = one\\ \n two ; ignored\n " , "one two" ),
155+ (b'[a]\n \t k = one\\ \n "two"\n ' , "one two" ),
156+ (b"[a]\n \t k = one\\ \n two\\ tthree\n " , "one two\t three" ),
157+ (b"[a]\n \t k = val\\ \\ \n next\n " , "val\\ \\ " ),
158+ (b"[a]\n \t k = end\\ \n " , "end" ),
159+ (b"[alias]\n \t co = checkout \\ \n \t \t -v\n " , "checkout \t \t -v" ),
160+ ]
161+ for content , expected in cases :
162+ config_file = io .BytesIO (content )
163+ config_file .name = "backslash_continuation.config"
164+ config = GitConfigParser (config_file )
165+ config .read ()
166+ section = "alias" if b"[alias]" in content else "a"
167+ key = "co" if section == "alias" else "k"
168+ self .assertEqual (config .get_value (section , key ), expected )
169+
170+ @with_rw_directory
171+ def test_comment_backslash_does_not_continue_value (self , rw_dir ):
172+ config_path = osp .join (rw_dir , "config" )
173+ with open (config_path , "wb" ) as config_file :
174+ config_file .write (b"[a]\n \t k = one\\ \n two ; ignored \\ \n \t x = two\n " )
175+
176+ with GitConfigParser (config_path , read_only = False ) as config :
177+ self .assertEqual (config .get_value ("a" , "k" ), "one two" )
178+ self .assertEqual (config .get_value ("a" , "x" ), "two" )
179+ config .set_value ("a" , "added" , "three" )
180+
181+ with GitConfigParser (config_path ) as config :
182+ self .assertEqual (config .get_value ("a" , "x" ), "two" )
183+
146184 def test_config_value_with_trailing_new_line (self ):
147185 config_content = b'[section-header]\n key:"value\n "'
148186 config_file = io .BytesIO (config_content )
0 commit comments