Git钩前推送提示首先压缩提交

时间:2018-02-09 21:10:26

标签: git github version-control githooks gitkraken

我不确定我是否以正确的方式解决这个问题。排序Git和GitKraken。我想在推送和创建拉取请求之前强制其他人压缩他们的功能分支提交。所以我尝试了以下pre-push git hook,但即使我先挤压它仍然认为有多个提交。我错过了什么?谢谢!

#!/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

1 个答案:

答案 0 :(得分:1)

TL; DR

您想要git rev-list --count $local_sha ^$remote_sha(但请参阅下面的警告)。

git rev-listgit log的大兄弟(姐妹?)管道变体:默认情况下,开始提交你的提交,并且找到从这些提交中可以访问的每个提交

也就是说,给定一个提交图:

... <-E <-F <-G   <-- branchname

你告诉Git从branchname开始,它标识了提交G(此处G代表实际的40个字符的哈希ID),因此git log显示提交。然后,由于G已将F作为其父级G指向F),git log会向您显示F。由于F已将E作为其父级,git log会向您显示E,依此类推。

rev-list代码做同样的事情:你告诉它从哪里开始 - $local_sha - 它列出了提交的哈希,它的父哈希(s),以及它们父母的更多哈希, 等等。添加--count会使它计算起来,并且可能有很多。

您需要告诉Git命令走图停止的位置。给出:

E--F--G   <-- branchname

您可以告诉git rev-listG开始(按哈希ID或按名称),但停止(不包括)E(通过哈希ID或名称,如果有一个名称指向E)。您可以通过多种方式命名停止点提交,但最直接的是帽子前缀:^E表示停在E,或任何可从E到达的提交

可达性概念在更复杂的图表中非常重要:

  B--C
 /    \
A      F--G   <-- branchname
 \    /
  D--E

连接提交的箭头(我在这里作为线条绘制)都是单向的:它们都指向时间倒退。因此,此F指向EC,因为此处F合并提交C指向B,指向A; E指向D,也指向A

如果您将E命名为停靠点而G为起点,git rev-list将跳过提交ED和{{1但仍然会包含提交AB,因为可以从C访问这些提交。要同时排除FB,您必须将C添加到停靠点列表中。

通常,在预推钩中,您可以将远程哈希列为(单个)停止点,但是存在一个更普遍的问题:您可能 提交了remote-hash points-to。您可以通过运行^C从远程进行提交。它们 - 您在其中提交的git fetch ing-get提交的其他存储库,或者由其他人git push提交到该存储库。你可能还没有他们的提交。如果是这样,你必须首先运行git push,这样你自己的Git才能提交,这样你的Git就可以从它们的哈希ID开始提交提交图。