tags:

views:

246

answers:

5

I started playing with git on my new project and I had a bunch of separate branches and I just wanted to merge them as each of them were an update to different parts of the program and I guess I was supposed to merge them but I run a "git commit -a" after cheking out each branch and then I realized the whole program went back in time and then I read an article hear that said run "git reset --soft HEAD^ and that didn't do anything, I also got this message from git about manually removing some ./git/index.lock so I moved it to ./git/backup_of_index.lock and now I am hopeless! Please help!

+2  A: 

Mistakes: 1. "I started playing with git on my new project" 2. "I just wanted to merge them as each of them were an update to different parts of the program"

You should not be playing with unfamiliar territory when your code means something. If you wish to do this, at least have a fall back plan.

Disaster recovery seems is only important to those that need it the most but at that point it is too late.

I am all for experimentation but I hate seeing this type of situation, I feel bad for the developer as I know his shoes all too well however after you learn this mistake once you will never forget it.

Before you decide to play, take your code and toss it somewhere else so when sh*t hits the fan you can go back to your comfort zone and continue working as a happy developer and go back to playing after you get your work done.

Chris
While I agree with your points, this is not an answer to the question. It should be posted as a comment (although I'm aware that comments can't accommodate this much text).
Jeff
I originally started typing in the comment and ran out of room. :-/
Chris
+1  A: 

Git is great, and you really should know how to use it from the command line. However, when it comes to branching/merges/pretty much anything aside from simple commits and pushes, I am much more comfortable using a good GUI. If you are on windows, I would strongly suggest "Git Extensions". Oddly enough, there isnt a good all in one solution on linux, but plain old git-gui and giggle get the job done for me.

jdc0589
While I agree with your suggestions, this is not an answer to the question. It should be posted as a comment.
Jeff
oops, actually meant to post it as a comment
jdc0589
+4  A: 

Unless you have hacked at the data in the .git directory, it is unlikely that you've lost anything. You may have a terrible mess to clean up, and it may take a lot of working out what you did and where it is, but you probably haven't lost anything.

That's the good news.

The bad news is that it is going to be fiendishly difficult for anyone to help you much.

You are likely to need to identify all the branches, and trace backwards the commits on each. You'll need to decide whether all those 'git commit -a' operations were a good idea. It sounds unlikely - so you may need to do your merges properly, working from the next to last commit on each branch.

You also need to decide what you were really trying to do.

It sounds like you wanted to merge some number of branches - call them BranchA, BranchB, and BranchC - onto the main branch, master. But it is not clear that is what you tried.

Given that things are something of a mess, I recommend creating another branch which we can call 'Fixup'. Create this from the head of the master branch. Then, merge the appropriate version of each of BranchA, BranchB and BranchC into the Fixup branch. At each stage, check that the code actually works correctly - passing its test suite, etc. Check in each merge separately on the Fixup branch.

When you are satisfied that the Fixup branch is correct, switch back to the master branch and merge the Fixup branch to master.


Charles Bailey makes the very sensible suggestion (in a comment to the question): before you do anything else, make a backup copy of what you've got, exactly as it currently is. Only then proceed with any cleanup operations. And his suggestion to get interactive help is also sensible.

Jonathan Leffler
+9  A: 

The most important git command in this situation is git reflog. The reflog tracks all changes to each particular branch head, and the git reflog command lists all of the changes to the branch head going back in time.

If you can identify a "good" commit id using the reflog (and it will be there, somewhere), then you are way ahead of where you are now. If a good commit id is say, abc123, then the command:

git checkout -b rescue abc123

creates a new branch called rescue at the commit id abc123.

When I was learning git, I had a similar sort of "where the heck am I and how did I get here?" moment. I learned about the reflog on a different Stack Overflow question, and it's been the most valuable thing to know about Git.

Greg Hewgill
I second this comment as the one you should pay attention to Jonathan. Run `git reflog` (or `git log -g` to get the same information with some more data), find the last commit that was good and checkout a branch at that point.
Scott Chacon
Also, there is a bit of documentation on a situation like this here: http://progit.org/book/ch9-7.html#data_recovery
Scott Chacon
I was coming in here to say "reflog!" just from the title of the question alone.
masonk
unfortunately I already listen to someone else and reset the head so when I run git reflog, the head{0} is already after the mess
jsd911
@jsd911: That's fine. Resetting the head doesn't delete the reflog or anything. The reflog keeps track of each change to the head of your branch. It remembers them all, so whenever the branch changes, the *previous* value is stored at the top of the reflog. Looking at the reflog is a walk back in time that contains every change to your branch. So if your branch at some point in the past contained a "correct" commit id, then it will be in the reflog.
Greg Hewgill
A: 

One of the awesome things about Git is that you can easily duplicate your entire working repository. This allows you to preserve a backup copy while you experiment with branching and merging.

My suggested approach for resolving your current issue:

  1. Create a backup copy of your entire repository
  2. Experiment with throw-away copies of the repository
  3. Each time you screw up a throw-away repository -- throw it away and start over with a new copy from your backup
  4. Eventually, you will begin to master repo hacking -- you will have recovered your work, and you will feel good about what you've learned

Also, I hope you are using gitk (or similar) to review the effects of your changes -- it can really help you to visualize the different lines of code and how they are related.

gitk --all ## show me all the branches
nobar