简体   繁体   中英

Merging part of git branch into master

I have a simple branch with multiplpe changes:

Master ---A---B---C
                   \
              Foo   E---F---G---H

Now I need to merge into the Master only a part of my changes. I am new to git ( currently using it with SourceCode on Windows ), and was thinking of doing it like this:

Master ---A---B---C---?---J---?---?---
                   \     /
              Foo   E---G'
                         \
                    Bar   F'---H'---

I need only certain parts from the branch. I've been working on 4 different manufacturer APIs to implement. Now, only 1 needs to go in production and the rest are on hold. Let's say there are total of 19 files modified, but I only need 7 of them. Now, I need to split those 7 away, synchronize with the master and push as a different branch, so that the CTO can merge them into Master later on.

Is that the way to do it? And how do I do it correctly?

If we breakdown your problem, you need to:

  1. Split 4 (E,F,G,H) commits from Foo into 2 branches, Foo will have only: E, G, but Bar will have all 4, E -> G -> F -> H.
  2. Remove some commits : ie on Foo, remove commit F and H.
  3. I am not sure if you want to "Re-order" the commits on the branch Bar, ie have E,G,F,H --> I am assuming this solves no purpose, so I will leave it out of my answer.

There are many ways of doing it, but I will keep it to the simplest flow that I can think of, since you are new to git. so, let us look at splitting the branch:

From your current Foo (head = H) do git checkout -b Bar This will create the branch Bar with commits E, F, G, H

Now, there are two ways you can reset your Foo branch:
#1 Discard Foo and re-create it git branch -D Foo (to delete from local) git push origin :Foo (to delete from remote, if you have already pushed it)

Then you need to create a new Foo from commit "C" of your master:

git checkout -b Foo <CommitIdShaForC>

Then you can cherry-pick commits E and G either from git gui by doing gitk Bar and then right clicking on the commit and choosing cherry-pick, or from console by:

git cherry-pick <Commit Id for E> <Commit Id for G>

In case of merge issues, look at this answer

#2 Revert commits from Foo If you don't mind having history of F and H in your foo, you can simply revert them in git, essentially git creates a reverse patch of your commits F and H and applies them as new commits:

  • You are on branch Foo and it has E -> F -> G -> H
  • git revert F
  • Your branch should now show E -> F -> G -> H -> F' where F' is undoing what the commit F added
  • git revert H would lead to: E -> F -> G -> H -> F' -> H' whose end result in the source code would be: same as having only commits E and G.

Alternatively still, you can use the --no-commit flag on git revert to revert both F and H in 1 commit:

git revert --no-commit F
git revert --no-commit H
git commit -a -m "reverting commits F and H"

This would lead to:

E -> F -> G -> H -> I where I is the commit which undoes F and H

#Update 1 After writing a lengthy answer, I see that OP wants to have "part of the commits" into few branches. For this case, I would highly recommend an interactive rebase so that the commits can be split. Please refer to the official documentation about git rebase, in particular the section about "Splitting Commits". Also, I think you will find this question particularly helpful

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