在服务器上,有两个选项,即
预接收
和
更新
钩子。(对于这种特殊情况,我可能会自己使用更新挂钩。)
预接收钩子调用一次,标准输入连接到包含所有建议的引用更新的管道。您应该读取所有stdin行,并使用新旧散列ID和所有引用的名称来决定
整个的
允许继续推送,或
整个的
一次拒绝所有名称更新。也就是说,假设某个客户端已运行:
git push origin hash1:name1 hash2:name2 ... hashN:nameN
所以有
n
上的更新请求
n
stdin的行,你的预接收钩子要么接受全部,要么拒绝全部。若要接受全部,请以零状态退出;若要禁止全部,请以任何非零状态退出。最好打印
原因
对于拒绝,如果您退出非零,那么客户将看到您为什么这样做。
在预接收钩子(如果有)允许整个进程进入第二阶段之后,每次建议的更新都调用一次更新钩子。它有三个
位置的
参数,该参数提供与预接收挂钩的一个输入行上输入的信息相同的信息。您应该检查这两个散列ID和名称,并决定是否
这个特别的更新
是允许的。
也就是说,给定相同的客户端调用,将调用更新挂钩
n
分开的时间。例如,第二个将有:
$1: refs/heads/name2
$2: the old hash ID (or the all-zeros "null hash")
$3: the new hash ID (or all-zeros)
如果你愿意
name2
设置为指向新的散列ID,使更新挂钩以零(成功)状态退出。如果不是,让它以非零状态退出。同样,如果要拒绝更新,最好打印一些内容。
关于服务器端钩子
每个引用,钩子接收一个旧的散列ID(
$old
在下面),一个新的(
$new
)
全名
参考文献:
refs/heads/
name
如果引用是分支名称,
refs/tags/
name
如果是标记名,
refs/notes/
name
如果它是一个注释引用,等等。更新挂钩具有更细的粒度,但无法将建议的更新作为一个整体查看。
最多一个
旧美元
或
$新
都是零。如果是这样,则引用将被createde.g.,一个新的分支或标记销毁。否则,它是一个就地更新:引用
目前
指向哈希ID
旧美元
还有跑步的人
git push
建议将其更改为指向哈希ID
$新
。
这些钩子非常有效,但很难写。特别是,如果引用是
更新的
很清楚该做什么:更新将在
$old..$new
范围,因此:
git rev-list $old..$new | while read rev; do
# examine the files in $rev
done
足以让你检查每个提议的内容
新的
承诺。(有些犯罪可能是
删除
这些可以通过检查找到。
$new..$old
)
但是,如果引用是
新创建的
,
旧美元
都是零。仅凭这一特定的参考文献是不可能确定哪些参考文献是新引入的。你
可以
使用以下技巧:
git rev-list $new --not --all
枚举可从建议的新引用(而不是从任何当前引用)访问的提交。不过,这可能会产生误导:可能是请求创建三个新的分支名称:
...--o--o--o <-- master
\
A--B <-- newbranch1
\
C <-- newbranch2
\
D--E--F <-- newbranch3
在隔离状态下,设置
newbranch3
指向哈希ID为的提交
F
看起来像是一个添加所有六个提交的请求(它是!)但你可能更愿意
看法
作为一个请求
三
在其他添加的分支之后提交
newbranch2
,例如。无法在更新挂钩中生成此视图。它
是
可能(但很难)在预接收钩子中产生它,因为它可以告诉所有三个
newbranch*
名字是新的。