Bagaimana cara cd secara otomatis setelah git clone?


37

Saya ingin secara otomatis cdke direktori yang dibuat oleh cloneperintah setelah saya git cloned sesuatu.

Penting: Saya tidak ingin mengubah sintaks untuk perintah (misalnya menggunakan alias / fungsi) karena itu akan merusak zsh-melengkapi saya dapatkan secara otomatis dari Pretzoproyek.

EDIT : Alasan saya tidak memilih jawaban yang benar, adalah karena tidak ada jawaban yang memenuhi persyaratan di atas.

Saya menggunakan ZSH, tetapi jawaban di shell lain juga dapat diterima.


Saya suka jawabannya unix.stackexchange.com/questions/97920/... tetapi perlu disebutkan untuk menulis fungsi itu di ~/.bashrcfile (misalnya) dan bagi saya setidaknya itu tidak berfungsi, saya perlu memperbaikinya dengan mengganti baris:/usr/bin/git "$@" 2>&1 | tee $tmp
lcestari

Jawaban:


19

Buat fungsi:

gclonecd() {
  git clone "$1" && cd "$(basename "$1" .git)"
}

(Berfungsi untuk tautan baik dengan dan tanpa ".git")


2
Saya ingin tetap menggunakan git clonekarena semua alat yang harus saya ubah jika saya tidak menggunakan git. Hub alias git, oh-my-zsh menyediakan penyelesaian otomatis, dll ...
Daniel K.

3
@Wildeyes gittidak dapat mengubah direktori kerja shell Anda, jadi Anda harus membungkusnya dengan alias / fungsi yang melakukan apa yang Anda inginkan dan mengikutinya dengan builtin cd. Jika Anda ingin menelepon hubalih-alih git, lakukan di fungsi. Jika Anda hanya ingin memengaruhi cloneperintah, periksa tindakan di fungsi. dll
frostschutz

Saya perhatikan bahwa basename git@github.com:pckujawa/pattern-rec.gitmenghasilkan pola-rec.git - apakah Anda meninggalkan ekstensi .git saat Anda mengkloning?
Pat

8
@Pat basenamejuga membutuhkan argumen sufiks, sehingga Anda dapat melakukan:git clone $1 && cd $(basename $1 .git)
Henrik N

17

git clonemembutuhkan argumen tambahan: direktori untuk digunakan. Anda dapat membuatnya klon ke direktori kerja saat ini dengan git clone URL . Lalu, tidak perlu mengubah direktori kerja; kamu sudah ada di sana.

Jika Anda benar-benar ingin gitperintah untuk benar-benar mengubah direktori kerja, Anda dapat mengubahnya ke fungsi yang memanggil yang sebenarnya gitsaat diperlukan:

git()
{
   local tmp=$(mktemp)
   local repo_name

   if [ "$1" = clone ] ; then
     /usr/bin/git "$@" | tee $tmp
     repo_name=$(awk -F\' '/Cloning into/ {print $2}' $tmp)
     rm $tmp
     printf "changing to directory %s\n" "$repo_name"
     cd "$repo_name"
   else
     /usr/bin/git "$@"
   fi
}

Itulah tepatnya yang saya cari. Setelah saya sadari tidak ada kaitan internal atau sesuatu seperti itu, saya menulis fungsi yang hampir pasti :)
Daniel K.

2
@Wildeyes Ya: memiliki /tmpvolume yang ada dalam RAM, seperti halnya Linux modern lainnya melalui tmpfs. Ngomong-ngomong, mengapa Anda peduli menulis ke disk, ketika Anda baru saja melakukan klon git, yang membuat direktori dan mungkin menulis ratusan file ke disk ...
Kaz

1
Anda mungkin benar tentang hal "nvm jika itu menulis ke disk", saya hanya ingin menyimpan operasi tambahan. Terima kasih banyak, Kaz.
Daniel K.

3
Hati-hati. itu git [flags] command [arguments], jadi membabi buta meminta clonepada posisi tertentu akan gagal.
vonbrand

1
Apakah menambahkan jalur "nyata" membantu? Seperti: git_real_home = which git git () {... $ git_real_home "$ @" | tee $ tmp
aakoch

7

Jika Anda memberikan nama lokal dari repo itu, sangat mudah menggunakan $ _ :

git clone git@github.com:npm/npm.git npm-local-dir && cd $_

Tetapi jika Anda tidak ingin mengetik ulang nama panjang, itu agak jelek tapi bisa dilakukan dengan sed:

git clone git@github.com:pckujawa/pattern-rec.git && 
cd `echo $_ | sed -n -e 's/^.*\/\([^.]*\)\(.git\)*/\1/p'`

EDIT: Ya, saya akan berterima kasih kepada Manav (komentar di bawah) untuk singkatnya

git clone foo/bar && cd !$:t

tetapi itu tidak bekerja di zsh (sesuatu tentang bagaimana zsh melakukan ekspansi menyebabkannya tidak memperlakukan perintah pertama sebagai input ke !$). Saya harus mencari tahu apa yang !$:tterjadi ( Memajukan dalam Bash Shell | $ {me: -apapun} ). !$ambil bagian terakhir dari perintah sebelumnya dan :takan "Hapus semua komponen nama file terkemuka, biarkan ekor." Informasi yang bagus, tetapi saya berharap saya bisa membuatnya bekerja dengan zsh (saya mencoba noglobtanpa hasil).

EDIT: Alih-alih menggunakan sedatau !$:t(yang tidak berfungsi di zsh, bagi saya toh), saya menemukan dua opsi lain (satu mengadaptasi https://unix.stackexchange.com/users/5685/frederik-deweerdt jawaban dengan https : //unix.stackexchange.com/users/129926/henrik-n komentar):

git clone git@github.com:npm/npm.git && cd $(basename $_ .git)

atau

git clone git@github.com:npm/npm.git && cd ${${_%%.git*}##*/}

git clone foo/bar && cd !$:t
Manav

Jika url repo Anda berakhir, .gitAnda dapat menggunakan !$:t:runtuk mendapatkan nama folder.
Michael Stramel

2

Solusi sederhana untuk setiap shell POSIX adalah menentukan direktori yang akan dikloning secara eksplisit (jalur sistem file apa pun) dan menggunakannya kembali:

git clone <repository> <directory> &&
cd "$_"

dan

cd -

ketika kamu selesai.


2

Anda dapat melakukan sesuatu seperti:

clone_check() {
  (($? != 0)) && return
  local cmd=$history[$((HISTCMD-1))]
  cmd=("${(@Q)${(z)cmd}}")
  if [[ $cmd = "git clone "* ]]; then
    local dir
    if (($#cmd == 3)); then
      dir=${cmd[3]:t}
      dir=${dir%.git}
      dir=${dir#*:}
    elif (($#cmd > 3)); then
      dir=$cmd[-1]
    else
      return
    fi
    print -r CDing into $dir > /dev/tty
    cd -- $dir
  fi
}
precmd_functions+=(clone_check)

Ini sangat sederhana. Ini adalah precmdpengait (dijalankan sebelum setiap prompt), yang memeriksa apakah baris perintah terakhir terlihat seperti git clone .../somethingatau git clone .../something dir, tebak direktori dari itu dan masukkan ke dalamnya.

Tidak bekerja jika Anda memasukkan git clone foo; whateveratau whatever; git clone fooatau git clone --option repo...


+1 Terima kasih banyak atas kodenya; Saya menggunakannya sejak beberapa hari. Saya baru saja memperhatikan satu masalah; jika Anda menutup terminal tepat setelah kloning suatu proyek, saat berikutnya Anda membuka terminal, zsh mengeluh dengan dua pesan kesalahan: CDing into <project>dan clone_check:cd:17: no such file or directory: <project>. Kesalahan menghilang segera setelah perintah terakhir yang Anda jalankan sebelum menutup terminal berbeda $ git clone.
user938271

2

Berikut adalah adaptasi dari jawaban di atas untuk OSX

  • mktemp memerlukan parameter tambahan
  • git clonemenulis ke STDERRsecara default (lihat ini )

Fungsi:

function git {
   local tmp=$(mktemp -t git)
   local repo_name

   if [ "$1" = clone ] ; then
     command git "$@" --progress 2>&1 | tee $tmp
     repo_name=$(awk -F\' '/Cloning into/ {print $2}' $tmp)
     rm $tmp
     printf "changing to directory %s\n" "$repo_name"
     cd "$repo_name"
   else
     command git "$@"
   fi
}

1
Ada 7 jawaban yang menampilkan "di atas" milik Anda. Tapi itu bisa berubah seiring waktu. Referensi semacam itu tidak masuk akal di SE, harap edit jawaban Anda dan sertakan tautan ke jawaban yang Anda maksud.
techraf

0

Saya tidak akan merekomendasikannya, tetapi Anda bisa menggunakan ini satu-liner:

echo 'project' | xargs -I % sh -c 'git clone https://github.com/username/%.git && cd %'


0

Sertakan ini di shell Anda:

git(){
  case "$1" in clone) git-clone "${@:2}";; *) command git "$@";; esac
}
git-clone(){ 
   local tgt 
   tgt=$(command git clone "$@" 2> >(tee /dev/stderr |head -n1 | cut -d \' -f2)) ||
      return $?
   cd "$tgt"
}

Ini bekerja dengan secara diam-diam mengumpulkan target kloning dari kesalahan standar git dan cdmemasuki target jika (dan hanya jika) kloning berhasil.

Ia menerima semua argumen dan opsi yang biasa git clonedilakukan.

Entah Anda bisa menggunakan pembungkus git dan tidak perlu khawatir tentang kelengkapan Anda, atau Anda bisa menyingkirkan pembungkus git dan rewire git clonekelengkapan Anda untuk git-clone.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.