Update projects

dfetch update fetches every dependency listed in dfetch.yaml and places the requested version in its destination folder. VCS type (Git, SVN, or plain archive) is detected automatically.

Fetching all projects

Run without arguments to fetch every project in the manifest:

$ dfetch update

Dfetch reads dfetch.yaml, resolves each project’s VCS type, and writes the requested revision into the destination folder. A .dfetch_data.yaml metadata file is created inside each destination so Dfetch can track what version is present.

Example: Git projects are specified in the manifest
../features/fetch-git-repo.feature
Given the manifest 'dfetch.yaml'
    """
    manifest:
      version: '0.0'

      remotes:
        - name: github-com-dfetch-org
          url-base: https://github.com/dfetch-org/test-repo

      projects:
        - name: ext/test-repo-rev-only
          revision: e1fda19a57b873eb8e6ae37780594cbb77b70f1a
          dst: ext/test-repo-rev-only

        - name: ext/test-rev-and-branch
          revision: 8df389d0524863b85f484f15a91c5f2c40aefda1
          branch: main
          dst: ext/test-rev-and-branch

        - name: ext/test-repo-tag-v1
          tag: v1
          dst: ext/test-repo-tag-v1

    """
When I run "dfetch update"
Then the following projects are fetched
    | path                       |
    | ext/test-repo-rev-only     |
    | ext/test-rev-and-branch    |
    | ext/test-repo-tag-v1       |
Example: Tag is updated in manifest
../features/fetch-git-repo.feature
Given the manifest 'dfetch.yaml'
    """
    manifest:
      version: '0.0'

      projects:
        - name: ext/test-repo-tag
          url: https://github.com/dfetch-org/test-repo
          tag: v1

    """
And all projects are updated
When the manifest 'dfetch.yaml' is changed to
    """
    manifest:
      version: '0.0'

      projects:
        - name: ext/test-repo-tag
          url: https://github.com/dfetch-org/test-repo
          tag: v2.0

    """
And I run "dfetch update"
Then the output shows
    """
    Dfetch (0.13.0)
      ext/test-repo-tag:
      > Fetched v2.0
    """
Example: Version check ignored when force flag is given
../features/fetch-git-repo.feature
Given the manifest 'dfetch.yaml'
    """
    manifest:
      version: '0.0'

      projects:
        - name: ext/test-repo-tag
          url: https://github.com/dfetch-org/test-repo
          tag: v1

    """
And all projects are updated
When I run "dfetch update --force"
Then the output shows
    """
    Dfetch (0.13.0)
      ext/test-repo-tag:
      > Fetched v1
    """

Updating a single project

Pass one or more project names to limit which entries are updated:

$ dfetch update mylib
$ dfetch update mylib myother

Overwriting local changes

By default Dfetch skips a project that is already at the requested version or that has local modifications. Use --force (-f) to re-fetch and overwrite regardless:

$ dfetch update --force mylib

Warning

Any unsaved local edits in the destination directory will be lost. Capture them first with dfetch diff — see Patch a project for the full patch workflow.

Sub-manifests

A fetched project may itself contain a dfetch.yaml. Dfetch reads it after fetching and reports any further dependencies it finds, so you can decide whether to vendor those as well.

To skip this check entirely:

$ dfetch update --no-recommendations
Example: Git projects are specified in the manifest
../features/updated-project-has-dependencies.feature
Given the manifest 'dfetch.yaml' in MyProject
    """
    manifest:
        version: 0.0
        projects:
            - name: SomeProjectWithManifest
              dst: third-party/SomeProjectWithManifest
              url: some-remote-server/SomeProjectWithManifest.git
              tag: v1
            - name: SomeProjectWithoutManifest
              dst: third-party/SomeProjectWithoutManifest
              url: some-remote-server/SomeProjectWithoutManifest.git
              tag: v1
    """
And a git-repository "SomeProjectWithManifest.git" with the manifest:
    """
    manifest:
        version: 0.0
        remotes:
            - name: github-com-dfetch-org
              url-base: https://github.com/dfetch-org/test-repo

        projects:
            - name: SomeOtherProject
              dst: SomeOtherProject
              url: some-remote-server/SomeOtherProject.git
              tag: v1

            - name: ext/test-repo-tag-v1
              tag: v1
    """
And a git repository "SomeProjectWithoutManifest.git"
When I run "dfetch update" in MyProject
Then the output shows
    """
    Dfetch (0.13.0)
      SomeProjectWithManifest:
      > Fetched v1
      > "SomeProjectWithManifest" depends on the following project(s) which are not part of your manifest:
        (found in third-party/SomeProjectWithManifest/dfetch.yaml)

        -   name: SomeOtherProject
            url: some-remote-server/SomeOtherProject.git
            tag: v1
        -   name: ext/test-repo-tag-v1
            url: https://github.com/dfetch-org/test-repo
            tag: v1

      SomeProjectWithoutManifest:
      > Fetched v1
    """
And 'MyProject' looks like:
    """
    MyProject/
        dfetch.yaml
        third-party/
            SomeProjectWithManifest/
                .dfetch_data.yaml
                README.md
                dfetch.yaml
            SomeProjectWithoutManifest/
                .dfetch_data.yaml
                README.md
    """
Example: A project from a submanifest has an invalid manifest
../features/updated-project-has-dependencies.feature
Given the manifest 'dfetch.yaml' in MyProject
    """
    manifest:
        version: 0.0
        projects:
            - name: SomeProject
              dst: third-party/SomeProject
              url: some-remote-server/SomeProject.git
              tag: v1
    """
And a git-repository "SomeProject.git" with the manifest:
    """
    very-invalid-manifest
    """
When I run "dfetch update" in MyProject
Then the output shows
    """
    Dfetch (0.13.0)
      SomeProject:
      > Fetched v1
    SomeProject/dfetch.yaml: Schema validation failed:

        "very-invalid-manifest\n"
         ^ (line: 1)

    found arbitrary text
    """
And 'MyProject' looks like:
    """
    MyProject/
        dfetch.yaml
        third-party/
            SomeProject/
                .dfetch_data.yaml
                README.md
                dfetch.yaml
    """

Git submodules

When a Git dependency contains submodules, Dfetch fetches and resolves them automatically — no extra manifest entries or git submodule commands are needed. Each submodule is checked out at the exact revision pinned by the parent repository.

$ dfetch update

Dfetch (0.13.0)
my-project:
> Found & fetched submodule "./ext/vendor-lib"  (https://github.com/example/vendor-lib @ master - 79698c9…)
> Fetched master - e1fda19…

Nested submodules are resolved recursively. Pinned details for each submodule are recorded in .dfetch_data.yaml and are visible in Report.

Example: A project with a git submodule is fetched at the pinned revision
../features/fetch-git-repo-with-submodule.feature
Given the manifest 'dfetch.yaml' in MyProject
    """
    manifest:
        version: 0.0
        projects:
            - name: my-project-with-submodules
              url: some-remote-server/SomeInterestingProject.git
    """
When I run "dfetch update"
Then the output shows
    """
    Dfetch (0.13.0)
      my-project-with-submodules:
      > Found & fetched submodule "./ext/test-repo1"  (some-remote-server/TestRepo.git @ master - 79698c99152e4a4b7b759c9def50a130bc91a2ff)
      > Found & fetched submodule "./ext/test-repo2"  (some-remote-server/TestRepo.git @ master - 79698c99152e4a4b7b759c9def50a130bc91a2ff)
      > Fetched master - e1fda19a57b873eb8e6ae37780594cbb77b70f1a
    """
Then 'MyProject' looks like:
    """
    MyProject/
        dfetch.yaml
        my-project-with-submodules/
            .dfetch_data.yaml
            README.md
            ext/
                test-repo1/
                    README.md
                test-repo2/
                    README.md
    """
Example: A project with a git submodule that itself has a nested submodule is fetched at the pinned revision
../features/fetch-git-repo-with-submodule.feature
Given a git repository "LeafProject.git"
And a git-repository "MiddleProject.git" with the following submodules
    | path     | url                                | revision |
    | ext/leaf | some-remote-server/LeafProject.git | master   |
And a git-repository "OuterProject.git" with the following submodules
    | path       | url                                  | revision |
    | ext/middle | some-remote-server/MiddleProject.git | master   |
Given the manifest 'dfetch.yaml' in MyProject
    """
    manifest:
        version: 0.0
        projects:
            - name: outer-project
              url: some-remote-server/OuterProject.git
    """
When I run "dfetch update"
Then the output shows
    """
    Dfetch (0.13.0)
      outer-project:
      > Found & fetched submodule "./ext/middle"  (some-remote-server/MiddleProject.git @ master - 79698c99152e4a4b7b759c9def50a130bc91a2ff)
      > Fetched master - e1fda19a57b873eb8e6ae37780594cbb77b70f1a
    """
Then 'MyProject' looks like:
    """
    MyProject/
        dfetch.yaml
        outer-project/
            .dfetch_data.yaml
            README.md
            ext/
                middle/
                    README.md
                    ext/
                        leaf/
                            README.md
    """
Example: Submodule changes are reported in the project report
../features/fetch-git-repo-with-submodule.feature
Given a fetched and committed MyProject with the manifest
    """
    manifest:
        version: 0.0
        projects:
            - name: my-project-with-submodules
              url: some-remote-server/SomeInterestingProject.git
    """
When I run "dfetch report" in MyProject
Then the output shows
    """
    Dfetch (0.13.0)
      my-project-with-submodules:
      - remote            : <none>
        remote url        : some-remote-server/SomeInterestingProject.git
        branch            : master
        tag               : <none>
        last fetch        : 26/02/2026, 20:28:24
        revision          : 79698c99152e4a4b7b759c9def50a130bc91a2ff
        patch             : <none>
        licenses          : <none>

        dependencies      :
        - path            : ext/test-repo1
          url             : some-remote-server/TestRepo.git
          branch          : master
          tag             : <none>
          revision        : e1fda19a57b873eb8e6ae37780594cbb77b70f1a
          source-type     : git-submodule

        - path            : ext/test-repo2
          url             : some-remote-server/TestRepo.git
          branch          : master
          tag             : <none>
          revision        : 8df389d0524863b85f484f15a91c5f2c40aefda1
          source-type     : git-submodule
    """
Example: Subfolder is matched through a glob is fetched and submodules are resolved
../features/fetch-git-repo-with-submodule.feature
Given a git-repository "GlobProject.git" with the following submodules
    | path                     | url                             | revision |
    | some_dir_a/ext/test-repo | some-remote-server/TestRepo.git | master   |
Given the manifest 'dfetch.yaml' in MyProject
    """
    manifest:
        version: 0.0
        projects:
            - name: glob-project
              url: some-remote-server/GlobProject.git
              src: some_dir_*
    """
When I run "dfetch update"
Then the output shows
    """
    Dfetch (0.13.0)
      glob-project:
      > Found & fetched submodule "./ext/test-repo"  (some-remote-server/TestRepo.git @ master - 79698c99152e4a4b7b759c9def50a130bc91a2ff)
      > Fetched master - e1fda19a57b873eb8e6ae37780594cbb77b70f1a
    """
Then 'MyProject' looks like:
    """
    MyProject/
        dfetch.yaml
        glob-project/
            .dfetch_data.yaml
            ext/
                test-repo/
                    README.md
    """