tgunr
tgunr

Reputation: 1548

How to remove unattached commit from git history

I have been searching for sometime and can't a similar situation. I have an old repo, unshared with anyone that somehow has a dangling commit completely unattached to any orther branch. How do I remove this from the history. The commit tree looks like:

enter image description here

Upvotes: 1

Views: 144

Answers (2)

torek
torek

Reputation: 488183

If a commit is truly unreachable, a log viewer won't show it in the first place. Log viewers like git log --graph --oneline work by starting with some set of references—usually branches and or tags, or whatever arguments you pass on the command line, but any reference in the refs/ namespace will do if you pass --all. To get git log --graph to decorate (annotate with branch and tag names and the like) any commits that have one of these references, add --decorate.

Your display looks a bit like the graph display from gitk --all, although gitk normally decorates each referenced commit so that you can tell why it appears in your graph. It also looks a bit (more) like the display from TortoiseGit or SourceTree, but I use neither of these (and rarely bother with gitk either) so I can't say how to get them to cough up the reason they are showing you these commits.

Note that the stash reference (used by git stash, named refs/stash can keep a series of otherwise-abandoned commits, such as those left behind by git rebase, alive in a repository, well past their normal recovery lifetime. If you have old useless stashes you may need to git stash drop them. The git filter-branch command also copies all the references it modifies, leaving the originals in refs/originals/ (so, for instance, refs/heads/master, the ref-name for branch master, gets moved to refs/originals/refs/heads/master when you get a new refs/heads/master by filter-copying all the commits from master).

Besides these, the other normally-hidden references are in Git's reflogs, which are what keep abandoned commits around for the 30 day recovery period, and also some special reference names like ORIG_HEAD, MERGE_HEAD, CHERRY_PICK_HEAD, and FETCH_HEAD (and of course HEAD itself, but that normally just contains a branch name).

When a commit chain is truly unreachable, log viewers won't show it and git gc will reap it.

Upvotes: 1

Cameron Skinner
Cameron Skinner

Reputation: 54306

You could run the Git garbage collector with git-gc.

That should remove your dangling commits, so long as there are no tags or branches pointing to any of them.

To quote the official documentation:

Runs a number of housekeeping tasks within the current repository, such as compressing file revisions (to reduce disk space and increase performance) and removing unreachable objects which may have been created from prior invocations of git add.

Upvotes: 1

Related Questions