git-upload-archive is the server-side process that git archive --remote quietly starts on the other end. Know its rules and you avoid both shipping hidden history and baffling rejections. Allow about fifteen minutes if the repository and a test client are already available.
This guide describes Git 2.43.0, installed here from git-man version 1:2.43.0-1ubuntu7.3. Check your own version before relying on details in an automated service:
$ git --version
git version 2.43.0
Checkpoint: this is a read-only archive service. It does not push commits, change branches or edit the working tree. The security setting shown later does change repository configuration and counts as an administrative action.
Do not invoke git-upload-archive by hand. A client asks for an archive with git archive --remote, and Git starts the upload-archive endpoint through the repository transport. For a repository whose remote is named origin, the basic shape is:
$ git archive --remote=origin v1.0 > project-v1.0.tar
The first argument after --remote identifies the remote repository. The tree argument, v1.0 here, must be an allowed ref expression on that server. Archive bytes go to standard output, so the shell redirection is what creates the local file. Reading the remote repository and writing in your current directory normally needs no elevated privileges.
Check the result before unpacking it:
$ file project-v1.0.tar
$ tar -tf project-v1.0.tar | sed -n '1,10p'
Output depends on the repository, but file should identify a tar archive and the listing should contain the expected top-level paths. Command failed? Inspect the error before retrying with a different expression.
The installed server applies a deliberately narrow rule set. A client may request a commit or tree pointed to directly by a ref, such as a tag or branch, and may select a directory below that ref with ref:path syntax:
$ git archive --remote=origin v1.0:Documentation > documentation-v1.0.tar
That path is still anchored at the named ref. It is not a request for an arbitrary object followed by a path search. Confirm the archive contents with tar -tf before extracting anything.
Checkpoint: use a published tag or branch name first. A remote server may have a different set of refs from your local clone, so a name that works locally is not automatically available remotely.
Relative revisions and literal object IDs are not accepted by the default upload-archive rules, even where the resulting object would be reachable from a ref. The examples below are intentionally unsafe as a first choice, shown here only to explain a common failure:
$ git archive --remote=origin main^ > previous.tar
$ git archive --remote=origin abcdef1234567890abcdef1234567890abcdef12 > object.tar
Expect an error from the remote archiver and a non-zero client status; exact wording varies with transport and Git version. A rejected expression is not proof the commit is missing: it may simply violate the server's privacy boundary.
On a local test repository, requesting an unavailable expression returned status 1 and reported git upload-archive: archiver died with error. Capture a status immediately after a failed request if a script needs to tell failure apart from an empty-looking archive:
$ git archive --remote=origin main^ > previous.tar
$ rc=$?
$ printf 'archive status: %s\n' "$rc"
The restriction exists because objects removed from visible history can linger in the object database until pruning. Letting an archive request name any object could disclose that retained history. The default is the safer choice: serve ref tips and sub-trees below them, refuse other SHA-1 expressions.
Do not weaken this boundary just to make a deployment script convenient. An administrator can opt out with the repository configuration key uploadArchive.allowUnreachable, but that permits clients to use arbitrary object expressions. It is defensible only where the object database is already public through another service and the disclosure is understood:
$ git -C /srv/git/project.git config uploadArchive.allowUnreachable true
Warning: this is an administrative, security-sensitive change. Review the repository path and its access policy first. Do not run it with sudo unless the repository ownership requires that elevation. To undo it and return to the default:
$ git -C /srv/git/project.git config --unset uploadArchive.allowUnreachable
If the key was set in a different configuration scope, use your normal configuration management to remove it there instead. Verify the effective value without changing it:
$ git -C /srv/git/project.git config --show-origin --get uploadArchive.allowUnreachable
A working Git repository does not guarantee remote archive service is enabled. The client transport must be configured to invoke an upload-archive endpoint, and the remote side may impose its own restrictions. For HTTP or HTTPS hosting, the Git HTTP backend has a separate http.uploadarchive service setting; current Git documentation says that service is disabled by default and works with protocol version 2.
Diagnosing a failure, check these in order:
git remote -v.Do not replace a service failure with a broad permission change. If the server is not meant to provide archives, use a normal clone or fetch workflow and build the archive from a checked-out ref under your own access controls.
Creating the tar file does not extract anything, which makes it a useful review point. List names first, and watch for an unexpected absolute path, parent-directory component or surprising top-level directory. Archive from a source you do not control? Inspect it before extraction and use an isolated destination. The upload-archive protocol controls which Git tree is selected; it does not make every later archive-handling step safe.
Need to discard a failed local download? Remove only the named output after checking it is the file you meant to create. There is no server-side undo for a client download. A repository configuration change, though, can be reverted with the config --unset command above.
git --version confirmed the Git version you are documenting.tar -tf showed the expected files.ref:path for a sub-tree rather than an arbitrary object expression.uploadArchive.allowUnreachable remains unset unless an administrator has reviewed the disclosure risk.