19

I have a situation. Let's say two developers are working on two different branches A and B.

 -- master --
|            |
A     <--    B  

Branch B is dependent on changes in A. However, changes in A are not yet merged into master. I would like to start working on my feature (branch B) with changes in A and then discard them when I am done testing. What is the recommended way ?

jub0bs
  • 60,866
  • 25
  • 183
  • 186
Conans
  • 461
  • 1
  • 4
  • 14
  • 3
    It's not really clear what you want, but I think you just want to start a new branch C based on B, merge A in to C, then work on C. Once you're done, delete C. – chepner Apr 16 '15 at 16:27
  • Yeah. How do I discard the merge A after testing my changes in C. – Conans Apr 16 '15 at 16:30
  • Just delete C (`git branch -D C`). You will still have A and B. Git branches are lightweight and meant to be created/deleted often. Or keep C around for testing, work on B and merge additional changes from B into C as you want to test them (try to avoid making any non-merge commits on C, do all work on A or B and just merge into C for testing). – Jonathan Wakely Apr 16 '15 at 16:32
  • 1
    From your ASCII graph, it's difficult to figure out what state your repo is in. Have a look [there](http://stackoverflow.com/questions/25488138/move-initial-commits-off-master-to-another-branch-in-git/25490288#25490288) for a clearer example of ASCII commit graphs. – jub0bs Apr 16 '15 at 16:45

3 Answers3

8

Let's say branch B is currently on commit abc1234. The most direct answer to your question is

git checkout B
git merge A
# run your tests
git reset --hard abc1234

But as others have mentioned, this is a really really really odd workflow. Why do you want to unmerge the branches in the first place if B depends on A? Perhaps you want a 3rd "integration" branch instead?

raylu
  • 2,630
  • 3
  • 17
  • 23
  • I figured out that this is an odd workflow. I merged B to A and started working on A. Thanks for the response. – Conans Apr 17 '15 at 20:29
  • 1
    well, I see scenario such that if each branch represents separate feature then somehow find out later the dependency of one branch in the other. However you want the code review and any dev-side verification needs to be done before merging them together, otherwise it is just one big mess being created. – swcraft Nov 14 '20 at 16:23
2

There are two valid ways to approach this:

  1. You do a full, normal merge. This is the easiest approach, git does not care how many times you merge back and forth, it can sort it out. This approach is the most honest one: Your changes depend on what's been done in the other branch, so that's reflected in the recorded history.

    The only problem with this approach is people (probably with an SVN or similar background) who want to retain a linear history on master, or an SVN repository that contains the official development history.

  2. You rebase your work onto the other branch. Some people like this because it retains a linear history, and it makes interacting with an upstream SVN repository easier. The downside is, that you are lying about history (see my answer to another SO question for more details on why that is problematic). So, if you choose to rebase, you should make sure that you at least compile-test your new commits.

    Another downside with this approach is, that you will need to rebase your entire work every time you need to draw on changes in another branch (including master) to retain a linear history. And to repeat the testing of all the new commits that the new rebase creates.

    That is why I strongly prefer the merge approach: It allows merging at any point, and the only new commit that needs to be tested is the merge commit. All my previous commits remain unchanged and don't need to be retested.

Community
  • 1
  • 1
cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106
1

I use for this the git cherry-pick command which works very well for this example

On branch B:

git branch B-tmp
git checkout B-tmp
git rebase A
# Do your wanted modifications
git commit

Supposing your are now on commit abc1234, you can now return on your B branch and 'pick' commit abc1234:

git checkout B
git cherry-pick abc1234
Furlings
  • 71
  • 1
  • 10