push - примусово з орендою за замовчуванням


130

Я щойно дізнався про це git push --force-with-lease. Це досить приголомшливо. Але, звичайно, я часто не використовую силу, тому переживаю, що можу забути про цю вишукану особливість наступного разу, коли мені це буде потрібно.

Чи є спосіб налаштування git так git push -fавтоматично використовуватись, --force-with-leaseякщо я навмисно не перекрию його --no-force-with-lease?

(Не можу собі уявити, коли б хотіли застосувати силу без оренди!)

Відповіді:


141

AFAIK не існує доступної конфігурації, щоб сказати git завжди використовувати force-with-leaseзамість force. Це здається хорошим прикладом для запиту на функцію; якщо у вас немає проблем зануритися в базу коду git, ви можете їх реалізувати самостійно та подати на розгляд.

РЕДАКЦІЯ Як і зараз, це все-таки справедливо у квітні 2019 року.

До цього часу я бачу єдиний варіант, як це часто, створити такий, aliasякий служить цій цілі.

Створіть псевдонім

Щоб створити псевдонім, який би використовувався git config --global alias.<alias-name> <command>, у нашому випадку я б запропонував щось подібне до цього.

git config --global alias.pushf "push --force-with-lease"

Це створить запис у вашому глобальному .gitconfigфайлі (який зазвичай можна знайти у домашньому каталозі ). Після цього ви можете просто використовувати git pushfдля примусового оренди .

Забруднити руки

Якщо ви хочете реалізувати цю функцію самостійно, але не знаєте, з чого почати, спершу слід переглянути каталог документації у сховищі git . Тут ви можете знайти вказівки щодо кодування та інформацію про те, як подати виправлення .

Ви можете знайти всі ці посилання та інше на офіційній сторінці спільноти .


25
Зауваження, що це не є особливістю: загальний аргумент проти переписування стандартних команд ("push --force") полягає в тому, що ти звикаєш до них, забуваєш їх походження та одного дня випадково використовуєш їх таким чином у новій системі. Багато що , як згладжування , rmщоб rm -iв вашому .bashrc; ви забудете і видалите важливий файл на сервері одного дня. Поїхати з власним псевдонімом не має такої проблеми :)
hraban

2
Особистий анекдот / слово обережності: Я намагався його відстежувати, pushfале завжди перевіряв, чи не роблю це push -f, через те, що він схожий на псевдонім. Деякі члени команди все push -fодно використовували , думаючи, що псевдонім - це лише косметична стенограма. Врешті-решт, ми замінили безпечнішу форму pushflзамість цього і перестали турбуватися про це.
кельвін

31

Я переживаю, що я можу забути про цю вишукану особливість наступного разу, коли мені це буде потрібно.

Git 2.13 (Q2 2017) пояснює, чому немає "захисту" від забуття цієї опції push, тому що навіть якщо ви цього не зробите забудете його на git pushрівні, він все одно може бути проігнорований.

Див. Комісію f17d642 (19 квітня 2017 р.) Від Ævar Arnfjörð Bjarmason ( avar) .
(Об’єднав Хуніо С Хамано - gitster- в комітці 46bdfa3 , 26 квітня 2017 р.)

push: документ і тест --force-with-lease з кількома видаленнями

Документ і тест для випадків, коли два пульти вказують на одну і ту ж URL-адресу, а також фонове отримання та наступне git push --force-with-lease не повинно перекручувати оновлені посилання, які ми не отримали.

Деякі редактори, такі як VSC Майкрософт, мають функцію автоматичного вибору у фоновому режимі, це обходить захист, пропонований --force-with-lease&--force-with-lease=<refname> , як зазначено в доданій тут документації.

Тож документація наgit push наразі включає:

загальна примітка щодо безпеки: надання цього варіанта без очікуваного значення, тобто як --force-with-leaseабо --force-with-lease=<refname> дуже погано взаємодіє з усім, що неявно працюєgit fetch на пульті дистанційного керування, щоб пересунути його у фоновому режимі, наприклад, git fetch origin у вашому сховищі під час роботи.

Захист, який він пропонує --force , забезпечує те, що наступні зміни, на яких не ґрунтувалася ваша робота, не халопуються, але це тривіально зазнає поразки, якщо якийсь фоновий процес оновлює рефлекси у фоновому режимі. У нас немає нічого, окрім інформації про віддалене відстеження, щоб пройти як евристику для рецензій, які, як ви очікували, побачили, і які готові пограбувати.

Якщо ваш редактор або якась інша система працює git fetchу фоновому режимі, для вас спосіб пом'якшити це просто встановити інший пульт:

git remote add origin-push $(git config remote.origin.url)
git fetch origin-push

Тепер, коли фоновий процес запускається, 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чого оновлено вашу локальну версію в тло.


30

Моє рішення полягало в тому, щоб створити сценарій обгортки і використовувати псевдонім, щоб я завжди використовував його замість реального 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буде працювати.

Як це здійснити:

  1. створити користувальницький скрипт, який пройде через будь-які парами для git, за винятком -f
  2. псевдонім цей сценарій, тому ми використовуємо його замість цього 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тепер ви повинні отримати пошкодження, коли ви намагаєтесь натиснути.


17
Це здається зручним. +1. Можливо, замініть "ей ідіот" на "ей, ти ніжна, але проста душа" або щось подібне;)
VonC

5

Для людей, які використовують OMYZSH, ви можете просто використовувати ggfl.


3

Мені хочеться нагадати, що я не повинен використовувати -f, але я не хочу, щоб його обдурили, щоб повірити, що це -fозначає --force-with-lease. Отже, це моя думка:

git() {
  if [[ $@ == 'push -f'* ]]; then
    echo Hey stupid, use --force-with-lease instead
  else
    command git "$@"
  fi
}

Додайте до свого .bash_profile, .bashrcабо .zshrc.


1

Ви можете створити функцію bash, яка замінює gitта використовує --force-with-leaseзамість--force

# replaces `git push --force` with `git push --force-with-lease`
git() {
  if [[ $@ == 'push -f'* || $@ == 'push --force'* ]]; then
    command git push --force-with-lease
  else
    command git "$@"
  fi
}

або, в одному рядку:

git() { if [[ $@ == 'push -f'* || $@ == 'push --force'* ]]; then command git push --force-with-lease; else command git "$@"; fi; }

Просто додайте його до свого ~/.bashrcабо ~/.zshrc.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.