2

I know Git has tons of documentation and there are tons of posts on SO about it (I've looked at How to delete a 'git commit' and this, for example) but nothing has worked yet and I'm not sure what to do here.

I have a repo that so far only I'm committing to, but I recently started working from two different laptops and somehow I accidentally pushed some nonsense that Git saw as a merge and then I pushed the latest changes as well.

I've been trying to figure out how to delete those last 2 commits completely, rewinding the repo to the state before that fateful day (as I now have a bunch of new commits I need to get into that repo). If you're willing to give me any pointers, note that the repo is hosted on github here.

Community
  • 1
  • 1
rsaw
  • 3,315
  • 2
  • 28
  • 30
  • 2
    Have you see [this question](http://stackoverflow.com/q/448919/912144)? – Shahbaz Jul 29 '12 at 21:25
  • Is there any reason that the merge representation is wrong? If you made concurrent changes on two different machines, a merge is arguably the correct representation. – cdhowie Jul 29 '12 at 21:25
  • @cdhowie: Many people prefer merges to have actual semantic meaning within the history. The OP probably prefers rebase. – Lily Ballard Jul 29 '12 at 21:26
  • @KevinBallard To me, "changed stuff concurrently and then brought the histories together" *is* the semantic meaning of a merge. :) – cdhowie Jul 30 '12 at 20:35
  • 1
    @cdhowie: Git history should be revisionist. It doesn't matter what literal steps you took to produce it, it matters what meaning the history has. If I work on a separate feature on a branch and merge it in, that's a meaningful merge. If I make two once-off changes on separate computers and want to reconcile that, there's no meaningful merge there so it should be a rebase. – Lily Ballard Jul 30 '12 at 21:31
  • @KevinBallard I've always seen the choice regarding when to merge or rebase as more of an art than a science. I prefer to keep my history in terms of "what really happened" so in exactly this scenario, I usually prefer merges. – cdhowie Jul 30 '12 at 21:34
  • @cdhowie: To answer your question that spawned this discussion ... Firstly, the merge didn't work -- I don't know what it did, but it completely screwed everything up and it required me to just bring in a backup file and push that as a second commit (to fix it). Secondly, if the merge hadn't produced garbage, it still would have been bad, as what I really should have done was `git pull`, make my changes, and then push the updates. I just screwed up. – rsaw Jul 31 '12 at 06:03

4 Answers4

2

for someone new, the easiest thing to do instead of git reset --hard HEAD^, is to use gitk --all.

This way you see all your history. The current branch is in bold. You can right-click the commit that you were on before and select "reset current branch here". You will be prompted for what kind of reset to perform. Select "hard" and you should be back to where you want to be.

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
1

In order to delete the most recent commit, just use git reset --hard HEAD^. If the most recent commit is a merge, this will revert back to the first parent (i.e. the state before the merge/pull was run).

If you can identify the exact commit that you wish to be the tip of the branch, you can use git reset --hard $SHA where $SHA is the commit in question.

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • Thanks for responding Kevin. I still haven't been able to get it to work. What do I do after `git reset --hard HEAD^^`? – rsaw Jul 29 '12 at 22:24
0

This worked for me (by memory):

git reset --hard HEAD^^
git push --force HEAD:master
git pull
shkschneider
  • 17,833
  • 13
  • 59
  • 112
  • Thanks for taking the time @shkschneider, but I must be missing something about that push command as it fails -- ssh seems to think `HEAD` is a hostname. – rsaw Jul 29 '12 at 22:25
  • Strange... Then try `git push --force HEAD^^:master ; git reset --hard HEAD^^ ; git pull` – shkschneider Jul 30 '12 at 08:22
  • 1
    should be `git push --force origin master`. You have reset master to the desired commit locally. Now you have to force-push the new master reference to the remote (usually called origin). – patthoyts Aug 07 '12 at 07:52
0

Thanks to an answer in the question Shahbaz posted, I initially tried

git push -f origin HEAD^^:master

which appeared to remove the last two commits perfectly. But as soon as I made some changes to the local files and did a push, the old commits showed back up! :(

After trying it again, this time with HEAD^^^ (since I now needed to remove the last 3 commits), I looked at git log and saw that everything was still there locally. Ignorant as to how to resolve this, I just wiped out the local directory, re-cloned the repo, and manually copied in my newly-modified files. Finally, adds and pushes didn't bring back the old unwanted commits.

Obviously, I'm sure there's a better way, but I wasn't able to make it happen by following you lovely peoples' suggestions. (Example: I tried doing git rebase -i HEAD~4 but I didn't understand the output I got in the editor -- it gave way too many lines (9) and I didn't know what to do.)

I'll leave it to someone more experienced to decide if this question should be deleted as a duplicate.

Community
  • 1
  • 1
rsaw
  • 3,315
  • 2
  • 28
  • 30