Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git 如何防止我的';硕士';分支机构?_Git_Merge_Git Merge - Fatal编程技术网

Git 如何防止我的';硕士';分支机构?

Git 如何防止我的';硕士';分支机构?,git,merge,git-merge,Git,Merge,Git Merge,foxtrot合并是一种合并,其中“origin/master”作为第二个(或更高版本)父级合并,如下所示: 提交'D'是狐步合并,因为'origin/master'是它的第二个父级。请注意,此时来自“origin/master”的第一个父历史记录如何包含提交“B” 但在我的git回购中,我需要所有涉及“origin/master”的合并,以保持“origin/master”作为第一个父级。不幸的是,git在评估提交是否符合快进条件时并不关心父顺序。这会导致我的主分支上的第一个父级历史记录有时

foxtrot合并是一种合并,其中“origin/master”作为第二个(或更高版本)父级合并,如下所示:

提交'D'是狐步合并,因为'origin/master'是它的第二个父级。请注意,此时来自“origin/master”的第一个父历史记录如何包含提交“B”

但在我的git回购中,我需要所有涉及“origin/master”的合并,以保持“origin/master”作为第一个父级。不幸的是,git在评估提交是否符合快进条件时并不关心父顺序。这会导致我的主分支上的第一个父级历史记录有时会丢失以前存在的提交(例如,“git log--first parent”的输出)

以下是推送前面关系图中的提交“D”时发生的情况:

我怎样才能防止这种推送?推送foxtrot合并后,“origin/master”的第一个父历史不再包含提交“B”

显然,没有任何提交或工作实际上会丢失,只是在我的环境中,我真的需要“git log——第一个父级”作为提交的稳定累积记录——如果您愿意的话,这是一种“一次写入多次读取”(WORM)数据库。我有一些脚本和流程,它们使用“git log——第一个父对象”来生成变更日志和发行说明,并在我的票务系统(JIRA)中管理票务转换。Foxtrot合并正在破坏我的脚本

是否有某种预接收钩子可以安装在我的git存储库中以防止foxtrot合并被推送


p、 此stackoverflow问题中的提交图是使用生成的。

以下预接收挂钩将阻止这些提交图:

#/bin/bash
#版权所有(c)2016 G.Sylvie Davies。http://bit-booster.com/
#版权所有(c)2016 torek。http://stackoverflow.com/users/1256452/torek
#许可证:麻省理工学院许可证。https://opensource.org/licenses/MIT
读取oldrev newrev refname时
做
如果[“$refname”=“refs/heads/master”];然后
MATCH=`git log--first parent--pretty='%H%P'$oldrev..$newrev|
grep$oldrev|
awk'{print\$2}'`
如果[“$oldrev”=“$MATCH”];然后
出口0
其他的
回显“***推送被拒绝!狐步合并被阻止!!!***”
出口1
fi
fi
完成
如果您使用的是Github/Gitlab/Bitbucket Cloud,您可能需要考虑创建对其的某种调用(以下是api文档:,;不确定Gitlab是否有),因为您无法访问预接收挂钩,即使访问了,您仍然需要与单击“合并”的人打交道按钮直接出现在这些产品的web ui中(在这种情况下没有“推送”)

使用Bitbucket服务器,您可以安装

安装后,在给定存储库的“挂钩”设置中,单击“保护第一个父挂钩”上的“启用”:

它将通过推送和Bitbucket服务器UI中的“合并”按钮阻止foxtrot合并。即使其许可证过期,它也会这样做,从而使“保护第一个父钩子”成为更大附加组件的免费组件

下面是我的“保护第一个家长”预接收钩子的一个示例:

$ ​git pull
$ git push

remote: *** PUSH REJECTED BY Protect-First-Parent HOOK ***
remote: 
remote: Merge [1f70043b34d3] is not allowed. *Current* master must appear
remote: in the 'first-parent' position of the subsequent commit. To see how
remote: master is merging into the wrong side (not as 1st parent), try this:
remote: 
remote:   git show --graph -s --pretty='%h %d%n' \
remote:      1f70043b34d3 1f70043b34d3~1 origin/master
remote: 
remote: To fix, there are two traditional solutions:
remote: 
remote:   1. (Preferred) rebase your branch:
remote: 
remote:       git rebase origin/master
remote:       git push origin master
remote: 
remote:   2. Redo the merge in the correct direction:
remote: 
remote:       git checkout master 
remote:       git reset --hard origin/master 
remote:       git merge --no-ff 1f70043b34d3eaedb750~1
remote:       git push origin master
remote: 

有关foxtrot合并的更多背景信息。

这里有一个钩子代码,可以满足您的要求:

#/垃圾箱/垃圾箱
#检查这是否是存储库中的第一次提交
如果git rev parse--验证HEAD>/dev/null 2>&1
然后
#我们将更改与上一次提交进行比较
顶头^
其他的
#初始提交:针对空树对象的差异
反对=4B825DC642CB6EB9A060E54BF8D6928FBEE4904
fi
#将输出重定向到屏幕。
执行器1>&2
#检查是否已更新主分支
如果[“$refname”eq“refs/heads/master”];
然后
#输出颜色
红色='\033[0;31m';
绿色='\033[0;32m';
黄色='\033[0;33m';
默认值='\033[0;m';
#个人接触:-)
回显“${red}”
回声“”
回声“|ZZzzz”
回声“|”
回声“|”
回声“|ZZzzz/^\|ZZzzz”
回声“| | ~~~| |”
回声“||-|/\”
回声“/^\|[]+| ^^^”
回声“|^^^^^^ | |+[]| | | |”
回音“|+[]|/\/\/\/\/\/\/\/\/\/\/\/\/\/^^^^^”
回声“|+[]+|~~~~~~~~~~~~~~~~~~~~~~~~~+[].”
回声“| |[]/^\[]+[]+[]+|”
回声“|+[]+|[]| | | |[]|+[]+|”
回声“|[]+| | | | | |[]+|”
回声“||||||||||||-------------------------|||||||||
回声“”
回声“”
echo“${green}您刚刚提交了代码${red}”
echo“您的代码${yellow}不正确。!!!”
echo“${red}不再提交”
回声“”
回显“${default}”
fi;
#根据需要将退出代码设置为0或1
#0=好推
#1=不推动退出。
出口0;

我写这篇文章是为了尽早提供反馈(
pre-receive
hook也是需要的).I为此使用
post merge
pre push
钩子。无法在commit msg钩子中阻止foxtrot合并,因为检测信息仅在之后可用。在
post merge
钩子中,我只是警告。在
pre push
钩子中,我抛出并阻止推送。请参阅(“狐步:添加子钩子以检测狐步合并”,2017-08-05)

~/.git hooks/helpers/foxtrot合并检测器:

#!/bin/sh

#usage:
#   foxtrot-merge-detector [<branch>]
#
# If foxtrot merge detected for branch (current branch if no branch),
# exit with 1.

# foxtrot merges:
# See http://bit-booster.blogspot.cz/2016/02/no-foxtrots-allowed.html
# https://stackoverflow.com/questions/35962754/git-how-can-i-prevent-foxtrot-merges-in-my-master-branch

remoteBranch=$(git rev-parse --abbrev-ref "$1"@{u} 2>/dev/null)
# no remote tracking branch, exit
if [[ -z "$remoteBranch" ]]; then
    exit 0
fi
branch=$(git rev-parse --abbrev-ref "${1-@}" 2>/dev/null)
# branch commit does not cover remote branch commit, exit
if ! $(git merge-base --is-ancestor $remoteBranch $branch); then
    exit 0
fi
remoteBranchCommit=$(git rev-parse $remoteBranch)
# branch commit is same as remote branch commit, exit
if [[ $(git rev-parse $branch) == $remoteBranchCommit ]]; then
    exit 0
fi
# remote branch commit is first-parent of branch, exit
if [[ $(git log --first-parent --pretty='%P' $remoteBranchCommit..$branch | \
    cut -d' ' -f1 | \
    grep $remoteBranchCommit | wc -l) -eq 1 ]]; then
    exit 0
fi
# foxtrot merge detected if here
exit 1
#!/bin/sh

remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000
while read local_ref local_sha remote_ref remote_sha
do
    if [ "$local_sha" = $z40 ]; then
        # handle delete, do nothing
        :
    else
        # ex $local_ref as "refs/heads/dev"
        branch=$(git rev-parse --abbrev-ref "$local_ref")
        ~/.git-hooks/helpers/foxtrot-merge-detector "$branch"
        # check exit code and exit if needed
        exitcode=$?
        if [ $exitcode -ne 0 ]; then
            echo 1>&2 "fatal: foxtrot merge detected, aborting push"
            echo 1>&2 "fatal: branch $branch"
            exit $exitcode
        fi
    fi
done
#!/bin/sh

~/.git-hooks/helpers/foxtrot-merge-detector
# check exit code and exit if needed
exitcode=$?
if [ $exitcode -ne 0 ]; then
    echo -e "  ${Yellow}WARNING:${None} foxtrot merge detected"
    # swallow exit code
fi
合并后:

#!/bin/sh

#usage:
#   foxtrot-merge-detector [<branch>]
#
# If foxtrot merge detected for branch (current branch if no branch),
# exit with 1.

# foxtrot merges:
# See http://bit-booster.blogspot.cz/2016/02/no-foxtrots-allowed.html
# https://stackoverflow.com/questions/35962754/git-how-can-i-prevent-foxtrot-merges-in-my-master-branch

remoteBranch=$(git rev-parse --abbrev-ref "$1"@{u} 2>/dev/null)
# no remote tracking branch, exit
if [[ -z "$remoteBranch" ]]; then
    exit 0
fi
branch=$(git rev-parse --abbrev-ref "${1-@}" 2>/dev/null)
# branch commit does not cover remote branch commit, exit
if ! $(git merge-base --is-ancestor $remoteBranch $branch); then
    exit 0
fi
remoteBranchCommit=$(git rev-parse $remoteBranch)
# branch commit is same as remote branch commit, exit
if [[ $(git rev-parse $branch) == $remoteBranchCommit ]]; then
    exit 0
fi
# remote branch commit is first-parent of branch, exit
if [[ $(git log --first-parent --pretty='%P' $remoteBranchCommit..$branch | \
    cut -d' ' -f1 | \
    grep $remoteBranchCommit | wc -l) -eq 1 ]]; then
    exit 0
fi
# foxtrot merge detected if here
exit 1
#!/bin/sh

remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000
while read local_ref local_sha remote_ref remote_sha
do
    if [ "$local_sha" = $z40 ]; then
        # handle delete, do nothing
        :
    else
        # ex $local_ref as "refs/heads/dev"
        branch=$(git rev-parse --abbrev-ref "$local_ref")
        ~/.git-hooks/helpers/foxtrot-merge-detector "$branch"
        # check exit code and exit if needed
        exitcode=$?
        if [ $exitcode -ne 0 ]; then
            echo 1>&2 "fatal: foxtrot merge detected, aborting push"
            echo 1>&2 "fatal: branch $branch"
            exit $exitcode
        fi
    fi
done
#!/bin/sh

~/.git-hooks/helpers/foxtrot-merge-detector
# check exit code and exit if needed
exitcode=$?
if [ $exitcode -ne 0 ]; then
    echo -e "  ${Yellow}WARNING:${None} foxtrot merge detected"
    # swallow exit code
fi

我很好奇“狐步合并”这个术语是从哪里来的…我发明了它!为什么只
master
分支?我想这适用于任何分支。是的,它适用于所有分支。我花了几个月的时间才意识到这一点。很好,尽管我会使用,例如
awk'{print$2}'
而不是