简体   繁体   中英

How can I move commits from the trunk to a branch in Git?

I made a bunch of commits to the master and realized after the fact that they should have been in a branch.

I've looked at various things about rebasing and merging and resetting the master. But no attempts at manipulation have yielded a history that looks like what I'm trying to do.

My attempts lead me to believe it requires some combination of rebase --onto and reset --hard to move the master back in time. But my understanding of Git's branching leaves something to be desired. Part of doing this is to learn how I can use it.

Should be noted none of the changes that I'm trying to move have been pushed out.

Current

  * remote/trunk
--o--a--b--c--d--e--f     <- master
  |
  o                       <- remote branch foo

Desired Outcome

  * remote/trunk
--o                       <- master
  |
  o--a--b--c--d--e--f     <- remote branch foo

A variation on Martin's answer that won't necessarily be applicable to your situation, but I wanna post it anyway :)

Suppose you forgot to create the branch at commit o , so you have:

x--y--z--o--a--b--c--d--e--f  master
         |
         +
   [forgot to make a branch here]

And then you realized that what you really wanted was:

x--y--z--o   master
         |
         +--a--b--c--d--e--f  topic

What you can do in this case is create a branch at o using it's hash:

git branch topic # creates new branch 'topic' - will be at commit `f`
git checkout o -b newmaster # creates new branch called newmaster pointing on commit `o` (please replace `o` with the actual hash)
git branch -M newmaster master # force rename newmaster to master (means master points on hash `o`)

You'll be at the master branch (commit o ), so as a last step you can:

git checkout topic

The hash of course can be just the first 5 characters ..

EDIT

It shouldn't matter much that you're using git-svn , what really matters is that you haven't published your master branch at any point after o

A branch in git is really nothing but a pointer to a commit. That's why branching is so cheap: you just create a pointer, and you have a branch.

I don't know about tracking remote branches though, you might need to set that up after renaming/moving your branches.

I am not sure renaming the branches is the right solution, since it would get you from:

  * remote/trunk
--M--a--b--c--d--e--f     <- master
  |
  F                       <- remote branch foo

to:

--F                       <- master
  |
  M--a--b--c--d--e--f     <- remote branch foo
  * remote/trunk

(provided you rename remote/foo , which is not advisable: you should track it first, and then rename it, but even though the end result differ from what you need)

which is not the "Desired Outcome" you want (foo needs to start from F, not M):

  * remote/trunk
--M                       <- master
  |
  F--a--b--c--d--e--f     <- remote branch foo

You can only achieve that through a rebase --onto

git checkout --track -b origin/foo  # create a local branch named after the remote one
git branch tmp                      # mark current foo HEAD to 'F'
git branch -f foo master            # put foo where it should b: at 'f'
git branch -f master tmp^           # reset master to M, parent of tmp
git checkout tmp                    # go to where we must replay the commits
git rebase --onto tmp master foo    # replay a to f on top of tmp
git svn dcommit                     # push the local foo in order to update remote/foo

giving you:

  * remote/trunk
--M                             <- master
  |
  F--a'--b'--c'--d'--e'--f'     <- local foo and remote branch foo

Nearly correct what hasen j suggests, but I had to make a few small modifications (and I use git-svn):

# create the branch with your commits
git branch performance
# fork the master to a new branch at the commit before your local, non pushed commits
git branch newmaster 2d0516dfe8252de87
# checkout your branch 
git checkout performance
# rename the newmaster
git branch -M newmaster master
# now checkout the master
git checkout master

You can't rename a branch you are on, so I checked out the performance branch where I moved my commits.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM