Shell script, чтобы проверить git на изменения, а затем прокрутить измененные файлы?
Я пытаюсь написать оболочку script, которая делает следующее:
- Проверяет удаленный репозиторий git на любые изменения.
- Если изменения в удаленном репозитории git вызывают эти изменения.
- Прокручивает файлы, которые являются новыми или были изменены.
В ходе моих исследований я нашел некоторые необходимые команды для выполнения этих задач, но мне не удалось заставить их работать вместе в оболочке script.
Вот script с некоторыми из команд, которые у меня есть:
#!/bin/sh
#Check if there are any changed files
git --git-dir="/dir/.git" fetch origin
if git --git-dir="/dir/.git" log HEAD..origin/master --oneline
then
#Output the modified files from the last pull
git --git-dir="/dir/.git" diff --name-status ORIG_HEAD..
fi
То, что мне не удалось получить с командами в этом script, это:
- Оператор if, проверяющий, есть ли изменения или не всегда, является истинным. Я пробовал, если инструкции с другими командами git, и они также всегда верны. Кажется, что git не работает, как обычные команды оболочки, где вы получаете ответ 0 или 1. Как я могу получить команду git, подобную той или иной команде git, чтобы возвращать правильные ответы в инструкции if?
- Как я могу назначить переменные, выводимые из команды, чтобы увидеть измененные файлы в массиве, чтобы я мог их прокручивать, используя для?
Если команды в моем script не будут работать в этом случае, что лучший способ сделать это?
Изменить: извините, если я прокрутил измененные файлы, мне нужно вытащить изменения из удаленного репозитория, прежде чем прокручивать файлы, чтобы при работе с этими файлами у меня были последние изменения.
Ответы
Ответ 1
Для вашего первого вопроса вы можете использовать git diff --quiet
(или git diff --exit-code
), но обычно, когда вы используете его для кода выхода, вы хотите, чтобы он не печатал вывод так или иначе, а git diff --quiet
подразумевал --exit-code
). чтобы определить, были ли какие-либо изменения. Это даст вам 1 значение, если есть изменения, и 0, если нет. Поэтому, если вы хотите иметь код, который будет работать, только если есть изменения:
if ! git --git-dir="/dir/.git" diff --quiet
then
# do stuff...
fi
Для вашего второго вопроса я рекомендую цикл while read ...
для чтения строк из git diff-tree
:
git --git-dir="/dir/.git" diff-tree ORIG_HEAD.. | \
while read srcmode dstmode srcsha dstsha status srcfile dstfile
do
# do something with $srcfile and $dstfile
done
Обратите внимание, что $srcmode
будет иметь дополнительный :
в начале, а $dstfile
будет иметь значение, только если файл был переименован. Если вы не хотите беспокоиться о переименованиях, перейдите в --no-renames
, и вместо просмотра переименований вы увидите только добавление и удаление.
Ответ 2
Вы правы, git
обычно не выходит с ненулевым статусом, если нет ошибки. Самый простой способ обнаружить незафиксированные изменения - вот что:
let changes=0
while read status filename; do
let changes=1
# do something with this filename/status
done < <(git status --porcelain)
if (( ! changes )); then
echo "No changes."
fi
В общем случае, если вы попытаетесь использовать git из кода, вы должны использовать --porcelain
для тех подкоманд, которые его поддерживают, чтобы сделать его более удобным для автоматизации. Вы также можете исследовать библиотеки для других языков для взаимодействия с git без создания собственных команд оболочки; например, в Ruby grit.
Теперь, в вашем случае, вы хотите определить, что изменилось вверх по течению. Для этого вы, вероятно, захотите использовать git diff-tree
. Аналогичная логика выше:
git fetch # not pull
while read filename; do
# do something with filename
done < <(git diff-tree --name-only origin/master master) # or whatever branch you're using
Ответ 3
Вы можете просто использовать git diff --name-only
для отображения всех файлов с именами файлов.
Например, здесь простой script для отображения всех файлов PHP, отредактированных и протестированных синтаксисом.
#!/bin/bash
files=`git diff --name-only | grep -E '.php$' `
for file in $files; do
php -l $file
done