2

我有一个裸仓库,开发人员将他们的修补程序分支从他们在 Windows 上的本地仓库推送到。当分支被推送时,我会触发一个钩子来在 Linux 上构建他们的更改。如果我为分支创建工作树,这很容易做到。然而,repo 包含数十个数千个文件,并且让每个开发人员的修补程序分支为所有对象创建一个工作树,而他们只对少数几个对象进行更改,这会耗费大量时间并消耗文件系统。

有没有办法让开发人员推送到裸仓库,然后在挂钩中仅将更改的源提取到目录结构,以便我可以进行有效的构建过程?

想法?

示例 developer_a 将他从 Dev 分支分支出来的 HF1 分支推送回 Linux 构建服务器上的远程裸仓库。

如果我执行 HF1 和 dev 分支的“git diff”,我可以看到已更改的文件列表。

diff-tree -r --no-commit-id --name-only HF1..dev

/APP/SOURCE/Program1.cbl

在上述命令中使用该文件的任何尝试都会失败,因为工作树不存在。

我想生成这个 diff,然后直接从 repo 中提取 diff 中列出的文件到目标目录。

4

2 回答 2

1

我想生成这个 diff,然后直接从 repo 中提取 diff 中列出的文件到目标目录。

这听起来像是 Git在检查已设置为给定提交的工作树中的分支时已经在本地执行的操作。

如果您的构建工作树处于某个提交状态,则该钩子可以触发对新推送的 SHA1 的 git checkout:工作树将检测更改并自行更新(通过 post-receive 钩子触发的 git checkout)以仅更新是需要的。

于 2019-04-20T01:23:32.060 回答
1

这是我编写的一个接收后脚本,用于消除分支使用工作树进行构建的需要,该构建触发了将分支推送到构建服务器。该脚本执行以下操作:

  • 确定要推送的分支。
  • 标识更改的源组件。
  • 在定义的构建环境中构建构建树。
  • 填充构建树并触发编译和部署。

如果有诸如包含文件之类的通用组件,那么 master 和 dev 分支需要一个工作树。构建环境将根据需要连接这些包含目录。

dev 推送将与主仓库不同,而从 dev 分支分支的用户分支将与 dev 不同。

接收后挂钩

#!/bin/bash
###########################################################################

function get_files {
# determine the changed files and extract them from the repo to the build structure.
    git diff-tree -r ${ORIGIN}..${BRANCH} |
        while IFS= read -r line
        do
        COMMIT_ID=$(echo $line | cut -f4 -d" " )
        SOURCE=$(echo $line | cut -f6 -d" " )
            echo "Identified: " ${SOURCE} " Commit: " ${COMMIT_ID}
        TARGET=$(basename ${SOURCE})
        echo "Target : " ${TARGET}  
        echo ${TARGET} >> ${BUILD_PATH}/etc/build.txt

        echo "Extracting source from repo: " $SOURCE
        git show ${COMMIT_ID} > ${BUILD_PATH}/${SOURCE}
    done
}

function build_targets {
    FILES=$(cat ${BUILD_PATH}/etc/build.txt)
    for i in $FILES
    do
        echo "Compiling: " $i
    done
}

function prep_build_tree {
#Check if build structure exists
        if [[ -d ${BUILD_PATH} ]]
        then
# clean source from the local build structre by removing and rebuilding it
            echo "Cleaning old build structure"
            find ${BUILD_PATH} -type f -exec rm -v {} \;
        else
# Create build structure
            echo "Creating build structure"
            mkdir -p ${BUILD_PATH}/APP/SOURCE
            mkdir -p ${BUILD_PATH}/APP/COPY
            mkdir -p ${BUILD_PATH}/etc
            mkdir -p ${BUILD_PATH}/LOADLIB
        fi
}

##############################################################################

read oldrev newrev refname
echo "Old revision: $oldrev"
echo "New revision: $newrev"
echo "Reference name: $refname"

BASE_DIR=/home/mfcobol/SDLC/BUILD/Dev-Build
BRANCH=$(basename $refname)

#determine build type:
#   dev branch performs build using the dev build structure checked against master
#       other branches perform local builds for that branch only checked against dev.
case $BRANCH in

    dev ) BUILD=dev 
        echo "Dev build identified: Branch: "${BRANCH} 
        ORIGIN=master
        BUILD_PATH=${BASE_DIR}/${BUILD}/${BRANCH}
        prep_build_tree
        get_files
        build_targets ;;


    * )   BUILD=user
        echo "User build identified: Branch: "${BRANCH}
        ORIGIN=dev
        BUILD_PATH=${BASE_DIR}/${BUILD}/${BRANCH}
        prep_build_tree
        get_files
        build_targets ;;
esac
于 2019-04-22T23:40:52.120 回答