_images/dfetch_header.png

Dfetch

Vendor dependencies without the pain.

Dfetch copies source code directly into your project — no Git submodules, no SVN externals, no hidden external links. Dependencies live as plain, readable files inside your own repository. You stay in full control of every line.

How it works

1

Install

Download or pip install dfetch

2

Configure

Add projects to dfetch.yaml

3

Fetch

dfetch update

See it in action

What makes Dfetch different

Any VCS, mixed freely

Works with Git and SVN — even mixed in the same project. The only dependency manager that bridges both without compromise.

Any language, any build system

C, C++, Python, Go, Rust, Java — dfetch doesn’t care. No build-system assumptions. Bring your own toolchain.

Built for long lifecycles

Designed for long-lived embedded and industrial products. Reproducible builds from source — no registry, no CDN, no service required.

How it works — from manifest to vendored folder

One project entry in dfetch.yaml. One command. Dfetch copies exactly what you specified, pins the version in .dfetch_data.yaml, and keeps everything inside your repository.

dfetch.yaml
manifest:
  version: '0.0'

  remotes:
    - name: github
      url-base: https://github.com/

  projects:
    - name: ext/cunit  # (1)
      remote: github
      repo-path: org/cunit
      tag: v3.2.7      # (2)
      src: src/        # (3)

(1) name: — destination path in your repo

(2) tag: — exact version to fetch

(3) src: — subfolder to copy from upstream

After dfetch update
your-project/
├─ dfetch.yaml
└─ ext/
   └─ cunit/         # (a)
      ├─ .dfetch_data.yaml
      ├─ LICENSE     # (b)
      └─ CUnit.h     # (c)

(a) folder created at the path given by name:

(b) license always retained, even with src:

(c) contents of src: placed directly here

Why teams choose Dfetch

VCS-agnostic

Works seamlessly with Git and SVN — even mixed within the same project. Pin by tag, branch, revision, or exact commit hash. Adapt to your team’s workflow, not the other way around.

Fully self-contained

Every dependency is stored inside your repository as plain source code. No external links means simpler audits, offline builds, and hassle-free deployments that stay reproducible forever.

Fetch only what you need

Point Dfetch at a single subfolder inside a larger repo using the src: attribute. Pull in just the files you need — no bloat, no noise, and license files are always retained.

Zero lock-in

Your vendored code stays as plain source files. Switch tools any time — no proprietary formats, no migration work. Dfetch respects that your source code belongs to you.

Stay up to date — effortlessly

Check which dependencies have available updates and pull them in when you are ready. Dfetch puts you in control of every change — no surprise breakages, no forced upgrades.

Supply-chain ready out of the box

SBOM generation

Generate a machine-readable Software Bill of Materials to track every vendored dependency — ready for audits, compliance checks, and vulnerability scans.

Automatic license detection

Infers and reports the license for every dependency automatically. Stay legally compliant — even when fetching a single subfolder from a larger repository.

Multi-format reports

Export to Jenkins JSON, SARIF, Code Climate, DependencyTrack formats. Plug into your existing security toolchain with zero extra work.

Customize without losing upstream

Dfetch has mature patch stack support. dfetch diff captures each local change as a numbered .patch file. Declare them in your manifest — they are re-applied in order on every dfetch update, even as upstream evolves. Fuzzy matching keeps patches applying cleanly even when surrounding lines shift.

When a fix is ready to share, dfetch format-patch produces a contributor-ready unified diff for direct PR submission. Drop the patch once it lands upstream — no forks, no divergence.

upstream v 1.2 # upstream # your project dfetch update ext/mylib/ ├─ .dfetch_data.yaml ├─ mylib.py └─ LICENSE ↻ re-applied on every dfetch update 1 001-null-check.patch + if val is None: return default + # safety guard added locally 2 002-fix-timeout.patch → PR ready - TIMEOUT = 5 + TIMEOUT = 30 3 003-add-feature.patch + feature_flag = True + if flag: run_feature() dfetch format-patch patches re-applied in order on every dfetch update fuzzy matching keeps them clean as upstream evolves

Built for modern CI/CD

Dfetch plugs right into your automation pipeline, allowing you to push dependency status to your existing tools automatically.

$ dfetch check $ dfetch report -t sbom GitHub SARIF · code scanning GitLab code quality in MRs Jenkins warnings-ng plugin Code Climate quality reports GitHub CycloneDX · dep. graph GitLab CycloneDX · dep. scan DependencyTrack vulnerability tracking
Already using submodules? Migrate in seconds.

dfetch import automatically converts Git submodules and SVN externals into a dfetch manifest. No manual work, no lost history — start benefiting from dfetch’s workflow immediately.

Read the migration guide

Get started in seconds

Generated: 22 Mar 2026 at 17:19