Как узнать, есть ли в репозитории 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 'с учетом параметров, которые я предоставляю, но, похоже, выплескивает информацию, которую я хочу.