简体   繁体   中英

git merge subfolder of branch

I'm pretty sure this situation is quite common, but I haven't found any information on how to deal with it in git.


Here's what's happened so far:

Imagine the following folder structure in a git repo:

/server
/client
.gitignore

The repo contains both the server and client code of a Client-Server application.

This is the revision history of the master branch:

a01... (changes /server content)
b02... (changes /client content)
c03... (changes /server content)
d04... (changes /client content)
c05... (changes /server content)
d06... (changes /client content)

At this point, we pick the commit b02 and create a new branch server_v2 out of it. On that branch, we make two commits e07.. and e08.. . Here's the revision history of server_v2 :

a01... (changes /server content)
b02... (changes /client content)  <---- here, master and server_v2 are forked
e07... (changes /server content)
e08... (changes /server content)

And here's the revision graph:

a01
b02
 * *
 *    *
 *       *
 *          *
c03            *
d04               *
c05                  *
d06 <-- master          *
                       e07
                       e08 <-- server_v2

Note that all commits affect only one of the subfolders, and the first character of the commit hash indicates which one:

a: commit on /server, before the fork
b: commit on /client, before the fork
c: commit on /server, only in master
d: commit on /client, only in master
e: commit on /server, only in server_v2

Here's what we're trying to do:

Now we want to put version 2.0 of the server online. So we want master to contain the e07 and e08 commits instead of the c03 and c05 commits. This is what we want the branches to look like:

master:     a01, b02, d04, d06, e07, e08
server_v1:  a01, b02, c03, c05

In other words, master should contain the new server ( e07 and e08 ) as well as the changes on the client ( d04 and d06 ). server_v1 should contain the old server ( c03 and c05 ).

Option 1:

We could rename the branches:

master    --> server_v1
server_v2 --> master

Now master indeed contains the new server version.

Problem: We lose the d04 and d06 commits on /client .

Option 2:

Merge server_v2 into master . Now the revision graph looks like this:

a01
b02
 * *
 *    *
 *       *
 *          *
c03            *
d04               *
c05                  *
d06                     *
 *                     e07
 *                     e08 <-- server_v2
 *                   *
 *               *
 *           *
 *       *
 *   *
[merge] <-- master

Problem: This way, the c03 and c05 commits are part of master . We don't want the changes on the old server to be part of the new master branch.

Is there a way to achieve this?

git checkout master

git checkout -b server_v1 ## create server_v1 branch as off the current master

git checkout master
git revert c03  ##revert commits you don't need
git revert c05 

git merge server_v2 ##merge your server_v2 changes into master (you can also rebase server_v2 onto master and fast-forward master to server_v2 if you want linear history)

That's 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