-4

EDIT: This questions is not "how to revert to a previous commit".

Let's say my master looks like this:

A B C D

Let's say I want to push commit B to the origin/master without resetting it and losing commit C and D.

This is what I get with a normal git reset --hard, but like I said I lose any commits after B so that's no good:

A B

Instead, I want the commit chain to look like this:

A B C D B

Is this possible? Put it other words, I want to make the local files match commit B and then committing them, without resetting the chain. The new commit will technically be commit E but it's files will be identical to commit B.

Since this will be run by an automated script I don't want to use branches, potentially creating a crow's nest.

Sarke
  • 2,805
  • 2
  • 18
  • 28
  • If I understand you correctly, you want to revert changes made in `C` and `D` but don't want to delete these changes. Something like this. `A B C D D' C'` (where ' refers to revert commit). If this is the case, use git revert then git revert . This is equal to `A B` with changes of `C` and `D` are available in the history. – Royal Pinto Feb 14 '16 at 07:09
  • @RoyalPinto thanks, but reverting it's a good option either, since it can create really long chains as well (e.g. what if we're reverting 20 commits?). – Sarke Feb 14 '16 at 07:27
  • re committing B wouldn't revert changes of `C` and `D` unless changes in `C` and `D` are exactly equal to the reverse of changes in B. You would have to either revert or delete `C` and `D`. – Royal Pinto Feb 14 '16 at 07:34
  • sorry, I meant to type "*isn't* a good option" – Sarke Feb 14 '16 at 07:41
  • 1
    Maybe this is what you are looking for: Push a single commit: http://stackoverflow.com/questions/1789017/git-push-a-single-commit – Igal S. Feb 14 '16 at 07:49
  • Possible duplicate of [Checkout old commit and make it a new commit](http://stackoverflow.com/questions/3380805/checkout-old-commit-and-make-it-a-new-commit) – Jeremy Fortune Feb 14 '16 at 17:25
  • Possible duplicate of [Revert Git repo to a previous commit](http://stackoverflow.com/questions/4114095/revert-git-repo-to-a-previous-commit) – Andrew C Feb 14 '16 at 18:39

1 Answers1

0

I think I might have found a solution to this. In searching for a solution, I found that this can also be considered "how to commit a detached head". Which is generally considered bad and git doesn't want you to do it, because you would be obliterating any other commits by other people.

However, since no one is pulling from this repo and making changes, there won't be any risk of overwriting anyone else's work. The only pulls are automatic from web servers.

So the steps are:

git reset --hard master get rid of any uncommitted changes that would trip up the script.

git checkout B this changes the files to the correct commit.

git reset --soft master this changes the HEAD to master, but leaves the files like they were in commit B

git checkout master this solves the "detached HEAD" issue by getting us back to the tip of the tree, but since the previous command already put us back there, no files are changed.

At this point we can add and commit like normal, and git will make the commit patch in essence from commit master to B.

I'll have to do some more testing to make sure that this works as I expect it to.

Sarke
  • 2,805
  • 2
  • 18
  • 28
  • If you wish read this about the head. might give you some more ideas, http://stackoverflow.com/questions/34519665/how-to-move-head-checkout-revert-reflog-reset/34519716#34519716 – CodeWizard Feb 14 '16 at 07:48
  • This way (answer) would leave commit `C and D` in a separate detached branch and master branch would have just `A B`. – Royal Pinto Feb 14 '16 at 08:33
  • Sarke, this answer is correct for what you want to do. But I am curious as to *why* you want to do this? Depending on your use case, I suspect there are changes to your workflow you could make that would be more optimal. – David Deutsch Feb 14 '16 at 16:46
  • @RoyalPinto No, this way creates a new commit and there are no detached branches. – Sarke Feb 15 '16 at 09:44
  • @DavidDeutsch I'm using it like snapshots to be able to revert to a specific version of a website. – Sarke Feb 15 '16 at 09:44
  • @Sarke, it will create a branch without a name. use `git log --graph` and you should see a small branch without name. – Royal Pinto Feb 15 '16 at 09:48
  • @RoyalPinto as far as I can tell his answer is correct. What do you mean by a branch with no name? I do not believe that is even possible. – David Deutsch Feb 15 '16 at 11:03
  • @Sarke, one thing to watch out for is that you will probably get a lot of conflicts next time you merge your develop branch into `master`. Perhaps a better approach is to checkout `B` on your web server, if possible. Or maybe get some deployment software instead of automatically publishing `master` or something. – David Deutsch Feb 15 '16 at 11:12
  • @Sarke: The answer will work but since you did not want to create a branch, I commented saying this would create a detached anonymous branch. I was referring to Section `DETACHED HEAD ` at `http://git-scm.com/docs/git-checkout`. Which will be deleted by the routine Git garbage collection process. – Royal Pinto Feb 15 '16 at 13:42