Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Steps to move a commit from one branch to another as changes

Tags:

git

Normally if I make changes in a branch and realize I meant to do it in a different branch, then I can simply stash the changes and then checkout the branch I want.

How do I effectively accomplish the same thing if I've already committed locally (but not pushed to remote)?

I want my local branch to be as though I never made any changes... in particular I don't want to have to push two commits (one with the changes, and one that reverts the changes). I just want the commit to go away as if it never happened. And when I checkout the branch I want, I want my changes to be there... or I want to be able to restore them (as changes, but not as a commit, obviously).

I've done some searching and the answers I've found primarily focus on the first case I mentioned where changes weren't committed. It's very possible I've run across the exact answer I need, but didn't realize it because I wasn't 100% if the scenario was the same as mine. So obviously I'm a bit new to git and I'm sure this has got to be a duplicate question, but maybe I am just having trouble identifying which existing questions are the duplicates with confidence.

Also I tagged vs 2017 and 2019 because I use both and welcome any answers that explain how to do this through the IDE in either of those versions in additions to how to accomplish this in a shell.

This particular commit is the only one. Though I am interested to hear solutions for both scenarios (this one, and one where I had other valid commits).

like image 636
BVernon Avatar asked Nov 30 '25 12:11

BVernon


1 Answers

Things to keep in mind:

  • Git traffics in commits. Not changes. Not files. Commits.

  • A branch is just a label for one commit.

  • You can move a branch, attaching it to any commit you like, with git reset.

Let's start with a two-branch situation:

% git log --oneline --all --graph
* 102fa13 (br) z
| * 7e0ddf5 (HEAD -> master) d
| * 3a460a5 c
|/  
* e7547cb b
* 0bcb421 a

So I regret that c and d were made on master; I wish they had been on some other branch. So I can think of two main scenarios here. Does that other branch already exist or not?

If not, then simply make the new branch here (where master is now) and slide master back down to before c:

% git branch newbranch
% git reset --hard e7547cb

Result:

% git log --oneline --all --graph              
* 102fa13 (br) z
| * 7e0ddf5 (newbranch) d
| * 3a460a5 c
|/  
* e7547cb (HEAD -> master) b
* 0bcb421 a

That's the easy case. The harder case is that the other branch already exists: let's say it's br in the first graph above. Then rebase the c and d commits onto br. After that, reset br up to where master is now, and then slide master back down to where it was before c:

% git rebase --onto br e7547cb master
% git switch br
% git reset --hard master
% git switch master
% git reset --hard e7547cb

Result:

% git log --oneline --all --graph
* f9ff4a0 (br) d
* 5c43690 c
* 102fa13 z
* e7547cb (HEAD -> master) b
* 0bcb421 a

Note that the d and c commits here are copies (they have new unique ids); that's inevitable when you move commits around, as commits themselves are immutable.

like image 83
matt Avatar answered Dec 03 '25 13:12

matt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!