Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.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_Githooks_Changeset - Fatal编程技术网

git钩子在自动提交后获取变更集

git钩子在自动提交后获取变更集,git,githooks,changeset,Git,Githooks,Changeset,我有一个钩子,它可以将更改的文件复制到一个目录,它可以用于标准提交,但是合并的自动提交会破坏它,因为最后两次提交不包含任何更改的文件 这是我目前的代码 generateChangeSet() { if [ ! -d $WORKDIR ];then mkdir $WORKDIR fi CHANGESET=$(git log -1 --name-status $oldrev $newrev | grep -v -e "^Merge" -e "^commit"

我有一个钩子,它可以将更改的文件复制到一个目录,它可以用于标准提交,但是合并的自动提交会破坏它,因为最后两次提交不包含任何更改的文件

这是我目前的代码

generateChangeSet() {
    if [ ! -d $WORKDIR ];then
        mkdir $WORKDIR
    fi

    CHANGESET=$(git log -1 --name-status $oldrev $newrev | grep -v -e "^Merge" -e "^commit" -e "^Author" -e "^Date" -e "^ " -e "^$")
    if [ -z $CHANGESET ]; then
      echo Could not detect any files in the change set, aborting push
      exit $RETVAL
    fi

    # Get a list of deleted files
    DELFILES=$WORKDIR/deletedFiles.sh
    if [ -f $DELFILES ];then
        rm -rf $DELFILES
    fi

    for dFile in $(echo $CHANGESET | grep "^D" | awk '{print $2}'); do
        echo deleted file $dFile
        echo rm -f $dFile >> $DELFILES
    done
    if [ -f $DELFILES ];then
        sed -i '1s/^/#!\/bin\/bash\n/' $DELFILES
        chmod +x $DELFILES
        echo find . -depth -type d -empty >> $DELFILES
        echo rm deletedFiles.sh >> $DELFILES
    fi

    echo "Generating diff between $newrev and $oldrev"
    git archive HEAD $(echo $CHANGESET | grep -v "^D" | awk '{print $2}') | (cd $WORKDIR && tar xf -)
}
关于如何让脚本始终获取最新更改的文件,有什么想法吗


谢谢

首先,我担心目标(
$WORKDIR
?)可能与此处计算的增量不同步。为什么要通过shell脚本导出删除?为什么不
git checkout
直接进入一个新的目标(设置
git\u WORK\u TREE
这样做),例如:

(这可能需要添加某种锁定,以及更多的充实)。但是,如果您决定继续使用现有的代码(可能有这样做的原因),那么这一部分就是愚蠢的:

CHANGESET=$(git log-1——名称状态$oldrev$newrev | grep-v-e“^Merge”-e“^commit”-e“^Author”-e“^Date”-e“^”-e“^$”


相反,使用
git diff tree--name status$oldrev$newrev
来区分与给定提交关联的树。剩下的应该很简单。当然,这一切都假设,
$oldrev
准确地反映了正在更新的内容的状态。

关于$WORKDIR不同步的说法是正确的。首先,我这样做的原因是,出于历史原因,源包含硬编码的DB模式,我的任务是在修复到位之前,将代码从git获取到测试服务器,并用测试服务器上的模式替换DB模式。我在变更集上这样做的原因是,只要有超过25k的文件,对整个源代码执行搜索和替换就需要很长时间。我面临的问题是,$oldrev在自动提交发生时没有正确反映,例如在合并之后,也许您应该在某处记录($WORKDIR?)上次更新(通过挂钩)是什么。然后,您可以使用
git diff tree
将该版本与
$newrev
进行比较,而不是
$oldrev
(我假设$oldrev来自钩子的输入)。
what_to_replace=/some/where/tree
tmp_replacement=/some/where/tree.new

rm -rf $tmp_replacement
mkdir $tmp_replacement || fatal "can't create $tmp_replacement"

GIT_WORK_TREE=$tmp_replacement git checkout master -- . ||
    fatal "can't create updated master branch tree"
mv $what_to_replace ${what_to_replace}.old &&
    mv $tmp_replacement $what_to_replace ||
    fatal "can't swap in $tmp_replacement"
rm -rf ${what_to_replace}.old ||
    warn "can't clean up ${what_to_replace}.old"