5

This is similar to my another question ( Switch to another branch without changing the workspace files ) but solution that worked there, doesn't work now.

I needed to remove some changes, which were long time ago pushed to remote master. So I don't want to remove commits from master, but I want to change the files just like these changes were reverted. So I did this:

  1. While on master, git branch limits
  2. git checkout limits
  3. git rebase --interactive <commit before the ones I wanted to remove>
  4. in interactive console I removed the commits with changes I wanted to revert

So now in limits I have the code like I'd like it in master. How can I "move" it to master? With the code from limits I'd like to change to master branch, but without changing any file in workspace, so I can then commit the changes as a new change to master.

Community
  • 1
  • 1
amorfis
  • 15,390
  • 15
  • 77
  • 125
  • 3
    Isn't this situation what `git revert` is for? – Carl Norum Jul 13 '12 at 15:31
  • Yes, I didn't know it. Always good to learn something new. Nevertheless, still I'd like my question answered :) – amorfis Jul 13 '12 at 15:34
  • @CarlNorum `git revert` is the correct answer here, i'd upvote it if you post that answer. Interactive rebase here would change history and there's no need for that, and we all know changing pushed history isn't a good idea. – KurzedMetal Jul 13 '12 at 15:39
  • I was using my iPad when I made that comment; I'm happy to cede the rep to those who had the time and energy to write a better answer. – Carl Norum Jul 13 '12 at 21:51

4 Answers4

6

The answer to your stated question is:

$ git checkout master             # switch to master branch

$ git reset --hard limits         # hard-reset it to the limits commit
$ git reset --soft master@{1}     # move the reference back to where it was, but
                                  #  don't modify the working tree or index

This will leave your working tree and index exactly as it would be if you had limits checked out, but you will be on the master branch at its original location.


However, the proper way to do something like this would be to git revert each change that you are trying to undo.

vergenzt
  • 9,669
  • 4
  • 40
  • 47
5

Rather than use interactive rebase, you can just revert each commit that you don't want. When you use git revert <object-name-of-commit>, git will introduce a new commit that backs-out the change introduced by the one you name. So, suppose that the commits you want to remove are abc123 and def456, you can just do:

git checkout master
git revert abc123
git revert def456

However, if it was a lot of work to find those commits, and you're happy with the tip of limits, you can just create a new commit on master that contains the state of the tree from there. Firstly, make sure that git status is clean, since you're going to use git reset --hard, and that will wipe out uncommited changes:

git checkout master
git reset --hard limits
git reset --soft HEAD@{1}
git commit -m "Reverting unwanted commits"

That recipe is a variation of one in this question:

Community
  • 1
  • 1
Mark Longair
  • 446,582
  • 72
  • 411
  • 327
  • Thanks. What does `HEAD@{1}` mean? – amorfis Jul 13 '12 at 20:00
  • 1
    git keeps track of the history of where each ref is with something called the "reflog" - `foo@{n}` means roughly "the position of the ref `foo` as it was `n` changes ago". If you want to look at the reflog for `HEAD`, just do `git reflog`, and you'll get the idea. Note that this tracking of the position of particular refs is completely orthogonal to the history represented by the commit graph, into which the refs point. – Mark Longair Jul 13 '12 at 21:57
  • Just for the record: IIRC, drastic `HEAD` movements also save the original state in the `ORIG_HEAD` ref so possibly it would also work instead of `HEAD@{1}`. – kostix Jul 15 '12 at 20:30
1

This asks for revert :-)

I would go back to master and git-revert each of the commits you want to unapply. This creates a "unapplying" commit for each - so no history changes, but you get the effect you wanted.

Konrad 'ktoso' Malawski
  • 13,102
  • 3
  • 47
  • 52
0

Move Branch Pointer

If what you actually are trying to do is to move your branch pointer for master after a complex rebase or merge in a separate branch, you can do that in a variety of ways. For example, to forcibly move some interim branch so that it becomes your new master branch, you can do one of the following:

# Use git porcelain to move the branch over top of one that already
# exists.
git branch -M limits master

# Explicitly move the branch pointer to wherever the head for limits
# is pointing.
git reset --hard refs/heads/limits

There are also ways you can do this various plumbing commands, but this isn't meant to be an exhaustive treatise. It should be enough to get you pointed in the right direction.

Reverting Commits

As other posts and comments have correctly pointed out, if all you want to do is to undo targeted commits from master, then you can use git-revert(1). Note that this leaves both the original commits and the reversions in your history; this is usually what you want.

Also, please note that git-revert may cause conflicts or undesirable changes that you will have to manually resolve, especially if the commits you are reverting were not small, atomic changes. Think of git-revert as a reverse patch (which it fundamentally is, under the hood), and you can see where potential conflicts could arise.

Your mileage will certainly vary.

Todd A. Jacobs
  • 81,402
  • 15
  • 141
  • 199
  • I know stash, but it is for uncommited changes. I don't have any uncommited ones. – amorfis Jul 13 '12 at 15:35
  • 1
    He wants to basically throw away `master` and replace the contents with `limits`. Not just apply changes. – Shahbaz Jul 13 '12 at 15:35
  • @Shahbaz It wasn't clear from the original question. The question as posed still talks about moving a rebased branch onto master, so I'm going to leave my answer, but I think that `git-revert` is the correct solution for the *underlying* objective. – Todd A. Jacobs Jul 13 '12 at 15:56