git-dumper: recovering a website's exposed .git directory
A tool to dump a git repository from a website
At a glance
- What is it?
- git-dumper reconstructs a Git repository from a web server that still serves its .git folder. It is a security and CTF tool, and it carries an explicit remote code execution warning.
- Who is it for?
- Adopt git-dumper if you are auditing a site you are authorised to test, or working a CTF challenge where a .git directory is reachable, and you want the refs, objects and working tree rather than a hand-written loop over wget.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 25 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The exposure git-dumper is built to exploit
A deployed web application that was pushed with its .git directory still in place leaves the whole history reachable over HTTP. The files are plain: .git/HEAD, .git/config, .git/index, .git/packed-refs, .git/logs/HEAD, and the object files under .git/objects. Anyone who can request those paths can reconstruct source that was never meant to be public, including commits that were later reverted. git-dumper automates that reconstruction. It is aimed at penetration testers and CTF players rather than at people who want to mirror a Git host: it does not talk to GitHub or GitLab's API, it walks a web root. The README is blunt about the audience, carrying a disclaimer in bold that says to use the software at your own risk and that a repository controlled by an attacker could lead to remote code execution on your machine. That warning is the most important sentence in the project.
Directory listing first, then guessing at the object graph
The README describes two paths through the tool. If the server has directory listing enabled, git-dumper does the simple thing: it recursively downloads the .git directory, which the README compares to what you would do with wget. Most real targets do not cooperate that way, so the fallback is a staged reconstruction. First it fetches a set of common files: .gitignore, .git/HEAD, .git/index and similar. Then it mines refs out of .git/HEAD, .git/logs/HEAD, .git/config and .git/packed-refs, looking for names like refs/heads/master and refs/remotes/origin/HEAD. From packed-refs, index, refs and logs it extracts as many object SHA-1s as it can, then fetches those objects and reads each commit to find its parents, walking backwards until the graph is exhausted. The last step is a local git checkout . to materialise the working tree. The design assumption is that the server leaks some files but not all, so the tool treats each file it finds as a lead rather than as a complete picture. That is why a partial dump can still be useful, and also why a dump can silently miss objects that no reachable ref or log entry points at.
Installing git-dumper with uv, pip, or Docker
The README gives uv as the easy path. The command below installs the tool as a standalone command; after it finishes, git-dumper should be on your PATH.
uv tool install git-dumperThe pip route is documented as an alternative, with a note that modern Python environments may need a virtual environment or the --user flag to avoid conflicts. Either of these produces the same git-dumper entry point.
python3 -m venv .venv
source .venv/bin/activate
pip install git-dumperThe repository also ships a Dockerfile and a docker-compose.yml, so there is a third route that avoids touching the host Python at all. The compose file bind-mounts ./dump on the host to /dump in the container, which is where the recovered repository lands.
docker compose build
docker compose run --rm git-dumper http://target/.git /dumpThe README's own example is the shortest useful invocation: pass the URL of the .git directory and an output directory, and the tool does the rest.
git-dumper http://website.com/.git ~/websiteIf you prefer to run from a source checkout, the README says to install the dependencies with pip from requirements.txt and then call the script directly.
pip install -r requirements.txt
./git_dumper.py http://website.com/.git ~/websiteA first real use should start small. Point it at a target you control or are authorised to test, watch which files it reports, and confirm that the output directory contains a .git folder before you try anything more ambitious. The --jobs, --retry and --timeout flags exist because the fetch is a large number of small HTTP requests, and the defaults may not suit a slow or rate-limiting target.
When the target refuses to behave like a normal web server
Two documented flags exist for targets that do not serve raw .git files in the usual way. Some servers only return the files over a non-GET method, which is what -X/--method is for; the README's example switches every request to POST. Others answer with a status such as 500 while still returning the real body, and --any-status tells git-dumper to accept any status code as long as the body is non-empty and not HTML. That second flag is a deliberate loosening of a safety check: without it, a 500 is treated as a failure, and with it, an HTML error page is still rejected but a 500 carrying binary content is accepted. The remaining options cover the plumbing around the fetch: --proxy for routing through a proxy, -H NAME=VALUE for extra headers, -u for the user agent, --client-cert-p12 and --client-cert-p12-password for mutual TLS, and a repeatable -b/--branch to check additional branch names. Note that -b adds branches to check rather than restricting the dump to one; the README describes it as an additional branch name, repeatable.
The failure modes the README does not paper over
The headline risk is not a bug, it is the tool's own disclaimer: if the repository you download is controlled by an attacker, the README says this could lead to remote code execution on your machine. A recovered working tree is untrusted code, and nothing in the dump step sandboxes it. Treat the output as evidence, not as something to run. Beyond that, the reconstruction strategy has an inherent ceiling. Objects are discovered by reading refs, the index, packed-refs and logs; an object that no ref, index entry or reflog mentions has no pointer to follow, so it will not be fetched. Dangling commits and unreferenced blobs from a garbage-collected or aggressively rewritten repository can be missed entirely, and the README does not document a mode that brute-forces object hashes. The README also does not document rollback or resume behaviour, so a dump interrupted halfway has no stated way to continue where it stopped. Finally, if the server has directory listing off and returns a uniform 404 for every path, the tool has nothing to analyse and the dump will be empty or near-empty.
git-dumper against a plain wget mirror
The obvious alternative is wget or curl with recursion, and the README says as much: when directory listing is available, git-dumper is doing what wget would do. The difference appears only when listing is off. A recursive downloader needs the server to enumerate paths for it; it has no notion of Git's internal structure. git-dumper parses .git/HEAD, .git/config, .git/packed-refs, .git/index and the logs to derive the ref names and object hashes that a plain mirror cannot guess, and it follows commit parents to walk history that is not referenced by any branch tip. It also finishes the job by running git checkout . to produce a working tree, which a file mirror does not do. The trade-off is that git-dumper is a specialised, single-purpose fetch: it will not mirror a site's HTML, it will not follow links outside .git, and its object discovery is bounded by what the metadata files reveal. For a target with listing enabled and a small repository, wget is simpler and has no Python dependency.
Maintenance, licence and the cost of upgrading
The repository is not archived, and the last push was on 2026-09-06, the same day as release 1.0.9. The previous release, 1.0.8, was on 2024-11-23, so the gap between them is roughly twenty-one months. That pattern suggests a tool that is touched when a target or an environment forces a change rather than one that moves continuously, and it means an upgrade from 1.0.8 to 1.0.9 is worth reading the release notes for rather than assuming it is cosmetic. The dependency surface is five packages: PySocks, requests, beautifulsoup4, dulwich and requests-pkcs12. dulwich is the one to watch, since it implements Git's object and repository handling in Python and is what the tool leans on for the checkout step. The licence is MIT, which is permissive; if you redistribute the tool or embed it in another product, keep the copyright notice and licence text with it. That is a description of the licence terms, not legal advice, and anyone shipping it commercially should read the LICENSE file in the repository themselves.
Editorial conclusion
Adopt git-dumper if you are auditing a site you are authorised to test, or working a CTF challenge where a .git directory is reachable, and you want the refs, objects and working tree rather than a hand-written loop over wget. Do not run it against hosts you do not control, and do not treat a successful dump as proof that the target is safe to open: the README states that a repository controlled by an attacker could lead to remote code execution on your machine, so inspect the recovered tree before you run anything from it. Before relying on it, verify that your Python environment can install the five requirements (PySocks, requests, beautifulsoup4, dulwich, requests-pkcs12) and that the target responds to the method and status codes you intend to use; if it does not, try the -X and --any-status flags described in the README before assuming the dump is impossible.
Frequently asked questions
How do I install git-dumper?
The README gives uv as the simple route, with uv tool install git-dumper, and pip as the alternative, either inside a virtual environment created with python3 -m venv .venv or with the --user flag. The repository also provides a Dockerfile and docker-compose.yml for running it in a container.
How do I install git dumper on Kali or Linux?
The README does not describe a Kali-specific package. The documented install paths are uv tool install git-dumper, pip install git-dumper in a virtual environment or with --user, or building the container from the repository's Dockerfile.
How do I use git dumper?
Run git-dumper with the URL of the .git directory and an output directory, as in the README example git-dumper http://website.com/.git ~/website. The tool fetches common .git files, derives refs and object hashes from them, walks commit parents, and finishes with git checkout . to recover the working tree.
What does git dumper do?
It reconstructs a Git repository from a website that still serves its .git directory. When directory listing is available it recursively downloads .git; when it is not, it analyses .git/HEAD, .git/config, .git/packed-refs, .git/index and logs to find refs and objects, then checks out the working tree.
What is the alternative to git dumper?
The README notes that with directory listing enabled, git-dumper is doing what wget would do, so a recursive wget or curl mirror is the plain alternative. The difference is that a recursive downloader cannot parse Git metadata to derive refs and object hashes, and it does not run the final git checkout . step.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/arthaud-git-dumper)