Как узнать, есть ли в репозитории git изменения, которые не были синхронизированы с сервером (origin)?

У меня есть большое количество проектов настройки в Git, которые ранее управлялись в CVS. Tortoise CVS, а также Eclipse очень легко увидеть (через наложение значков), если я внес изменения в репозиторий, который еще не был отправлен на центральный сервер.

есть ли удобный способ достичь этого с помощью Git? Мне действительно не нужны наложения значков - мне просто нужно знать, есть ли у меня выдающиеся изменения при сравнении моих ветвей с ветвями в origin. Я не против использовать какой-то скрипт для запроса всех репозиториев Git.

4 ответов


что-то вроде git log origin/master..master должен дать вам коммиты, которые вы сделали и не толкнул. Если вы получаете origin, а затем делаете git log master..origin/master вы можете видеть коммиты в remote master. Вы также можете сделать git log origin/master...master видеть новые коммиты как локально, так и удаленно.

вы можете заменить git log С git rev-list и легко выяснить, если и что не нажимается в скрипте, если это необходимо.


следующие примеры касаются только одного репозитория. Используйте цикл в окружающем скрипте, чтобы запустить их в нескольких репозиториях.

вы, вероятно, захотите запустить (например) git fetch origin чтобы обновить локальные ветви удаленного отслеживания перед использованием следующих команд (так что вы проверяете против самых современных советов восходящих ветвей).

если вас интересует только ветка, которая в настоящее время проверена:

git status -sb

если первая строка сообщает "вперед", затем текущая ветвь имеет фиксации, которые не являются частью ее восходящей ветви. Вывод этой команды не подходит для потребления непосредственно программой (это команда" фарфор"). Для программного потребления используйте "сантехника" команда чтобы перечислить коммиты" вперед":

git rev-list HEAD@{upstream}..HEAD

вы можете передать это в wc -l чтобы получить граф. Если вас интересует только статус "вперед" (не точное количество), то test -n "$(git rev-list -n 1 HEAD@{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 операторы (или замените их другими командами) в соответствии с вашими целями.


если у вас есть пульт с именем, скажем, origin, - попробуйте запустить это:

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 как я описал здесь. Вы можете перенаправить вывод и проанализировать его, чтобы получить то, что вам нужно.


вчера я попытался свернуть свое собственное решение. Вот что я придумал (для одного репозитория):

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