Pada dasarnya saya mencoba alias:
git files 9fa3
... untuk menjalankan perintah:
git diff --name-status 9fa3^ 9fa3
tetapi git tampaknya tidak memberikan parameter posisi ke perintah alias. Saya telah mencoba:
[alias]
files = "!git diff --name-status $1^ $1"
files = "!git diff --name-status {1}^ {1}"
... dan beberapa yang lain tetapi itu tidak berhasil.
Kasus degenerasi adalah:
$ git echo_reverse_these_params a b c d e
e d c b a
... bagaimana saya bisa membuat ini berfungsi?
$1
seharusnya bekerja).Jawaban:
Cara yang paling jelas adalah dengan menggunakan fungsi shell:
Alias tanpa
!
diperlakukan sebagai perintah Git; miscommit-all = commit -a
.Dengan
!
itu, dijalankan sebagai perintahnya sendiri di shell, membiarkan Anda menggunakan sihir yang lebih kuat seperti ini.UPD
Karena perintah dijalankan di root repositori, Anda dapat menggunakan
${GIT_PREFIX}
variabel saat merujuk ke nama file dalam perintahsumber
!
diperlakukan sebagai perintah Git; miscommit-all = commit -a
. Dengan!
itu, dijalankan sebagai perintahnya sendiri di shell, membiarkan Anda menggunakan sihir yang lebih kuat seperti ini.!
akan berjalan di root repositori, jadi menggunakan jalur relatif saat memanggil alias Anda tidak akan memberikan hasil yang Anda harapkan.Anda juga dapat merujuk
sh
langsung (alih-alih membuat fungsi):(Perhatikan tanda hubung di akhir baris - Anda akan membutuhkannya.)
sumber
sh
, karena itu sendiri merupakan sebuah shell, dan itu tersedia di sebagian besar sistem. Menggunakan shell default hanya berfungsi jika perintah berfungsi seperti yang ditulis untuk semua shell.--
untuk-
karena lebih familiar dan cenderung sengaja berarti stdin di beberapa titik. ("Argumen dari - setara dengan -" di bash (1) tidak dapat diubah)sh -c
) juga tidak perlu. Lihat jawaban saya untuk alternatif.Alias yang Anda cari adalah:
Dengan validasi argumen:
Itu akhir
#
ini penting - mencegah semua argumen yang disediakan pengguna dari yang diproses oleh shell (itu komentar mereka keluar).catatan:
git
menempatkan semua argumen yang disediakan pengguna di akhir baris perintah. Untuk melihat ini dalam tindakan, coba:GIT_TRACE=2 git files a b c d
Kutipan yang lolos (karena bersarang) penting untuk nama file yang mengandung spasi atau
"; rm -rf --no-preserve-root /;
)sumber
!
sudah tersiratsh -c
(diperlihatkan saat prabandingGIT_TRACE=2
), jadi tidak perlu menjalankan sub-shell lain. Masalah apa yang Anda lihat dalam kasus yang lebih rumit?fp = "! 1=${1:-$(git headBranch)}; 2=${2:-up}; git fetch -fu $2 pull/$1/head:$1; git checkout $1; git branch -u $2 #"
. Ini berfungsi baik tanpa dua pernyataan pertama, tetapi jatuh jika Anda menggunakannya. (Saya juga punyaheadBranch = symbolic-ref --short HEAD
).fp = "! a=${1:-$(git headBranch)}; b=${2:-up}; git fetch -fu $b pull/$a/head:$a; git checkout $a; git branch -u $b #"
."
kutipan diperlukan?Gunakan GIT_TRACE = 1 yang dijelaskan pada halaman manual git untuk membuat pemrosesan alias transparan:
Perintah asli Anda berfungsi dengan git versi 1.8.3.4 (Eimantas mencatat ini berubah pada 1.8.2.1).
The
sh -c '..' --
danf() {..}; f
pilihan kedua bersih menangani "$ @" parameter dalam cara yang berbeda (lihat dengan GIT_TRACE). Menambahkan "#" ke alias juga akan memungkinkan parameter posisi tanpa meninggalkan yang tertinggal.sumber
files = "!git diff --name-status $1^ $1 #"
files = "!git diff --name-status $1^"
Seperti yang dinyatakan oleh Drealmer di atas :
GIT_PREFIX
diset oleh git ke subdirektori tempat Anda berada, Anda dapat mengelak dari ini dengan terlebih dahulu mengubah direktori:sumber
cd ${GIT_PREFIX:-.} &&.
" (sumber: stackoverflow.com/a/21929373/266309 )!cd "${GIT_PREFIX:-.}" && ls -al
Saya ingin melakukan ini dengan alias yang melakukan ini:
Pada akhirnya, saya membuat skrip shell bernama git-m yang memiliki konten ini:
Ini memiliki manfaat yang jauh lebih mudah dibaca karena ada di banyak baris. Ditambah lagi, aku suka bisa memanggil bash dengan
-x
danset -e
. Anda mungkin dapat melakukan semua ini sebagai alias, tetapi itu akan sangat jelek dan sulit untuk dipertahankan.Karena file tersebut bernama
git-m
Anda dapat menjalankannya seperti ini:git m foo bar
sumber
'!f() { : git branch ; ... }; f'
dan ini akan melengkapi secara otomatis alias sebagai cabang yang sangat berguna..bashrc
file saya yang saya sumber. Tapi saya tidak berpikir saya mengubah cara saya melengkapi argumen ke skrip sebanyak skrip itu sendiri, dan itu hanya akan terjadi selama dev.Hanya menabrak sesuatu yang serupa; Saya harap posting catatan saya. Satu hal yang membingungkan saya tentang
git
alias dengan argumen, mungkin berasal darigit help config
(saya punya git versi 1.7.9.5):Cara saya melihatnya - jika alias "akan diperlakukan sebagai perintah shell" ketika diawali dengan tanda seru - mengapa saya harus menggunakan fungsi, atau
sh -c
dengan argumen; mengapa tidak menulis perintah saya apa adanya?Saya masih belum tahu jawabannya - tetapi saya pikir sebenarnya ada sedikit perbedaan dalam hasil. Inilah sedikit tes - lemparkan ini pada Anda
.git/config
atau Anda~/.gitconfig
:Inilah yang saya dapat menjalankan alias ini:
... atau: ketika Anda menggunakan perintah "biasa" setelah
!
"apa adanya" digit
alias - makagit
secara otomatis menambahkan daftar argumen ke perintah itu! Memang cara untuk menghindarinya adalah dengan memanggil skrip Anda sebagai fungsi - atau sebagai argumensh -c
.Hal lain yang menarik di sini (bagi saya), adalah bahwa dalam skrip shell, seseorang biasanya mengharapkan variabel otomatis
$0
menjadi nama file skrip. Tetapi untukgit
fungsi alias,$0
argumennya adalah, pada dasarnya, isi dari seluruh string yang menentukan perintah itu (seperti yang dimasukkan dalam file konfigurasi).Itulah sebabnya, saya kira, jika Anda salah mengutip - dalam kasus di bawah ini, itu akan menghindari kutip ganda luar:
... - maka
git
akan gagal dengan (bagi saya, setidaknya) pesan yang agak samar:Saya pikir, karena
git
"melihat" seluruh string sebagai hanya satu argumen untuk!
- ia mencoba menjalankannya sebagai file yang dapat dieksekusi; dan karenanya gagal menemukan"echo 'A' 'B'"
sebagai file.Bagaimanapun, dalam konteks
git help config
kutipan di atas, saya berspekulasi bahwa lebih akurat untuk menyatakan sesuatu seperti: " ... doa" git baru "setara dengan menjalankan perintah shell" gitk --semua --tidak ORIG_HEAD $ @ ", di mana $ @ adalah argumen yang diteruskan ke alias perintah git dari baris perintah saat runtime ... ... ". Saya pikir itu juga akan menjelaskan, mengapa pendekatan "langsung" di OP tidak bekerja dengan parameter posisi.sumber
fail
sedang mencoba menjalankan perintah yang disebut "echo 'A' 'B" (mis. panjang 10 karakter). Kesalahan yang sama darish -c "'echo a b'"
dan penyebab yang sama, terlalu banyak lapisan kutipan