Skip to content

Git Dependencies

df-cli can install packages directly from Git repositories. This is useful for private libraries, internal packages that are not published to a package repository, or for depending on a specific branch or commit of a project.

Prerequisites

Git must be installed and available on your system PATH. df-cli invokes git as a command-line tool — it does not bundle its own Git implementation.

Installing Git

Windows:

winget install Git.Git

Or download Git for Windows and run the installer. The default settings are fine — make sure "Git from the command line" is selected during installation.

macOS:

Git is included with the Xcode Command Line Tools. Install them with:

xcode-select --install

Or install via Homebrew:

brew install git

Linux (Debian/Ubuntu):

sudo apt install git

Linux (Fedora/RHEL):

sudo dnf install git

After installing, restart your terminal (and IDE, if applicable) so that git is available on the PATH. You can verify with:

git --version

If Git is not found when df-cli needs it, you will receive exit code 2 (DF_GIT_NOT_AVAILABLE).


Declaring a Git Dependency

Git dependencies are declared in the dependencies array of your workspace .sws file. A URL is treated as a Git dependency when it contains .git in the path.

String Format

The simplest form is a URL with an optional version after #:

"dependencies": [
  "https://github.com/publisher/library.git",
  "https://github.com/publisher/library.git#v1.0.0",
  "https://github.com/publisher/library.git#main"
]

If the workspace file is not in the repository root, append the subdirectory path before the #:

"dependencies": [
  "https://github.com/publisher/monorepo.git/Libraries/MyPackage#v2.0.0"
]

Object Format

For more control — especially when you need to specify a subdirectory for monorepos:

"dependencies": [
  {
    "source": "https://github.com/publisher/library.git",
    "version": "^1.0.0",
    "sws": "Libraries/MyPackage"
  }
]
Property Required Description
source Yes The Git repository URL. Must contain .git in the path. Only https:// and http:// are supported (SSH is not).
version No A version constraint, tag name, branch name, or commit hash. See Specifying Versions below.
sws No Subdirectory within the repository that contains the .sws file. Used for monorepos where the package is not at the root.

Specifying Versions

The version field (or the part after # in string format) controls which version of the repository is checked out.

Tags

Reference a specific Git tag:

"https://github.com/publisher/library.git#v1.0.0"

If the tag follows semantic versioning (e.g. v1.0.0, 2.1.3), it participates in version constraint matching when updating.

Branches

Reference a branch to track its latest commit:

"https://github.com/publisher/library.git#main"
"https://github.com/publisher/library.git#develop"

When a branch is specified, df-cli resolves the latest commit hash on that branch via git ls-remote. The resolved commit is pinned in the lock file so that subsequent builds use the same commit until you explicitly upgrade.

Commit Hashes

Pin to an exact commit (40-character hex SHA-1):

"https://github.com/publisher/library.git#a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"

Commit hashes cannot be updated — they are permanently fixed. Use this when you need an exact reproducible snapshot.

Semver Constraints

Use a version constraint expression to match against semver-compatible Git tags:

{
  "source": "https://github.com/publisher/library.git",
  "version": "^1.0.0"
}

df-cli will fetch all tags from the repository, filter them to those that parse as valid semver, and select the latest tag that satisfies the constraint. If no semver-compatible tags exist at all, df-cli falls back to the repository's default branch.

All constraint operators are supported against semver tags: ^, ~, >=, <=, >, <, compound ranges, and OR expressions with overlapping windows (e.g. ^1.0.0||^2.0.0). The resolved tag is stored in the workspace file; the expression is not kept unless it was placed in the .sws file manually. See Constraint Behaviour Reference for the full resolution table.

No Version

If no version is specified, df-cli uses the repository's default branch (typically main or master) and resolves to its latest commit:

"https://github.com/publisher/library.git"

Lock File Pinning

When a Git dependency is resolved, the exact ref (commit hash, tag, or branch name) is recorded in the .sws.lock file:

{
  "lockVersion": "1.0.0",
  "dependencies": {
    "github.com/publisher/library.git": {
      "ref": "a1b2c3d4e5f6..."
    }
  }
}

On subsequent builds, the locked ref is used as long as it still satisfies the version constraint. This means:

  • Branches are pinned to the commit that was resolved at install time. Running df-cli package upgrade will fetch the latest commit on that branch.
  • Tags are pinned to the exact tag. They do not change unless the version constraint is updated.
  • Commit hashes are always pinned and never change.

Commit the lock file to version control so that all team members and CI pipelines use the same dependency versions. See Versioning and Dependency Resolution for more details on how the lock file works.


Private Repositories

Git Credential Helpers

Configure Git's built-in credential storage so df-cli can authenticate without embedding secrets:

# Store credentials in memory for the session
git config --global credential.helper cache

# Or store credentials on disk (less secure)
git config --global credential.helper store

# Windows: use the built-in Credential Manager
git config --global credential.helper manager

With a credential helper configured, Git will prompt for credentials once and remember them for subsequent operations.

Personal Access Tokens in CI

In CI pipelines, configure Git to use a token globally before running df-cli:

git config --global url."https://x-access-token:${GH_TOKEN}@github.com/".insteadOf "https://github.com/"

Monorepo Support

If the .sws workspace file is not at the root of the Git repository, use the sws field to specify the subdirectory:

{
  "source": "https://github.com/publisher/monorepo.git",
  "version": "^1.0.0",
  "sws": "packages/my-library"
}

Or in string format, include the path between .git and #:

"https://github.com/publisher/monorepo.git/packages/my-library#^1.0.0"

df-cli will clone the entire repository (as a shallow clone) and then load the workspace from the specified subdirectory.


How Git Dependencies Are Stored

When a Git dependency is installed, the repository is cloned into the workspace's DfPkg/ directory:

MyWorkspace/
  DfPkg/
    github.com_publisher_library.git-1.0.0/
      AppSrc/
      Programs/
      df.sws

The directory name is derived from the Git URL (with special characters replaced by _) and the resolved version. The .git folder is removed after checkout to save disk space. Only the checked-out working tree is kept.


Updating Git Dependencies

Check for Updates

df-cli package update MyWorkspace.sws

For Git dependencies, this command: - Branches: Checks if the remote has newer commits than what is pinned in the lock file. - Semver tags: Checks if newer tags exist that satisfy the version constraint. - Commit hashes: Always reports as up to date (cannot be updated).

Upgrade

df-cli package upgrade MyWorkspace.sws

This fetches the latest matching ref, re-clones the repository, and updates the lock file.


Compatibility with Repository Packages

Git dependencies and repository packages (from packages.dataflex.dev) can coexist in the same workspace. However, there are differences in how they are resolved:

Feature Repository Packages Git Dependencies
Version constraints Full semver ranges (^, ~, >=, \|\|) Full semver ranges against tags, plus branch names and commit hashes
Updates Latest version from API Latest semver tag or branch HEAD commit from remote
Authentication df-cli login (OAuth/tokens) Git credentials (URL, helpers, tokens)
Lock file Pins resolved version string Pins resolved ref (commit hash or tag)
Storage DfPkg/<publisher_name-version>/ DfPkg/<url_name-version>/
Shared dependency conflict Constraint window intersected across all dependents Resolved ref must match across all dependents

When two packages depend on the same Git dependency, the resolved ref must be identical — if one package resolves ^1.0.0 to tag 1.0.1 and another independently resolves it to 1.0.0, df-cli will report an incompatibility error. Unlike repository packages, Git dependencies do not re-run range intersection at the workspace level.


Examples

Public Repository with Semver Tags

"dependencies": [
  {
    "source": "https://github.com/DataFlex-dev/Security.git",
    "version": "^2.0.0"
  }
]

Installs the latest 2.x.x tag from the repository.

Track a Branch

"dependencies": [
  "https://github.com/my-team/shared-utils.git#develop"
]

Installs the latest commit on develop. The exact commit is pinned in the lock file.

Pin to a Commit

"dependencies": [
  "https://github.com/my-team/shared-utils.git#9f86d081884c7d659a2feaa0c55ad015a3bf4f1b"
]

Always uses this exact commit. Cannot be updated.

Private Monorepo

"dependencies": [
  {
    "source": "https://github.com/my-company/platform.git",
    "version": "^3.0.0",
    "sws": "packages/DataAccess"
  }
]

Clones the private repository (using credentials from your Git credential helper), checks out the latest 3.x.x tag, and loads the workspace from packages/DataAccess/.

Lower-bound constraint — latest tag at or above a floor

"https://github.com/publisher/library.git#>=1.0.0"

Installs the newest semver tag that is 1.0.0 or higher. No upper limit — will pick up future major versions.

Upper-bound constraint — latest tag at or below a ceiling

"https://github.com/publisher/library.git#<=1.0.1"

Installs the newest semver tag that does not exceed 1.0.1. Useful to stay on a known-good release while newer tags are still being validated.

OR expression — accept two major version lines

"https://github.com/publisher/library.git#^1.0.0||^2.0.0"

Accepts any 1.x.x or 2.x.x tag. df-cli computes the union window >=1.0.0 <3.0.0 and picks the newest tag within it. The installed version will satisfy at least one of the two branches. Only OR expressions whose ranges overlap (sharing a continuous window) are supported; disjoint exact-version OR (e.g. 1.0.0||2.0.0) is not.