Git --force-with-lease с + в ветке (refspec)

В текущем состоянии Git существует ли разница между git push --force-with-lease origin +somebranch, git push --force-with-lease origin somebranch и git push origin +somebranch (без плюса)? Кажется, что все трое делают то же самое.

Я попытался найти документацию. Я попытался просмотреть refspec в документации, но я не знаю, есть ли разница, и если да, то какой из них следует предпочесть по умолчанию когда мне нравится, например, тянуть к рабочему ветку через git pull --rebase origin master.

Ответ 1

Это хороший вопрос; документация немного неоднозначна, и источник очень запутан (фактическое применение силовых флагов широко разбросано).

Один ответ достаточно ясен. Вот что документация git push, с добавлением жирного текста:

--[no-]force-with-lease
--force-with-lease=<refname>
--force-with-lease=<refname>:<expect>

                Обычно < git push "отказывается обновлять удаленный ref, который не является предком локального ref,

        Этот параметр переопределяет это ограничение, если текущее значение удаленного ref является ожидаемым значением." git push "не работает иначе.

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

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

      - one-force-with-lease, без указания деталей, будет защищать все удаленные ссылки, которые будут обновляться, требуя их текущее значение будет таким же, как и ветвь удаленного отслеживания, которую мы имеем для них.

        - force-with-lease = <refname> , без указания ожидаемого значения, будет защищать именованный ref (один), если он будет обновлен, требуя, чтобы его текущее значение было таким же, как и ветвь удаленного отслеживания, которую мы имеем для нее.

      - сила-с-аренды = < refname & GТ;: < ожидать, > будет защищать именованный ref (один), если он будет обновлен, требуя, чтобы его текущее значение было таким же, как указанное значение (которое может отличаться от ветки удаленного отслеживания мы имеем для refname, или мы даже не должны иметь такую ​​ветвь удаленного слежения, когда эта форма используется).

      Примечание: все формы, отличные от -force-with-lease = <refname> : <expect> что указывает, что ожидаемое текущее значение ref явно все еще экспериментально, и их семантика может измениться по мере приобретения опыта этой функции.

     " - no-force-with-lease" отменяет все предыдущие -force-with-lease в командной строке.

Следовательно, если опция сравнения и подкачки 1 поддерживается транспортом, и вы написали --force-with-lease, а не --no-force-with-lease, то все обновления, принудительные или нет, используют режим аренды.

--no-force-with-lease, однако, очищает сохраненную структуру push_cas_option, и это не сразу становится очевидным для меня, когда эти сохраненные значения применяются к каждому refspec.

Использование явного <refname> также явно защищает только одну ссылку, независимо от установленного для нее флага силы.

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


1 Внутри исходный код Git использует макрос CAS_OPT_NAME: функция force-with-lease вдохновлена ​​командами сравнения и обмена мгновенными процессорами, которые атомарно тестируют будет ли какая-либо переменная 2 установлена ​​на предсказанное значение, заменив ее новым значением, если это так, а также вернет в какой-то форме фактическое значение, найденное в переменной.

Это может привести к появлению кодов условий, если архитектура ЦП использует коды условий, но в большинстве случаев, если не во всех случаях, вы получаете старое значение, чтобы при необходимости повторить сравнение и обмен. Например, чтобы реализовать атомный add-one, вы можете выполнить цикл с помощью: load r1,(r0); label: add r1,1,r2; cas r1,r2,(r0); bne label; для реализации атомного теста и набора бит 2: load r1,(r0); label: or r1,4,r2; cas r1,r2,(r0); bne label; и так далее. Этот метод используется, например, для систем Intel Pentium и SPARC.

Некоторые процессоры вместо этого используют кэширование. Если кэш-память ближайшего к процессору имеет общие или эксклюзивные режимы (например, MESI или MOESI), мы можем использовать команду "load linked" или "load locked", за которой следует инструкция "store conditional". Условное хранилище выполняется только в том случае, если линия кэша все еще принадлежит исключительно текущему процессору. В этом случае мы должны повторно выполнить начальную заблокированную нагрузку переменной, и наши петли выглядят больше: label: ll r1,(r0); add 1,r1; sc (r0),r1; bne label. Это используется для архитектуры PowerPC и MIPS.

2 Обычно переменная, о которой идет речь, - это место памяти, часто с ограничениями выравнивания, даже на процессорах, которые номинально поддерживают неприсоединившуюся память. Например, в Intel Haswell команда сравнения и swap-8-байта будет завершена на 4-байтной границе, но на самом деле она не будет атомарной. Я обнаружил это с трудом, когда распределитель памяти коллеги предоставил только 4-байтовое выравнивание.: -)

Ответ 2

который, по умолчанию, должен предпочесть , когда мне нравится тянуть к рабочей ветке через git pull --rebase origin master?

Я сообщил о force-with-lease в 2013 для git 1.8.5 и март 2016 для git 2.8".

Я бы сказал... ни один из них.
A pull --rebase выполняется, чтобы избежать принудительного нажатия (с лимитом или без него).

Я просто устанавливаю (с git 2.6)

git config pull.rebase true
git config rebase.autoStash true

Это позволяет мне сделать несколько простых git pull, за которыми следует простой git push (без принудительного нажатия)