Экспорт измененных и добавленных файлов из простого репозитория без рабочего дерева в каталог для компиляции или развертывания

#git #git-diff #git-archive

#git #git-diff #git-архив

Вопрос:

У меня есть простой репозиторий, в который разработчики отправляют свои ветки исправлений из своего локального репозитория в Windows. При нажатии на ветку я запускаю перехват для создания их изменений в Linux. Это легко сделать, если я создам рабочее дерево для ветки. Тем не менее, репозиторий содержит 10 тысяч файлов, и то, что каждая ветвь исправлений разработчика создает рабочее дерево для всех объектов, когда они вносят изменения только в несколько, требует огромных затрат времени и истощает файловую систему.

Есть ли способ позволить разработчикам перейти к голому репозиторию, а затем извлечь только измененные источники в структуру каталогов, чтобы у меня был эффективный процесс сборки?

Идеи?

Пример developer_a отправляет свою ветку HF1, которая была отделена от ветки Dev, обратно в удаленное открытое репозиторий на сервере сборки Linux.

В перехватчике, если я выполняю «git diff» ветки HF1 и dev, я вижу список файлов, которые были изменены.

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

/APP/SOURCE/Program1.cbl

Любая попытка использовать этот файл в приведенной выше команде завершается неудачей, поскольку рабочее дерево не существует.

Я хотел бы сгенерировать этот diff, а затем извлечь непосредственно из репозитория файлы, перечисленные в diff, в целевой каталог.

Ответ №1:

Я хотел бы сгенерировать этот diff, а затем извлечь непосредственно из репозитория файлы, перечисленные в diff, в целевой каталог.

Это похоже на то, что Git уже делает изначально, когда проверяет ветку в рабочем дереве, уже установленную для данного коммита.

Если ваше рабочее дерево построения находится на определенной фиксации, перехват может вызвать проверку git нового нажатого SHA1: рабочее дерево само обнаружит изменения и обновит себя (через проверку git, запускаемую перехватом после получения), чтобы обновить только то, что необходимо.

Комментарии:

1. Да, «Git diff» выполнит эту задачу. Тем не менее, у меня есть репозиторий из более чем 10 000 программ. Для того, чтобы это работало из ворот, вам нужно рабочее дерево. Рабочее дерево автоматически заполняется всеми 10 000 программами. 50 разработчиков создают свою собственную работу в своих отдельных ветвях исправлений, что требует, чтобы все 50 ветвей имели собственное рабочее дерево. Это создает не только проблему с производительностью, но и массовое дублирование на диске для тысяч компонентов, которые не нужны для поддержки сборки нескольких объектов, измененных в ветке. Смотрите Мой следующий пост для лучшего решения.

Ответ №2:

Вот сценарий после получения, который я написал, чтобы исключить необходимость использования веткой рабочего дерева для сборки, запускаемой при отправке ветки на сервер сборки. Этот скрипт выполняет следующее:

  • Определяет передаваемую ветку.
  • Определяет измененные исходные компоненты.
  • Создает дерево сборки в определенной среде сборки.
  • Заполняет дерево сборки и запускает компиляцию и развертывание.

Если есть общие компоненты, такие как включаемые файлы, то для ветвей 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