Allen
Allen

Reputation: 3374

How to cleanly reset local git repository with no remnants left

We just started using git in production at our company and everyone seems to have the same concern/issues. Since we are still getting the hang of using git, we frequently end up messing up our local repsitories. (bad merges, wrong commands, etc). What we want to do is reset our local repositories back to a given revision and get rid of all remnants of the bad changes.

I have been reading up on it, and I see how I can use 'git reset' with it's various options to move the head around and general get my working area back to the correct state, but I am unclear as to what this leaves in the respository and how to clean that up.

For example if I perform a bad merge in my local repository:

git checkout master git merge wrong_branch

I can reset in master to get back to the commit before that, but is the merge commit still sitting in the respository object database? Similarly, if it is sitting there and I push my branch to a remote repository, will it pass along the bad merge data?

It there some way to absolutely remote the bad merge commit (or any other bad revision) from my local repository to make sure I don't pollute the public repository with data that should be ignored as if it never happened?

Upvotes: 1

Views: 842

Answers (4)

gilligan
gilligan

Reputation: 508

The other answers already pointed out that you can use the reset feature to move the HEAD back to the commit before the commit occurred. Lets just have a run down with a tiny example. You want did work on a feature branch and want to merge it back into the master branch..

Merge & Reset Example

$ git log --online
695d21b add some content
9aefcac initial commit

Now you merge in the feature-branch ..

$ git merge --no-ff feature-123
Merge made by the 'recursive' strategy.
feature-123.txt |    1 +
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 feature-123.txt

However after looking at the changes you realize that you did not want to merge in this branch after all. No problem. The log output from before shows that the master branch was at 695d21b before - so just move the HEAD pointer back there:

$ git reset --hard 695d21b

The reflog

Now your working copy looks like it never happened. But since you were wondering if there is something still lingering in the repository from that merge - the commit object still remains in the repository:

ec4b538 HEAD@{2}: merge feature-123: Merge made by the 'recursive' strategy.
695d21b HEAD@{6}: checkout: moving from feature-123 to master
c08056a HEAD@{7}: commit: add feature 123
695d21b HEAD@{8}: checkout: moving from master to feature-123
695d21b HEAD@{9}: commit: add some content
9aefcac HEAD@{10}: commit (initial): initial commit

This list shows all the commits that HEAD pointed to at some point. Which is pretty cool because it what it means is that even if you screw something up there is pretty much always a way to get back to your last stable state.

Testing ..

Now if you still feel unsafe about some merge or other operation you are about to do, you could always just create a throw-away branch and try it there first. Of course this might technically not be necessary as I've just shown you, but it might be helpful because it doesn't really matter what happens in that branch. You can just get rid of it afterwards.

Pushing ..

If you move back HEAD like in the example above you don't have to be concerned about pushing trash to the public repo : 'git push' won't push anything beyond your current HEAD. What you need to be aware of though is that once you pushed something to a public repo you should not fiddle with the history locally anymore.

Maybe I got a bit too elaborate on this - hope it helped :)

Upvotes: 1

kubi
kubi

Reputation: 49354

Gitx has the best GUI for visualizing and resetting branches I've seen. If you need to reset a branch to a previous commit you just need to drag the branch icon to whatever commit would like to be current. I do most of my git work on the command line, but Gitx is invaluable for visualizing your history and cleaning up your branches.

OS X only.

Upvotes: 0

manojlds
manojlds

Reputation: 301037

First of all, if you are still learning git and are working on a project, have a backup( having a backup is good even if you are an expert, of course)

For the example that you stated, you can simply do:

git reset --hard ORIG_HEAD

to go back.

The merge commits will still be there, but it will be "dangling" and cleaned up sometime and you need not worry about them. They will not be pushed to another repository.

Also, git reflog is something that you should know and get familiar with.

Upvotes: 2

Adam Dymitruk
Adam Dymitruk

Reputation: 129526

As long as no references are pointing to it, it will get removed in 90 days. Unless you accidentally committed a very large file as part of that merge, I would not worry about it.

Upvotes: 0

Related Questions