简体   繁体   中英

Move git commit to new branch

With git I committed some changes and now would like to have them in a new branch. How to acchieve this is explained in several places, for example here

My confusion is more related to the local/remote aspect of this task.

I started by forking a repository on github to myForkOnGitHubRepo. Then I cloned that repository to my local PC:

local: git clone myForkOnGitHubRepo

Then I changed the source, commited and pushed:

local: git add .
local: git commit
local: git push # (actually I used the minGW Gui for that one since the command line push issued a warning)

Now my local changes are visible in myForkOnGitHubRepo. Fine. And now I note that I would have preferred to use a new branch (and to have the change in that new branch at myForkOnGitHubRepo, too).

Is it correct that I can just follow the instructions in the link I posted in the beginning, ie

local: git branch newbranch
local: git reset --hard HEAD~1 # only one commit was done

and then -- well, now what? Do I just have to push again? Or do I need to push the new branch explicitly? (Sorry if that's very basic, I never used this before).

And is there anything else I need to do before creating the newbranch? My understanding is that, after the push, local and remote are in the same state, is that correct?

local: git branch newbranch
local: git reset --hard HEAD~1 # only one commit was done

Now, do force(-f) push to remote/master as git history is changed.

$ git push -f origin master

Checkout to newbranch and push newbranch also.

$ git checkout newbranch
$ git push origin newbranch

  • Common scenario is master branch should keep working or not broken. So, when need to work on a new feature, create a new branch(say, feature ) from master .

     $ git checkout master $ git checkout -b feature 
  • Work on feature branch. When done with feature branch add , commit and push to remote.

     $ git add. $ git commit -m 'message' $ git push origin feature 
  • Now, if all test is ok with feature branch then create Pull request or merge with master

     $ git checkout master $ git pull origin feature # pull = fetch + merge $ git push origin master # update remote/master 

My understanding is that, after the push, local and remote are in the same state, is that correct?

Yes, when you push to remote, your local & remote are in sync (same data)

Now, if you need the changes/commits of feature branch (assume feature is not merged with master yet) in another branch (say, dev ) then, just create a branch ( dev ) from master and pull feature branch into dev

$ git checkout master
$ git checkout -b dev

$ git pull origin feature     # pull 'feature' into 'dev'

# do changes here

$ git commit -am 'Added new feature'     # add & commit
$ git push origin dev

If you have already pushed the branch to remote with the commit, then simply create a new branch out of it and push it to remote, as:

$ git checkout -b newbranch
$ git push origin newbranch

But, if you created a branch directly from forked branch or from the branch which does not have commit you want to push then cherry pick the commit into your new branch using commit id and push it to remote.

$ git checkout branch
$ git log // look for commit id you want to move to another branch
$ git checkout newbranch
$ git cherry-pick <commit-d>
$ git push origin newbranch

My understanding is that, after the push, local and remote are in the same state, is that correct?

Yes , as long as you are not modifying these files: .gitignore , .git/info/excludes and ~/.gitexclude to avoid content to push to remote.

Is it correct that I can just follow the instructions in the link I posted in the beginning, ie

 local: git branch newbranch local: git reset --hard HEAD~1 # only one commit was done 

Yes.

and then -- well, now what? Do I just have to push again?

Yes. Moreover, you must push two branch names, and one of them needs a "forced push".

Or do I need to push the new branch explicitly? (Sorry if that's very basic, I never used this before).

While it's basic, there are a bunch of historical issues here. Git used to behave differently by default, and that behavior was wrong for most users. Git had options to override the default, but the default was wrong. So the default behavior changed in Git version 2.0. To get there, Git added a whole heap of configuration items, so that you can set the default behavior, if you liked the old behavior, and now we have to talk about the "default default behavior": ie, what Git does if you don't set your own default.

I'm going to assume you did not set a lot of fiddly Git configuration knobs, so you are getting the default default. (I think this is the case because of a detail you mentioned: using minGW GUI.)

Assuming your Git version is at least 2.0 , you would typically do this in two steps. (Because Git is what it is, you can do it all in one, in any version of Git, but let's do it in two.)

You didn't mention the name of the old branch ( master ?) so I've used oldbranch below, but you'll need to use whatever the actual name is.

git push -u origin newbranch
git push -f origin oldbranch

You can actually do these in either order.

The first command, git push -u origin newbranch , has your Git call up another Git at origin and deliver to them the new branch name, and any new commit(s) that go with it if they need them. The -u flag means: "I am pretty sure this is a new branch for you; please create or update your newbranch , making your branch match mine, and then I'll make mine have yours as my upstream ." (See other questions for more about "upstreams".) Since this branch really is new to them, they will obey your polite request, creating the new branch with the one commit specific to that branch.

(That one commit points back to all the old commits on the old branch, so those commits are now on both branches, in both your Git repository, and the one at your remote.)

The second push, with -f or --force , tells your Git to call up the other Git again, and tell it (rather than politely asking it) to move its oldbranch back to where you moved yours back to.

We have to force this push because they will normally say "no" to the more polite request, because that loses the new commit . But you want to toss the commit from the old branch.

(If someone else is sharing your fork on the remote, this step is slightly dangerous, because you're telling their Git to toss all new commits, including any that the other sharers might have pushed.)

For your questions:

  1. The two commands ( git branch newbranch and git reset --hard HEAD~1 ) you mentioned is quite efficient to meet your requirement (move the latest commit from master branch to newbranch).
  2. Since you make changes both for master (reset) and newbranch, so you should push both of them:

git push -f origin master git push origin newbranch

  1. Before creating the newbranch you should switch to master branch ( git checkout master ) if you have more than one branch locally. And yes, after push, local and remote state are same.

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