В чем причина использования Push только в том случае, если удаленные ссылки не меняются в среднем времени в EGit?

Плагин eclipse EGit предоставляет мастер отправки для отправки изменений в репозиторий Git. В конце мастера есть диалоговое окно подтверждения с флажком «Отправлять только в том случае, если удаленные ссылки не меняются в это время», как описано на странице документации EGit «http://wiki.eclipse.org/EGit/User_Guide#Push_Confirmation".

Согласно книге Git, глава 2.5 (https://book.git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes), Git отклонит отправку в удаленный репозиторий, если другой человек внес некоторые изменения в среднее время (с момента последней синхронизации/выборки).

Итак, мой вопрос: Какая польза от описанного флажка, если отправка будет отклонена в любом случае, если удаленный репозиторий изменился с момента последней выборки?

Чтобы открыть диалог с описанной опцией, вам необходимо выполнить следующие действия:

  • создать несколько локальных коммитов в репозитории Git через EGit
  • Щелкните правой кнопкой мыши связанный проект eclipse и нажмите "Команда > Удаленный > Нажать..."
  • Выберите нужный удаленный репозиторий
  • Добавьте хотя бы одну спецификацию push с исходной и целевой ссылками.
  • Нажмите "Далее'

person Jeff S.    schedule 12.04.2017    source источник


Ответы (1)


Я не использую EGit, поэтому мне приходится немного догадываться, но из того, что находится на их странице, на которую вы ссылаетесь, кажется, что их push-диалог использует несколько функций Git за кулисами.

Задний план

Согласно книге Git, глава 2.5 (https://book.git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes), Git отклонит отправку в удаленный репозиторий, если другой человек внес некоторые изменения в среднее время (с момента последней синхронизации/выборки).

Это не ошибка, но и не вся картина.

Когда вы бежите:

git push <remote> <refspec>

ваш Git вызывает другого Git по интернет-телефону, а ваш Git и их Git — «чужой» Git, как это называется в документации по gitooks — поговорите. Ваш Git отправляет чужой Git, который коммитит ваш новый для них, а затем отправляет запросы или команды в форме:

Пожалуйста, если хотите, установите master так, чтобы он указывал на коммит 1234567.

or:

Я приказываю тебе: немедленно переведи master в 1234567!

В этом разговоре есть три части: одна — установить, о чем вообще собираются говорить ваш Git и чужой Git; один для передачи коммитов (и любых других соответствующих объектов Git); и последний, чтобы направить чужой Git о том, какие ссылочные обновления делать, то есть, являются ли обновления вашей ветки вежливыми просьбами («сделай это, если тебе это нравится») или командами («возьми это сейчас, черт возьми»). (Мы также должны отметить, что это не просто имена ветвей; то же самое относится к тегам и любым другим ссылкам. Однако все они работают примерно одинаково.)

Но в этом разговоре также участвуют два Гита: ваш и иностранный Гит. Это все хорошо, но в мире больше двух мерзавцев. Что, если третий Git общается с чужим Git? Возможно, что ваш Git и другой Git оба взаимодействуют с внешним Git одновременно.

Книга Pro Git касается здесь большой проблемы, которая заключается в том, что сторонний Git может получить новые коммиты в своих ветках за некоторое время до того, как вы отправите вежливый запрос «пожалуйста, установите». В этом случае, когда вы отправляете вежливый запрос «пожалуйста, установите», чужой Git говорит: «нет, если я это сделаю, я забуду коммиты, которые у меня есть, а у вас нет». В этом случае, как говорится в книге, они отклоняют отправку, и вы можете получить их новые коммиты, интегрировать все их новые для вас коммиты с вашими и повторить попытку.

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

Следовательно, в современных версиях Git есть еще одна возможность атомарно устанавливать ссылки, если и только если они соответствуют тому, что, по вашему мнению, соответствует. То есть ваш Git отправляет команду: «установить master в 1234567!» закваска с "... но только если сейчас fedcba9!" Это дает вам возможность получить данные из внешнего Git, решить, что делать, а затем отправить им команды, которые являются условными для внешнего Git, не изменив эти ветки (или другие ссылки). тем не менее, чтобы убедиться, что вы не мешаете третьему Git.

Git называет эти атомарные обновления сравнения и замены --force-with-lease.

Вернуться к EGit

EGЭто кажется особенно полезным для вас (с вашей стороны этого разговора), чтобы выяснить, что произойдет в будущем, в каждой половине этого разговора, который еще даже не началось! Здесь вы смотрите на свой графический интерфейс с его щелкающими полями и кнопками, и ваш Git еще даже не вызвал чужой Git через Интернет-телефон, чтобы начать передачу, и ваш графический интерфейс EGit пытается угадать, что будет< /em> произойдет в будущем, даже несмотря на то, что прямо сейчас могут быть другие мерзавцы, разговаривающие с иностранным мерзавцем.

Таким образом, ваш графический интерфейс EGit использует небольшую хитрость: у него есть ранний диалог с чужим Git. Прямо сейчас он вызывает этот Git и спрашивает его: «Эй, как называются ваши ветки в коммитах?» Если в вашем EGit есть эти коммиты, ваш EGit может определить, какие коммиты вы им отправите. Если в вашем EGit нет этих коммитов, ваш EGit может получить их, а затем выяснить, какие коммиты вы будете отправлять.1 Итак, теперь у вашего EGit есть действительно хорошее представление о том, что он отправит им и что он увидит в названии их ветки (и других ссылках) для отображения хэш-идентификатора.

Итак, ваш графический интерфейс EGit может показать вам эти вещи. Но затем, когда вы нажмете последнюю кнопку «Перейти», ваш EGit вызовет свой Git снова и фактически начнет диалог, состоящий из двух частей — и, возможно, какой-то третий Git доберется до него первым, и разговор выиграет. Не делайте так, как думает ваш графический интерфейс EGit. Вот тут-то и появляются эти дополнительные подтверждающие клики.

Не совсем ясно, использует ли EGit параметр «условная команда». Принимающий чужой Git не полностью блокирует обновления «третьего Git» во время возможно продолжительного разговора, который отправляет коммит и другие объекты по интернет-телефонным проводам. Они действительно получают первоначальный набор сопоставлений имени и идентификатора и могут немедленно прервать диалог, если он не соответствует их ожиданиям; затем у них должна быть средняя часть беседы, которая фактически отправляет объекты; а затем у них есть заключительная часть разговора, посвященная обновлению внешних ссылок Git. Работают ли щелкающие поля только в первой части или они также влияют на любые окончательные команды и вежливые запросы? Это мне непонятно.

Но это есть ответ на этот вопрос:

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

Он может использовать условную функцию (принудительное нажатие, только если ничего не изменилось) или может прервать разговор, если что-то даже не начало< /em>, как и планировалось», или даже и то, и другое. Изображения в документации, на которую вы ссылаетесь, имеют отдельный щелчок для «принудительного нажатия», поэтому, по-видимому, графический интерфейс EGit не будет отправлять свои окончательные запросы в виде команд, если этот флажок не установлен также. Я не знаю, превращает ли проверка второго окна подтверждения их в команды атомарной замены; но если это нет, начальной проверки недостаточно, потому что "третьи Git" могут обновить внешние ссылки Git во время передачи объекта в части диалога.

Следовательно, я бы сказал: это либо предлагает вам приятную вещь, которая на самом деле не имеет никакого эффекта; или включается --force-with-lease.


1Я не знаю, действительно ли EGit делает это — запускает git fetch невидимо — но если это нет, он не может правильно рассчитать набор коммитов, которые будут отправлены в будущее.

person torek    schedule 12.04.2017
comment
Большое спасибо за подробный ответ. Я уже предположил, что упомянутый флажок связан с принудительным нажатием (смеется), но не был полностью уверен. И я не очень был знаком с опцией «принудительно с арендой». Итак, подведем итог: скорее всего, флажок активирует опцию «force-with-lease». Тем не менее, я думаю, что это происходит только в том случае, если есть хотя бы одна спецификация push с активированным флажком «принудительное обновление». В противном случае удаленный Git откажется от толчка в случае конфликтов. Я отмечаю ответ как правильный, предполагая, что более надежного ответа не будет. - person Jeff S.; 16.04.2017
comment
Еще одна полезная статья, связанная с опцией «принудительно с арендой»: developer.atlassian.com/blog/2015/04/force-with-lease - person Jeff S.; 16.04.2017
comment
Я отметил этот ответ как правильный, предполагая, что не будет более надежного ответа на фактическое поведение EGit. - person Jeff S.; 16.04.2017