Как узнать, есть ли в репозитории git изменения, которые не были синхронизированы с сервером (источником)?
У меня есть большое количество проектов в Git, которые ранее управлялись в CVS. Tortoise CVS, а также Eclipse сделали очень легко увидеть (через наложения значков), если я внес изменения в репозиторий, который еще не был отправлен на центральный сервер.
Есть ли удобный способ достичь этого с помощью Git? Мне действительно не нужны оверлеи для значков - мне просто нужно знать, есть ли у меня выдающиеся изменения при сравнении моих ветвей с теми, что происходили. Я не против использовать script какого-либо типа для запроса всех репозиций Git.
Ответы
Ответ 1
Что-то вроде git log origin/master..master
должно дать вам совершенные вами коммиты, а не нажатые. Если вы выберете источник, а затем выполните git log master..origin/master
, вы можете увидеть фиксации в удаленном главном. Вы также можете сделать git log origin/master...master
, чтобы увидеть новые коммиты как локально, так и дистанционно.
Вы можете заменить git log
на git rev-list
и легко выяснить, если и что не нажато в script, если это необходимо.
Ответ 2
Следующие примеры относятся только к одному репозиторию. Используйте цикл в окружении script, чтобы запустить их в нескольких репозиториях.
Вы, вероятно, захотите запустить (например) git fetch origin
, чтобы обновить свои локальные ветки удаленного отслеживания, прежде чем использовать следующие команды (чтобы вы проверяли самые современные советы ветвей вверх по течению).
Если вы беспокоитесь о ветке, которая в настоящее время выгружена:
git status -sb
Если первая строка сообщает "впереди", то текущая ветка имеет фиксации, которые не являются частью ее восходящей ветки. Вывод этой команды не подходит для потребления непосредственно программой (это "фарфоровая" команда). Для программного потребления используйте команду "сантехника" , чтобы перечислить "вперед":
git rev-list [email protected]{upstream}..HEAD
Вы можете передать это на wc -l
, чтобы получить счет. Если вас интересует только статус "вперед" (не точное количество), тогда test -n "$(git rev-list -n 1 [email protected]{upstream}..HEAD)"
может быть быстрее.
Если вы хотите проверить все ветки репозитория:
git branch -v
Опять же, вы увидите "впереди" для ветвей с фиксациями, которые не являются частью их восходящей ветки. Это также "фарфоровая" команда, поэтому, если вы хотите надежно обнаружить состояние в программе, тогда вы захотите использовать некоторые команды "сантехника":
git for-each-ref --shell --format='
b=%(refname:short)
u=${b}'@{upstream}'
if git rev-parse --verify --quiet "$u" >/dev/null 2>&1; then
test -n "$(git rev-list -n 1 "$u..$b")" &&
echo "$b: has unpushed commits"
else
echo "$b: no upstream configuration" >&2
fi
' refs/heads | sh
Отрегулируйте операторы echo
(или замените их другими командами) в соответствии с вашими потребностями.
Ответ 3
Если у вас есть удаленный именованный, скажем, источник, - попробуйте запустить это:
git remote show origin
Это даст вам хорошее резюме.
Например, это то, что я получаю
git % git remote show origin
* remote origin
Fetch URL: git://git.kernel.org/pub/scm/git/git.git
Push URL: git://git.kernel.org/pub/scm/git/git.git
HEAD branch: master
Remote branches:
html tracked
maint tracked
man tracked
master tracked
next tracked
pu tracked
todo tracked
Local branches configured for 'git pull':
html merges with remote html
master merges with remote master
Local refs configured for 'git push':
html pushes to html (local out of date)
master pushes to master (local out of date)
который показывает, что мои локальные ветки html
и master
устарели. Если мой удаленный компьютер совершил транзакции, которые не были в моем локальном репо, это будет отображаться в разделе ветвей, настроенных для git pull.
замените origin
на имя любого удаленного репозитория.
Если вы не знаете, что имена вашего происхождения, или их URL-адреса, попробуйте это:
git remote -v
который предоставит вам список ваших пультов и их URL-адресов.
Отредактировано для добавления
Если у вас много подмодулей, вы можете использовать git submodule foreach
, как я описал здесь. Вы можете перенаправить вывод и проанализировать его, чтобы получить то, что вам нужно.
Ответ 4
Вчера я попытался опрокинуть свое решение. Вот что я придумал (для одного репозитория):
#!/bin/sh
for ref in $(git for-each-ref --format='%(refname)' refs/remotes/); do
ending=${ref#refs/remotes/}
remote=${ending%/*}
branch=${ending#*/}
if [ "${branch}" == "HEAD" ]; then continue; fi
echo -e "\e[1;34m$branch on $remote\e[0m"
echo "AHEAD by:"
git log --oneline $branch ^$remote/$branch
echo "BEHIND by:"
git log --oneline $remote/$branch ^$branch
done
Это было основано на информации, которую я привел в нескольких источниках, включая ответы здесь. Я все еще немного затенен тем, что делает команда git log 'с учетом параметров, которые я предоставляю, но, похоже, выплескивает информацию, которую я хочу.