Chcę automatycznie cd do katalogu utworzonego przez clone polecenie po I git clone d czymś.

Ważne: Nie chcę zmieniać składni polecenia (np. użyć aliasu / funkcji), ponieważ złamałoby to uzupełnienia zsh, które otrzymuję automatycznie z projektu Pretzo.

EDYTUJ : Powodem, dla którego nie wybrałem żadnej poprawnej odpowiedzi, jest brak odpowiedzi biorąc pod uwagę, że spełniał powyższy warunek.

Używam ZSH, ale odpowiedź w jakiejkolwiek innej powłoce jest również akceptowalna.

Komentarze

  • Podoba mi się odpowiedź unix.stackexchange.com/questions/97920/… , ale potrzebuję wspomnieć o zapisaniu tej funkcji w pliku ~/.bashrc (na przykład) i dla mnie w l na wschód nie zadziałało ' t, musiałem to naprawić, zastępując wiersz: /usr/bin/git "$@" 2>&1 | tee $tmp

Odpowiedź

Utwórz funkcję:

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

(Działa dla łączy z i bez „.git”)

Komentarze

  • Chciałbym nadal używać git clone, ponieważ wszystkich narzędzi, które musiałbym zmienić, gdybym nie używał git. Hub ma alias git, oh-my-zsh zapewnia automatyczne uzupełnianie itd …
  • @Wildeyes git może ' t zmienić katalog roboczy powłoki, więc tak czy inaczej ' będziesz musiał go opakować w aliasie / funkcji, która robi to, co chcesz i podąża za tym wbudowanym cd. Jeśli chcesz wywołać hub zamiast git, zrób to w funkcji. Jeśli chcesz, aby miało to wpływ tylko na polecenie clone, sprawdź działanie w funkcji. itd.
  • Zauważyłem, że basename [email protected]:pckujawa/pattern-rec.git powoduje powstanie wzorca-rec.git – czy po prostu pomijasz rozszerzenie .git podczas klonowania?
  • @Pat basename również przyjmuje argument sufiksu, więc możesz zrobić: git clone $1 && cd $(basename $1 .git)

Odpowiedź

git clone przyjmuje dodatkowy argument: katalog do użycia. Możesz go sklonować do bieżącego katalogu roboczego za pomocą git clone URL .. Wtedy nie ma potrzeby zmiany katalogu roboczego; już tam jesteś.

Jeśli naprawdę chcesz, aby polecenie git zmieniło katalog roboczy, możesz zmienić go na funkcję, która wywołuje rzeczywisty git w razie potrzeby:

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 } 

Komentarze

  • To było dokładnie to, czego szukałem. Gdy zdałem sobie sprawę, że nie ma żadnych wewnętrznych punktów zaczepienia lub czegoś w tym rodzaju, napisałem prawie dokładną funkcję 🙂
  • @Wildeyes Tak: miej /tmp wolumin, który jest w RAM, jak każdy nowoczesny Linux za pośrednictwem tmpfs. W każdym razie, dlaczego miałbyś przejmować się zapisywaniem na dysk, skoro ' właśnie wykonałeś klon gita, który tworzy katalogi i zapisuje prawdopodobnie setki plików na dysku …
  • Masz ' prawdopodobnie masz rację co do całego ” nvm, jeśli zapisuje na dysku ” rzecz, chciałem tylko zaoszczędzić dodatkowe operacje. Wielkie dzięki, Kaz.
  • Uważaj. jest git [flags] command [arguments], więc ślepe proszenie o clone w określonej pozycji zakończy się niepowodzeniem.
  • Dodanie ” real ” ścieżka pomoc? Na przykład: git_real_home = which git git () {… $ git_real_home ” $ @ ” | tee $ tmp

Odpowiedź

Jeśli podasz lokalną nazwę repozytorium, użycie $ _ :

git clone [email protected]:npm/npm.git npm-local-dir && cd $_ 

Ale jeśli nie chcesz wpisywać długo imiona, to „trochę brzydkie, ale wykonalne z sedem:

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

EDYCJA: Cóż, chciałem podziękować Manavowi (komentarz poniżej) za zwięzły

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

ale nie działa w zsh ( coś na temat sposobu, w jaki zsh robi rozwinięcia powoduje, że nie traktuje pierwszego polecenia jako wejścia do !$). Musiałem sprawdzić, co !$:t zrobił ( Postęp w powłoce Bash | $ {me: -cokolwiek} ) . !$ przechwytuje ostatnią część poprzedniego polecenia, a :t „usuwa wszystkie początkowe składniki nazwy pliku, pozostawiając koniec.„Dobra informacja, ale chciałbym móc go uruchomić z zsh (próbowałem noglob bez powodzenia).

EDYTUJ: Zamiast używać sed lub !$:t (co i tak nie działa w zsh, dla mnie i tak), znalazłem dwie inne opcje (jedna dostosowująca https://unix.stackexchange.com/users/5685/frederik-deweerdt ” z odpowiedzią https://unix.stackexchange.com/users/129926/henrik-n ”):

git clone [email protected]:npm/npm.git && cd $(basename $_ .git) 

lub

git clone [email protected]:npm/npm.git && cd ${${_%%.git*}##*/} 

Komentarze

  • git clone foo/bar && cd !$:t
  • Jeśli adres URL repozytorium kończy się na .git możesz użyć !$:t:r, aby uzyskać nazwę folderu.

Odpowiedź

Prostym rozwiązaniem dla każdej powłoki POSIX jest jawne określenie katalogu do sklonowania (dowolna ścieżka systemu plików) i ponowne użycie go:

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

i

cd - 

kiedy skończysz.

Odpowiedz er

Możesz zrobić coś takiego:

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) 

To jest dość uproszczone. To „sa precmd hook (wykonywany przed każdym monitem), który sprawdza, czy ostatnia linia poleceń wyglądała jak git clone .../something czy git clone .../something dir, zgadnij znajdujący się w nim katalog i przejdź do niego.

Nie działa, jeśli wpiszesz git clone foo; whatever lub whatever; git clone foo lub git clone --option repo

Komentarze

  • +1 Dziękujemy bardzo za kod; ' Używam go od kilku dni. ' właśnie zauważyłem jeden problem; jeśli zamkniesz terminal zaraz po sklonowaniu jakiegoś projektu, następnym razem, gdy otworzysz terminal, zsh narzeka z dwoma komunikatami o błędach: CDing into <project> i clone_check:cd:17: no such file or directory: <project>. Błąd znika, gdy ostatnie polecenie uruchomione przed zamknięciem terminala różni się od $ git clone.

Odpowiedź

Oto adaptacja powyższej odpowiedzi dla OSX

  • mktemp wymaga dodatkowego parametru
  • git clone zapisuje domyślnie do STDERR (patrz this )

Funkcja:

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 } 

Komentarze

  • Istnieje 7 odpowiedzi, które są wyświetlane ” nad ” Twoimi. Ale z czasem może się to zmienić. Takie odniesienia nie mają sensu w SE, edytuj swoją odpowiedź i dołącz link do odpowiedzi, do której się odnosisz.

Odpowiedź

Z żądaniem jest podstawowy problem, który sprawia, że jest prawie niemożliwe do osiągnięcia: git jest w tym przypadku procesem potomnym powłoki, a procesy potomne nie są w stanie zmodyfikować środowiska nadrzędnego w większości systemów operacyjnych. , jedynym sposobem byłoby to od strony powłoki – poprzez zaimplementowanie aliasu lub funkcji.

Dodatkowe informacje można znaleźć tutaj: https://stackoverflow.com/questions/2375003/how-do-i-set-the-working-directory-of-the-parent-process

Odpowiedź

Nie polecałbym tego, ale możesz użyć tej jednej linijki:

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

Odpowiedź

Uwzględnij to w swojej powłoce:

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

Działa to przez ukradkowe zebranie celu klonowania ze standardowego błędu gita i cd „ing do celu, jeśli (i tylko jeśli) klonowanie się powiodło.

Akceptuje wszystkie argumenty i opcje, które ma zwykły git clone.

Albo możesz użyć opakowania gita i nie martwić się o swoje uzupełnienia, albo możesz pozbyć się opakowania git i ponownie połączyć git clone uzupełnienia na git-clone.

Odpowiedź

Zrobiłem to na podstawie @ frederik-deweerdt odpowiedź.

Możesz więc po prostu sklonować do clone linku repozytorium, które jest w schowku, jeśli poinformujesz repozytorium, klonuje, a potem wchodzi. >

Wymagane jest zainstalowanie xclip.

clone() { if [ -z "$1" ] then local repo=$(xclip -o) else local repo=$1 fi git clone "$repo" && cd "$(basename "$repo" .git)" } 

Odpowiedź

Inna implementacja obsługuje również dodatkowe argumenty polecenia git clone.

Prawidłowo cd ”do podanego folderu lub domyślnej nazwy repozytorium git.

Użycie

gclonecd https://github.com/example/repo gclonecd https://github.com/example/repo my-custom-folder 

Funkcja Bash

 # Clones git repo and cd"s into it gclonecd() { git_dir="$(basename "$1" .git)" git_dir_resolved=${2:-$git_dir} git clone "$@" && cd "$git_dir_resolved"; }  

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *