Git: how to maintain permanent parallel branches

We have project (PHP application), but instalation for each client vary, sometimes very little, sometimes more. Still, big part of source code is common. We manage specific installations as parallel branches to master branch and we need to transfer changes from master to other branches. Same situation was solved in Git: how maintain (mostly) parallel branches with only a few difference? The most voted solution was to transfer changes between braches this way:

git pull
git checkout local
git rebase master

As mentioned in the solution it creates non-fast-forward pushes after rebasing which I find very unpleasant complication. My QUESTION is – why not to do instead:

  • Git svn: how do I work with “partial” branches?
  • Show commits in a git merge?
  • Rename a branch in git flow
  • git: rename local branch failed
  • git push branch to a new repo with a different name
  • Branch target prediction in conjunction with branch prediction?
  • git pull
    git checkout local
    git merge master
    

  • git doesn't ignore 2 specifically named files
  • git checkout remote reference
  • Vim ignore specifc file in autocommand
  • Git: When does Git perform garbage collection?
  • How to remove selected commit log entries from a Git repository while keeping their changes?
  • How does --no-ff merge break bisect and blame?
  • 3 Solutions collect form web for “Git: how to maintain permanent parallel branches”

    It really depends on what you want to do with the branch. Yes, if you rebase local, it’ll create non-fast-forward pushes after rebasing. On the other hand, you’ll be maintaining a set of distinct changes going forward and what’s on your branch will be a set of changes AS IF THEY HAD BEEN MADE TO THE NEWEST HEAD OF MASTER.

    Merging the master to local, instead, will keep local marching forward in time with master, and will record the history as it happened. If you need to be able to reconstruct the state of local in the past, then you’ll want to do this. The history will never change. But, you’ll have a more complicated history to deal with.

    The idea is you use one common branch, and two (or as many as you
    need) customer specific branches. All common changes go into the
    master, and each customer branch gets changes that pertain only to
    that customer. Periodically (when master is considered to be at a
    stable point), you’ll merge changes from master into the customer
    branch (git checkout custA; git merge master). This brings in newer
    “common” code into the customer branch. You will never merge the other
    way — that would pollute master with customer-specific code.

    When you make a delivery to customer A, you checkout the “custA”
    branch and send that. And of course similarly for other customers.

    Now let’s say you acquire a new customer, “C”, and a bit later find a
    feature that customers A and C want, but B doesn’t. You create (aka
    “fork”) a branch off of master (git checkout -b AC_feature master),
    code/test it, making commits as you go, and then merge it into A and C
    (git checkout A; git merge AC_feature and similarly for customer C).
    You do not code it in A and then rely on merging A into C, because
    that would get all of A into C.

    If, sometime later, you find a minor bug in that feature, you make the
    change in the same branch (git checkout AC_feature; edit/test/commit),
    and then you merge it into custA and custC as above.

    Source: These refreshingly clear and helpful articles from the developer of Gitolite – Sitaram Chamarty, written in part with direct input from Junio Hamano (Linus Torvalds’ partner in maintaining Git).

    Maintaining Parallel Customer Branches:

    http://gitolite.com/archived/special-branches.html

    Followup Article on “Fixing Up” Common and Customer Branches:

    http://gitolite.com/archived/special-branch-fixups.html

    Greg’s answer to your other question seems to view different branches as remaining local to particular installations, not pushed to other repos (emphasis added):

    If it’s local to a system, commit it to that system’s “local” branch, else commit it to “master” and push it up to a common repository.

    You almost always want fast-forward pushes to branches in a shared repository. The git rebase documentation explains how to recover from an upstream rebase (i.e., git rebase then git push -f), and it’s no fun for anyone involved.

    For another approach, see Never merging back:

    There are valid cases where you once fork with the intention to never merge back, but in general you should try very hard to keep changes on such a fork to the minimum.

    The author goes on to discuss branching policy for various customer releases within the same repository.

    Git Baby is a git and github fan, let's start git clone.