简体   繁体   中英

Merging branch and sub-branch back to master

I have limited knowledge of git.

I have created a branch B1 from master, made some edits and committed to this branch.

I want to create another branch B2 from B1, I make some edits in B2

And I also want to commit and push B2 (with edits from B2 and B1) back to master

How do I do this, the documentation assumes you are always creating a branch from master , not another branch. I apologise for my git stupidity.

tayfun's answer is fundamentally correct. If you want more conceptual background on why:

The documentation should not be making assumptions about branching from master (at least not if you're looking at canonical git documentation; obviously I don't know what docs you're looking at). Examples may typically start from master just because they're simple examples, but the thing to understand is this:

There is nothing special about master .

A branch is a branch; one of them just happens to be there first, and by convention it's called master .

Additionally, git has no memory of "parent branches" or anything like that. At any given time, you can focus on the current commit topology. So:

I have created a branch B1 from master, made some edits and committed to this branch.

x -- O <--(master)
      \
       A <--(B1)

I want to create another branch B2 from B1, I make some edits in B2

x -- O <--(master)
      \
       A <--(B1)
        \
         B <--(B2)

At this point, git doesn't know or care that B2 was "created from B1 ". Instead of following the above steps, you could have said:

  • Create B2 from master
  • Make some changes and commit (creating A )
  • Make some changes and commit (creating B )
  • Go back to A and create branch B1

and everything would be the same.

And I also want to commit and push B2 (with edits from B2 and B1) back to master

Here your terminology is confused.

To push is to update a remote repository ref. Typically your remote could have a branch corresponding to each local branch. Although git is very flexible and you could use push in a different way, it still doesn't seem like what you mean here.

To combine the changes from one local branch into another local branch is to merge . (There are actually a few ways to go about this, but conceptually the most straightforward is a merge...)

Also, this touches on a common misconception about branches in git - that a change "belongs to" this branch or that branch. In many source control systems that may be true, but in git it's not. Instead a change either is, or is not, "reachable" from a branch (or other ref); and a change can be (often is) reachable from many refs.

(Essentially a branch (or other ref) is a pointer to a commit; that commit is reachable from the ref. If that commit has a parent, the parent commit is reachable. This continues recursively through parent pointers, so that the entire history leading up to a ref is reachable from that ref.)

So going back to the diagram

x -- O <--(master)
      \
       A <--(B1)
        \
         B <--(B2)

What you've described is that A and B should be merged to master . Because A and B are exactly the commits that are reachable from B2 but not reachable from master , this is as simple as

git checkout master
git merge B2

Note that by default git will take a shortcut here, by performing a "fast-forward" instead of a true merge. This can be done because master has no changes that are unreachable from B2 . In that situation, git can just update master to moving it to the same commit as B2 .

x -- O -- A <--(B1)
           \
            B <--(B2)(master)

You may not want git to do that. (Some branch/merge strategies call for preservation of branch topology.) In that case you could say

git checkout master
git merge --no-ff B2

which would give you

x -- O --------------- M <--(master)
      \               /
       A <--(B1)     /
        \           /
         B --------/
         ^
       (B2)

where M is a "merge commit". If there were additional changes reachable from master but unreachable from B2 , the merge commit would combine those with the changes from A and B .

Either way, B1 remains pointed at A and B2 remains pointed at B , so they are both fully reachable from master .

There's nothing preventing you from merging any branch back to master. That branch could be branched from master or any other branch. Simply do:

git checkout master
git merge B2

Try this. You can always do git reset --hard origin/master if you want to reset it to be like origin (assuming your remote repo is called origin, or if you don't have a remote you can also provide a commit hash).

Let me give you a brief explanation of how git works so that you understand.
Let's create a repository in temp/ folder

$ cd temp
$ git init

Now, create a file hello.txt with following text

in master

Save it, commit changes and check your branch name using

$ git add hello.txt
$ git commit -m 'committed in master'
$ git branch
* master                                  # the output

Ok, now you create a branch names B1

$ git checkout -b B1

Now check what the hello.txt has inside it.

$ cat hello.txt
in master

It has same text as master branch. Now edit the file and add some text

in master
in B1

You save the file in B1 branch and it has the updated data. Commit the changes and create a new branch while being in B1

$ git add hello.txt
$ git commit -m 'committed in B1'

Create a branch names B2 without going back to master

$ git checkout -b B2

If you check the content of hello.txt in B2 you will have same text as in B2, because the branch B2 is originated from branch B1. And now if you go back to master branch and see the content of hello.txt you will find ==> in master only, changes in branches B1 and B2 will not affect master branch
Now change the content of hello.txt

in master
in B1
in B2

Save and commit the changes.

Now coming back to your question , you want to merge ( Not push ) changes from B2 branch to B1 . You can go back to branch B1 to do that.

$ git branch B1                        # To change the branch to B1
$ git merge B2                         # It will merge changes made in B2 to B1

Now check the content of hello.txt in B1 . Nice. Right?
Similarly go to master branch and merge the changes made in B1 to master. And there you have it.

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