【问题标题】:prevent some commit/code to be merged into master防止某些提交/代码合并到主控中
【发布时间】:2013-09-20 23:20:00
【问题描述】:

对于我正在进行的项目,我们决定开发一个工具来帮助开发,所以这不应该在生产中。
所以我想知道,由于 git 太棒了,是否有一个功能可以防止某些 文件 (是的,只有文件:这是一个 Magento 项目,我们将要开发的工具将在他自己的模块,与应用程序的其余部分没有交集)要合并到 master 中,但应该在其他分支中可用。
如果有帮助,我们正在考虑使用 git-flow。所以我们会有master,我们将从它创建develop,从中创建我们所有的功能分支。我们的想法是让这个模块处于开发状态,但永远不会合并回主模块。

我现在在想,像只在 master 分支中忽略那些文件(.gitignore)这样行吗?

编辑 1:项目结构
我觉得我必须提供有关项目结构的更多信息,这里是:

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

开发工具模块必须包含在不同位置的主项目(仅magento部分)中,即app/code/local/Namespace1/Module3/、app/design/frontend /layout/dev.xml、app/design/frontend/template/dev/tool.phtml 和 js/dev/

编辑 2:子模块选项
探索@VonC 的answer,这是我所做的:

  • 在分支主控中:
    • git submodule add git@github.com:path/to/submodule.git devtool
    • cd 开发工具
    • git checkout 123abc #submodule 的初始提交
    • cd ..
    • git 添加开发工具
    • git commit -m "在初始提交时添加子模块"
  • 在分支开发中:
    • cd 开发工具
    • git checkout abc213 #submodule's last commit
    • cd ..
    • git 添加开发工具
    • git commit -m "子模块最后一次提交"
  • 回到主分支:
    • 触摸 .gitattributes
    • 在 .gitattributes 我把这个:devtool merge=ours
    • git add .gitattributes
    • git commit -m ".gitattributes 指令"

但是 master 中的子模块具有最后一次提交的内容,如果我签出 master 中的初始提交并签出回开发,初始提交仍然存在(当我想要开发中的最后一次提交时)。
所以我显然做错了什么,但是什么?

【问题讨论】:

  • 这是一个想法,因为我不知道而且我认为它不存在任何 git 构造来防止文件存在于分支上,除了 .gitignore。问题是您将始终在分支中拥有该代码。此外,如果您的代码依赖于 master 分支中的代码,您将不得不不断地 rebase 或将 master 合并到您的工具分支中,但如果这不是问题,那就去吧。
  • @bitoiu 代码将不依赖于 master,所以这不会是一个问题。但我找不到任何关于每个分支有不同的.gitignore 的信息。当我尝试时,当我将分支合并到 master 时,master 的 .gitignore 也包括分支。有任何相关信息吗?
  • @OSdave,这是关于每个分支有不同的 .gitignore:这里有很好的解释 stackoverflow.com/questions/1836742/…(请查看“excludesfile”部分)
  • 你试过我的答案了吗?
  • @Meabed 还没有,刚打开电脑,今天晚些时候再做,我会及时通知你

标签: git magento merge git-merge git-flow


【解决方案1】:

我真的建议使用submodule 将一组文件隔离在自己的存储库中。

想法是:如果您使用的是子模块,您需要在父目录中做的就是防止合并一个元素(并且只有一个):special entry 记录所述子模块的 SHA1。
您不必担心子模块文件的合并。

你可以:

【讨论】:

  • 感谢您的回答。我已经用我认为我应该做些什么来应用你的建议来扩展我的问题。由于我不熟悉子模块,您介意查看我确定的步骤并告诉我我是否走在正确的道路上吗?
  • @OSdave gitattribute 应该包含为该子模块添加的文件夹的名称,而不是 SHA1 引用。该文件夹实际上作为一个特殊条目存在于 git repo 中。
  • @OSdave 在您的子模块中,您可以添加一个远程 (git remote add /url/of/your/submodule/repo) 以获取并签出您希望从您的父仓库中看到的正确提交。
  • 再次感谢:我现在正在处理,会及时通知您我的进度,并会在我开始工作后立即接受您的回答
  • 我一定做错了:我已经用我所做的事情编辑了我的问题,您介意查看一下是否可以发现我的错误吗?
【解决方案2】:

用

切换分支后

git checkout <branch>,

你必须跑

git submodule update

这是为了解决您遇到的问题,如编辑 2 中所述。

根据 VonC 的回答,gitsubmodule 对象是存储库中映射到 SHA 提交的一个对象,而不是子模块本身的内容。

因此,git submodule update 是使用此提交的内容初始化本地目录所必需的。执行全新克隆或切换分支后,必须运行此命令。您遇到的问题是,当您切换分支时,最后一个分支的子模块内容仍然存在。运行 git submodule update 将这些内容替换为新分支的子模块对象指向的内容。

编辑:

运行git submodule update 覆盖子模块中的所有当前更改,子模块对象也指向(在父仓库中)。如果您想更改父 repo 指向的提交,请在子模块中签出正确的版本,然后 cd .. 并将更改提交到子模块对象。

【讨论】:

  • 我已经尝试过了,但是当我执行git submodule update 时,它会回到最新的提交
  • 你在你的开发分支中做了'git submodule add'吗?
  • 我什至不在那里:在分支 master 中,在检查子模块的特定提交并执行 git submodule update 之后,子模块回到了我不想要的最后一次提交(我想要子模块在之前的提交中,没有代码)
  • 切换到你的主分支并从顶层运行git submodule status。您的子模块旁边显示的提交哈希是否与您想要在主模块中的提交相对应?
  • 而且您似乎正在覆盖子模块内容。请参阅我上次编辑的覆盖子模块更改。
【解决方案3】:

最好的解决方案是使用 git hooks !

这是一个工作示例“我已经对其进行了测试并确保它可以正常工作”

用法:

混帐添加。 // 例如添加所有文件(包括要排除的文件)
git commit -am 'Test pre-commit' // 提交所有文件 “pre-commit” 钩子会运行


目录结构示例

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

在您的 git 根目录中创建文件并将其命名为 { .ignorefolders },其中包含您要排除的文件或文件夹“示例如下”

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

我在每行的开头添加了“/”,因为我希望它与根目录相关
"您可以添加完整的文件夹、单个文件"


在文件夹 { .git/hooks } 中创建文件 { pre-commit },内容如下

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

注意事项:

条件语句中的代码有据可查(您可以使用 exit 或 return )取决于您想要的逻辑!

return ==> 提交将继续
exit ===> 提交将被中止

用例:

如果你添加“git-add .”并且您添加的所有文件都被排除在配置文件“.ignorefolders”中,然后您尝试提交!
这些文件将从提交中删除,但您将能够提交一个空的“没有任何更改”的提交。

【讨论】:

  • 我已完全按照您的指示进行操作,但是当我将分支(包含我不希望在 master 中的文件)合并到 master 时,文件存在于 master 中:(
  • 我已经测试了这个及其工作。预提交是否有效?你能看到这条消息 Executing pre-commit hook in master Branch
  • 我在现场环境中使用它,它工作得很好!可以试试吗?
猜你喜欢
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 2011-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多