Home / Alt manpages / git-http-push(1)

  • git-http-push(1)
  • User command
  • linux

Push a Git Ref over HTTP DAV with git http-push

Some Git hosts never learned smart HTTP, so git http-push sends objects and updates refs straight over WebDAV instead. It is the older transport, not the one git push normally uses. This guide gets you from a reviewed local ref to a confirmed remote update, using the installed Git 2.43.0 from git-man 2.43.0. Allow about fifteen minutes, plus time to confirm the remote server is actually configured for DAV writes.

  • You need: a local repository with the ref you intend to publish, the remote DAV URL from your administrator, and credentials that server accepts.
  • It will not touch: anything reachable only by the normal smart HTTP push. This is a separate, older transport.

Do not guess a DAV URL from a normal clone address. Make sure the server administrator has explicitly provided one for this protocol.

1. Confirm the installed command

Check the version and syntax first. This is ordinary, read-only work and needs no elevated privileges:

$ git --version
git version 2.43.0
$ git http-push -h
usage: git http-push [--all] [--dry-run] [--force] [--verbose] <remote> [<head>...]

The local manpage documents Git 2.43.0. The upstream page currently describes the same manual as unchanged through Git 2.55.0, but always check the binary on the machine that will actually do the push.

Checkpoint

Confirm the command exists and that you are in the intended repository.

$ command -v git
/usr/bin/git
$ git rev-parse --show-toplevel
/path/to/your/repository

2. Inspect the ref before sending anything

List the local refs and pick an exact source name. Swap the example branch for the ref you have already reviewed:

$ git show-ref --heads
<commit-id> refs/heads/main
$ git rev-parse --verify refs/heads/main^{commit}
<commit-id>

A ref argument can be a single name, meaning the same source and destination, or a source:destination pair. The source must match exactly one local ref. Use full names when the destination matters:

$ git http-push --dry-run https://dav.example.invalid/project.git \
    refs/heads/main:refs/heads/main

That URL is a placeholder and is not expected to connect. Replace it with the real DAV URL. The destination should normally start with refs/ when you are creating a remote ref explicitly.

3. Preview the update

Run the real command with --dry-run first. It does everything except actually send the updates, which makes it the safest checkpoint before touching the remote:

$ git http-push --dry-run --verbose \
    https://dav.example.invalid/project.git \
    refs/heads/main:refs/heads/main

With --verbose, Git reports the objects it walks locally and the objects it would send; exact diagnostics depend on the server and URL. A failed preview is not a reason to reach for --force. Check the URL, authentication, DAV configuration, ref spelling and network access first.

Checkpoint

Record the local commit and compare it against the remote ref using an independent, read-only method the server provides. Do not continue if the destination contains commits your local history does not include.

4. Push a fast-forward ref

Once the preview and the remote review both check out, run the same command without --dry-run:

$ git http-push --verbose \
    https://dav.example.invalid/project.git \
    refs/heads/main:refs/heads/main
<objects walked and sent by Git>

Without --force, the remote ref only updates when it does not exist yet, or when its current value is an ancestor of your local source. That fast-forward check exists to protect other people's commits: the command sends missing objects before it updates the ref, so a successful run leaves the remote able to resolve the new commit.

If Git reports a non-fast-forward refusal, stop and inspect both histories. Merge or rebase locally to match your project's policy, then preview again. A refusal is not a prompt to force the update.

5. Map one local ref to another remote name

Use a source and destination pair when the names differ. This example publishes the local branch release as a remote branch named stable:

$ git http-push --dry-run \
    https://dav.example.invalid/project.git \
    refs/heads/release:refs/heads/stable

The colon belongs to the refspec, not to a ref name. If the destination does not match an existing remote ref, the explicit destination must start with refs/. A bare release is shorthand for release:release, not a request to rename the branch.

6. Handle force and deletion as change controls

Force pushing disables the fast-forward check for every ref in that invocation:

$ git http-push --dry-run --force \
    https://dav.example.invalid/project.git \
    refs/heads/main:refs/heads/main

Warning

This can make the remote lose commits. Treat it as a destructive, security-sensitive change: get approval, save the current remote commit ID, check the destination carefully, and arrange a recovery copy before you use --force. A leading plus sign, for example +refs/heads/main:refs/heads/main, disables the check for just that one ref; the same review rules still apply.

The -d and -D forms remove a remote ref. They cannot remove the remote HEAD, and the manpage adds extra ancestry and object checks on top. Do not use deletion as a troubleshooting step:

$ git http-push --dry-run -d \
    https://dav.example.invalid/project.git \
    refs/heads/old-release

Before a real deletion, record the ref's commit ID and confirm no consumer still needs it. Recovery means recreating the ref from a known commit, and only works if the remote still holds the objects:

$ git http-push \
    https://dav.example.invalid/project.git \
    <known-local-ref>:refs/heads/old-release

Common traps

  • Assuming any clone URL works. A normal clone address is not a DAV endpoint. Use only a URL your administrator has documented for this protocol.
  • Treating a preview failure as a force signal. Fix the URL, auth, DAV config or ref spelling instead of reaching for --force.
  • Old libcurl. The transport is disabled when libcurl is older than 7.16, because that combination has been reported to fail and sometimes corrupt repositories. Check the linked library and system logs if Git refuses to run it, rather than forcing unrelated options.
  • Reaching for this on a normal hosted service. Prefer the service's documented smart HTTP, SSH or other supported transport. If a server does not advertise or document HTTP/DAV writes, stop and ask for the correct push method; this command cannot turn a read-only HTTP endpoint into a writable remote.

7. Diagnose the boundaries

--all tells Git not to assume the remote is complete. It verifies every object in the entire history of the local ref, which can take longer than an ordinary update:

$ git http-push --dry-run --all --verbose \
    https://dav.example.invalid/project.git \
    refs/heads/main:refs/heads/main

Use it when the remote may have been copied incompletely, or when an administrator specifically asks for a full object check. It does not bypass ref safety checks and it does not repair a broken DAV server.

Done means

  • Version confirmed. You checked Git 2.43.0, or recorded the version on the actual push host.
  • URL and ref checked. You used a documented HTTP/DAV URL and selected an exact local source ref.
  • Preview run. You ran a verbose dry run and checked the destination history.
  • Fast-forward preserved. Your normal push omitted --force.
  • Force or delete reviewed. Any force update or deletion had explicit approval, a recorded commit ID and a recovery path.
  • Transport confirmed. You know whether the server actually supports this legacy transport, rather than assuming a clone URL does.