0

I have some commit in my local repository. In remote server, someone commits more.

How to discard my local commit? (But retains the commits)

I think I need to use git reset or git rebase or git checkout? or something like git revert?

I am really confused about those commands.

BJ Myers
  • 6,617
  • 6
  • 34
  • 50
Adam Lee
  • 24,710
  • 51
  • 156
  • 236

2 Answers2

1

Assuming you have already commit your changes then I would use rebase (unless you're still working on your changes, then you might want to keep them in your local copy).

Rebase will compare two branches and will pop off the changes of your current branch (e.g. your local changes), pull the other branch (e.g. the remote), and replay your changes on top one-by-one

Rebase works when you've already commit your changes. For example,

master: A - B - C

origin/master: A - B - D

Rebasing master on origin/master turns this into

master: A - B - D -C

There is a convenience option for this with git pull

git pull --rebase

I tend to also like to use interactive rebase a lot which gives you more flexibility allowing you to rename commits, reorder them, squash them into other commits, etc.

git rebase -i origin/master

One caveat with rebase is that it will recreate all of the commits it rebases. This means they will all get new SHA's and that Git won't recognize them as the same commits

EDIT:

If you don't want to rebase then you should be able to use reset.

git reset <commit>

In the below I add a "bad commit" and want to rollback my log while keeping the changes from bad commit in my working copy. I use the HEAD~1 alias, but you could also give it a SHA.

Bodah@jbodah-local 2.1.3p242 ~/repos/spy_rb (master) $ git log origin/master -1
commit 8fd6a1a7704d2c0dc1323c4d8e5e169c169c833c
Author: Josh Bodah <jb3689@yahoo.com>
Date:   Thu Dec 18 17:55:14 2014 -0500

    generate tags in change_version
Bodah@jbodah-local 2.1.3p242 ~/repos/spy_rb (master) $ git log -2
commit b925445207000905d535e715a06d312ca65be5c1
Author: Josh Bodah <jb3689@yahoo.com>
Date:   Tue Dec 30 09:31:36 2014 -0500

    bad commit

commit 8fd6a1a7704d2c0dc1323c4d8e5e169c169c833c
Author: Josh Bodah <jb3689@yahoo.com>
Date:   Thu Dec 18 17:55:14 2014 -0500

    generate tags in change_version
Bodah@jbodah-local 2.1.3p242 ~/repos/spy_rb (master) $ git log origin/master -1
commit 8fd6a1a7704d2c0dc1323c4d8e5e169c169c833c
Author: Josh Bodah <jb3689@yahoo.com>
Date:   Thu Dec 18 17:55:14 2014 -0500

    generate tags in change_version
Bodah@jbodah-local 2.1.3p242 ~/repos/spy_rb (master) $ git reset HEAD~1
Unstaged changes after reset:
M   README.md
Bodah@jbodah-local 2.1.3p242 ~/repos/spy_rb (master) $ git log -1
commit 8fd6a1a7704d2c0dc1323c4d8e5e169c169c833c
Author: Josh Bodah <jb3689@yahoo.com>
Date:   Thu Dec 18 17:55:14 2014 -0500

    generate tags in change_version
Bodah@jbodah-local 2.1.3p242 ~/repos/spy_rb (master) $ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   README.md

no changes added to commit (use "git add" and/or "git commit -a")
Josh Bodah
  • 1,223
  • 6
  • 17
  • Basically I just want to revert the last commit; but keep the commit, say, create a new commit which rollback the last commit? do I need to use rebase? any convenient command? – Adam Lee Dec 30 '14 at 14:30
  • Really good answer. I need to use rebase first; then I should use revert since I still need to save commit. – Adam Lee Dec 30 '14 at 14:50
  • I will not accept either one since I need the combined solution. – Adam Lee Dec 30 '14 at 14:50
  • Rebase will leave your commit in the tree, it will just put other commits in front of it (see diagram). So it changes the "base" of your branch. It does so by inspecting the common commits (again checking common SHA's) and putting all of the foreign commits before yours, generating new SHA's for all of your commits – Josh Bodah Dec 30 '14 at 15:17
1

Use

git revert {commit hash}

You can use git log to find the commit hash (it's the string of letters and numbers). This will "revert" (works like undo does in notepad) your commit, but leave it intact. Later, someone might want to revert your revert, so it's good to leave it.

Someone else posted about

git reset --hard {commit hash}

This is probably not what you want. This will remove all commits AND the changes to the files beginning at HEAD down to the {commit hash} provided.

git reset --soft {commit hash}

A "soft reset" will remove all the commits, but keep the changes to the files. You can then do something really ugly like recommit the entirety of your reset. Again, probably not what you're looking for.

Kyle
  • 181
  • 7
  • Actually, the best way to discard commits is probably `git reset --keep {commit hash}`, which discards the commits but keeps the uncommited changes. – Matthieu Moy May 04 '15 at 06:29