Подтвердить что ты не робот

Что и где потенциально может потерять материал, когда git говорит "принудительное обновление"?

Недавно я получил предупреждение "принудительное обновление" из git в репозитории, который я только совершил. Я не делал повторного базирования, поэтому я не знаю, почему это произошло. Я хочу знать, где я должен искать изменения, которые потенциально были потеряны?

Чтобы проиллюстрировать, пусть есть три копии репозитория, L, D и S (ноутбук, рабочий стол, сервер).

Для начала все три репозитория синхронизированы. Затем выполняется работа над D и сдвигается на S. Затем L запускает git pull и получает "принудительное обновление". Означает ли это, что произошли изменения на L, которые были перезаписаны, или они где-то еще? Как я могу их найти? Спасибо.

4b9b3361

Ответ 1

"принудительное обновление" означает, что ветвь удаленного отслеживания была последней. Это происходит, если вы извлекаете (или вытягиваете) после того, как кто-то делает принудительное нажатие на репозиторий.

Однако при выполнении git pull ваш локальный ветвь не потеряет историю. Поскольку история удаленных веток теперь расходится с вашей локальной, git pull выполнит слияние. Если вы посмотрите на последнюю фиксацию (просто запустите git log), вы должны увидеть фиксацию слияния, при этом первым родителем будет прежнее состояние вашей локальной ветки, а вторым родителем будет новое значение вашей удаленной ветки.

Для иллюстрации я просто воспроизвел сценарий принудительного обновления, а git pull печатает следующее:

> git pull
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 2 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (2/2), done.
From /Volumes/UserData/Users/kballard/Dev/Scratch/foo/server
 + 7193788...a978889 master     -> origin/master  (forced update)
Merge made by the 'recursive' strategy.
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 d

Участок извлечения отрывных отпечатков (forced update), но новое значение origin/master впоследствии объединяется в локальную ветвь.

Ответ 2

Что я хочу знать, где я должен искать изменения, которые потенциально были потеряны?

Кевин прав, когда писал, что никакая местная история не будет потеряна. Тем не менее, некоторая удаленная история может быть потеряна, хотя она будет потеряна специально.

Пример

Например:

  • D совершает и толкает master в S.
  • L выбирается.
  • D изменяет ум (изменяет фиксацию или изменяет историю master любым способом).
  • D толкает измененный (без перемотки вперед) master в S.

На выборке L будет предупреждать "принудительное обновление", потому что предыдущий кончик ветки больше не доступен через ссылку на ветку master. Но это то, что D хотел в любом случае.

Что искать

От ответа Кевина:

 + 7193788...a978889 master     -> origin/master  (forced update)

Эта строка появится только один раз. Ссылка на возможное потерянное сообщение - 7193788.

Как исследовать его

Если L хочет сохранить ссылку на то, что может быть потеряно, L может возникнуть в примере выше: git branch whateverbranchname 7193788. Это может быть сделано независимо от текущего состояния местной проверки.

Или просто git checkout 7193788, чтобы исследовать его в отдельной голове, затем, например, git checkout master, чтобы вернуться к мастеру. Это может потребовать сначала совершить любое локальное изменение.

Хорошая практика

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

Другими словами, никто не должен удивляться, увидев "принудительное обновление" при выполнении выборки в общем репозитории. Если кто-то толкнул плохой фиксатор, им следует рассмотреть возможность просто надавить исправленную фиксацию сверху, а не изменять существующую историю. В качестве альтернативы, они должны соглашаться с другими, прежде чем нажимать измененную историю. Этот последний вариант недоступен в публичном репозитории.

Ответ 3

Git 2.23 (Q3 2019) иллюстрирует, когда обнаружено "принудительное обновление", и предлагает вариант не показывать его.

См. commit 3883c55, commit 377444b, commit cdbd70c (18 июня 2019) от Деррик Столи (derrickstolee).
. (Merged by Junio C Hamano -- [TG41] -- in commit cde9a64, 09 Jul 2019)

fetch: добавить аргумент --[no-]show-forced-updates

После обновления набора удаленных ссылок во время 'git fetch' мы переходим коммиты в новое значение ссылки, а не в старое значение ссылки, чтобы определить, было ли обновление принудительным обновлением.

Это приводит к двум вещам, происходящим во время команды:

  1. Строка, включающая обновление ref, имеет дополнительный маркер (принудительное обновление) в конце.

  2. Журнал ссылок для этой удаленной ветки включает в себя сообщение о том, что обновление является принудительным обновлением.

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

Добавьте опцию "--[no-]show-forced-updates", которая позволяет пользователю пропустить это расчет.
Единственный постоянный результат - удаление бита принудительного обновления в reflog.

Включите новый параметр конфигурации fetch.showForcedUpdates, который позволяет поведение без включения аргумента в каждую команду.
Настройка config переопределяется аргументами командной строки.

Это означает, что документация теперь имеет:

fetch.showForcedUpdates:

Установите false, чтобы включить --no-show-forced-updates в командах git-fetch и git-pull.
По умолчанию true.

--show-forced-updates:

По умолчанию Git проверяет, принудительно ли обновляется ветвь во время выборки.
Это можно отключить с помощью fetch.showForcedUpdates, но опция --show-forced-updates гарантирует, что эта проверка произойдет.

--no-show-forced-updates:

По умолчанию Git проверяет, принудительно ли обновляется ветвь во время выборки.
Передайте --no-show-forced-updates или установите fetch.showForcedUpdates на false , чтобы пропустить эту проверку по соображениям производительности.

При использовании во время "git-pull" опция --ff-only будет по-прежнему проверять наличие принудительных обновлений, прежде чем пытаться выполнить ускоренное обновление.

И:

fetch: предупреждать о принудительных обновлениях в списке ветвей

Опция --[no-]show-forced-updates в "git fetch" может сбивать с толку некоторых пользователей, особенно если она включена через настройку конфигурации, а не по аргументу.
Добавьте совет, чтобы предупредить пользователя о том, что (принудительное обновление) сообщений не было в списке.

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

документация с рекомендациями по конфигурации теперь включает в себя:

fetchShowForcedUpdates:

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

Обратите внимание, что тест исправлен в Git 2.3.1/2.24 (Q4 2019)

См. коммит 814291c (30 июля 2019 г.) от СЗЕДЕР Габор (szeder).
(Merged by Junio C Hamano -- [TG429] -- in commit 8aa76ab, 22 Aug 2019)

См. commit decfe05, commit 7f005b0, commit 12b1826 (01 августа 2019) от СЗЕДЕР Габор (szeder).
. (Merged by Junio C Hamano -- [TG431] -- in commit 77067b6, 22 Aug 2019)