Перевірте, чи потрібно тягнути в Git


622

Як перевірити, чи змінився віддалений сховище, і мені потрібно витягнути?

Зараз я використовую цей простий сценарій:

git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1

Але він досить важкий.

Чи є кращий спосіб? Ідеальним рішенням було б перевірити всі віддалені гілки та повернути назви змінених гілок та кількість нових комісій у кожній.


14
Зверніть увагу: "git pull --dry-run" працює не так, як можливо, очікувалося. Здається, що git pull передає невідомі варіанти безпосередньо для отримання git fetch. Результат - нормальне тягнення кишки.

27
"тягнути" - це лише короткий спосіб зробити "витягнення" та "злиття" одразу, якщо вам потрібно перевірити стан віддаленого репо, ви справді імітуєте "отримання". Так git fetch -v --dry-runце те, що вам потрібно.
Клаудіо Флореані

Відповіді:


858

Спочатку скористайтеся git remote updateдля оновлення віддалених записів. Тоді ви можете зробити одну з кількох речей, наприклад:

  1. git status -unoпідкаже, чи йде гілка, яку ви відстежуєте, попереду, позаду чи відхилилася. Якщо нічого не говорить, місцевий і віддалений - це те саме.

  2. git show-branch *masterпокаже ваші зобов’язання у всіх галузях, назви яких закінчуються на "master" (наприклад, master та origin / master ).

Якщо ви користуєтесь -vз git remote update( git remote -v update), ви можете бачити, які гілки оновлювалися, тому вам не потрібні додаткові команди.

Однак, схоже, ви хочете зробити це в сценарії чи програмі і в кінцевому підсумку зі значенням true / false. Якщо так, то існують способи перевірити взаємозв'язок між вашим поточним зобов'язанням HEAD та керівником відділення, яке ви відстежуєте, хоча, оскільки є чотири можливі результати, ви не можете зменшити його до відповіді "так" чи "ні". Однак якщо ви готові зробити цеpull --rebase ви можете ставитися до "місцевий позаду", а "місцевий розбігся" як "потрібно тягнути", а два інших - як "не потрібно тягнути".

Ви можете отримати ідентифікатор фіксації будь-якого посилання, використовуючи git rev-parse <ref>, так що ви можете зробити це для master та origin / master та порівняти їх. Якщо вони рівні, гілки однакові. Якщо вони нерівні, ви хочете знати, що попереду іншого. Використання git merge-base master origin/masterскаже вам спільного предка обох гілок, і якщо вони не розійшлися, це буде те саме, що і те, і інше. Якщо ви отримали три різні ідентифікатори, гілки розійшлися.

Для цього правильно, наприклад, у сценарії, ви повинні мати можливість посилатися на поточну гілку та віддалену гілку, яку вона відстежує. Функція налаштування підказок bash у /etc/bash_completion.dмає корисний код для отримання імен гілок. Однак вам, мабуть, насправді не потрібно отримувати імена. У Git є кілька акуратних скорочень для посилань на гілки та комітети (як це зафіксовано в git rev-parse --help). Зокрема, ви можете використовувати @для поточної гілки (якщо припустити, що ви не перебуваєте у відстороненому стані) та @{u}для її гілки вгору (наприклад origin/master). Так git merge-base @ @{u}буде повертати (хеш з) фіксації , при якому струм гілки і її вгору по течії і розходяться , git rev-parse @і git rev-parse @{u}дасть вам хеші двох рад. Це можна узагальнити за наступним сценарієм:

#!/bin/sh

UPSTREAM=${1:-'@{u}'}
LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse "$UPSTREAM")
BASE=$(git merge-base @ "$UPSTREAM")

if [ $LOCAL = $REMOTE ]; then
    echo "Up-to-date"
elif [ $LOCAL = $BASE ]; then
    echo "Need to pull"
elif [ $REMOTE = $BASE ]; then
    echo "Need to push"
else
    echo "Diverged"
fi

Примітка: старіші версії git не дозволяли @самостійно, тому вам, можливо, доведеться використовувати @{0}замість цього.

Рядок UPSTREAM=${1:-'@{u}'}дозволяє необов'язково пропускати гілку вищого потоку, якщо ви хочете перевірити іншу віддалену гілку, ніж ту, налаштовану для поточної гілки. Зазвичай це має видалене ім’я / ім'я гілки . Якщо параметр не заданий, значення за замовчуванням до @{u}.

Сценарій передбачає, що ви зробили git fetchабо git remote updateперше, щоб оновити гілки відстеження. Я не вбудовував це в сценарій, тому що це більш гнучко, щоб можна було вибирати і зіставляти як окремі операції, наприклад, якщо ви хочете порівняти без отримання, тому що ви вже отримали нещодавно.


4
@takeshin Я думаю, ви могли б поєднати git ls-віддалене походження -h refs / heads / master, як запропонував @brool з git rev-list --max-count = 1 походження / master. Якщо вони повернуть той самий хеш, віддалена гілка не змінилася з моменту останнього оновлення віддалених каналів (із витягненням, завантаженням, віддаленим оновленням тощо). всі зобов’язання здійснюються відразу, але можна залишити це на більш зручний час. Однак, оскільки віддалене оновлення не є руйнівним, ви все одно можете це зробити.
Ніл Мейхью

2
Ви також можете спробувати git status -s -u no, що дає коротший вихід, ніж git status -u no.
Філліп Хмара

2
@mhulse, git remote -v update. Подивіться на результат git remote --helpдля більш повного пояснення.
Ніл Мейхью

1
@ChrisMaes Добре. Більш чіткий синтаксис потрібен для старих версій git. Я експериментував з різними системами, які у мене є, і виявив, що @{u}працює з git 1.8.3.2, але @не працює. Однак @працює з 1.8.5.4. Мораль історії: git постійно вдосконалюється, і варто мати найновішу версію, яку ви можете.
Ніл Мейхью

1
Тепер для @ потрібен специфікатор. Ви можете використовувати @ {0} замість @.
Бен Девіс

132

Якщо у вас є гілка вище

git fetch <remote>
git status

Якщо у вас немає гілки вище за течією

Порівняйте дві гілки:

git fetch <remote>
git log <local_branch_name>..<remote_branch_name> --oneline

Наприклад:

git fetch origin

# See if there are any incoming changes
git log HEAD..origin/master --oneline

(Я припускаю, що origin/masterце ваше відділення віддаленого відстеження)

Якщо будь-які комісії перераховані у висновку вище, то у вас є вхідні зміни - вам потрібно об'єднатись. Якщо до цього часу жодних комісій не перераховано, git logто злиття нічого немає.

Зауважте, що це буде працювати, навіть якщо ви знаходитесь на гілці функції - у неї немає пульта дистанційного відстеження, оскільки, якщо явно посилається, origin/masterзамість того, щоб неявно використовувати гілку, що запам'ятовується Git.


2
Навіть короткі позначення git fetch; git log HEAD.. --onelineможуть бути використані, якщо для локальної є віддалена гілка за замовчуванням.
phil pirozhkov

@philpirozhkov Якщо ви маєте віддалену гілку за замовчуванням, я повинен вважати простий "git status". Моя відповідь була загальною для будь-яких двох гілок, де одна може або не може відслідковувати іншу.
PlagueHammer

55
git rev-list HEAD...origin/master --countдасть вам загальну кількість "різних" фіксацій між ними.
Джейк Бергер

1
короткий і простий. Моє улюблене рішення, яке показує лише нові
поступки

Як я можу використовувати це у пакетному файлі (Ubuntu), щоб я міг запускати інші команди лише в тому випадку, якщо ця команда покаже, що потрібно потягнути?
Улісс Алвес

69

Якщо це сценарій, ви можете використовувати:

git fetch
$(git rev-parse HEAD) == $(git rev-parse @{u})

(Примітка. Перевага цього порівняно з попередніми відповідями полягає в тому, що для отримання поточної назви гілки вам не потрібна окрема команда. Про неї дбають "HEAD" і "@ {u}" (поточна гілка потоку). Див. "git rev-parse --help" для більш детальної інформації.)


Я відкрив @ {u} незалежно і оновив свою відповідь, перш ніж побачив вашу.
Ніл Мейхев

1
Чи git rev-parse @{u}справді буде показано останнє зобов’язання без git fetch?
Кайл Странд

3
Це був квиток! Хоча, ваша логіка використовує, ==що означає "якщо НЕ буде змін у потоці". Раніше я !=перевіряв "чи є зміни вгорі" для моєї програми. Не забудьте git fetchспочатку!
ChrisPrime

1
Я додав git fetch, тому що дійсно потрібно відповісти на початкове запитання. @коротке для HEADbtw.
користувач1338062

Користувачам Windows знадобляться окремі цитати, @{u}наприклад,git rev-parse '@{u}'
spuder

36

Команда

git ls-remote origin -h refs/heads/master

відобразить поточну головку на пульті дистанційного керування - ви можете порівняти її з попереднім значенням або побачити, чи є у вас SHA у вашому місцевому репо.


1
Будь-який зразок сценарію для порівняння цих значень?
приймає

18
git rev-list HEAD...origin/master --countдасть вам загальну кількість "різних" фіксацій між ними.
Джейк Бергер

3
@jberger, щоб уточнити, це покаже лише кількість комісій, які ви позаду (а не вперед і ззаду), і це працює лише в тому випадку, якщо ви git fetchабо git remote updateперший. git statusтакож показує підрахунок, btw.
Денніс

1
@ Денніс я думав .., що "здійснює походження / головне, віднімання HEAD" (тобто кількість комірок позаду). Тоді ...як симетрична різниця (тобто вперед і позаду)
Джейк Бергер

3
Відмінно. Наскільки я можу сказати, це єдине рішення, яке фактично перевіряє походження на оновлення, але не неявно це робить fetch.
Кайл Странд

35

Ось Bash один вкладиш , який порівнює ГОЛОВА поточної гілки в фіксації хеш від свого віддаленого філії вгору по течії, не важкий git fetchабо git pull --dry-runне потрібно операції:

[ $(git rev-parse HEAD) = $(git ls-remote $(git rev-parse --abbrev-ref @{u} | \
sed 's/\// /g') | cut -f1) ] && echo up to date || echo not up to date

Ось як розбита ця дещо щільна лінія:

  • Команди групуються та вкладаються за допомогою синтаксису підстановки команд$(x) Bash .
  • git rev-parse --abbrev-ref @{u}повертає скорочений посилання за течією (наприклад origin/master), яке потім перетворюється на розділені пробілом поля за допомогою sedкоманди " pipepe" , наприклад origin master.
  • Ця рядок подається, в git ls-remoteяку повертається головна комісія віддаленої гілки. Ця команда зв’яжеться з віддаленим сховищем. ТрубопровіднаcutКомандна команда витягує лише перше поле (хеш фіксування), видаляючи відокремлений вкладку опорний рядок.
  • git rev-parse HEAD повертає локальний хеш комісії.
  • Синтаксис Bash [ a = b ] && x || yдоповнює однолінійку: це порівняння рядків Bash =у тестовій конструкції [ test ], за яким послідують конструкції and-list та--list && true || false.

2
Я б не використовував / g на sed, якщо ви використовуєте косої риси у назвах гілок. Це лише "sed 's / \ // /".
Мартін Девіс

@wjordan Ваше рішення виходить з ладу, коли віддалений сховище недоступне (або знаходиться в обслуговуванні) і призведе до "оновлення"
кадр

20

Пропоную переглянути сценарій https://github.com/badele/gitcheck . Я зашифрував цей скрипт для перевірки за один прохід у всіх ваших сховищах Git, і він показує, хто не здійснив і хто не натиснув / не потягнув.

Ось зразок результату:

Введіть тут опис зображення


6
акуратно, думаючи над тим, щоб переписати його в чисту оболонку
Олів'є Рефало

1
Тепер ви також можете використовувати gitcheck безпосередньо з докерного контейнера (з файлами у своєму хості). Для отримання додаткової інформації дивіться проект gitcheck github
Bruno Adelé

Подібний інструмент у bash git-multi-repo-tooling . git mrepo -cце відобразить усі очікувані комісії.
Грег

11

Я базував це рішення на коментарях @jberger.

if git checkout master &&
    git fetch origin master &&
    [ `git rev-list HEAD...origin/master --count` != 0 ] &&
    git merge origin/master
then
    echo 'Updated!'
else
    echo 'Not updated.'
fi

посилаючись на ваш попередній коментар , в цей момент часу я не можу дати вам однозначної відповіді. У той час, коли я робив ці коментарі, я занурювався в глибину git і особливо віддаляв і відрізнявся. З тих пір пройшло кілька місяців, і дуже багато цих знань поховано у моєму мозку. ;) Якщо ви шукаєте кількість "різних" комітетів між ними, то, ...здається, є вагомою частиною вашого рішення.
Джейк Бергер

1
Дякую. Це було чисто.
Шобхіт Пурі

10

Наразі вже багато дуже функціональних і геніальних відповідей. Для забезпечення контрасту я міг би зробити дуже просту лінію.

# Check return value to see if there are incoming updates.
if ! git diff --quiet remotes/origin/HEAD; then
 # pull or whatever you want to do
fi

2
Оригінальної відповіді бракувало "!" у if. Повернене значення з git diff дорівнює нулю, коли немає змін.
thuovila

Найкраще рішення IMO там, хоча мені потрібно замінити "віддалені / походження / HEAD" на "origin / master" або інша редакція
Matthias Michael Engh

9

Я думаю, що найкращий спосіб зробити це:

git diff remotes/origin/HEAD

Якщо припустити, що у вас зареєстровано цю інформацію. Вам слід, якщо ви клонували сховище, в іншому випадку (тобто, якщо репо було створено de novo локально і було висунуто на віддалений), вам потрібно додати рефлекс явно.


9

Наведений нижче сценарій працює чудово.

changed=0
git remote update && git status -uno | grep -q 'Your branch is behind' && changed=1
if [ $changed = 1 ]; then
    git pull
    echo "Updated successfully";
else
    echo "Up-to-date"
fi

6

Я би зробив так, як запропонував брил. Наступний однорядковий скрипт бере SHA1 останньої зафіксованої версії та порівнює його з віддаленим походженням та витягує зміни, лише якщо вони відрізняються. І це ще більш легка вага розчинів на основі git pullабо git fetch.

[ `git log --pretty=%H ...refs/heads/master^` != `git ls-remote origin
-h refs/heads/master |cut -f1` ] && git pull

Ця команда виходить з ладу, якщо сховище git клоновано "--depth 1" (щоб обмежити розмір завантаження). Чи знаєте ви, чи є спосіб це виправити?
Адам Річковський

Журнал git це повертає багато рядків і видає помилку "bash: [: занадто багато аргументів", які я перейшов би наgit rev-parse --verify HEAD
Дрю Пірс

1
Це просте порівняння рядків, здійснене bash. Якщо щось не вдається, я б запропонував вам перевірити свій синтаксис (тобто ви неправильно набираєте його). Спочатку запустіть, git log --pretty=%H ...refs/heads/master^ щоб отримати SHA1 останньої зафіксованої версії, а потім запустіть, git ls-remote origin -h refs/heads/master |cut -f1 щоб отримати SHA1 віддаленого походження. Ці два команди - git і не мають нічого спільного з bash. Що bash робить всередині квадратних дужок, це порівняння результатів з першої команди з другою, і якщо вони рівні, він повертає true та запускається git pull.
Клаудіо Флореані

"і якщо вони рівні, він повертає істинність і запускається git pull". Я знаю, що я нудотний, але просто для того, щоб врятувати когось плутанину, це повинно бути "і якщо вони не рівні". Крім того, з будь-якої причини перша команда git не працює для мене. (Я на git 2.4.1.) Тому я просто використовую git log --pretty=%H master | head -n1замість цього. Але я не впевнений, чи точно так.
xd1le

6

Якщо ви запустите цей скрипт, він перевірить, чи потрібна поточна гілка git pull:

#!/bin/bash

git fetch -v --dry-run 2>&1 |
    grep -qE "\[up\s+to\s+date\]\s+$(
        git branch 2>/dev/null |
           sed -n '/^\*/s/^\* //p' |
                sed -r 's:(\+|\*|\$):\\\1:g'
    )\s+" || {
        echo >&2 "Current branch need a 'git pull' before commit"
        exit 1
}

Дуже зручно ставити це як попередній вчинок, щоб уникнути

Merge branch 'foobar' of url:/path/to/git/foobar into foobar

коли ти commitраніше pulling.

Щоб використовувати цей код як гачок, просто скопіюйте та вставте сценарій у

.git/hooks/pre-commit

і

chmod +x .git/hooks/pre-commit

6

Я просто хочу розмістити це як фактичне повідомлення, оскільки це легко пропустити в коментарях.

Правильну та найкращу відповідь на це запитання дав @Jake Berger, Дякую дуже чувак, це потрібно всім і всі пропускають це у коментарях. Отже, для всіх, хто бореться з цим, ось правильна відповідь, просто використовуйте результат цієї команди, щоб знати, чи потрібно вам робити тягу. якщо вихід 0, то, очевидно, немає нічого для оновлення.

@stackoverflow, дай хлопцеві дзвони. Спасибі @ Джейк Бергер

git rev-list HEAD...origin/master --count will give you the total number of "different" commits between the two.  Jake Berger Feb 5 '13 at 19:23

4

Запустіть git fetch (remote)для оновлення віддалених запитів, він покаже, що нового. Потім, коли ви оформили місцеве відділення, він покаже, чи знаходиться він позаду течії.


Я думаю, що у нього вже перевірено місцеве відділення, тому йому потрібно щось інше, щоб показати, чи є позаду тощо. Він може це зробити зі статусом git.
Ніл Мейхью,

Щоправда, після того, як ви отримаєте дистанційні, це також git statusбуде показано.
че

1
Це щось під настрій git pull --dry-run, але я думаю, що це важкий для крон сценарій, що працює кожну хвилину.
приймає

@takeshin: Ви не можете перевірити віддалені сховища, не переходячи до мережі. Якщо немає нічого нового fetch, не буде робити нічого більше, ніж перевірити статус. Якщо вам потрібна дуже швидка і легка реакція на віддалені оновлення, ви можете розглянути можливість підключення певного сповіщення до віддаленого сховища.
че

@takeshin: якщо ти хочеш щохвилини перевіряти віддалене репо, я думаю, що ти пропустив точку DVCS. Вся ідея полягає в тому, щоб мати можливість розвиватися самостійно на деякий час, а потім все це плавно скласти згодом. Це не так, як резюме, svn, p4 тощо, де завжди потрібно працювати над тим, що є найновішим у сховищі. Якщо вам дійсно потрібно щось, над чим працює хтось інший, тоді вам слід скористатися іншим механізмом комунікації, наприклад електронною поштою, щоб повідомити, коли він готовий витягнути.
Ніл Мейхью

4

Усі такі складні дози, поки рішення настільки коротке і просте:

#!/bin/bash

BRANCH="<your branch name>"
LAST_UPDATE=`git show --no-notes --format=format:"%H" $BRANCH | head -n 1`
LAST_COMMIT=`git show --no-notes --format=format:"%H" origin/$BRANCH | head -n 1`

git remote update
if [ $LAST_COMMIT != $LAST_UPDATE ]; then
        echo "Updating your branch $BRANCH"
        git pull --no-edit
else
        echo "No updates available"
fi

LAST_COMMIT і LAST_UPDATE завжди рівні, навіть якщо є зміни
canbax

Це рішення хороше і просте, його потрібно git remote updateвиконати перед кодом, щоб отримати останню інформацію про походження даних
ak93

Не git remote updateслід додавати перед git showкомандами?
Сетоп

2

Ось моя версія сценарію Bash, яка перевіряє всі сховища у заздалегідь заданій папці:

https://gist.github.com/henryiii/5841984

Він може розрізняти загальні ситуації, такі як необхідне потягнення та натискання, і він є багатопотоковим, тому видобуток відбувається відразу. Він має декілька команд, як тягнути і статус.

Помістіть символьну посилання (або сценарій) у папку на своєму шляху, тоді вона працює як git all status(і т.д.). Він підтримує лише походження / головне, але його можна редагувати або комбінувати з іншим методом.


1
git ls-remote | cut -f1 | git cat-file --batch-check >&-

перерахує все, на що посилається, у будь-якому віддаленому пристрої, який не знаходиться у вашій репо-репо. Для отримання віддалених змін до речей, які ви вже мали (наприклад, скидання попередніх комісій), потрібно трохи більше:

git pack-refs --all
mine=`mktemp`
sed '/^#/d;/^^/{G;s/.\(.*\)\n.* \(.*\)/\1 \2^{}/;};h' .git/packed-refs | sort -k2 >$mine
for r in `git remote`; do 
    echo Checking $r ...
    git ls-remote $r | sort -k2 | diff -b - $mine | grep ^\<
done

1

Можливо, це, якщо ви хочете додати завдання як crontab:

#!/bin/bash
dir="/path/to/root"
lock=/tmp/update.lock
msglog="/var/log/update.log"

log()
{
        echo "$(date) ${1:-missing}" >> $msglog
}

if [ -f $lock ]; then
        log "Already run, exiting..."
else
        > $lock
        git -C ~/$dir remote update &> /dev/null
        checkgit=`git -C ~/$dir status`
        if [[ ! "$checkgit" =~ "Your branch is up-to-date" ]]; then
                log "-------------- Update ---------------"
                git -C ~/$dir pull &>> $msglog
                log "-------------------------------------"
        fi
        rm $lock

fi
exit 0

1

Використання простого regexp:

str=$(git status) 
if [[ $str =~ .*Your\ branch\ is\ behind.*by.*commits,\ and\ can\ be\ fast-forwarded ]]; then
    echo `date "+%Y-%m-%d %H:%M:%S"` "Needs pull"
else
    echo "Code is up to date"
fi

Це не вийде. статус git - це лише місцевий чек, тому він повідомляє лише про те, чи знаходиться ваша філія, якщо ви вже оновили віддалені налаштування.
minhaz1

0

Я використовую версію сценарію на основі відповіді Стівена Хабермана:

if [ -n "$1" ]; then
    gitbin="git -C $1"
else
    gitbin="git"
fi

# Fetches from all the remotes, although --all can be replaced with origin
$gitbin fetch --all
if [ $($gitbin rev-parse HEAD) != $($gitbin rev-parse @{u}) ]; then
    $gitbin rebase @{u} --preserve-merges
fi

Якщо припустити, що цей скрипт викликається git-fetch-and-rebase, його можна викликати додатковим аргументомdirectory name локального сховища Git для виконання операції. Якщо скрипт викликається без аргументів, він передбачає, що поточний каталог є частиною репозиторію Git.

Приклади:

# Operates on /abc/def/my-git-repo-dir
git-fetch-and-rebase /abc/def/my-git-repo-dir

# Operates on the Git repository which the current working directory is part of
git-fetch-and-rebase

Він також доступний тут .


0

Прочитавши багато відповідей і декілька дописів і витративши півдня на пробування різних перестановок, ось що я придумав.

Якщо ви працюєте в Windows, ви можете запустити цей скрипт у Windows за допомогою Git Bash, наданого Git для Windows (інсталяція або портативний).

Цей сценарій вимагає аргументів

- локальний шлях, наприклад, / d / джерело / проект1
- Git URL, наприклад https: //username@bitbucket.org/username/project1.git
- пароль

якщо пароль не повинен бути введений у командному рядку простим текстом,
потім змініть скрипт, щоб перевірити, чи GITPASS порожній; не
замініть і нехай Git запросить пароль

Сценарій буде

- Find the current branch
- Get the SHA1 of the remote on that branch
- Get the SHA1 of the local on that branch
- Compare them.

Якщо є зміна, як надруковано сценарієм, ви можете перейти до вибору або витягування. Сценарій може бути неефективним, але він робить роботу для мене.

Оновлення - 2015-10-30: stderr to dev null, щоб запобігти друку URL-адреси з паролем на консоль.

#!/bin/bash

# Shell script to check if a Git pull is required.

LOCALPATH=$1
GITURL=$2
GITPASS=$3

cd $LOCALPATH
BRANCH="$(git rev-parse --abbrev-ref HEAD)"

echo
echo git url = $GITURL
echo branch = $BRANCH

# Bash replace - replace @ with :password@ in the GIT URL
GITURL2="${GITURL/@/:$GITPASS@}"
FOO="$(git ls-remote $GITURL2 -h $BRANCH 2> /dev/null)"
if [ "$?" != "0" ]; then
  echo cannot get remote status
  exit 2
fi
FOO_ARRAY=($FOO)
BAR=${FOO_ARRAY[0]}
echo [$BAR]

LOCALBAR="$(git rev-parse HEAD)"
echo [$LOCALBAR]
echo

if [ "$BAR" == "$LOCALBAR" ]; then
  #read -t10 -n1 -r -p 'Press any key in the next ten seconds...' key
  echo No changes
  exit 0
else
  #read -t10 -n1 -r -p 'Press any key in the next ten seconds...' key
  #echo pressed $key
  echo There are changes between local and remote repositories.
  exit 1
fi

0

Для користувачів Windows, які опиняються на цьому питанні, я змінив частину відповіді в сценарій повноважень. Налаштуйте за необхідності, збережіть у .ps1файл та запустіть на вимогу чи заплановано, якщо хочете.

cd C:\<path to repo>
git remote update                           #update remote
$msg = git remote show origin               #capture status
$update = $msg -like '*local out of date*'
if($update.length -gt 0){                   #if local needs update
    Write-Host ('needs update')
    git pull
    git reset --hard origin/master
    Write-Host ('local updated')
} else {
    Write-Host ('no update needed')
}

0

Оскільки відповідь Нілса мені так допомогла, ось переклад Python без залежностей:

import os
import logging
import subprocess

def check_for_updates(directory:str) -> None:
    """Check git repo state in respect to remote"""
    git_cmd = lambda cmd: subprocess.run(
        ["git"] + cmd,
        cwd=directory,
        stdout=subprocess.PIPE,
        check=True,
        universal_newlines=True).stdout.rstrip("\n")

    origin = git_cmd(["config", "--get", "remote.origin.url"])
    logging.debug("Git repo origin: %r", origin)
    for line in git_cmd(["fetch"]):
        logging.debug(line)
    local_sha = git_cmd(["rev-parse", "@"])
    remote_sha = git_cmd(["rev-parse", "@{u}"])
    base_sha = git_cmd(["merge-base", "@", "@{u}"])
    if local_sha == remote_sha:
        logging.info("Repo is up to date")
    elif local_sha == base_sha:
        logging.info("You need to pull")
    elif remote_sha == base_sha:
        logging.info("You need to push")
    else:
        logging.info("Diverged")

check_for_updates(os.path.dirname(__file__))

чт


-5

Ви також можете знайти сценарій Phing, який це робить зараз.

Мені потрібне було рішення для автоматичного оновлення виробничого середовища, і ми дуже раді завдяки цьому сценарію, яким я ділюсь.

Сценарій написаний XML і потребує Phing .


Можливо, це не гарна ідея скопіювати сюди скрипт, я все одно його
оновлюю
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.