René's URL Explorer Experiment


Title: Fix two remaining Windows untrusted search path cases by EliahKagan · Pull Request #1792 · gitpython-developers/GitPython · GitHub

Open Graph Title: Fix two remaining Windows untrusted search path cases by EliahKagan · Pull Request #1792 · gitpython-developers/GitPython

X Title: Fix two remaining Windows untrusted search path cases by EliahKagan · Pull Request #1792 · gitpython-developers/GitPython

Description: This fixes CVE-2024-22190. Although #1636 caused GitPython to avoid using an untrusted search path on Windows under the most typical circumstances, it turns out that some cases remained. I believe only two remain at this time. This pull request fixes those. The CI status on all commits appears to be as I expected and intended. This vulnerability was reported privately, initially without a full public writeup, since I wanted to get the pull request out as coordinated/requested, without extra delays. A summary of the vulnerability this fixes is now available in the CVE-2024-22190 advisory. Further information about these changes is present in the commit messages. For the benefit of future readers, I have also since added some more information below, lightly adapted from my original disclosure. I have found that the fix for CVE-2023-40590 (#1635) that I contributed in #1636 was unfortunately incomplete, missing two cases. When git is run with a shell, setting the NoDefaultCurrentDirectoryInExePath environment variable in the caller's environment is insufficient, because the shell subprocess is what performs the path search. When a shell is used, the child process's environment needs to have that variable set. This does not happen automatically, because while the env dict is based on os.environ, it is created before NoDefaultCurrentDirectoryInExePath is set in the caller environment. Omitting that variable from the child process's environment was intentional, to avoid modifying the operation of child processes more than necessary. (git itself does not need that variable to be set to avoid looking in the current directory to run its own subprocesses, including custom commands.) But it has to be done when a shell is used. In addition, when GitPython uses bash.exe to run hooks, it does not do anything to avoid finding and running bash.exe in the current directory, which may be the working tree of an untrusted repository. Because in some reasonable workflows one checks out a branch from an untrusted remote to review it, and such a branch could contain a malicious bash.exe, this is exploitable. The description of CVE-2023-40590 had mentioned "And there are other commands executed that should probably be aware of this problem," but I had not given enough attention to that point when working on the fix, nor recognized its full ramifications. Historically there have been other places in GitPython where a subprocess was created insecurely on Windows, but I believe that is no longer the case. The call to taskkill was removed (#1754), and a call to ps does not occur on Windows because it is part of the kill_after_timeout feature of Git.execute (#1756, #1761). This is not true of the test suite, but when running tests, a more trusted environment can reasonably be assumed: people trust the directory out of which they are intentionally running the test suite, and I don't think any test cases attempt git operations directly in /tmp anymore, as opposed to a subdirectory (#1744, #1759). Therefore I believe these are the only places that need to be changed. I searched for the names of all subprocess module functions and I did not find other problematic calls. The shell=True bug was not detected before, due to a combination of two flaws in the regression tests I wrote in #1636 for CVE-2023-40590. First, I did not commit a test with shell=True. Second, although I had also tried it locally with shell=True, the test contained a shortcoming that prevented it from revealing the vulnerability in that case. It entered a new temporary directory with an impostor git.exe in it. But when shell=True, the relevant CWD is that of the cmd.exe shell subprocess, which was the rorepo working tree rather than the GitPython process's CWD. My patch clarifies the test, creating a repository explicitly so that all the test logic is plain, and it parameterizes the test to cover substantially more cases, including when the devious git.exe is in the repository and git is run with a shell. I have likewise undertaken efforts to make the newly introduced bash.exe impostor test robust, tried it out with each of the WinBashStatus cases, and set up the impostor scenario in a way that allows the effect to be observed whether or not a real bash.exe is available and whether or not it is usable. To avoid code duplication, make intent clearer, and make it easier to avoid introducing new untrusted search path bugs, this patch extracts both the shell and non-shell logic for preventing such bugs to a safer_popen function that can be used like Popen with no special forethought. This function also documents the relevant issues, including the strange but important distinction on Windows between shell and non-shell executable search behavior (i.e., why facilities such as shutil.which or the external where command often don't do what we need, on Windows). Having this in one place should also aid in future improvements to the technique used, such as to mitigate or eliminate the race condition on os.environ that irwand commented about in #1650. On non-Windows systems, safer_popen is simply an alias for Popen. Because Git.USE_SHELL = True was useful for suppressing undesired console windows in graphical applications on Windows (#126, 1c2dd54, #360) prior to 2.0.8 (0d93908, #469), and is only much more recently longer documented as recommended for that (#1781, #1782, #1787), it is likely that a significant minority of applications use it on Windows. Searching on GitHub, and the web more broadly, turns up some uses and makes me think this may be so. In contrast, I doubt many people intentionally use GitPython to run hooks. But this happens automatically if it is used in a repository with a pre-commit hook enabled.

Open Graph Description: This fixes CVE-2024-22190. Although #1636 caused GitPython to avoid using an untrusted search path on Windows under the most typical circumstances, it turns out that some cases remained. I believe ...

X Description: This fixes CVE-2024-22190. Although #1636 caused GitPython to avoid using an untrusted search path on Windows under the most typical circumstances, it turns out that some cases remained. I believe ...

Opengraph URL: https://github.com/gitpython-developers/GitPython/pull/1792

X: @github

direct link

Domain: github.com

route-pattern/:user_id/:repository/pull/:id/files(.:format)
route-controllerpull_requests
route-actionfiles
fetch-noncev2:1dcd5764-0169-45f1-28e3-9cf91128e82d
current-catalog-service-hashae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b
request-idDD22:1A2FF2:9C21B4:DE0B73:69690155
html-safe-nonce6a9ea736353e81042b0fef7e2993eee6d8f458bdaf6d6c4976faa102456e2c5f
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJERDIyOjFBMkZGMjo5QzIxQjQ6REUwQjczOjY5NjkwMTU1IiwidmlzaXRvcl9pZCI6IjEyMjU3NjA2OTg1NjE3OTAyOTMiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ==
visitor-hmacdae7a02d864caf56892a7b58936a387afa9897b05727cb9bd5a0f195ae4974c2
hovercard-subject-tagpull_request:1672093385
github-keyboard-shortcutsrepository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///pull_requests/show/files
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/gitpython-developers/GitPython/pull/1792/files
twitter:imagehttps://avatars.githubusercontent.com/u/1771172?s=400&v=4
twitter:cardsummary_large_image
og:imagehttps://avatars.githubusercontent.com/u/1771172?s=400&v=4
og:image:altThis fixes CVE-2024-22190. Although #1636 caused GitPython to avoid using an untrusted search path on Windows under the most typical circumstances, it turns out that some cases remained. I believe ...
og:site_nameGitHub
og:typeobject
hostnamegithub.com
expected-hostnamegithub.com
Nonee6156bd4ef9f2dc8dadf4c49a8f7ed8532186388cef72eda3ccb9f0ab3b8cfca
turbo-cache-controlno-preview
diff-viewunified
go-importgithub.com/gitpython-developers/GitPython git https://github.com/gitpython-developers/GitPython.git
octolytics-dimension-user_id503709
octolytics-dimension-user_logingitpython-developers
octolytics-dimension-repository_id1126087
octolytics-dimension-repository_nwogitpython-developers/GitPython
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id1126087
octolytics-dimension-repository_network_root_nwogitpython-developers/GitPython
turbo-body-classeslogged-out env-production page-responsive full-width
disable-turbotrue
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
releasefd1938215b152e2c6a29cf56fec07fd9f91f1203
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://github.com/gitpython-developers/GitPython/pull/1792/files#start-of-content
https://github.com/
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fgitpython-developers%2FGitPython%2Fpull%2F1792%2Ffiles
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub SparkBuild and deploy intelligent appshttps://github.com/features/spark
GitHub ModelsManage and compare promptshttps://github.com/features/models
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
GitHub SponsorsFund open source developershttps://github.com/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/accelerator
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fgitpython-developers%2FGitPython%2Fpull%2F1792%2Ffiles
Sign up https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fpull_requests%2Fshow%2Ffiles&source=header-repo&source_repo=gitpython-developers%2FGitPython
Reloadhttps://github.com/gitpython-developers/GitPython/pull/1792/files
Reloadhttps://github.com/gitpython-developers/GitPython/pull/1792/files
Reloadhttps://github.com/gitpython-developers/GitPython/pull/1792/files
gitpython-developers https://github.com/gitpython-developers
GitPythonhttps://github.com/gitpython-developers/GitPython
Please reload this pagehttps://github.com/gitpython-developers/GitPython/pull/1792/files
Notifications https://github.com/login?return_to=%2Fgitpython-developers%2FGitPython
Fork 964 https://github.com/login?return_to=%2Fgitpython-developers%2FGitPython
Star 5k https://github.com/login?return_to=%2Fgitpython-developers%2FGitPython
Code https://github.com/gitpython-developers/GitPython
Issues 169 https://github.com/gitpython-developers/GitPython/issues
Pull requests 8 https://github.com/gitpython-developers/GitPython/pulls
Discussions https://github.com/gitpython-developers/GitPython/discussions
Actions https://github.com/gitpython-developers/GitPython/actions
Security Uh oh! There was an error while loading. Please reload this page. https://github.com/gitpython-developers/GitPython/security
Please reload this pagehttps://github.com/gitpython-developers/GitPython/pull/1792/files
Insights https://github.com/gitpython-developers/GitPython/pulse
Code https://github.com/gitpython-developers/GitPython
Issues https://github.com/gitpython-developers/GitPython/issues
Pull requests https://github.com/gitpython-developers/GitPython/pulls
Discussions https://github.com/gitpython-developers/GitPython/discussions
Actions https://github.com/gitpython-developers/GitPython/actions
Security https://github.com/gitpython-developers/GitPython/security
Insights https://github.com/gitpython-developers/GitPython/pulse
Sign up for GitHub https://github.com/signup?return_to=%2Fgitpython-developers%2FGitPython%2Fissues%2Fnew%2Fchoose
terms of servicehttps://docs.github.com/terms
privacy statementhttps://docs.github.com/privacy
Sign inhttps://github.com/login?return_to=%2Fgitpython-developers%2FGitPython%2Fissues%2Fnew%2Fchoose
Byronhttps://github.com/Byron
gitpython-developers:mainhttps://github.com/gitpython-developers/GitPython/tree/main
EliahKagan:popenhttps://github.com/EliahKagan/GitPython/tree/popen
Conversation 4 https://github.com/gitpython-developers/GitPython/pull/1792
Commits 16 https://github.com/gitpython-developers/GitPython/pull/1792/commits
Checks 0 https://github.com/gitpython-developers/GitPython/pull/1792/checks
Files changed https://github.com/gitpython-developers/GitPython/pull/1792/files
Please reload this pagehttps://github.com/gitpython-developers/GitPython/pull/1792/files
Fix two remaining Windows untrusted search path cases https://github.com/gitpython-developers/GitPython/pull/1792/files#top
Show all changes 16 commits https://github.com/gitpython-developers/GitPython/pull/1792/files
1c65efb Show "not from cwd" test is broken for shell=True EliahKagan Dec 15, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/1c65efbe73513028510fe3fb599777a721f8d80c
2b47933 Correct the "not from cwd" test and add more cases EliahKagan Dec 15, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/2b47933fba1e9266edb1bb71163768288bbfd409
c1f6c17 Use SystemRoot instead of WINDIR, to fix tox EliahKagan Dec 15, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/c1f6c17182d59b9098aeac272dba79d912c5fa42
06bd2c7 Omit CWD in executable search even when shell=True EliahKagan Dec 15, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/06bd2c7ee2b9a4169c02ba6f4e3bc34ab674af73
7da9c3b Refactor "not from cwd" test for readability EliahKagan Dec 15, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/7da9c3b45a19302b346474ea3fdcda1594c33b08
865c6e8 Further expand "not from cwd" test re: cmd.exe EliahKagan Dec 15, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/865c6e8315e8700737981e8fe43a1ac62eb1423a
d2506c7 Make Git.execute a bit simpler and very slightly more robust EliahKagan Dec 15, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/d2506c73b6ad59bff1f2f58c4edd15f717012591
61b4dda Start on test_hook_uses_shell_not_from_cwd EliahKagan Dec 15, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/61b4ddacc509b67ec809e15d74de1b60a2a28282
66ff4c1 Omit CWD in search for bash.exe to run hooks on Windows EliahKagan Dec 17, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/66ff4c177accfb4f21d3eb476381d248d99fd8b5
7751436 Extract venv management from test_installation EliahKagan Dec 18, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/7751436b94d96ce0978b301681b851edd6efed63
a42ea0a Cover absent/no-distro bash.exe in hooks "not from cwd" test EliahKagan Dec 18, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/a42ea0a38c489caf9969836141120d760d3754b4
f44524a Avoid spurious "location may have moved" on Windows EliahKagan Dec 19, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/f44524a9a9c8122b9b98d6e5797e1dfc3211c0b7
15ebb25 Clarify comment in test_hook_uses_shell_not_from_cwd EliahKagan Dec 19, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/15ebb258d4eebd9bf0f38780570d57e0b968b8de
c551e91 Extract shared logic for using Popen safely on Windows EliahKagan Dec 20, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/c551e916c7b9e2d623b9d76f3352849a707d9bbe
3eb7c2a Move safer_popen from git.util to git.cmd EliahKagan Dec 21, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/3eb7c2ab82e6dbe101ff916fca29d539cc2793af
1f3caa3 Further clarify comment in test_hook_uses_shell_not_from_cwd EliahKagan Dec 25, 2023 https://github.com/gitpython-developers/GitPython/pull/1792/commits/1f3caa31f1b63908235e341418a0804ed37a320a
Clear filters https://github.com/gitpython-developers/GitPython/pull/1792/files
Please reload this pagehttps://github.com/gitpython-developers/GitPython/pull/1792/files
Please reload this pagehttps://github.com/gitpython-developers/GitPython/pull/1792/files
.pre-commit-config.yaml https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-63a9c44a44acf85fea213a857769990937107cf072831e1a26808cfde9d096b9
cmd.py https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-35a18a749eb4d6efad45e56e78a9554926be5526e2ba2159b44311e718450e88
fun.py https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-1d155f283cbf575ea2d0cce3e16d9c60d5fab54c83626603f47eabd2334084b6
util.py https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-cb13395ac36dd593e722ec548880a091f39732af5c934880144d1a95de67944e
polyglot https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-3a791d165bade5f5b150bbea8cc186179fefbb248e87998a730df62810a65bcb
helper.py https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-40ae45f85a8b0daaafdc002d6bd2f4c6701b6b248332c67f15d3c15a425de3ba
test_git.py https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-84c4b72d5c62026240fad69041a453efc37f7336a89035b69672cce0e8beaca1
test_index.py https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-21c27b991511d3d0e3a14b4dfb56017689de2fa114c3edf11c577bd1ce744b72
test_installation.py https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-0f34bc1d2b35fde2cfcc7e8b51af2d499374e8e8ba49672fd39ffa1a92045131
.pre-commit-config.yamlhttps://github.com/gitpython-developers/GitPython/pull/1792/files#diff-63a9c44a44acf85fea213a857769990937107cf072831e1a26808cfde9d096b9
View file https://github.com/EliahKagan/GitPython/blob/1f3caa31f1b63908235e341418a0804ed37a320a/.pre-commit-config.yaml
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/gitpython-developers/GitPython/pull/1792/{{ revealButtonHref }}
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-63a9c44a44acf85fea213a857769990937107cf072831e1a26808cfde9d096b9
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-63a9c44a44acf85fea213a857769990937107cf072831e1a26808cfde9d096b9
git/cmd.pyhttps://github.com/gitpython-developers/GitPython/pull/1792/files#diff-35a18a749eb4d6efad45e56e78a9554926be5526e2ba2159b44311e718450e88
View file https://github.com/EliahKagan/GitPython/blob/1f3caa31f1b63908235e341418a0804ed37a320a/git/cmd.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/gitpython-developers/GitPython/pull/1792/{{ revealButtonHref }}
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-35a18a749eb4d6efad45e56e78a9554926be5526e2ba2159b44311e718450e88
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-35a18a749eb4d6efad45e56e78a9554926be5526e2ba2159b44311e718450e88
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-35a18a749eb4d6efad45e56e78a9554926be5526e2ba2159b44311e718450e88
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-35a18a749eb4d6efad45e56e78a9554926be5526e2ba2159b44311e718450e88
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-35a18a749eb4d6efad45e56e78a9554926be5526e2ba2159b44311e718450e88
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-35a18a749eb4d6efad45e56e78a9554926be5526e2ba2159b44311e718450e88
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-35a18a749eb4d6efad45e56e78a9554926be5526e2ba2159b44311e718450e88
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-35a18a749eb4d6efad45e56e78a9554926be5526e2ba2159b44311e718450e88
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-35a18a749eb4d6efad45e56e78a9554926be5526e2ba2159b44311e718450e88
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-35a18a749eb4d6efad45e56e78a9554926be5526e2ba2159b44311e718450e88
git/index/fun.pyhttps://github.com/gitpython-developers/GitPython/pull/1792/files#diff-1d155f283cbf575ea2d0cce3e16d9c60d5fab54c83626603f47eabd2334084b6
View file https://github.com/EliahKagan/GitPython/blob/1f3caa31f1b63908235e341418a0804ed37a320a/git/index/fun.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/gitpython-developers/GitPython/pull/1792/{{ revealButtonHref }}
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-1d155f283cbf575ea2d0cce3e16d9c60d5fab54c83626603f47eabd2334084b6
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-1d155f283cbf575ea2d0cce3e16d9c60d5fab54c83626603f47eabd2334084b6
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-1d155f283cbf575ea2d0cce3e16d9c60d5fab54c83626603f47eabd2334084b6
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-1d155f283cbf575ea2d0cce3e16d9c60d5fab54c83626603f47eabd2334084b6
git/util.pyhttps://github.com/gitpython-developers/GitPython/pull/1792/files#diff-cb13395ac36dd593e722ec548880a091f39732af5c934880144d1a95de67944e
View file https://github.com/EliahKagan/GitPython/blob/1f3caa31f1b63908235e341418a0804ed37a320a/git/util.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/gitpython-developers/GitPython/pull/1792/{{ revealButtonHref }}
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-cb13395ac36dd593e722ec548880a091f39732af5c934880144d1a95de67944e
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-cb13395ac36dd593e722ec548880a091f39732af5c934880144d1a95de67944e
test/fixtures/polyglothttps://github.com/gitpython-developers/GitPython/pull/1792/files#diff-3a791d165bade5f5b150bbea8cc186179fefbb248e87998a730df62810a65bcb
View file https://github.com/EliahKagan/GitPython/blob/1f3caa31f1b63908235e341418a0804ed37a320a/test/fixtures/polyglot
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/gitpython-developers/GitPython/pull/1792/{{ revealButtonHref }}
test/lib/helper.pyhttps://github.com/gitpython-developers/GitPython/pull/1792/files#diff-40ae45f85a8b0daaafdc002d6bd2f4c6701b6b248332c67f15d3c15a425de3ba
View file https://github.com/EliahKagan/GitPython/blob/1f3caa31f1b63908235e341418a0804ed37a320a/test/lib/helper.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/gitpython-developers/GitPython/pull/1792/{{ revealButtonHref }}
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-40ae45f85a8b0daaafdc002d6bd2f4c6701b6b248332c67f15d3c15a425de3ba
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-40ae45f85a8b0daaafdc002d6bd2f4c6701b6b248332c67f15d3c15a425de3ba
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-40ae45f85a8b0daaafdc002d6bd2f4c6701b6b248332c67f15d3c15a425de3ba
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-40ae45f85a8b0daaafdc002d6bd2f4c6701b6b248332c67f15d3c15a425de3ba
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-40ae45f85a8b0daaafdc002d6bd2f4c6701b6b248332c67f15d3c15a425de3ba
https://github.com/gitpython-developers/GitPython/pull/1792/files#diff-40ae45f85a8b0daaafdc002d6bd2f4c6701b6b248332c67f15d3c15a425de3ba
Please reload this pagehttps://github.com/gitpython-developers/GitPython/pull/1792/files
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.