newren / git-filter-repo

Quickly rewrite git repository history (filter-branch replacement)
Other
8.55k stars 708 forks source link

Since changing history changes hashes, what is the best approach to recreate the tags with the new hash? #366

Closed jerkstorecaller closed 2 years ago

jerkstorecaller commented 2 years ago

Let's say I have the tag "1.0" for commit abcdef123. I use git-filter-repo to rewrite history to delete secrets, replace tabs with spaces, or whatever. Now abcdef123 no longer exists (let's say it's become ffff1234 but I have no way to know that).

How do I retag 1.0? How do I find out which commit was equivalent to abcdef123?

Bonus related question: I'm also wondering what happens to Github pull requests, reviews, etc, on commits that no longer exist. Do they disappear? Do they remain with a warning message that the commit is gone?

newren commented 2 years ago

As long as your clone has the tags, git-filter-repo automatically updates the tags to point at the new commits. If tag 1.0 used to point to abcdef123, and commit abcdef123 was rewritten to commit fff1234, then 1.0 will now point to fff1234. If abcdef123 was deleted because it only added files that you deleted as part of your rewrite, then 1.0 will now point to the commit which corresponds to the most recent ancestor of abcdef123 that was not dropped.

So, you don't have to do anything to retag. However, note that if you forcibly push the new tags to the original repository, then most users will never see the new tags and will instead keep using the old ones (See the "On Re-tagging" section of the git-tag manual for why and how to work around it.) That's one reason I suggest folks do not push the rewritten history to the original repository but instead push to a different repository.

git-filter-repo only rewrites history that exists in your local clone. By default, clones only include stuff under refs/heads/ and refs/tags/ from the original repository. GitHub pull requests are stored under refs/pull/. So, by default, nothing is done with those and they continue referencing the old commits instead of the new rewritten ones (so yes, your repository will have two copies of history contained within it). You could include the pull request commits in your clone and have git-filter-repo rewrite those commits...but GitHub will not allow you to upload the changes back to refs/pull/ on the server, meaning that you can't push the rewritten pull requests. GitHub has a separate process on updating/deleting pull requests with some docs written on how to do that, but the update process is some request put in a website rather than running some Git command, as best I recall. (Also, GitHub review comments aren't stored in Git, so there's no way for this tool to affect them, but they could be expunged along with the GitHub PR if you want to go that route.)

Does that help?