Как проверить, изменился ли удаленный репозиторий и нужно ли его вытащить?
Теперь я использую этот простой скрипт:
git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1
Но это довольно тяжело.
Есть ли способ лучше? Идеальное решение будет проверять все удаленные ветви и возвращать имена измененных веток и количество новых коммитов в каждой.
git fetch -v --dry-run
это то, что вам нужно.Ответы:
Первое использование
git remote update
, чтобы обновить ваши удаленные ссылки. Затем вы можете сделать одну из нескольких вещей, таких как:git status -uno
сообщит вам, находится ли отслеживаемая вами ветка впереди, позади или разошлась. Если это ничего не говорит, локальный и удаленный - то же самое.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}
даст вам хэши двух советов. Это можно обобщить в следующем сценарии:Примечание: старые версии git не разрешали
@
сами по себе, поэтому вам, возможно, придется использовать@{0}
вместо этого.Линия
UPSTREAM=${1:-'@{u}'}
позволяет вам при желании явно передать ветвь вверх по течению, если вы хотите проверить другую удаленную ветвь, отличную от настроенной для текущей ветки. Это, как правило, имеет вид remotename / branchname . Если параметр не указан, по умолчанию используется значение@{u}
.Сценарий предполагает, что вы уже сделали первый
git fetch
илиgit remote update
первый шаг, чтобы обновить ветки отслеживания. Я не встроил это в скрипт, потому что он более гибок, чтобы можно было выполнять выборку и сравнение как отдельные операции, например, если вы хотите сравнить без выборки, потому что вы уже загрузили недавно.источник
git status -s -u no
, что дает более короткий вывод, чемgit status -u no
.git remote -v update
. Посмотрите на выводgit remote --help
для более полного объяснения.@{u}
работает с git 1.8.3.2, но@
не работает. Однако@
работает с1.8.5.4
. Мораль истории: git продолжает улучшаться, и стоит иметь самую последнюю версию, какую только можно.Если у вас есть ветка upstream
Если у вас нет ветки вверх по течению
Сравните две ветви:
Например:
(Я предполагаю, что
origin/master
это ваша удаленная ветка отслеживания)Если какие-либо коммиты перечислены в выводе выше, то у вас есть входящие изменения - вам нужно объединить. Если никакие коммиты не перечислены,
git log
тогда объединять нечего.Обратите внимание, что это будет работать, даже если вы находитесь в ветви функций - у которой нет удаленного отслеживания, поскольку, если явно ссылается на нее, а не
origin/master
косвенно использует восходящую ветку, запомненную Git.источник
git fetch; git log HEAD.. --oneline
Можно использовать даже более короткую запись , если для локальной ветки по умолчанию существует удаленная ветвь.git rev-list HEAD...origin/master --count
даст вам общее количество «разных» коммитов между ними.Если это для скрипта, вы можете использовать:
(Примечание: преимущество этого по сравнению с предыдущими ответами состоит в том, что вам не нужна отдельная команда для получения имени текущей ветви. "HEAD" и "@ {u}" (восходящая ветка текущей ветви) позаботятся об этом. См. "git rev-parse --help" для более подробной информации.)
источник
git rev-parse @{u}
показывать последний коммит безgit fetch
?==
что означает «если нет никаких изменений от восходящего потока». Я использовал!=
для проверки «если есть изменения из апстрима» для моего приложения. Не забудьтеgit fetch
сначала!@
это сокращение отHEAD
Btw.@{u}
напримерgit rev-parse '@{u}'
Команда
отобразит текущий заголовок на пульте - вы можете сравнить его с предыдущим значением или посмотреть, есть ли у вас SHA в вашем локальном репо.
источник
git rev-list HEAD...origin/master --count
даст вам общее количество «разных» коммитов между ними.git fetch
илиgit remote update
первый.git status
также показывает счет, кстати...
это «коммиты в оригинале / мастере, вычитающие ГОЛОВУ» (т.е. количество коммитов позади). Принимая во внимание, что...
есть симметричная разница (то есть впереди и сзади)fetch
.Вот одна строчка Bash, которая сравнивает хэш коммита HEAD текущей ветки с его удаленной веткой восходящей ветки, не требуя тяжелых операций
git fetch
илиgit pull --dry-run
операций:Вот как эта несколько плотная линия разбита:
$(x)
Bash .git rev-parse --abbrev-ref @{u}
возвращает сокращенный восходящий ref (напримерorigin/master
), который затем преобразуется в разделенные пробелами поля с помощью конвейернойsed
команды, напримерorigin master
.git ls-remote
которая возвращает фиксированный заголовок удаленной ветви. Эта команда будет связываться с удаленным хранилищем. Команда pipedcut
извлекает только первое поле (хеш коммита), удаляя разделенную табуляцией справочную строку.git rev-parse HEAD
возвращает хеш локального коммита[ a = b ] && x || y
завершает однострочное: это сравнение строк Bash=
внутри тестовой конструкции[ test ]
, за которым следуют конструкции and-list и or-list&& true || false
.источник
Я предлагаю вам посмотреть скрипт https://github.com/badele/gitcheck . Я написал этот сценарий для проверки за один проход всех ваших репозиториев Git, и он показывает, кто не совершал, а кто не выдвигал / вытягивал.
Вот пример результата:
источник
git mrepo -c
это отобразит все ожидающие коммиты.Я основал это решение на комментариях @jberger.
источник
...
похоже, это правильная часть вашего решения.Уже есть много очень богатых и оригинальных ответов. Чтобы обеспечить некоторый контраст, я мог бы обойтись очень простой строкой.
источник
Я думаю, что лучший способ сделать это будет:
Предполагая, что у вас есть этот refspec зарегистрирован. Если вы клонировали репозиторий, вы должны это сделать в противном случае (т. Е. Если репозиторий был создан de novo локально и перенесен на удаленный компьютер), вам необходимо явно добавить refspec.
источник
Приведенный ниже скрипт работает отлично.
источник
Я бы поступил так, как предложил Броул. Следующий однострочный скрипт берет SHA1 вашей последней зафиксированной версии и сравнивает его с версией удаленного источника, и извлекает изменения, только если они отличаются. И это еще более легкий из решений на основе
git pull
илиgit fetch
.источник
git rev-parse --verify HEAD
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 не работает для меня. (Я на Git2.4.1
.) Так что я просто используюgit log --pretty=%H master | head -n1
вместо этого. Но я не уверен, что это точно так же.Если вы запустите этот скрипт, он проверит, нужна ли текущей ветке
git pull
:Это очень удобно использовать в качестве предварительной фиксации Git, чтобы избежать
когда ты
commit
раньшеpulling
.Чтобы использовать этот код в качестве хука, просто скопируйте / вставьте скрипт в
а также
источник
Я просто хочу опубликовать это как фактическое сообщение, так как это легко пропустить в комментариях.
Правильный и лучший ответ на этот вопрос дал @Jake Berger, Большое спасибо, чувак, это нужно всем, и все упускают это в комментариях. Поэтому для всех, кто борется с этим, правильный ответ, просто используйте вывод этой команды, чтобы узнать, нужно ли вам делать git pull. если вывод равен 0, то, очевидно, обновлять нечего.
@stackoverflow, дай этому парню колокола. Спасибо @ Джейк Бергер
источник
Запустите
git fetch (remote)
для обновления ваших удаленных ссылок, он покажет вам, что нового. Затем, когда вы оформите заказ в своем местном отделении, он покажет, находится ли он за апстримом.источник
git status
тоже покажет.git pull --dry-run
делает, но я думаю, что это тяжело для cron-скрипта, запускаемого каждую минуту.fetch
, то не сделаю ничего, кроме проверки статуса. Если вам нужна очень быстрая и легкая реакция на удаленные обновления, вы можете захотеть подключить какие-то уведомления к удаленному хранилищу.Все такие сложные предложения, в то время как решение очень короткое и простое:
источник
git remote update
но для того, чтобы получить последнюю информацию оgit remote update
следует добавлять передgit show
командами?Вот моя версия скрипта Bash, который проверяет все репозитории в предопределенной папке:
https://gist.github.com/henryiii/5841984
Он может различать обычные ситуации, такие как «тянуть» и «толкать», и он многопоточный, поэтому выборка происходит сразу. У него есть несколько команд, таких как pull и status.
Поместите символическую ссылку (или скрипт) в папку на вашем пути, тогда она будет работать как
git all status
(и т. Д.). Он поддерживает только origin / master, но его можно редактировать или комбинировать с другим методом.источник
будет перечислять все ссылки на любой пульт, который не находится в вашем репо. Чтобы отловить удаленные изменения ссылок на вещи, которые у вас уже были (например, сбрасывает на предыдущие коммиты), требуется немного больше:
источник
Может быть, это, если вы хотите добавить задачу как crontab:
источник
Используя простое регулярное выражение:
источник
Я использую версию сценария, основанную на ответе Стивена Хабермана:
Предполагая, что этот скрипт вызывается
git-fetch-and-rebase
, он может быть вызван с необязательным аргументомdirectory name
локального репозитория Git для выполнения операции. Если скрипт вызывается без аргументов, предполагается, что текущий каталог является частью репозитория Git.Примеры:
Это доступно и здесь .
источник
Прочитав много ответов и несколько постов и потратив полдня на различные перестановки, я пришел к такому выводу.
Если вы работаете в Windows, вы можете запустить этот скрипт в Windows, используя Git Bash, предоставляемый Git для Windows (установка или переносная версия).
Этот скрипт требует аргументов
Сценарий будет
Если есть изменения, напечатанные сценарием, вы можете приступить к извлечению или извлечению. Сценарий может быть неэффективным, но он выполняет работу за меня.
Обновление - 2015-10-30: stderr в dev null для предотвращения печати URL-адреса с паролем на консоли.
источник
Для пользователей Windows, которые в конечном итоге задают этот вопрос, я модифицировал некоторые ответы в сценарий powershell. Настраивайте по необходимости, сохраняйте в
.ps1
файл и запускайте по требованию или по расписанию, если хотите.источник
Поскольку ответ Neils мне очень помог, вот перевод Python без каких-либо зависимостей:
НТН
источник
Вы также можете найти скрипт Phing, который делает это сейчас.
Мне нужно было решение для автоматического обновления моей производственной среды, и мы очень рады благодаря этому сценарию, которым я делюсь.
Сценарий написан на XML и требует Phing .
источник