Ключ для надійного "сценарію" Git - використання команд "сантехніка".
Розробники дбають про зміну команд сантехніки, щоб переконатися, що вони забезпечують дуже стабільні інтерфейси (тобто задана комбінація стану репозиторію, stdin, параметрів командного рядка, аргументів тощо) дасть однаковий вихід у всіх версіях Git, де команда / варіант існує). Нові варіанти виведення команд сантехніки можуть бути введені за допомогою нових параметрів, але це не може створити жодних проблем для програм, які вже написані проти старих версій (вони б не використовували нові параметри, оскільки їх не було (або принаймні були не використовується) на момент написання сценарію).
На жаль, "щоденні" команди Git - це "порцелянові" команди, тому більшість користувачів Git, можливо, не знайомі з сантехнічними командами. Розмежування порцелянової та сантехнічної команд проводиться на головній сторінці git (див. Підрозділи під назвою Команди високого рівня (фарфор) та команди низького рівня (сантехніка) .
Щоб дізнатися про невмілі зміни, вам, ймовірно, знадобиться git diff-index
(порівняйте індекс (а може бути відслідковуються біти робочого дерева) з деяким іншим деревним (наприклад HEAD
)), можливо git diff-files
(порівняйте робоче дерево з індексом) і, можливо,git ls-files
(список файлів; наприклад, список не відслідковується , невідомі файли).
(Зверніть увагу, що в наведених нижче командах HEAD --
використовується замість того, HEAD
що в іншому випадку команда не працює, якщо є файл з ім'ямHEAD
.)
Щоб перевірити, чи репозиторій здійснив поетапні зміни (ще не здійснені), скористайтеся цим:
git diff-index --quiet --cached HEAD --
- Якщо він закінчується,
0
тоді відмінностей 1
не було ( значить, були відмінності).
Щоб перевірити, чи має робоче дерево зміни, які можна було б поетапно:
git diff-files --quiet
- Код виходу такий же, як і для
git diff-index
( 0
== немає різниць; 1
== відмінності).
Щоб перевірити, чи змінилися комбінація індексу та відстежуваних файлів у робочому дереві стосовно HEAD
:
git diff-index --quiet HEAD --
- Це як поєднання попередніх двох. Одна з головних різниць полягає в тому, що він все одно буде повідомляти про "відсутність відмінностей", якщо у вас є поетапна зміна, яку ви "відмінили" в робочому дереві (повернувся до вмісту, який є
HEAD
). У цій самій ситуації обидві окремі команди обидва повертають звіти про «наявні відмінності».
Ви також згадали про незахищені файли. Ви можете означати "без трекінгу та без уваги", а також просто "без треку" (включаючи ігноровані файли). У будь-якому випадку,git ls-files
це інструмент для роботи:
Для "без трекінгу" (буде включати ігноровані файли, якщо вони є):
git ls-files --others
Для "не відстежуваних та невідомих":
git ls-files --exclude-standard --others
Перша моя думка - просто перевірити, чи мають ці команди вихід:
test -z "$(git ls-files --others)"
- Якщо він закінчується,
0
тоді файлів без відстеження немає. Якщо він закінчується, 1
тоді існують файли без відстеження.
Є невелика ймовірність, що це переведе ненормальні виходи із git ls-files
звітів "не відстежуваних файлів" (обидва призводять до ненульових виходів з вищевказаної команди). Трохи більш надійна версія може виглядати так:
u="$(git ls-files --others)" && test -z "$u"
- Ідея така ж, як і в попередній команді, але вона дозволяє несподіваним помилкам
git ls-files
поширюватися. У цьому випадку ненульовий вихід може означати "є неповернені файли", або це може означати помилку. Якщо ви хочете, щоб результати "помилки" поєднувалися з результатом "без відстежуваних файлів", скористайтеся test -n "$u"
(де вихід 0
означає "деякі незатребувані файли", а ненульовий означає помилку або "не відстежувані файли").
Інша ідея полягає у використанні --error-unmatch
для того, щоб викликати ненульовий вихід, коли файлів не відслідковується. Це також ризикує поєднати "файли без відстеження" (вихід 1
) з "помилкою" (вихід не нульовий, але, ймовірно, 128
). Але перевірка 0
порівняно 1
проти ненульових кодів виходу, ймовірно, є досить надійною:
git ls-files --others --error-unmatch . >/dev/null 2>&1; ec=$?
if test "$ec" = 0; then
echo some untracked files
elif test "$ec" = 1; then
echo no untracked files
else
echo error from ls-files
fi
Будь-який із перерахованих вище git ls-files
прикладів може взяти, --exclude-standard
якщо ви хочете врахувати лише неполічені та невідомі файли.