Какую команду bash можно использовать, чтобы узнать, не совпадает ли локальный репозиторий git с удаленным c - PullRequest
0 голосов
/ 10 апреля 2020

Выполняя поиск в StackOverflow и в Google, я могу найти множество элементов о том, как синхронизировать c, и делать все с помощью git, за исключением того, что я не могу найти надежный способ, используя скрипт bash, чтобы сказать, мой локальный репозиторий находится в синхронизации c с его удаленным. Я пытался:

1.

git branch -v |
perl -wlne'
   print "$ENV{reponame} [$1] --> $3 $2"
      if /^..(\S+)\s+([a-f0-9]+)\s+(\[(?:ahead|behind)\s+\d+\])/
' |
while IFS= read -r MOD; do
   printf ' %s\n' "$MOD"  # Replace with code that uses $MOD
done

и

2.

isInSync=`git remote update>/dev/null; git status -uno | grep -o "is up to date"`
if [ $? -ne 0  ]; then
    echo " $reponame [$br] --> Out of sync with remote at $d"
    ok=false
fi

и пытался найти способ Применение:

git log --oneline | голова -n1 | sed # это я не знаю

, чтобы попытаться получить первое слово в файле журнала, которое является коммитом ha sh последнего коммита, и сравнить его с:

rev = $ (git rev-parse --short HEAD)

, который является коммитом ha sh локальной ветки репозитория, в которой вы находитесь.

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

Проблема с # 2 заключается в том, что он вызывает локальный .git / config и вызывает странные попытки доступа к различным удаленным репозиториям, таким как heroi c.

Проблема с # 3, я не могу понять, как получить код ha sh из журнала git и сравнить его с $ rev выше. Казалось бы, это лучшая ставка, поскольку, когда я проверяю ее на разных компьютерах в разных штатах, она, кажется, передает правильную информацию.

Я пишу bash скрипт , который проверяет группа из git проецирует и сообщает мне их состояния, т. е. обновленные, неотслеживаемые файлы, незафиксированные файлы и не синхронизированные c с удаленным.

Помощь была бы признательна, предлагая лучшее способ или как сделать извлечение коммит-га sh из журнала и сравнить его с текущим коммитом-га sh локального последнего коммита.

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

Как вы видите, вы должны определить, что вы подразумеваете под в син c.

Хранилище Git в первую очередь - это способ хранения коммитов. Набор коммитов в хранилище, найденный по именам веток и тегов и другим подобным именам, равен тому, что находится в хранилище. Коммиты - это история.

Большинство Git репозиториев, с которыми пользователи работают, однако не являются "голыми". У них есть рабочее дерево или рабочее дерево , в которое можно извлекать файлы из любого коммита и / или создавать дополнительные файлы и / или изменять различные файлы и так далее. Эта рабочая область может быть «чистой» (соответствует коммиту, более или менее) или «грязной».

Это «грязный» репозиторий, в котором выполняется много работы », в син c "с каким-либо другим хранилищем, даже если оба хранилища имеют одинаковый набор коммитов? Или это "не в синхронизации c"? Что если в другом хранилище есть рабочее дерево, и оно «грязное» точно так же? Это то, что вам нужно определить.

(Кроме рабочего дерева, все репозитории, даже голые, имеют также index , который также может быть «чистым» или «грязным» и, возможно, вам следует учитывать и это.)

В хранилище также может быть определен один или несколько пультов . С учетом удаленного имени, такого как origin, Git можно сказать: подключиться к некоторому сетевому URL и получить новые коммиты от Git там, и поместить их в этот репозиторий. Вот что ваш git remote update делает. Сколько пультов, с которыми они контактируют, может получить некоторые из них, или все из них, или, возможно, некоторые из них недоступны в настоящий момент, - трудно ответить, поскольку все это достаточно настраиваемо.

.. . [get] commit ha sh последнего коммита

Каждое имя ветки автоматически содержит идентификатор ha sh последнего коммита в этой ветке. Другими словами, может быть несколько «последних коммитов». Использование HEAD - это правильный способ найти идентификатор ha sh для текущего коммита, но это может быть не коммитный коммит любой ветви:

rev=$(git rev-parse HEAD)

If HEAD содержит имя неродившейся ветви 1043 *, этот шаг не будет выполнен. Это состояние имеет место в любом полностью пустом репозитории (потому что нет коммитов, следовательно, не может быть никаких имен веток; имена ветвей требуются для именования некоторых существующих коммитов). Однако это также состояние после операции git checkout --orphan.

Я пишу сценарий bash, который проверяет группу проектов git и сообщает мне их состояния, т.е. неотслеживаемые файлы, незафиксированные файлы и не синхронизированные c с пультом.

Итак, вы можете выбрать, как определить каждую из этих вещей.

В общем, I будет:

  • По желанию, каждый репозиторий должен связываться со своими основными вышестоящими потоками, какими бы они ни были: вероятно, определенными тем, что делает git remote update; рассмотрите здесь, хорошо это или плохо, разрешить --prune (см. также настройку fetch.prune).
  • Проверить по крайней мере текущую ветвь , как сообщает git symbolic-ref HEAD: если это команда завершается с ошибкой , текущая ветвь отсутствует, т. е. мы находимся на отсоединенной ГОЛОВЕ.
  • Проверьте состояние в соответствии с git status --porcelain=v2 или аналогичным, чтобы посмотреть состояние индекс и дерево работ. Также рассмотрите возможность проверки статуса субмодуля; git status может сделать это для вас или нет, в зависимости от настроек.
  • Используйте настройку текущей ветви upstream , если (a) есть текущая ветка и (b) она имеет вверх по течению. Этот восходящий параметр часто является именем ветви в другом репозитории Git. (Вместо этого это может быть имя ветви в этом хранилище.) Если это так, используйте git rev-list --left-right --count branch...branch@{u} для подсчета количества коммитов впереди и / или позади, возможно, после git remote update с или без --prune.
  • При желании проверьте каждое имя ветки, помня, что каждый Git репозиторий имеет свои собственные имена веток, и нет никакой особой причины, кроме удобства и соглашения, использовать то же самое имен в двух разных Git репозиториях. То есть, например, dev может не относиться к origin/dev. Если мой dev идет с origin/develop, я, вероятно, установил восходящий поток dev на origin/develop, поэтому рассмотрите возможность проверки восходящего потока каждой ветви. Обратите внимание, что git branch -vv делает это (а также считает значения вперед / назад, если не указано иное, а также имеет дополнительную поддержку добавленных рабочих деревьев).

За исключением текущей ветви и грязности ( о котором git status уже сообщает), большая часть работы - просто git remote update -p и git branch -vv, действительно.

0 голосов
/ 10 апреля 2020

В приведенном выше коде для git_check я заменяю раздел: 2.

isInSync=`git remote update>/dev/null; git status -uno | grep -o "is up to date"`
if [ $? -ne 0  ]; then
    echo " $reponame [$br] --> Out of sync with remote at $d"
    ok=false
fi

на:

last_commit=`git log --oneline | head -n1 | grep -o "^\w*\b"`
rev=$(git rev-parse --short HEAD)
if [ "$last_commit" != "$rev"  ]; then
    echo " $reponame [$br] --> Out of sync with remote at $d"
    ok=false
fi

Вот вывод консоли с некоторыми комментариями

Modify a file that has been committed.

[:~/bin] develop(+4/-2) 2s ± git status
On branch develop
Your branch is up to date with 'origin/develop'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   git_check

no changes added to commit (use "git add" and/or "git commit -a")

[:~/bin] develop(+4/-2) ± git_check
 bin [develop] --> Changes to be staged/committed at /Users/userid/bin

[:~/bin] develop(+4/-2) 128 ± git add -A
[:~/bin] develop(+0/-0) ± git diff --cached --shortstat
 1 file changed, 4 insertions(+), 2 deletions(-)

[:~/bin] develop(+0/-0) ± git_check
 bin [develop] --> Changes to be committed at /Users/userid/bin

[:~/bin] develop(+0/-0) 2s ± git commit -m "Better way to check for remote sync"[develop fab4f1d] Better way to check for remote sync
 1 file changed, 4 insertions(+), 2 deletions(-)
[:~/bin] develop(1) ± git_check
 OK --> bin [develop] fab4f1d
 bin [develop] --> [ahead 1] fab4f1d

[:~/bin] develop(1) 2s ± git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 416 bytes | 416.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To https://github.com/userid/repo.git
   ee0f0ca..fab4f1d  develop -> develop
[:~/bin] develop 4s ± git_check
 OK --> bin [develop] fab4f1d

По крайней мере, для меня это, похоже, решает мою проблему. Как показывает вывод консоли, он дает мне информацию о том, что происходит на каждом этапе рабочего процесса. В частности, он говорит мне, что мой локальный репозиторий опережает удаленный репозиторий на 1, сообщая мне, что мне нужно сделать pu sh. На других машинах я увижу, что они отстают на 1, сказав мне, что мне нужно сделать попытку синхронизации c.

Спасибо Тореку за полезную информацию.

...