Git klonundan sonra otomatik olarak nasıl cd yapılır?


35

Bir şey yaptıktan sonra komut cdtarafından oluşturulan dizine otomatik olarak geçmek istiyorum .clonegit clone

Önemli: Komutun sözdizimini değiştirmek istemiyorum (örneğin, bir takma ad / işlev kullanın) çünkü Pretzoprojeden otomatik olarak elde ettiğim zsh tamamlamalarını kıracak .

EDIT : Herhangi bir cevabı doğru seçmememin nedeni, yukarıdaki koşula uyan bir cevap verilmemesidir.

ZSH kullanıyorum, ancak başka bir kabuğun içindeki bir cevap da kabul edilebilir.


Unix.stackexchange.com/questions/97920/… cevabını beğendim ancak bu işlevi ~/.bashrcdosyaya (örneğin) yazmaktan bahsetmem gerekiyor ve benim için en azından işe yaramadı. hat:/usr/bin/git "$@" 2>&1 | tee $tmp
lcestari

Yanıtlar:


19

Bir işlev oluşturun:

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

(Hem ".git" olan ve olmayan bağlantılar için çalışır)


2
Kullanmazsam git clonedeğiştirmem gereken tüm araçlar nedeniyle kullanmaya devam etmek isterim git. Hub git takma ad, oh-my-zsh otomatik tamamlama vb. Sağlar ...
Daniel K.

3
@Wildeyes git, kabuğunuzun çalışma dizinini değiştiremez; bu nedenle, istediğinizi yapan ve onu yerleşik olarak izleyen bir diğer ad / işlev içine sarmanız gerekir cd. hubBunun yerine aramak istiyorsanız git, işlevini yapın. Yalnızca clonekomutu etkilemesini istiyorsanız , işlevdeki eylemi kontrol edin. vs.
frostschutz

Bunun basename git@github.com:pckujawa/pattern-rec.gitpattern-rec.git sonuçlarına neden olduğunu farkettim - klonlama yaparken sadece .git uzantısını bırakıyor musunuz?
Pat

8
@Pat basenameayrıca bir sonek argümanını da alır, böylece şunları yapabilirsiniz:git clone $1 && cd $(basename $1 .git)
Henrik N

17

git cloneek bir argüman alır: kullanılacak dizin. Geçerli çalışma dizinine klonlamanızı sağlayabilirsiniz. git clone URL . Sonra çalışma dizinini değiştirmenize gerek yoktur; sen zaten oradasın

Eğer gerçekten istiyorsan gitaslında dizini çalışma değiştirmeye komutu, sen gerçek çağıran bir işleve değiştirebilirsiniz gitgerektiğinde:

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
}

Tam olarak aradığım şey buydu. İç kanca ya da benzeri bir şey olmadığını farkettikten sonra neredeyse kesin bir işlev yazdım :)
Daniel K.

2
@Wildeyes Evet: /tmptmpfs aracılığıyla herhangi bir modern Linux'un yaptığı gibi RAM'deki bir hacme sahip. Her neyse, neden diske yazmayı önemsiyorsun, az önce bir git klonu yaptığında, dizinler yaratıyor ve diske belki yüzlerce dosya yazıyor ...
Kaz

1
Muhtemelen bütün "nvm diske yazarsa" konusunda haklısın, sadece fazladan işlem yapmak istiyordum. Çok teşekkürler Kaz.
Daniel K.

3
Dikkatli ol. bu git [flags] command [arguments]yüzden, kör bir şekilde clonebelirli pozisyonda sormak başarısız olur.
vonbrand

1
"Gerçek" yol yardımı eklemek ister misiniz? Beğen: git_real_home = which git git () {... $ git_real_home "$ @" | tee $ tmp
aakoch

7

Deponun yerel adını girerseniz, $ _ kullanarak gerçekten kolaydır :

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

Fakat uzun isimleri tekrar yazmak istemiyorsanız, biraz çirkin fakat sed ile yapılabilir:

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

EDIT: Eh, ben vecize için Manav teşekkür ederim (aşağıdaki yorum)

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

ancak zsh iş yapmaz (hakkında bir şey zsh açılımları nasıl yaptığını girdi olarak ilk komutu tedavi etmek değil bunu neden !$). Ne olduğuna bakmak zorundaydım !$:t( Bash Shell'de ilerlemek | $ {me: -whatever} ). !$önceki komutun son kısmını alır ve :t"Baştaki tüm dosya adı bileşenlerini kaldır, kuyruğunu bırakarak" olur. İyi bilgi, ancak keşke zsh ile çalışabilseydim keşke ( noglobbaşarı olmadan denedim ).

DÜZENLEME: ( sedveya !$:tbenim için zsh ile çalışmazsa) kullanmak yerine, iki seçenek daha buldum (biri https://unix.stackexchange.com/users/5685/frederik-deweerdt'in https ile verdiği cevabı uyarladım) : //unix.stackexchange.com/users/129926/henrik- 'nin yorumu):

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

veya

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

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

Repo URL'niz bitiyorsa , klasör adını almak için .gitkullanabilirsiniz !$:t:r.
Michael Stramel

2

Herhangi bir POSIX kabuğu için basit bir çözüm, açıkça klonlanacak dizini (herhangi bir dosya sistemi yolu) belirtip yeniden kullanmaktır:

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

ve

cd -

İşin bittiğinde


2

Gibi bir şey yapabilirsin:

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)

Bu oldukça basit. precmdSon komut satırının nasıl görünüp görünmediğini kontrol eden bir kanca (her komut isteminden önce çalıştırılır) git clone .../somethingveya git clone .../something dirdizini bundan ve cd'den tahmin edip etmediğini kontrol eder .

Giriş yaptıysanız, git clone foo; whateverya whatever; git clone fooda git clone --option repo...


+1 Kod için çok teşekkür ederiz; Birkaç günden beri kullanıyorum. Sadece bir sorunu farkettim; bir projeyi klonladıktan hemen sonra terminali kapatırsanız, bir sonraki terminali açtığınızda, zsh iki hata mesajından şikayet eder: CDing into <project>ve clone_check:cd:17: no such file or directory: <project>. Terminali kapatmadan önce koştuğunuz komut en kısa sürede hata kaybolur $ git clone.
user938271

2

İşte yukarıdaki cevabın bir uyarlaması: OSX

  • mktemp ek parametre gerektirir
  • git cloneyazar STDERRvarsayılan olarak (bkz bu )

İşlev:

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
Sizinkinin üstünde "yukarıdaki" yazan 7 cevap var. Ancak zamanla değişebilir. Bu tür referanslar SE hakkında bir anlam ifade etmemektedir, lütfen cevabınızı düzenleyin ve atıfta olduğunuz cevaba bir bağlantı ekleyin.
Techraf

0

Ben bunu tavsiye etmem ama olabilir bu tek astar kullanın:

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


0

Bunu kabuğuna ekle:

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"
}

Bu, klonlama hedefini git'in standart hatasından gizlice gizleyerek ve klonlamanın cdbaşarılı olması halinde (ve sadece eğer) hedefe girerek çalışır.

Düzenli olan tüm argümanları ve seçenekleri kabul eder git clone.

Git paketleyicisini kullanabilir ve tamamlamalarınız için endişelenmenize gerek kalmayabilir veya git paketleyiciden kurtulup git clonetamamlamalarınızı yeniden değerlendirebilirsiniz git-clone.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.