Изменение каталога в bash не влияет на хук после фиксации

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

я пытался бежать 1- cd ../ && перед каждой командой 2- сделать псевдоним, но не получилось 3- запустить exec, но скрипт не продолжился

#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "post-commit".
commit_msg= git log -1 --pretty=%B
if [[ $(git branch | grep \* | cut -d ' ' -f2) == "int1177/next" ]]; then
    cd ..
    if [[ $(git branch | grep \* | cut -d ' ' -f2) == "B0/next" ]]; then
        git add 6_Tests
        git commit -m "bs esss"
        echo "development branch B0/next has now new commit"
    else
        echo "development branch isn't B0/next"
    fi
else
    echo "current branch isn't int1177/next"    
fi

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

tripleee 12.06.2019 04:50

Простая идея состоит в том, чтобы ваша интерактивная оболочка контролировала текущий каталог на наличие файла и source, а затем удаляла его, если он существует. Это достаточно просто, но, конечно, не совсем беспроблемно (безопасность? Угловые случаи, например, что, если несколько интерактивных оболочек имеют один и тот же рабочий каталог?)

tripleee 12.06.2019 04:54

я пытался создать файл foo.sh внутри репозитория и добавил в источник хука foo.sh, но он тоже не работает ... это то, что вы подразумеваете под интерактивным монитором оболочки?

Mo SAEED 12.06.2019 05:05

Я повторяю: хук не может изменить среду родительской оболочки, в которой вы запускаете Git. Вы должны заставить свою интерактивную оболочку каким-то образом взаимодействовать с хуком — тем, который отображает подсказку и позволяет вам вводить команды, такие как git commit. Если вы используете Bash, возможно, стоит добавить что-нибудь в PROMPT_COMMAND.

tripleee 12.06.2019 05:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
498
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На самом деле, эта конкретная проблема связана не с bash, а с Git.

Почему «cd» не работает в сценарии оболочки? в целом действителен и является подходящим ответом на многие вопросы разное. Но этот конкретный post-commit хук пытается chdir выйти из подмодуля в его родительский суперпроект, а затем сделать фиксацию внутри родительского суперпроекта. Это является возможно. Это может быть плохой идеей по другим причинам — в общем случае неразумно заставлять обработчики коммитов Git создавать коммиты, даже в других репозиториях1 — но в данном конкретном случае вы сталкиваетесь с тем фактом, что Git находит свои каталоги через переменные среды.

В частности, есть переменная среды GIT_DIR, которая сообщает Git: Каталог .git, содержащий репозиторий, находится по этому пути. Когда Git запускает хук Git, Git обычно устанавливает $GIT_DIR на . или .git. Если $GIT_DIR установлен нет, Git найдет каталог .git с помощью поиска в дереве каталогов, но если установлен $GIT_DIRявляется, Git предполагает, что $GIT_DIR установлен правильно.

Решение снят с охраныGIT_DIR:

unset GIT_DIR
cd ..

Остальные команды подоболочки будут выполняться в каталоге на один шаг вверх, и теперь, когда $GIT_DIR больше не установлено, Git будет искать в рабочем дереве суперпроекта каталог .git для суперпроекта.

Попутно это:

$(git branch | grep \* | cut -d ' ' -f2)

это неуклюжий способ получить имя текущей ветки. Использовать:

git rev-parse --abbrev-ref HEAD

вместо этого здесь. (Другой вариант — git symbolic-ref --short HEAD, но он не работает с отсоединенным HEAD, в то время как вы, вероятно, хотите, чтобы тихий результат был просто словом HEAD, которое выдаст метод rev-parse.)


1Основная опасность в случае с это заключается в том, что репозиторий суперпроекта не обязательно в состоянии обрабатывать коммит прямо сейчас. Редактировать: или, как обнаружено в этот комментарий, даже не настроен на быть суперпроект для этого подмодуля, тем более для добавления фиксации обновления подмодуля.

Большое спасибо, что касается упомянутой вами повышенной опасности, вы правы, если ветка int1177/next является нормальной веткой. однако это специальная ветвь (ветвь интеграции), в которой только интегратор имеет доступ к фиксации и фиксирует или объединяет только при добавлении или интеграции новой функции.

Mo SAEED 13.06.2019 12:10

я пробовал, и у меня это работает, но возникает другая проблема: выполнение git add 6_Tests создание подмодуля 6_Tests в 6_Tests со следующим предупреждением в журнале: warning: adding embedded git repository: 6_Tests hint: You've added another git repository inside your current repository. hint: Clones of the outer repository will not contain the contents of hint: the embedded repository and will not know how to obtain it. hint: If you meant to add a submodule, use: hint: git submodule add <url> 6_Tests hint: If you added this path by mistake, you can remove it

Mo SAEED 13.06.2019 13:53

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

torek 14.06.2019 03:05

Выполнение вложенного вызова git в очищенной подоболочке, например. ( eval unset ${!GIT_*}; your; commands; here) может быть лучшим планом, Git может установить другие, если не сейчас, то в будущем выпуске..

jthill 14.06.2019 03:47

@jthill: возможно, да. Однако неясно, будет ли правильным просто произвольное удаление переменных всеGIT_*.

torek 14.06.2019 04:02

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

jthill 14.06.2019 04:32

... Итак, прошло шесть недель, и мой задний мозг наконец понял, что вы говорите: вы не хотите сбрасывать такие вещи, как GIT_EDITOR и GIT_DISCOVERY_ACROSS_FILESYSTEMS, если у пользователя они установлены, вы должны использовать $(git rev-parse --local-env-vars) вместо ${!GIT_*}. Верно.

jthill 05.08.2019 18:40

@jthill: Верно, но я не знал, что --local-env-vars существует, это довольно мило!

torek 05.08.2019 18:41

Другие вопросы по теме