Repository: albertyw/git-browse

Issue:
Support running with multiple fetch configs
gitconfig allows for multiple fetch configs which breaks configparser: https://stackoverflow.com/questions/15507264/can-i-specify-in-git-config-to-fetch-multiple-refspecs

Discussion:

Patch:
diff --git a/git_browse/browse.py b/git_browse/browse.py
index 47ccaeb..451f605 100755
--- a/git_browse/browse.py
+++ b/git_browse/browse.py
@@ -369,7 +369,8 @@ def get_git_config() -> str:
 
 
 def get_git_url(git_config_file: str) -> str:
-    config = configparser.ConfigParser()
+    # strict is removed here because gitconfig allows for multiple "fetch" keys
+    config = configparser.ConfigParser(strict=False)
     config.read(git_config_file)
     try:
         git_url = config['remote "origin"']['url']


Test patch:
diff --git a/git_browse/tests/test.py b/git_browse/tests/test.py
index 9578999..cb3ba05 100644
--- a/git_browse/tests/test.py
+++ b/git_browse/tests/test.py
@@ -2,6 +2,7 @@ import os
 import re
 import shutil
 import sys
+import tempfile
 from typing import List, cast
 import unittest
 from unittest.mock import MagicMock, patch
@@ -248,14 +249,22 @@ class GetGitConfig(unittest.TestCase):
 
 class GetGitURL(unittest.TestCase):
     def setUp(self) -> None:
-        self.git_config_file = os.path.join(
+        git_config_file = os.path.join(
             BASE_DIRECTORY,
             '.git',
             'config'
         )
+        with open(git_config_file, 'rb') as handle:
+            configs = handle.read()
+        self.git_config_file = tempfile.NamedTemporaryFile()
+        self.git_config_file.write(configs)
+        self.git_config_file.seek(0)
+
+    def tearDown(self) -> None:
+        self.git_config_file.close()
 
     def test_url(self) -> None:
-        git_url = browse.get_git_url(self.git_config_file)
+        git_url = browse.get_git_url(self.git_config_file.name)
         expected = 'git@github.com:albertyw/git-browse'
         self.assertEqual(git_url.replace('.git', ''), expected)
 
@@ -263,6 +272,21 @@ class GetGitURL(unittest.TestCase):
         with self.assertRaises(RuntimeError):
             browse.get_git_url(BASE_DIRECTORY)
 
+    def test_multiple_fetch(self) -> None:
+        # For https://github.com/albertyw/git-browse/issues/48
+        config_contents = (
+            '[remote "origin"]\n'
+            '    fetch = refs/heads/my_name/*:refs/remotes/origin/my_name/*\n'
+            '    fetch = refs/heads/master:refs/remotes/origin/master\n'
+            '    url = git@github.com:albertyw/git-browse\n'
+        )
+        config_file = tempfile.NamedTemporaryFile()
+        config_file.write(config_contents.encode('utf-8'))
+        config_file.seek(0)
+        git_url = browse.get_git_url(config_file.name)
+        expected = 'git@github.com:albertyw/git-browse'
+        self.assertEqual(git_url.replace('.git', ''), expected)
+
 
 class ParseGitURL(unittest.TestCase):
     def setUp(self) -> None: