Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to the Power Users community on Codidact!

Power Users is a Q&A site for questions about the usage of computer software and hardware. We are still a small site and would like to grow, so please consider joining our community. We are looking forward to your questions and answers; they are the building blocks of a repository of knowledge we are building together.

Post History

71%
+3 −0
Q&A How to delete old files in GIT while keeping history?

Depending on some semantics, it is possible to do what you want, for a sufficiently motivated cohort of "we." The tricky part is that you're rewriting history, and everyone has to agree on that new...

posted 4d ago by Michael‭  ·  edited 4d ago by Michael‭

Answer
#2: Post edited by user avatar Michael‭ · 2025-03-28T21:19:22Z (4 days ago)
Fix a link. More footnotes.
  • Depending on some semantics, it is possible to do what you want, for a sufficiently motivated cohort of "we." The tricky part is that you're rewriting history, and everyone has to agree on that new history.
  • Specifically, when you say
  • > It would be nice to delete both these kinds of files, **but still keep the commit history.**
  • I'm interpreting that as "otherwise keep the commit messages with the diffs of files not to be removed."
  • ### Background
  • The commit SHA, the basic identifier of a specific commit, is dependent on the state of the files in the repository (and some dates, authorship, etc.). The implication here is that every single commit forward of your oldest one with an unwanted file will have a different SHA than you use now.
  • When you're the only consumer of the repository (or if your unwanted file hasn't yet been pushed), this isn't too much of a concern. Just make the change, `git push --force` and move on. The trouble is that everyone else will need to set all of their local (and remote) branches to stem from your changed history instead of the common commit.
  • ### Rewriting history
  • #### Interactive rebase
  • Recent commits[^recent] can be fixed with [an interactive rebase][rebase-i], as [a commenter mentioned][velvel].
  • I personally like to tag the current head (say `git tag tmp/master`), find the commit that made the change (say it's `deadbeef`), and interactive rebase against the next older one: `git rebase --interactive deadbeef^`.
  • You'll see a list of commits in your editor with `pick` next to each one. Change `pick` to `edit` next to the commit(s) you need to modify, save, and quit. At each pause, Git will ask you to set the files to the state you wish. Then `git add` them, commit, and `git rebase --continue`.
  • #### Bigger tools for older commits
  • Usually when someone grabs a big hammer to rewrite early history, it's [because they put an important credential][infosec] into Git history.
  • Then, you'll need to employ a tool like [`git-filter-repo`][f-repo] or [`git-filter-branch`][f-branch] to purge unwanted files from all of history.
  • ***Consider practicing on a clone first!!** These tools have extreme destructive power.*
  • [^recent]: If it was your *most recent* commit, you can even stage the changes away and `git commit --amend`.
  • [rebase-i]: https://git-scm.com/docs/git-rebase#_interactive_mode
  • [velvel]: https://powerusers.codidact.com/comments/thread/10651
  • [f-branch]: https://git-scm.com/docs/git-filter-branch
  • [f-repo]: https://github.com/newren/git-filter-repo
  • Depending on some semantics, it is possible to do what you want, for a sufficiently motivated cohort of "we." The tricky part is that you're *rewriting history,* and everyone has to agree on that new history.
  • Specifically, when you say
  • > It would be nice to delete both these kinds of files, **but still keep the commit history.**
  • I'm interpreting that as "otherwise keep the commit messages with the diffs of files not to be removed." If you want to get technical, there is *no way* to purge the files from history without rewriting that history.
  • ### Background
  • The commit SHA, the basic identifier of a specific commit, is dependent on the state of the files in the repository.[^sha] The implication here is that every single commit forward of your oldest one with an unwanted file will have a different SHA than you use now.
  • When you're the only consumer of the repository,[^prepush] this isn't too much of a concern. Just make the change, `git push --force`, and move on.
  • If you are **not** the only user, everyone else will need to reset *all of their local and remote branches* to stem from your changed history instead of the common commit.
  • ### Rewriting history
  • #### Interactive rebase
  • Recent commits[^recent] can be fixed with [an interactive rebase][rebase-i], as [a commenter mentioned][velvel].
  • I personally like to tag the current head (say `git tag tmp/master`), find the commit that made the change (say it's `deadbeef`), and interactive rebase against the next older one: `git rebase --interactive deadbeef^`.
  • You'll see a list of commits in your editor with `pick` next to each one. Change `pick` to `edit` next to the commit(s) you need to modify, save, and quit. At each pause, Git will ask you to set the files to the state you wish. Then `git add` them, commit, and `git rebase --continue`.
  • #### Bigger tools for older commits
  • Usually when someone grabs a big hammer to rewrite early history, it's [because they put an important credential][infosec] into Git history that needs to be excised in all its forms.
  • Then, you'll need to employ a tool like [`git-filter-repo`][f-repo] or [`git-filter-branch`][f-branch] to purge unwanted files from all of history.
  • ***Consider practicing on a clone first!!** These tools have extreme destructive power.*
  • [^sha]: Dependent on the files, the parent, some dates, authorship, etc.
  • [^recent]: If it was your *most recent* commit, you can even stage the changes away and `git commit --amend`.
  • [^prepush]: You're the only consumer or your unwanted file hasn't yet been pushed where others can see it
  • [rebase-i]: https://git-scm.com/docs/git-rebase#_interactive_mode
  • [velvel]: https://powerusers.codidact.com/comments/thread/10651
  • [infosec]: https://security.stackexchange.com/a/272958/56961
  • [f-branch]: https://git-scm.com/docs/git-filter-branch
  • [f-repo]: https://github.com/newren/git-filter-repo
#1: Initial revision by user avatar Michael‭ · 2025-03-28T21:12:17Z (4 days ago)
Depending on some semantics, it is possible to do what you want, for a sufficiently motivated cohort of "we." The tricky part is that you're rewriting history, and everyone has to agree on that new history.

Specifically, when you say

>  It would be nice to delete both these kinds of files, **but still keep the commit history.**

I'm interpreting that as "otherwise keep the commit messages with the diffs of files not to be removed."

### Background

The commit SHA, the basic identifier of a specific commit, is dependent on the state of the files in the repository (and some dates, authorship, etc.). The implication here is that every single commit forward of your oldest one with an unwanted file will have a different SHA than you use now.

When you're the only consumer of the repository (or if your unwanted file hasn't yet been pushed), this isn't too much of a concern. Just make the change, `git push --force` and move on. The trouble is that everyone else will need to set all of their local (and remote) branches to stem from your changed history instead of the common commit.

### Rewriting history

#### Interactive rebase

Recent commits[^recent] can be fixed with [an interactive rebase][rebase-i], as [a commenter mentioned][velvel].

I personally like to tag the current head (say `git tag tmp/master`), find the commit that made the change (say it's `deadbeef`), and interactive rebase against the next older one: `git rebase --interactive deadbeef^`.

You'll see a list of commits in your editor with `pick` next to each one. Change `pick` to `edit` next to the commit(s) you need to modify, save, and quit. At each pause, Git will ask you to set the files to the state you wish. Then `git add` them, commit, and `git rebase --continue`.

#### Bigger tools for older commits

Usually when someone grabs a big hammer to rewrite early history, it's [because they put an important credential][infosec] into Git history.

Then, you'll need to employ a tool like [`git-filter-repo`][f-repo] or [`git-filter-branch`][f-branch] to purge unwanted files from all of history.

***Consider practicing on a clone first!!** These tools have extreme destructive power.*



[^recent]: If it was your *most recent* commit, you can even stage the changes away and `git commit --amend`.

[rebase-i]: https://git-scm.com/docs/git-rebase#_interactive_mode
[velvel]: https://powerusers.codidact.com/comments/thread/10651
[f-branch]: https://git-scm.com/docs/git-filter-branch
[f-repo]: https://github.com/newren/git-filter-repo