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
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 oclone
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>
iclone_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 doSTDERR
(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"; }
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 …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 wbudowanymcd
. Jeśli chcesz wywołaćhub
zamiastgit
, zrób to w funkcji. Jeśli chcesz, aby miało to wpływ tylko na polecenieclone
, sprawdź działanie w funkcji. itd.basename [email protected]:pckujawa/pattern-rec.git
powoduje powstanie wzorca-rec.git – czy po prostu pomijasz rozszerzenie .git podczas klonowania?basename
również przyjmuje argument sufiksu, więc możesz zrobić:git clone $1 && cd $(basename $1 .git)