Git钩子预推提示来壁球首先提交 [英] Git hook pre-push prompt to squash commits first
问题描述
我不确定我是否要采用正确的方法.对Git和GitKraken来说是新的.我想强迫其他人在推送和创建请求请求之前压扁他们的功能分支提交.因此,我尝试了以下预按git钩,但是即使我先将其压扁认为有多个提交.我想念什么?谢谢!
I'm not sure if I'm going about this the correct way. Sorta new to Git and GitKraken. I want to force others to squash their feature branch commits before pushing and creating a pull request. So I've tried the following pre-push git hook but even when I squash first it still thinks there are multiple commits. What am I missing? Thanks!
#!/bin/sh
# An example hook script to verify what is about to be pushed. Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed. If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
# <local ref> <local sha1> <remote ref> <remote sha1>
remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000
while read local_ref local_sha remote_ref remote_sha
do
if [ "$local_sha" = $z40 ]
then
# Handle delete
:
else
# Check for number of commits
commits=`git rev-list --count "$local_sha"`
if [ "$commits" -ne "1" ]
then
echo "Multiple commits detected, push aborted. Please squash your local branch before pushing."
exit 1
#git reset --soft HEAD~"$commits"
#git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
fi
fi
done
exit 0
推荐答案
TL; DR
您要git rev-list --count $local_sha ^$remote_sha
(但请参见下面的警告).
TL;DR
You want git rev-list --count $local_sha ^$remote_sha
(but see caveat below).
git rev-list
是git log
的老大哥(姐姐?)管道变体:默认情况下,两者都会从开始您给他们的提交,然后找到这些提交中可以到达的每个提交.
git rev-list
is the big brother (sister?) plumbing variant of git log
: both will, by default, start from the commit(s) you give them, and find every commit reachable from those commits.
也就是说,给定一个提交图,例如:
That is, given a commit graph like:
... <-E <-F <-G <-- branchname
您告诉Git从branchname
开始,它标识了提交G
(这里的G
代表实际的40个字符的哈希ID),因此git log
向您显示该提交.然后,由于G
以F
作为其父级(G
指向F
),因此git log
向您显示F
.由于F
以E
作为其父级,因此git log
接下来将显示E
,依此类推.
you tell Git to start from branchname
, which identifies commit G
(G
here stands in for the actual 40-character hash ID), so git log
shows you that commit. Then, since G
has F
as its parent (G
points to F
), git log
shows you F
. Since F
has E
as its parent, git log
shows you E
next, and so on.
修订列表代码执行相同的操作:您告诉它从哪里开始-$local_sha
-它列出了提交的哈希,其父哈希,以及其父的更多哈希,以及很快.添加--count
使其计数,并且可能有很多.
The rev-list code does the same thing: you tell it where to start—$local_sha
—and it lists that commit's hash, and its parent(s) hash(es), and more hashes of their parents, and so on. Adding --count
makes it count them up, and there are probably many.
您需要告诉沿着图停止位置的Git命令.鉴于:
You need to tell the Git commands that walk the graph where to stop. Given:
E--F--G <-- branchname
您可以告诉git rev-list
以G
开头(按哈希ID或名称),但要 stop (不包括)E
(按哈希ID或依据)名称,如果有指向E
的名称).您可以通过多种方式来命名停止点提交,但是最直接的是帽子前缀:^E
表示在E
处停止,或者从E
可以到达的任何提交.
you can tell git rev-list
to start at G
(by hash ID, or by name), but to stop (and not include) E
(by hash ID, or by name if there's a name that points to E
). You can name stopping-point commits in many ways, but the most direct is the hat-prefix: ^E
means stop at E
, or any commit reachable from E
.
此可达性概念在更复杂的图形中非常重要:
This reachability notion is very important in more complex graphs:
B--C
/ \
A F--G <-- branchname
\ /
D--E
连接提交的箭头(我一直在这里绘制为线)都是单向的:它们都在时间上向后指向.所以F
在这里指向E
和C
,因为F
在这里是合并提交. C
指向B
,它指向A
; E
指向D
,它也指向A
.
The arrows connecting commits (which I've been drawing as lines here) are all one-way: they all point backwards in time. So F
points back to both E
and C
here, because F
here is a merge commit. C
points back to B
, which points back to A
; E
points back to D
, which also points back to A
.
如果将E
命名为终止点,并且将G
命名为起始点,则git rev-list
将跳过提交E
,D
和A
,但是仍将包含提交B
和C
,因为可以从F
进行访问.要同时排除B
和C
,必须在停止点列表中添加^C
.
If you name E
as a stopping point and G
as the starting point, git rev-list
will skip commits E
, D
, and A
, but will still include commits B
and C
, because those are reachable from F
. To exclude B
and C
as well, you must add ^C
to your list of stopping points.
通常,在预推钩子中,您可以仅将远程哈希列为(单个)停止点,但还有一个更普遍的问题:您可能没有提交远程哈希指向.您可以通过运行git fetch
从远程获取提交.它们-您正在访问的另一个存储库-由在此提交的某人或也对该存储库的其他人进行的提交.您可能还没有他们的提交.如果是这样,则必须首先运行git fetch
,以便您自己的Git拥有提交,以便您的Git可以从其哈希ID开始遍历提交图.
In general, in a pre-push hook, you can just list the remote hash as the (single) stopping point, but there's a more general problem: you might not have the commit that the remote-hash points-to. You get commits from the remote by running git fetch
. They—the other repository to which you are git push
ing—get commits by someone committing there, or by other people also git push
ing to that repository. You might not have their commit(s) yet. If so, you'll have to run git fetch
first, so that your own Git has the commit, so that your Git can walk the commit graph starting from their hash ID.
这篇关于Git钩子预推提示来壁球首先提交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!