Я только что узнал о git push --force-with-lease . Это довольно круто. Но, конечно, я не так часто использую силу, и поэтому я беспокоюсь, что могу забыть об этой замечательной функции, когда она мне понадобится в следующий раз.
Есть ли способ настроить git, который git push -fбудет использоваться автоматически, --force-with-leaseесли я намеренно не переопределю его с помощью--no-force-with-lease ?
(Я не могу представить, что когда-нибудь захочу применить силу без аренды!)
AFAIK нет конфигурации, чтобы указать git всегда использовать force-with-leaseвместо force. Кажется, это хороший пример запроса функции; если у вас нет проблем с погружением в базу кода git, вы можете реализовать ее самостоятельно и отправить на проверку.
ИЗМЕНИТЬ В нынешнем виде это все еще актуально в апреле 2019 года.
До тех пор единственный вариант, который я вижу, - как это часто бывает, - создать alias который служит этой цели.
Создать псевдоним
Чтобы создать псевдоним git config --global alias.<alias-name> <command>, в нашем случае я бы предложил нечто подобное.
Это создаст запись в вашем глобальном .gitconfigфайле (который обычно находится в вашем домашнем каталоге ). После этого вы можете просто использовать git pushfдля принудительной аренды .
Замечание о том, что это не особенность: общий аргумент против переписывания стандартных команд («push --force») состоит в том, что вы привыкаете к ним, забываете их происхождение и однажды случайно используете их таким образом в новой системе. Многое , как сглаживание , rmчтобы rm -iв вашем .bashrc; однажды вы забудете и удалите важный файл на сервере.
Использование
2
Личный анекдот / предостережение: я пробовал использовать псевдоним, pushfно всегда дважды проверял, что я не выполняю push -f, из-за того, что он похож на псевдоним. Некоторые члены команды все push -fравно использовали , думая, что псевдоним был просто косметическим сокращением для него. В конце концов, мы заменили более безопасную форму псевдонимом pushflи перестали об этом беспокоиться.
кельвин
31
Я боюсь, что забуду об этой замечательной функции в следующий раз, когда она мне понадобится.
Git 2.13 (второй квартал 2017 г.) объясняет, почему нет «защиты» от того, чтобы этот параметр push был забыт, потому что даже если вы не забудете его на git pushуровне, его все равно можно будет проигнорировать.
push: документ и тест --force-with-lease с несколькими пультами
Документируйте и тестируйте случаи, когда два пульта дистанционного управления указывают на один и тот же URL-адрес, а фоновая выборка и последующие git push --force-with-leaseне должны затирать необновленные ссылки, которые мы не получили.
Некоторые редакторы, такие как Microsoft VSC, имеют функцию автоматической загрузки в фоновом режиме, это позволяет обойти защиту, предлагаемую --force-with-lease&--force-with-lease=<refname> , как указано в добавляемой здесь документации.
Общее замечание по безопасности: предоставление этой опции без ожидаемого значения, т.е. как --force-with-leaseили --force-with-lease=<refname>
очень плохо взаимодействует с чем-либо, что неявно запускается git fetchна удаленном компьютере, чтобы быть отправленным в фоновом режиме, например, git fetch origin
в ваш репозиторий в cronjob.
Защита, которую он предлагает, --forceгарантирует, что последующие изменения, на которых ваша работа не была основана, не будут засорены, но это тривиально, если какой-то фоновый процесс обновляет ссылки в фоновом режиме. У нас нет ничего, кроме информации об удаленном трекинге, которая будет использоваться в качестве эвристики для рефсов, которых вы ожидали увидеть и которые готовы сработать.
Если ваш редактор или какая-либо другая система работает git fetchв фоновом режиме, для вас способ смягчить это просто настроить другой пульт:
Теперь, когда фоновый процесс запускается, git fetch originссылки на origin-pushне будут обновляться, и, таким образом, такие команды, как:
git push --force-with-lease origin-push
Сбой, если вы не запустите вручную git fetch origin-push.
Этот метод, конечно, полностью побежден чем-то, что работает git fetch
--all, в этом случае вам нужно будет либо отключить его, либо сделать что-то более утомительное, например:
git fetch # update 'master' from remote
git tag base master # mark our base point
git rebase -i master # rewrite some commits
git push --force-with-lease=master:base master:master
Т.е. создайте baseтег для версий вышестоящего кода, которые вы видели и готовы перезаписать, затем переписать историю и, наконец, принудительно принудительно изменить изменения, masterесли удаленная версия все еще работает base, независимо от того, какая локальная версия remotes/origin/masterбыла обновлена в задний план.
Мое решение заключалось в том, чтобы создать сценарий-оболочку и использовать псевдоним, чтобы я всегда использовал его вместо реального git .
Всякий раз, когда я пытаюсь это сделать git push -f, я вижу следующее:
⚡ git push -f
use this instead so you don't cause race conditions in the
repo: git push --force-with-lease
Некоторые преимущества этого скрипта:
он приучает меня к привычному использованию --force-with-lease, поэтому меня не волнуют, когда я ошибаюсь
если по какой-то причине нам действительно нужно принудительно нажимать, git push --force будет работать.
Как это реализовать:
создать собственный скрипт, который будет передавать любые параметры в git, кроме -f
псевдоним этого скрипта, поэтому мы используем его вместо git
Эти инструкции предполагают, что Linux или Mac работает под управлением bash. Я не пробовал это с zsh или Windows, но полагаю, что там тоже будет работать.
~/.bash_profile:
alias git=~/.git_wrapper.sh
~./git_wrapper.sh:
#!/bin/bash
for arg in "$@"; do
if [ "$arg" = "push" ]; then
ispush=1
elif [ "$ispush" = 1 -a "$arg" = '-f' ]; then
echo "use this instead so you don't cause race conflicts in the repo: git push --force-with-lease"
exit 1
fi
done
git "$@"
С этими изменениями перезапустите свой терминал, и gitтеперь вы должны возмущаться, когда пытаетесь принудительно нажать.
Я хочу напомнить , что я не должен использовать -f, но я не хочу вводить в заблуждение , полагая , что -fсредства --force-with-lease. Итак, это мое мнение:
git() {
if [[ $@ == 'push -f'* ]]; then
echo Hey stupid, use --force-with-lease instead
else
command git "$@"
fi
}
rm
чтобыrm -i
в вашем .bashrc; однажды вы забудете и удалите важный файл на сервере.pushf
но всегда дважды проверял, что я не выполняюpush -f
, из-за того, что он похож на псевдоним. Некоторые члены команды всеpush -f
равно использовали , думая, что псевдоним был просто косметическим сокращением для него. В конце концов, мы заменили более безопасную форму псевдонимомpushfl
и перестали об этом беспокоиться.Git 2.13 (второй квартал 2017 г.) объясняет, почему нет «защиты» от того, чтобы этот параметр push был забыт, потому что даже если вы не забудете его на
git push
уровне, его все равно можно будет проигнорировать.См. Коммит f17d642 (19 апреля 2017 г.), сделанный var Arnfjör Bjarmason (
avar
) .(Объединено Junio C Hamano -
gitster
- в коммите 46bdfa3 , 26 апреля 2017 г.)Итак, документация на
git push
данный момент включает:источник
Мое решение заключалось в том, чтобы создать сценарий-оболочку и использовать псевдоним, чтобы я всегда использовал его вместо реального
git
.Всякий раз, когда я пытаюсь это сделать
git push -f
, я вижу следующее:Некоторые преимущества этого скрипта:
--force-with-lease
, поэтому меня не волнуют, когда я ошибаюсьgit push --force
будет работать.Как это реализовать:
-f
git
Эти инструкции предполагают, что Linux или Mac работает под управлением bash. Я не пробовал это с zsh или Windows, но полагаю, что там тоже будет работать.
~/.bash_profile
:~./git_wrapper.sh
:С этими изменениями перезапустите свой терминал, и
git
теперь вы должны возмущаться, когда пытаетесь принудительно нажать.источник
Для людей, использующих OMYZSH, вы можете просто использовать
ggfl
.источник
Я хочу напомнить , что я не должен использовать
-f
, но я не хочу вводить в заблуждение , полагая , что-f
средства--force-with-lease
. Итак, это мое мнение:Добавьте в свой
.bash_profile
,.bashrc
или.zshrc
.источник
Вы можете создать функцию bash, которая заменяет
git
и использует--force-with-lease
вместо--force
или в одной строке:
Просто добавьте его в свой
~/.bashrc
или~/.zshrc
.источник