3

I have the following problem: We have a large product which is in master branch. Also we have other branches that have only few files, the files that are specific to this branch only. Each of those branches represent a plugin to the main product. So for example when you get the main product, you receive lots of files, install them, etc. and later when you decide to get a plugin, you receive a package containing several files only and by uploading these file (and replacing the original ones) you get the plugin installed.

Let's I have payment.php in master branch (as well as many other files). And I have paypal branch which has one file only which is payment.php. Now I fix a bug in master's payment.php and want to merge this fix in paypal branch. However when I run merge, absolutely all files get added to that branch. So in the end paypal branch has all the files from master branch. Do you by chance know how this can be fixed? I want GIT to merge the files that exist in this branch only, so in the example above the paypal branch should still have one file only (payment.php) with the bug fix merged in.

Eugene
  • 4,197
  • 7
  • 37
  • 54
  • As others say, you probably don't want to have a branch that's missing all the files. If you really want to track the plugin separately, it should be a separate repository, possibly included as a submodule in the main project. If you don't want it separate, then sure, it can have its own development branch, but as a branch of the project repository, that branch should contain the whole project, not just one plugin. – Cascabel Jun 24 '10 at 14:55

5 Answers5

4

This is why it's important to manage your branches well, in particular to use topic branches and to merge upwards.

You should make that fix on a topic branch, forked from a common ancestor of all branches which will need the fix, and then merge it into both master and paypal:

x - x - x - x ------------- X (master)
|\                          |
| x - x - x ---- X (paypal) |
 \              /           /
  x (bugfix) ---------------

If you have already made your bugfix, and you mistakenly made it on master instead of from the appropriate merge base, and the history on master hasn't been published, you should cherry-pick or rebase it to the right place:

# If the bugfix commit is not at the tip of master, you can rebase to get it there:
git rebase -i <commit before the bugfix> master
# rearrange the list of commits to put the bugfix at the tip, save and quit

# Now either cherry-pick or rebase the commit to the right place
# (rebase is easier if the bugfix is actually several commits)

# Cherry-pick
# make a branch and cherry-pick
git checkout -b bugfix <SHA1 of merge base>
git cherry-pick <SHA1 of bugfix>
# remove the commit from master, assuming it's still on the tip
git checkout master
git reset --hard master^

# or rebase
# make the bugfix branch (assuming it's still on the tip)
git branch bugfix master
# and remove the commit from master (assuming it's still on the tip)
git checkout master
git reset --hard master^    # or if the bugfix is composed of n commits, master~n
# rebase the bugfix branch to the right place
git rebase --onto <SHA1 of merge base> master bugfix

If the history has been published, all you can do is cherry-pick the bugfix onto the paypal branch, and remember to do it right the next time:

git checkout paypal
git cherry-pick <SHA1 of bugfix>
Cascabel
  • 479,068
  • 72
  • 370
  • 318
  • Hi, I was thinking of having the paypal branch and merging master into it from time to time. So when I need new features implemented or bugs fixed I'll be doing that in master's files and then before the release I'll be merging the changes in paypal branch (so that the paypal can have the new fixes and features). I am quite new to this stuff so please correct me if I don't see some hidden problems with this. Earlier I've been doing this work manually. So I was implementing the new feature in master and then manually copying the pieces of code to paypal branch. – Eugene Jun 25 '10 at 14:22
  • In the example above the two branches seem to be very different (all those commits after branching point) while my branches usually have one difference only (paypal functionality for example). All the rest is the same and the main work is to keep the new code modifications always go into both branches. Of course sometimes I have a fix specific for paypal branch only but this is rather rare because that code is well tested by this time. – Eugene Jun 25 '10 at 14:26
  • @Eugene: I'm really not sure what you're trying to ask in those comments. No matter what, you can always make the modifications from the right branch point, then merge them into all branches that need them. It doesn't matter how different those branches are, as long as your patch still applies... – Cascabel Jun 25 '10 at 14:42
1

Why don't your other branches contain all the files that are part of the master branch? You're just making things harder on yourself by going through the trouble of removing all the other files. Especially if you later end up needing to change some other file that you already removed.

jamessan
  • 41,569
  • 8
  • 85
  • 85
  • In actual practice; there is need for hotfixes to go into specific release branches and not main. In this case you would have a release branch that isnt up to date with main, aka the files are different, so there for you would need this cherry-picking option. – mark.inman Jul 07 '21 at 13:20
1

You're doing it wrong. You're supposed to have all the files in the branch.

It's Git's job to keep track of which files differ between the branches, not yours. That's sort of one of the points of using a VCS.

If you want to distribute just the files that differ between branches, those can easily be extracted by a script.

Christoffer Hammarström
  • 27,242
  • 4
  • 49
  • 58
  • 1
    Hi, thanks for your reply. I am testing this solution at the current moment and will most likely use it. – Eugene Jun 25 '10 at 14:17
0

Isolating your plugins in their own git repo allows you to make evolutions on them independently on a parent project.

If, however, you need them directly included in your project, recent Git releases (git1.7.11 ,June 2012), includes the git subtree script (previously developed on GitHub by apenwarr, now merged into mainline git)

That way, you can merge one repo (and its history) in another, keeping the option to extract its history later on (as opposed to the subtree merge).
That could be seen as an alternative to git submodules.

Another alternative is git slave, to keep parent repo and submodules tightly in sync.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
0

You can do something similar to this: http://nvie.com/git-model

(I hope this works)

master will continue to be your main branch. You create a second branch off master called bugfix. You create a third branch off bugfix called plugin-foo.

In plugin-foo you delete all the files that are not needed. Now, whenever you make a change to the files that are not in the plugin branch, you do those on the master branch. All bugfixes go into the bugfix branch. You periodically merge the bugfix branch into both master and the plugin branches. Which leads to bugfixes going into both of those branches.

igorw
  • 27,759
  • 5
  • 78
  • 90