Hub documentation

Removing Sensitive Data from a Repository

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Removing Sensitive Data from a Repository

This page only applies to git-backed repositories (models, datasets, and Spaces).

If you committed a secret, private data, or any file you don’t want on the Hub, deleting it in a new commit is not enough: older commits still contain it, and URLs such as /resolve/<old_sha>/<path>, /blob/<old_sha>/<path> or /commit/<old_sha> keep serving it. To fully remove a file, remove it from every ref that can reach it: branches, tags, and pull requests.

If the file contains a secret (token, API key, password), revoke or rotate it first and treat it as compromised: copies cached by the CDN or downloaded by users may outlive its removal. For Hugging Face tokens, see Revoking a leaked token.

Overview

ActionRemovesLeaves
Delete the file in a new commitThe file from the latest revisionAll previous commits, so not enough on its own
List Large Files → delete with “rewrite history”The file content (immediately), and its pointer from all branches, tags and PR refsOld commits with the file’s path, sha256 and size, until cleanup
git filter-repo + force-pushThe file from every branch and tag you pushRefs you don’t push, history pinned by pull requests
super_squash_historyThe history of one branchOther branches, tags, history pinned by pull requests
Delete the pull requestThe PR ref, releasing history only it keptThat history, until cleanup

Rewriting history (every option except a new commit) is irreversible and changes commit SHAs. Collaborators using git should re-clone, or reset their branches onto the rewritten ones, and must not push their old history back, which would reintroduce the file.

Recommended order

  1. Revoke or rotate any leaked secret.
  2. Remove LFS and Xet files with “rewrite history”.
  3. Remove regular git files from every branch and tag.
  4. For regular git files, delete pull requests opened after the file was committed.
  5. Clean up duplicated repositories you own.
  6. Contact us if needed.

LFS and Xet files

If the file appears in your repository’s “List Large Files” (this includes Xet-backed files):

  1. Go to your repository’s Settings page.
  2. Click on “List Large Files” in the “Storage” section.
  3. Delete the file, keeping “rewrite history” checked (the default).

Deleting a large file with “rewrite history” removes its content right away and strips its pointer from every branch, tag and PR ref. This changes the SHA of the first commit containing the file and all its descendants, and drops commits left empty (e.g. one that only added the file). The old commits still show the file’s path, sha256 and size until they’re cleaned up. See Storage Limits for more details.

If the file’s path or name is itself sensitive, it stays in those old commits until they’re cleaned up. “Rewrite history” removes it with them.

Regular git files

Option 1: rewrite history with git filter-repo and force-push every branch and tag that contains the file. Force-pushing is allowed for users with write access.

git clone https://huggingface.co/<namespace>/<repo>  # use /datasets/ or /spaces/ for those repo types
cd <repo>
git filter-repo --invert-paths --path path/to/file
git remote add origin https://huggingface.co/<namespace>/<repo>  # filter-repo removes the remote
git push --force --all origin
git push --force --tags origin

Option 2: delete the file and squash the history with super_squash_history. Each call squashes a single branch into one commit, so repeat it for every affected branch and delete the branches and tags you don’t need.

from huggingface_hub import HfApi

api = HfApi()
api.delete_file("path/to/file", repo_id="<namespace>/<repo>")
api.super_squash_history(repo_id="<namespace>/<repo>", branch="main")
api.delete_tag(repo_id="<namespace>/<repo>", tag="v1.0")

Pull requests

This only applies to regular git files: deleting a large file with “rewrite history” already rewrites pull requests.

Any pull request opened after the file was committed keeps that history reachable by SHA, even once you rewrite or squash main, and even if the PR was merged or closed. Deleting the pull request releases that history, which is then cleaned up.

Duplicated repositories

Duplicated repositories are independent, so clean up the ones you own the same way. Model and dataset duplicates only contain the files of main at the time of duplication (as a single commit), while Space duplicates keep main’s full history. Other branches and tags are not copied.

When old commits disappear

Old commits stay reachable by their SHA (in the web UI, the API, and with git fetch <sha>) until they’re cleaned up, which usually happens within about an hour after a force-push, a super_squash_history, a “rewrite history” delete, or deleting the pull request that kept them.

When to contact us

  • You need old commit URLs guaranteed to return 404
  • You need cached downloads invalidated
  • You need derived copies reset, such as Data Studio Parquet conversions (refs/convert/*) or Space builds
Update on GitHub