prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Streamlit fails to start without Git executable
  # Summary
  
  Streamlit version `0.69.1` fails to start when run inside a Docker container that doesn't have Git installed.
  
  # Steps to reproduce
  
  1. Create a `Dockerfile` with the following contents:
  ```dockerfile
  FROM python:3.8-slim
  RUN pip install streamlit
  CMD ["streamlit", "hello"]
  ```
  2. Build the image:
  ```bash
  docker build -t demo .
  ```
  3. Run the app:
  ```bash
  docker run -it --rm demo
  ```
  
  ## Expected behavior:
  
  Streamlit starts without issues.
  
  ## Actual behavior:
  
  Streamlit fails to start and displays the following error message:
  
  ```bash
  Traceback (most recent call last):
    File "/usr/local/lib/python3.8/site-packages/git/__init__.py", line 83, in <module>
      refresh()
    File "/usr/local/lib/python3.8/site-packages/git/__init__.py", line 73, in refresh
      if not Git.refresh(path=path):
    File "/usr/local/lib/python3.8/site-packages/git/cmd.py", line 278, in refresh
      raise ImportError(err)
  ImportError: Bad git executable.
  The git executable must be specified in one of the following ways:
      - be included in your $PATH
      - be set via $GIT_PYTHON_GIT_EXECUTABLE
      - explicitly set via git.refresh()
  
  All git commands will error until this is rectified.
  
  This initial warning can be silenced or aggravated in the future by setting the
  $GIT_PYTHON_REFRESH environment variable. Use one of the following values:
      - quiet|q|silence|s|none|n|0: for no warning or exception
      - warn|w|warning|1: for a printed warning
      - error|e|raise|r|2: for a raised exception
  
  Example:
      export GIT_PYTHON_REFRESH=quiet
  ```
  
  ## Is this a regression?
  
  **yes** (worked up until at least version `0.67.1`)
  
  # Debug info
  
  - Streamlit version: `0.69.1`
  - Python version: `3.8.6`
  - Using Conda? PipEnv? PyEnv? Pex? **NO**
  - OS version: `4.19.76-linuxkit`
  
  # Additional information
  
  This bug can be worked around by setting `GIT_PYTHON_REFRESH=quiet` environment variable inside the Docker image.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `lib/streamlit/git_util.py`
  Content:
  ```
  1 import os
  2 import re
  3 from typing import Optional, Tuple
  4 
  5 import git  # type: ignore[import]
  6 
  7 # Github has two URLs, one that is https and one that is ssh
  8 GITHUB_HTTP_URL = r"^https://(www\.)?github.com/(.+)/(.+).git$"
  9 GITHUB_SSH_URL = r"^git@github.com:(.+)/(.+).git$"
  10 
  11 # We don't support git < 2.7, because we can't get repo info without
  12 # talking to the remote server, which results in the user being prompted
  13 # for credentials.
  14 MIN_GIT_VERSION = (2, 7, 0)
  15 
  16 
  17 class GitRepo:
  18     def __init__(self, path):
  19         # If we have a valid repo, git_version will be a tuple of 3+ ints:
  20         # (major, minor, patch, possible_additional_patch_number)
  21         self.git_version = None  # type: Optional[Tuple[int, ...]]
  22 
  23         try:
  24             self.repo = git.Repo(path, search_parent_directories=True)
  25             self.git_version = self.repo.git.version_info
  26             if self.git_version >= MIN_GIT_VERSION:
  27                 git_root = self.repo.git.rev_parse("--show-toplevel")
  28                 self.module = os.path.relpath(path, git_root)
  29 
  30         except:
  31             # The git repo must be invalid for the following reasons:
  32             #  * No .git folder
  33             #  * Corrupted .git folder
  34             #  * Path is invalid
  35             self.repo = None
  36 
  37     def is_valid(self) -> bool:
  38         """True if there's a git repo here, and git.version >= MIN_GIT_VERSION."""
  39         return (
  40             self.repo is not None
  41             and self.git_version is not None
  42             and self.git_version >= MIN_GIT_VERSION
  43         )
  44 
  45     @property
  46     def tracking_branch(self):
  47         if not self.is_valid():
  48             return None
  49         return self.repo.active_branch.tracking_branch()
  50 
  51     def get_tracking_branch_remote(self):
  52         if not self.is_valid():
  53             return None
  54 
  55         tracking_branch = self.tracking_branch
  56         if tracking_branch is None:
  57             return None
  58 
  59         remote_name, *branch = tracking_branch.name.split("/")
  60         branch_name = "/".join(branch)
  61 
  62         return self.repo.remote(remote_name), branch_name
  63 
  64     def is_github_repo(self):
  65         if not self.is_valid():
  66             return False
  67 
  68         remote_info = self.get_tracking_branch_remote()
  69         if remote_info is None:
  70             return False
  71 
  72         remote, _branch = remote_info
  73 
  74         for url in remote.urls:
  75             if (
  76                 re.match(GITHUB_HTTP_URL, url) is not None
  77                 or re.match(GITHUB_SSH_URL, url) is not None
  78             ):
  79                 return True
  80 
  81         return False
  82 
  83     def get_repo_info(self):
  84         if not self.is_valid():
  85             return None
  86 
  87         remote_info = self.get_tracking_branch_remote()
  88         if remote_info is None:
  89             return None
  90 
  91         remote, branch = remote_info
  92 
  93         repo = None
  94         for url in remote.urls:
  95             https_matches = re.match(GITHUB_HTTP_URL, url)
  96             ssh_matches = re.match(GITHUB_SSH_URL, url)
  97             if https_matches is not None:
  98                 repo = f"{https_matches.group(2)}/{https_matches.group(3)}"
  99                 break
  100 
  101             if ssh_matches is not None:
  102                 repo = f"{ssh_matches.group(1)}/{ssh_matches.group(2)}"
  103                 break
  104 
  105         if repo is None:
  106             return None
  107 
  108         return repo, branch, self.module
  109
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/lib/streamlit/git_util.py b/lib/streamlit/git_util.py
  --- a/lib/streamlit/git_util.py
  +++ b/lib/streamlit/git_util.py
  @@ -2,8 +2,6 @@
   import re
   from typing import Optional, Tuple
   
  -import git  # type: ignore[import]
  -
   # Github has two URLs, one that is https and one that is ssh
   GITHUB_HTTP_URL = r"^https://(www\.)?github.com/(.+)/(.+).git$"
   GITHUB_SSH_URL = r"^git@github.com:(.+)/(.+).git$"
  @@ -21,6 +19,8 @@
           self.git_version = None  # type: Optional[Tuple[int, ...]]
   
           try:
  +            import git  # type: ignore[import]
  +
               self.repo = git.Repo(path, search_parent_directories=True)
               self.git_version = self.repo.git.version_info
               if self.git_version >= MIN_GIT_VERSION:
  @@ -29,6 +29,7 @@
   
           except:
               # The git repo must be invalid for the following reasons:
  +            #  * git binary or GitPython not installed
               #  * No .git folder
               #  * Corrupted .git folder
               #  * Path is invalid
  
verification_info: {"golden_diff": "diff --git a/lib/streamlit/git_util.py b/lib/streamlit/git_util.py\n--- a/lib/streamlit/git_util.py\n+++ b/lib/streamlit/git_util.py\n@@ -2,8 +2,6 @@\n import re\n from typing import Optional, Tuple\n \n-import git  # type: ignore[import]\n-\n # Github has two URLs, one that is https and one that is ssh\n GITHUB_HTTP_URL = r\"^https://(www\\.)?github.com/(.+)/(.+).git$\"\n GITHUB_SSH_URL = r\"^git@github.com:(.+)/(.+).git$\"\n@@ -21,6 +19,8 @@\n         self.git_version = None  # type: Optional[Tuple[int, ...]]\n \n         try:\n+            import git  # type: ignore[import]\n+\n             self.repo = git.Repo(path, search_parent_directories=True)\n             self.git_version = self.repo.git.version_info\n             if self.git_version >= MIN_GIT_VERSION:\n@@ -29,6 +29,7 @@\n \n         except:\n             # The git repo must be invalid for the following reasons:\n+            #  * git binary or GitPython not installed\n             #  * No .git folder\n             #  * Corrupted .git folder\n             #  * Path is invalid\n", "issue": "Streamlit fails to start without Git executable\n# Summary\r\n\r\nStreamlit version `0.69.1` fails to start when run inside a Docker container that doesn't have Git installed.\r\n\r\n# Steps to reproduce\r\n\r\n1. Create a `Dockerfile` with the following contents:\r\n```dockerfile\r\nFROM python:3.8-slim\r\nRUN pip install streamlit\r\nCMD [\"streamlit\", \"hello\"]\r\n```\r\n2. Build the image:\r\n```bash\r\ndocker build -t demo .\r\n```\r\n3. Run the app:\r\n```bash\r\ndocker run -it --rm demo\r\n```\r\n\r\n## Expected behavior:\r\n\r\nStreamlit starts without issues.\r\n\r\n## Actual behavior:\r\n\r\nStreamlit fails to start and displays the following error message:\r\n\r\n```bash\r\nTraceback (most recent call last):\r\n  File \"/usr/local/lib/python3.8/site-packages/git/__init__.py\", line 83, in <module>\r\n    refresh()\r\n  File \"/usr/local/lib/python3.8/site-packages/git/__init__.py\", line 73, in refresh\r\n    if not Git.refresh(path=path):\r\n  File \"/usr/local/lib/python3.8/site-packages/git/cmd.py\", line 278, in refresh\r\n    raise ImportError(err)\r\nImportError: Bad git executable.\r\nThe git executable must be specified in one of the following ways:\r\n    - be included in your $PATH\r\n    - be set via $GIT_PYTHON_GIT_EXECUTABLE\r\n    - explicitly set via git.refresh()\r\n\r\nAll git commands will error until this is rectified.\r\n\r\nThis initial warning can be silenced or aggravated in the future by setting the\r\n$GIT_PYTHON_REFRESH environment variable. Use one of the following values:\r\n    - quiet|q|silence|s|none|n|0: for no warning or exception\r\n    - warn|w|warning|1: for a printed warning\r\n    - error|e|raise|r|2: for a raised exception\r\n\r\nExample:\r\n    export GIT_PYTHON_REFRESH=quiet\r\n```\r\n\r\n## Is this a regression?\r\n\r\n**yes** (worked up until at least version `0.67.1`)\r\n\r\n# Debug info\r\n\r\n- Streamlit version: `0.69.1`\r\n- Python version: `3.8.6`\r\n- Using Conda? PipEnv? PyEnv? Pex? **NO**\r\n- OS version: `4.19.76-linuxkit`\r\n\r\n# Additional information\r\n\r\nThis bug can be worked around by setting `GIT_PYTHON_REFRESH=quiet` environment variable inside the Docker image.\r\n\n", "before_files": [{"content": "import os\nimport re\nfrom typing import Optional, Tuple\n\nimport git  # type: ignore[import]\n\n# Github has two URLs, one that is https and one that is ssh\nGITHUB_HTTP_URL = r\"^https://(www\\.)?github.com/(.+)/(.+).git$\"\nGITHUB_SSH_URL = r\"^git@github.com:(.+)/(.+).git$\"\n\n# We don't support git < 2.7, because we can't get repo info without\n# talking to the remote server, which results in the user being prompted\n# for credentials.\nMIN_GIT_VERSION = (2, 7, 0)\n\n\nclass GitRepo:\n    def __init__(self, path):\n        # If we have a valid repo, git_version will be a tuple of 3+ ints:\n        # (major, minor, patch, possible_additional_patch_number)\n        self.git_version = None  # type: Optional[Tuple[int, ...]]\n\n        try:\n            self.repo = git.Repo(path, search_parent_directories=True)\n            self.git_version = self.repo.git.version_info\n            if self.git_version >= MIN_GIT_VERSION:\n                git_root = self.repo.git.rev_parse(\"--show-toplevel\")\n                self.module = os.path.relpath(path, git_root)\n\n        except:\n            # The git repo must be invalid for the following reasons:\n            #  * No .git folder\n            #  * Corrupted .git folder\n            #  * Path is invalid\n            self.repo = None\n\n    def is_valid(self) -> bool:\n        \"\"\"True if there's a git repo here, and git.version >= MIN_GIT_VERSION.\"\"\"\n        return (\n            self.repo is not None\n            and self.git_version is not None\n            and self.git_version >= MIN_GIT_VERSION\n        )\n\n    @property\n    def tracking_branch(self):\n        if not self.is_valid():\n            return None\n        return self.repo.active_branch.tracking_branch()\n\n    def get_tracking_branch_remote(self):\n        if not self.is_valid():\n            return None\n\n        tracking_branch = self.tracking_branch\n        if tracking_branch is None:\n            return None\n\n        remote_name, *branch = tracking_branch.name.split(\"/\")\n        branch_name = \"/\".join(branch)\n\n        return self.repo.remote(remote_name), branch_name\n\n    def is_github_repo(self):\n        if not self.is_valid():\n            return False\n\n        remote_info = self.get_tracking_branch_remote()\n        if remote_info is None:\n            return False\n\n        remote, _branch = remote_info\n\n        for url in remote.urls:\n            if (\n                re.match(GITHUB_HTTP_URL, url) is not None\n                or re.match(GITHUB_SSH_URL, url) is not None\n            ):\n                return True\n\n        return False\n\n    def get_repo_info(self):\n        if not self.is_valid():\n            return None\n\n        remote_info = self.get_tracking_branch_remote()\n        if remote_info is None:\n            return None\n\n        remote, branch = remote_info\n\n        repo = None\n        for url in remote.urls:\n            https_matches = re.match(GITHUB_HTTP_URL, url)\n            ssh_matches = re.match(GITHUB_SSH_URL, url)\n            if https_matches is not None:\n                repo = f\"{https_matches.group(2)}/{https_matches.group(3)}\"\n                break\n\n            if ssh_matches is not None:\n                repo = f\"{ssh_matches.group(1)}/{ssh_matches.group(2)}\"\n                break\n\n        if repo is None:\n            return None\n\n        return repo, branch, self.module\n", "path": "lib/streamlit/git_util.py"}], "after_files": [{"content": "import os\nimport re\nfrom typing import Optional, Tuple\n\n# Github has two URLs, one that is https and one that is ssh\nGITHUB_HTTP_URL = r\"^https://(www\\.)?github.com/(.+)/(.+).git$\"\nGITHUB_SSH_URL = r\"^git@github.com:(.+)/(.+).git$\"\n\n# We don't support git < 2.7, because we can't get repo info without\n# talking to the remote server, which results in the user being prompted\n# for credentials.\nMIN_GIT_VERSION = (2, 7, 0)\n\n\nclass GitRepo:\n    def __init__(self, path):\n        # If we have a valid repo, git_version will be a tuple of 3+ ints:\n        # (major, minor, patch, possible_additional_patch_number)\n        self.git_version = None  # type: Optional[Tuple[int, ...]]\n\n        try:\n            import git  # type: ignore[import]\n\n            self.repo = git.Repo(path, search_parent_directories=True)\n            self.git_version = self.repo.git.version_info\n            if self.git_version >= MIN_GIT_VERSION:\n                git_root = self.repo.git.rev_parse(\"--show-toplevel\")\n                self.module = os.path.relpath(path, git_root)\n\n        except:\n            # The git repo must be invalid for the following reasons:\n            #  * git binary or GitPython not installed\n            #  * No .git folder\n            #  * Corrupted .git folder\n            #  * Path is invalid\n            self.repo = None\n\n    def is_valid(self) -> bool:\n        \"\"\"True if there's a git repo here, and git.version >= MIN_GIT_VERSION.\"\"\"\n        return (\n            self.repo is not None\n            and self.git_version is not None\n            and self.git_version >= MIN_GIT_VERSION\n        )\n\n    @property\n    def tracking_branch(self):\n        if not self.is_valid():\n            return None\n        return self.repo.active_branch.tracking_branch()\n\n    def get_tracking_branch_remote(self):\n        if not self.is_valid():\n            return None\n\n        tracking_branch = self.tracking_branch\n        if tracking_branch is None:\n            return None\n\n        remote_name, *branch = tracking_branch.name.split(\"/\")\n        branch_name = \"/\".join(branch)\n\n        return self.repo.remote(remote_name), branch_name\n\n    def is_github_repo(self):\n        if not self.is_valid():\n            return False\n\n        remote_info = self.get_tracking_branch_remote()\n        if remote_info is None:\n            return False\n\n        remote, _branch = remote_info\n\n        for url in remote.urls:\n            if (\n                re.match(GITHUB_HTTP_URL, url) is not None\n                or re.match(GITHUB_SSH_URL, url) is not None\n            ):\n                return True\n\n        return False\n\n    def get_repo_info(self):\n        if not self.is_valid():\n            return None\n\n        remote_info = self.get_tracking_branch_remote()\n        if remote_info is None:\n            return None\n\n        remote, branch = remote_info\n\n        repo = None\n        for url in remote.urls:\n            https_matches = re.match(GITHUB_HTTP_URL, url)\n            ssh_matches = re.match(GITHUB_SSH_URL, url)\n            if https_matches is not None:\n                repo = f\"{https_matches.group(2)}/{https_matches.group(3)}\"\n                break\n\n            if ssh_matches is not None:\n                repo = f\"{ssh_matches.group(1)}/{ssh_matches.group(2)}\"\n                break\n\n        if repo is None:\n            return None\n\n        return repo, branch, self.module\n", "path": "lib/streamlit/git_util.py"}]}