prevent some commit/code to be merged into master

For the project I am working on, we decided to develop a tool to help the development, so this is something that should not be in production.
So I was wondering, as git is so awesome, if maybe there was a feature to prevent some files (yes, only files: this is a Magento project and the tool we are going to develop will be in his own module, no intersection with the rest of the application) to be merged into master, but should be available in other branches.
We are thinking in using git-flow, if that helps. So we would have master, from which we'll create develop, from which will create all our feature branches. The idea would be to have this module in develop but never merged back into master.

I am thinking now, something like ignoring those files (.gitignore) only in the master branch, would that work?

edit 1: project structure
I feel I have to give more info about the structure of the project, here it comes:

+ main_folder/
    + magento/
    |---+ app/
    |   |--+ code/
    |   |  |--+ community/
    |   |  |--+ core/
    |   |  |--+ local/
    |   |     |--+ Namespace1/
    |   |        |--+ Module1/
    |   |        |--+ Module2/
    |   |     |--+ Namespace2/
    |   |        |--+ Module1/
    |   |        |--+ Module2/
    |   |--+ design/
    |   |  |--+ frontend/
    |   |     |--+ default/
    |   |        |--+ default/
    |   |           |--+ layout/
    |   |           |--+ template/
    |   +  js/
    |   +  lib/
    +  ezpublish/

the development tool module will have to be included in the main project (only the magento part) in differents places, ie app/code/local/Namespace1/ Module3 /, app/design/frontend/layout/ dev.xml , app/design/frontend/template/ dev/tool.phtml and js/ dev/

edit 2: submodule option
exploring @VonC's answer, here is what I've done:

  • in branch master:
  • git submodule add git@github.com:path/to/submodule.git devtool
  • cd devtool
  • git checkout 123abc #submodule's initial commit
  • cd ..
  • git add devtool
  • git commit -m "added submodule at initial commit"
  • in branch develop:
  • cd devtool
  • git checkout abc213 #submodule's last commit
  • cd ..
  • git add devtool
  • git commit -m "submodule at last commit"
  • back in branch master:
  • touch .gitattributes
  • in .gitattributes I've put this: devtool merge=ours
  • git add .gitattributes
  • git commit -m ".gitattributes directive"
  • but the submodule in master has the content of the last commit, and if I checkout the inital commit in master and checkout back to develop, the initial commit is still there (when I want the last commit in develop).
    So I am obviously doing something wrong, but what?


    I would really recommend to use a submodule to isolate a set of files in its own repo.

    The idea is: if you are using a submodule, all you need to do in your parent directory is to prevent the merge of one element (and only one): the special entry recording the SHA1 of said submodule.
    You don't have to worry about the merge of the submodule files.

    You can:

  • reference an empty submodule SHA1 in master
  • reference the last submodule commit in a ' devel ' branch
  • prevent the merge of the submodule special entry between devel and master .
    (see for instance "Is it possible to exclude specific commits when doing a git merge?", with a .gitattributes directive.)

  • After switching branches with

    git checkout <branch> ,

    you have to run

    git submodule update

    This is to resolve the problem you are having as described in Edit 2.

    As per VonC's answer, a gitsubmodule object is one object in the repo that maps to a SHA commit, not the contents of the submodule itself.

    Thus, git submodule update is necessary to initialize your local directory with the contents from this commit. Running this command is necessary after you do a fresh clone, or when you switch branches. The problem you are having is that when you are switching branches, the submodule contents from the last branch is still there. Run git submodule update to replace those contents with the contents pointed to by the new branch's submodule object.

    EDIT:

    Running git submodule update overrides all current changes in the submodule with the commit that the submodule object is pointing too (in the parent repo). If you want to change the commit that your parent repo is pointing to, checkout the right version in the submodule, then cd .. and commit the changes to the submodule object.


    Best Solution is to use git hooks !

    Here is working example " I have tested it and made sure it works fine "

    Usage :

    git add . // add all the files for example ( including the files you want to exclude )
    git commit -am 'Test pre-commit' // commit all the files "pre-commit" hook will run


    Directory Structure example

    |-- ex.file
    |-- module
    |   |-- f2.php
    |   |-- f3.php
    |   `-- file.php
    `-- xml
        |-- file.xml
        `-- file1.xml
    

    Create file in your git root directory and call it { .ignorefolders } with files or folders you want to exclude " example below "

    /module/
    /xml/file.xml
    /ex.file
    

    I have added "/" at the beginning of each line as i wanted it to be relevant to the root dir
    " You can add complete folders, individual files "


    Create file { pre-commit } in folder { .git/hooks } with content below

    ROOTDIR=$(git rev-parse --show-toplevel) #root folder
    FILENAME="$ROOTDIR/.ignorefolders" #configuration file
    
    if [ ! -f $FILENAME ]; then
        echo "File '.ignorefolders' not found!"
        exit 1
    fi
    
    BRANCHES=("master") # branches array to untrack this folders and files from if you want to remove this files from more than branch for example BRANCHES=("master" "branch2" "branch3")
    CURRENTBRANCH=$(git branch | sed -n -e 's/^* (.*)/1/p') #get current branch name
    
    if [[ ! "$(declare -p BRANCHES)" =~ '['([0-9]+)']="'$CURRENTBRANCH'"' ]];then  #check if the current branch is NOT in the array of the branches
        exit 0
    else
      echo "Executing pre-commit hook in $CURRENTBRANCH Branch"
    fi
    
    function removeFromGitAdd {
       PARAM="$ROOTDIR$1"
       if [ -e $PARAM ]; then
            #file or folder exist
            if [[ -n $(git ls-files $PARAM ) ]]; then
                #echo "there are files with this path added in the current commit"
                git rm --cached $PARAM -r #removing this files/folders
            else
                #echo "There is no file"
                echo ''
            fi
    
       fi
    }
    cat $FILENAME | while read LINE
    do
           #echo $LINE
           removeFromGitAdd $LINE
    done
    

    Notes :

    Code is well documented ( You can use exit or return ) in the conditional statements depends on the logic you want !

    return ==> commit will continue
    exit ===> commit will be aborted

    Use-case :

    If you add "git-add ." and all the files you added is excluded in the config file ".ignorefolders", Then you try to commit!
    The files will be removed from the commit but you will be able to commit an empty "without any changes" commit.

    链接地址: http://www.djcxy.com/p/92276.html

    上一篇: .gitmodules中的Git子模块未初始化

    下一篇: 防止一些提交/代码被合并到主机中