71

I created a branch to try a different approach and it worked, so I would like to merge the "Farmcrops" branch into "Master" to keep those changes but continue the "Farmcrops" branch to explore another possibility. That way, if this latest change doesn't work, I can revert back to "Master" which would now include the first round of changes.

How can I do that?

jub0bs
  • 60,866
  • 25
  • 183
  • 186
jgravois
  • 2,559
  • 8
  • 44
  • 65
  • The new exploration is still based on my changing cropfarms to farmcrops so it made sense to me to keep using that branch but if it is easier in git to merge and branch again, I can do that. – jgravois Sep 24 '14 at 19:21

4 Answers4

117

If I understand correctly, you're starting from

-- o -- o -- o [master]
    \
     o -- o [Farmcrops]

You shouldn't merge Farmcrops directly into master, because you run the risk of breaking the code in master, which, by convention, is supposed to be more stable. Instead, check out Farmcrops and merge master into it.

git checkout Farmcrops
git merge master

Then you'll get

-- o -- o -- o [master]
    \         \
     o -- o -- o [HEAD -> Farmcrops]

Run some tests; make sure everything works as expected. Then check out master and merge Farmcrops into it:

git checkout master
git merge Farmcrops

Your repo will then look like this:

-- o -- o -- o
    \         \
     o -- o -- o [HEAD -> master,Farmcrops]

(Note that this merge is a fast forward: it doesn't create a merge commit because Farmcrops is a direct descendant of master.)

Now check out Farmcrops again and continue your experiment, make more commits on it, etc...

-- o -- o -- o
    \         \
     o -- o -- o [master]
                \
                 o -- o -- o [HEAD -> Farmcrops]

You can always fall back on master (which now contains "the first round of changes", as you put it) if your new experiment on Farmcrops doesn't pan out so well.

jub0bs
  • 60,866
  • 25
  • 183
  • 186
  • 30
    The visuals on this are very helpful. Thank you for taking the time to put them in. – Jeromy French Feb 15 '18 at 01:09
  • 3
    Note that the second merge doesn't need to create another merge commit because `Farmcrops` is a direct descendent of `master`. It just moves the pointer (fast-forward). This helped me understand the graph. – Sam McCreery Mar 05 '19 at 11:16
  • 3
    This is why you should always read past the accepted answer and look for one with more votes! – Mark Oct 16 '19 at 18:14
  • If you merge Farmcrops into master you also have all changes from master in Farmcrops? I thought Farmcrops is still an independent branch after a merge, but it seems not. – testing Feb 19 '20 at 13:02
  • @SamMcCreery Thanks. I've added a note about that in my answer. – jub0bs Jul 06 '20 at 16:41
  • @jub0bs , suppose someone spins up a news feature branch say newFarm out of latest remote master and keep working on it, and then merge to master as you explained above and made a "new latest master", but I'm still working on Farmcrops and now I want to merge with the "new lastest` master" branch, how I'm gonna make that happen? Basically I need to achieve changes from newfarm` branch after it gets merged in master and at the same time preserve the clean history of commits, how the project devlpd over time. A clean network graph of the commits. https://pastebin.com/dKUTXazV – Anu Jul 22 '20 at 08:17
  • 1
    @Anu You should ask this as a separate question. – jub0bs Jul 22 '20 at 12:32
45

Here is the process you are looking for:

  1. git checkout master
  2. git merge Farmcrops
  3. git push origin master
  4. git branch -d Farmcrops
  5. git checkout master
  6. git checkout -b Farmcrops
  7. continue your commits on the branch Farmcrops...

Branches are just pointers, it's very easy to create/delete a branch and if your branch Farmcrops isn't pushed on remote repository, there is absolutely no dependency with it. You can delete it after the merge and recreate it from the master.

Hope this will help you.

Joël Salamin
  • 3,538
  • 3
  • 22
  • 33
  • 29
    You shouldn't merge `Farmcrops` directly into `master`, though. It would be safer to first merge `master` into `Farmcrops`, check that everything works there, and only then merge `Farmcrops` into `master`. – jub0bs Sep 24 '14 at 19:31
  • 1
    @Jubobs thank you for the advice, i never tried this approach. But the merging action is done locally, you have all the time you want to validate the new version, test it and ensure that everything is alright, no? It seems to be a useless step to first merge as you're suggested – Joël Salamin Sep 24 '14 at 19:34
  • 7
    Even if everything is local, the first merge is useful in that it promotes isolation: it saves you the risk of creating a "bad" commit on `master` and having to reset `master` to one of its parent, or revert the last commit on `master`. It's a safety net. – jub0bs Sep 24 '14 at 19:36
  • Ok i understand the advantage of doing this way. When i'm facing such kind of "bad" commit i usually reset it in order to restore the previous state and fix my issue – Joël Salamin Sep 24 '14 at 19:39
  • That works as well, but `reset` is a potentially riskier operation. That's why I like merging `master` into the feature branch first. – jub0bs Sep 24 '14 at 19:40
  • 1
    I'll try that the next time i'm facing this situation. Thanks for the tip – Joël Salamin Sep 24 '14 at 19:52
  • 4
    Why recreating and not just continuing? If Farmcrops is not just locally but also on a server (f.i. for backup-security), then one would need to delete it locally and remotely, create it locally again, push it to remote, track it again.......and so one. Isnt merging into master and continuing a lot easier? – treesoft Mar 23 '17 at 10:15
  • @JoëlSalamin, So you switched to `master` and merged `Farmcrops` into `master`. This happened locally! Then you pushed local `master` to the remote `master`. Q1: Until now, if I've pushed `Farmcrops ` changes remotely too, does it gonna effect continue working on the same branch locally in any way? Q2. Then, you deleted all local commits on `Farmcrops ` branch and checkout the latest `master`. 5th step wasn't needed? since after deleting `Farmcrops ` locally you're left with `master` only, isn't it? so the pointer will switch automatically to local `master`, correct? – Anu Jul 22 '20 at 06:46
  • @JoëlSalamin,Q3. if I cont. on `Farmcrops`, and suppose someone spins up a news feature branch say `newFarm` out of latest remote `master` and keep working on it, and then merge to master as you explained above and made a "new latest `master`", but I'm still working on `Farmcrops` and now I want to merge with the "new lastest` master`" branch, how I'm gonna make that happen? Basically I need to achieve changes from `newfarm` branch after it gets merged in `master` and at the same time preserve the clean history of commits, how the project devlpd over time. A clean network graph of the commits. – Anu Jul 22 '20 at 06:55
  • 1
    @Anu Q1: If you pushed the branch to your remote, after the merge+delete action on the branch you should also push these changes on your remote. Q2: Deleting the branch after mergin into master will not delete the commits. But you're correct the 5th step is just there to ensure that we're on the `master` branch, if you do all steps at the same moment it will not be needed to do this checkout. – Joël Salamin Jul 24 '20 at 20:54
  • 1
    @Anu Q3: In this case, to include all modifications done on the remote `master` before merging your branch, a `rebase` will be the solution to keep a clean history. – Joël Salamin Jul 24 '20 at 20:57
2

In the link below it is explained how to create a hotfix branch, make changes and merge it to the master. Only difference, hotfix branch is deleted after merge.

Just use Farmcrops as a branch name and do not delete branch after merge.

GIT-SCM: Basic Branching and Merging

[STEP 1] Create a branch and make your changes

$ git checkout Farmcrops
Switched to a new branch 'Farmcrops'
$ vim index.html
$ git commit -a -m 'fix the broken email address'
[Farmcrops 3a0874c] fix the broken email address
 1 files changed, 1 deletion(-)

[STEP 2] Then, go back to master branch and merge

$ git checkout master
$ git merge Farmcrops
Updating f42c576..3a0874c
Fast-forward
 README | 1 -
 1 file changed, 1 deletion(-)

And, if you want to make more changes on the same branch, apply [step 1] again.

When you complete changes apply [step 2] again.

Follow these steps as much as required.

Once you finished your job with this branch you can delete it.

$ git branch -d Farmcrops
Deleted branch Farmcrops (was 3a0874c).

NOT: Instead of merge I suggest rebase GIT-SCM: Rebase

git rebase Farmcrops
clockworks
  • 3,755
  • 5
  • 37
  • 46
  • I change the statement; "git checkout -b Farmcrops" --> "git checkout Farmcrops" since, branch aready exists and STEP 1 can be applied several times. – clockworks Sep 24 '14 at 19:38
1
  1. Merge feature branch PR
  2. Delete feature branch on GitHub
  3. git branch -d feature-branch
  4. git checkout -b feature-branch
albingroen
  • 27
  • 1
  • 1
  • 4