Search code examples
gitdeploymentbranch

How to realise a deployment branch in Git


I'm using git for a PHP project, I think it's really handy. There is one thing that would be great if I get it to work.

I have created a branch, meant for deployment. It has some differences, like different configuration files and documentation.

I can't just ignore them, because then they will stay in both branches, while I would like to keep them different in both branches.

The problem is that when I merge the branches, those files that are meant to be different are merged too.

Is there any convenient way to accomplish such a thing? How is this normally done?


Solution

  • Update Feb. 2021: Git itself is still not a good fit, but GitHub Action environment could help.

    2009: I am not sure Git is meant to be used this way.

    First a quick Linus advice, always "colorful" and informative ;)

    Git very fundamentally tracks project state, not file state. Which means that you very much can NOT try to "merge a file". It is a senseless operation in git, and in fact, any SCM that allows it pretty much is doomed to be a total piece of sh*t (*).

    (*) And I'm not saying that just because git doesn't do it. It's much more fundamental than that. Once you start doing per-file branching and merging, you've basically screwed yourself, and you'll never be able to work on the project as a "whole project" any more - you no longer have a well-defined history that actually is the history of the whole project.


    There.

    That said, you could:

    • manage those config/doc files a separate git sub-projects (note: the use of submodules has been discussed here)
    • or record partial merge (using "ours" strategy for files we don't want to merge), then --amend it.

    Other solutions in this thread involve working on a "server-specific" branch on your deployment server

    Development        Deployment
    
    #origin/master:
    x--x               $ git clone
    
                       # master
                       x--x
    
                       $ git checkout -b deployment origin/master
    
                       x--x
                           \ 
                            -- #deployment
    
                       $ .... #makes changes for config files
                              #or other specific deployment files
    
                       x--x
                           \
                            --d1--d2 # no need to push that branch ever.
    
    #new developments
    x--x--x--x
    
                       $ git pull --rebase #pull origin/master and 
                                           #replay current branch on top of it
                       x--x--x--x
                                 \
                                  --d1'--d2' #SHA1 rewritten in deployment branch
                                             #not important since this branch 
                                             #is not pushed (published)