push - force-with-leasing secara default

130

Saya baru belajar git push --force-with-lease. Cukup mengagumkan. Tapi, tentu saja, saya tidak terlalu sering menggunakan kekuatan, jadi saya khawatir saya akan melupakan fitur bagus ini saat nanti saya membutuhkannya.

Apakah ada cara untuk mengkonfigurasi git sehingga git push -fsecara otomatis akan digunakan --force-with-leasekecuali saya sengaja menimpanya --no-force-with-lease?

(Saya tidak bisa membayangkan pernah ingin menggunakan kekuatan tanpa sewa!)

Dan Fabulich
sumber

Jawaban:

141

AFAIK tidak ada konfigurasi yang tersedia untuk memberitahu git untuk selalu menggunakan force-with-leasebukan force. Ini tampaknya menjadi contoh yang baik untuk permintaan fitur; jika Anda tidak memiliki masalah untuk menyelam ke dalam basis kode git, Anda dapat menerapkannya sendiri dan mengirimkannya untuk ditinjau.

EDIT Seperti berdiri, ini masih berlaku di bulan April 2019.

Sampai saat itu satu-satunya pilihan yang saya lihat adalah, seperti yang sering terjadi, untuk membuat aliasyang melayani tujuan ini.

Buat alias

Untuk membuat alias yang akan digunakan git config --global alias.<alias-name> <command>, dalam kasus kami, saya akan menyarankan sesuatu yang mirip dengan ini.

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

Ini akan membuat entri dalam .gitconfigfile global Anda (yang biasanya dapat Anda temukan di direktori home Anda ). Setelah ini Anda hanya dapat menggunakan git pushfuntuk memaksa-dengan-sewa .

Jadikan tangan Anda kotor

Jika Anda ingin mengimplementasikan fitur ini sendiri tetapi tidak yakin harus mulai dari mana, Anda harus melihat direktori dokumentasi pada repositori git terlebih dahulu . Di sini Anda dapat menemukan pedoman pengkodean dan informasi tentang cara mengirim tambalan .

Anda dapat menemukan semua tautan ini dan lainnya di halaman komunitas resmi .

Sascha Wolf
sumber
25
Catatan tentang ini bukan fitur: argumen umum menentang penulisan ulang perintah standar ("push - force") adalah Anda terbiasa dengannya, lupa asal mereka, dan suatu hari tanpa sengaja menggunakannya dengan cara itu pada sistem baru. Sama seperti aliasing rmuntuk rm -idi .bashrc; Anda akan melupakan dan menghapus file penting di server suatu hari nanti. Pergi dengan alias Anda sendiri tidak memiliki masalah itu :)
hraban
2
Anekdot pribadi / kata hati-hati: Saya mencoba aliasing pushftetapi selalu memeriksa ulang bahwa saya tidak melakukan push -f, karena terlihat mirip dengan alias. Beberapa anggota tim menggunakan push -fanyways, berpikir bahwa alias itu hanya singkatan kosmetik untuk itu. Pada akhirnya, kami menggantinya dengan bentuk yang lebih aman pushfldan berhenti mengkhawatirkannya.
kelvin
31

Saya khawatir bahwa saya mungkin lupa tentang fitur bagus ini saat berikutnya saya membutuhkannya.

Git 2.13 (Q2 2017) menjelaskan mengapa tidak ada "perlindungan" terhadap opsi push ini yang dilupakan, karena bahkan jika Anda tidak melupakannya di git pushlevel, itu mungkin masih diabaikan.

Lihat komit f17d642 (19 Apr 2017) oleh Ævar Arnfjörð Bjarmason ( avar) .
(Digabung oleh Junio ​​C Hamano - gitster- dalam komit 46bdfa3 , 26 Apr 2017)

push: dokumentasikan & uji --force-with-leasedengan beberapa remote

Dokumentasikan & uji untuk kasus-kasus di mana ada dua remote yang menunjuk ke URL yang sama, dan latar belakang mengambil & selanjutnya git push --force-with-leaseseharusnya tidak mengganggu referensi yang tidak diperbarui yang belum kami ambil.

Beberapa editor seperti Microsoft VSC memiliki fitur untuk mengambil secara otomatis di latar belakang, ini memintas perlindungan yang ditawarkan oleh --force-with-lease&--force-with-lease=<refname> , sebagaimana dicatat dalam dokumentasi yang ditambahkan di sini.

Jadi dokumentasi untukgit push saat ini meliputi:

catatan umum tentang keamanan: menyediakan opsi ini tanpa nilai yang diharapkan, yaitu sebagai --force-with-leaseatau --force-with-lease=<refname> berinteraksi sangat buruk dengan apa pun yang secara implisit berjalan git fetchpada remote untuk didorong ke latar belakang, misalnya git fetch origin pada repositori Anda di cronjob.

Perlindungan yang ditawarkannya --forceadalah memastikan bahwa perubahan selanjutnya yang tidak didasarkan pada pekerjaan Anda tidak musnah, tetapi ini sepele dikalahkan jika beberapa proses latar belakang memperbarui referensi di latar belakang. Kami tidak memiliki apa-apa selain info pelacakan jarak jauh sebagai heuristik untuk referensi yang Anda harapkan telah dilihat & bersedia untuk musnah.

Jika editor Anda atau sistem lain berjalan git fetchdi latar belakang bagi Anda cara untuk mengurangi ini adalah dengan cukup mengatur remote lain:

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

Sekarang ketika proses latar belakang berjalan git fetch originreferensi origin-pushtidak akan diperbarui, dan dengan demikian perintah seperti:

git push --force-with-lease origin-push

Akan gagal kecuali Anda menjalankannya secara manual git fetch origin-push.
Metode ini tentu saja sepenuhnya dikalahkan oleh sesuatu yang berjalan git fetch --all, dalam hal ini Anda harus menonaktifkannya atau melakukan sesuatu yang lebih membosankan seperti:

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

Yaitu membuat basetag untuk versi kode hulu yang telah Anda lihat dan bersedia untuk ditimpa, lalu menulis ulang riwayat, dan akhirnya memaksa perubahan push ke masterjika versi jauh masih di base, terlepas dari apa lokal Anda remotes/origin/mastertelah diperbarui ke dalam Latar Belakang.

VONC
sumber
30

Solusi saya adalah membuat skrip pembungkus, dan menggunakan alias sehingga saya selalu menggunakannya sebagai pengganti yang asli git.

Setiap kali saya mencoba git push -f, saya melihat yang berikut:

⚡ git push -f
use this instead so you don't cause race conditions in the 
repo: git push --force-with-lease

Beberapa kelebihan dari skrip ini adalah:

  • itu melatih saya untuk terbiasa menggunakan --force-with-lease, jadi saya tidak merasa terganggu ketika saya salah
  • jika, karena alasan tertentu, kita benar-benar perlu memaksa, git push --forceakan berhasil.

Bagaimana cara mengimplementasikannya:

  1. buat skrip khusus yang akan melewati semua paro untuk git, kecuali untuk -f
  2. alias skrip itu jadi kami menggunakannya bukan git

Petunjuk ini menggunakan Linux atau Mac, menjalankan bash. Saya belum mencoba ini dengan zsh atau Windows, tetapi saya menganggap itu akan bekerja di sana juga.

~/.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 "$@"

Dengan perubahan itu, hidupkan ulang terminal Anda dan gitsekarang akan bertambah ketika Anda mencoba untuk memaksa.

Jessica Knight
sumber
17
Itu sepertinya nyaman. +1. Mungkin ganti "hey idiot" dengan "hey, kamu jiwa yang lembut tapi sederhana" atau semacam itu;)
VonC
5

Untuk orang yang menggunakan OMYZSH, Anda cukup menggunakan ggfl.

Nicolas
sumber
3

Saya ingin diingatkan bahwa saya tidak boleh menggunakan -f, tetapi saya tidak ingin tertipu untuk mempercayai itu -fberarti --force-with-lease. Jadi ini yang saya ambil:

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

Tambahkan ke Anda .bash_profile, .bashrcatau .zshrc.

neu242
sumber
1

Anda dapat membuat fungsi bash yang menggantikan gitdan menggunakan --force-with-leasealih-alih--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
}

atau, dalam satu baris:

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

Cukup tambahkan ke ~/.bashrcatau ~/.zshrc.

paulodiovani
sumber