Quiero automáticamente cd al directorio creado por clone después de git clone d algo.

Importante: No quiero alterar la sintaxis del comando (por ejemplo, usar un alias / función) porque rompería las finalizaciones zsh que obtengo automáticamente del proyecto Pretzo.

EDIT : La razón por la que no elegí ninguna respuesta como correcta, es porque ninguna respuesta fue dado que cumplió con la condición anterior.

Yo uso ZSH, pero una respuesta en cualquier otro shell también es aceptable.

Comentarios

  • Me gusta la respuesta unix.stackexchange.com/questions/97920/… , pero necesito mencionar escribir esa función en el archivo ~/.bashrc (por ejemplo) y para mí en l Este no ‘ t funcionaba, necesitaba arreglarlo reemplazando la línea: /usr/bin/git "$@" 2>&1 | tee $tmp

Respuesta

Crea una función:

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

(Funciona tanto para enlaces con y sin «.git»)

Comentarios

  • Me gustaría seguir usando git clone porque de todas las herramientas que tendría que cambiar si no estuviera usando git. Hub tiene un alias como git, oh-my-zsh proporciona autocompletado, etc.
  • @Wildeyes git no puede ‘ cambiar el directorio de trabajo de tu shell, así que de cualquier forma ‘ tendrás que ajustarlo en un alias / función que hace lo que quieres y lo sigue con el cd incorporado. Si desea llamar a hub en lugar de git, hágalo en la función. Si desea que solo afecte al comando clone, verifique la acción en la función. etc.
  • Me di cuenta de que basename [email protected]:pckujawa/pattern-rec.git da como resultado el patrón-rec.git. ¿Dejas la extensión .git cuando clonas?
  • @Pat basename también toma un argumento de sufijo, por lo que puede hacer: git clone $1 && cd $(basename $1 .git)

Respuesta

git clone toma un argumento adicional: el directorio a usar. Puede clonarlo en el directorio de trabajo actual con git clone URL . Entonces, no es necesario cambiar el directorio de trabajo; ya está allí.

Si realmente desea que el comando git cambie realmente el directorio de trabajo, puede cambiarlo a una función que llame al git cuando sea necesario:

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 } 

Comentarios

  • Eso fue exactamente lo que estaba buscando. Después de darme cuenta de que no hay ganchos internos o algo así, escribí una función casi exacta 🙂
  • @Wildeyes Sí: tener un /tmp volumen que está en RAM, como lo hace cualquier Linux moderno a través de tmpfs. De todos modos, ¿por qué le importaría escribir en el disco, cuando ‘ acaba de hacer un clon de git, que crea directorios y escribe quizás cientos de archivos en el disco …
  • Usted ‘ probablemente tenga razón sobre el » nvm completo si escribe en el disco » cosa, solo estaba buscando guardar operaciones adicionales. Muchas gracias Kaz.
  • Ten cuidado. es git [flags] command [arguments], por lo que pedir ciegamente clone en cierta posición fallará.
  • Agregaría el » real » ¿ayuda de ruta? Me gusta: git_real_home = which git git () {… $ git_real_home » $ @ » | tee $ tmp

Respuesta

Si proporciona el nombre local del repositorio, es realmente fácil de usar $ _ :

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

Pero si no quieres volver a escribir mucho nombres, es un poco feo pero factible con sed:

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

EDITAR: Bueno, iba a agradecer a Manav (comentario a continuación) por la brevedad

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

pero no funciona en zsh ( algo sobre cómo zsh hace las expansiones hace que no trate el primer comando como entrada a !$). Tuve que buscar lo que hizo !$:t ( Advancing in the Bash Shell | $ {me: -whatever} ) . !$ toma la última parte del comando anterior y :t eliminará todos los componentes principales del nombre de archivo, dejando la cola.»Buena información, pero me gustaría poder hacer que funcione con zsh (probé noglob sin éxito).

EDITAR: En lugar de usar sed o !$:t (que no funciona en zsh, para mí de todos modos), encontré otras dos opciones (una adaptando https://unix.stackexchange.com/users/5685/frederik-deweerdt » la respuesta con https://unix.stackexchange.com/users/129926/henrik-n «s comentario):

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

o

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

Comentarios

  • git clone foo/bar && cd !$:t
  • Si la URL de su repositorio termina en .git puede usar !$:t:r para obtener el nombre de la carpeta.

Respuesta

Una solución simple para cualquier shell POSIX es especificar el directorio para clonar explícitamente (cualquier ruta del sistema de archivos) y reutilizarlo:

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

y

cd - 

cuando «haya terminado.

Responder er

Podría hacer algo como:

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) 

Es bastante simplista. Es «un precmd gancho (ejecutado antes de cada solicitud), que comprueba si la última línea de comando se ve como git clone .../something o git clone .../something dir, adivine el directorio a partir de ahí y acceda a él.

No funciona si ingresó git clone foo; whatever o whatever; git clone foo o git clone --option repo

Comentarios

  • +1 Agradecimiento mucho por el código; Lo ‘ lo estoy usando desde hace unos días. ‘ acabo de notar un problema; si cierra la terminal justo después de clonar algún proyecto, la próxima vez que abra una terminal, zsh se queja con dos mensajes de error: CDing into <project> y clone_check:cd:17: no such file or directory: <project>. El error desaparece tan pronto como el último comando que ejecutó antes de cerrar la terminal es diferente de $ git clone.

Respuesta

Aquí hay una adaptación de la respuesta anterior para OSX

  • mktemp requiere un parámetro adicional
  • git clone escribe en STDERR de forma predeterminada (consulte esto )

Función:

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 } 

Comentarios

  • Hay 7 respuestas que muestran » sobre » la tuya. Pero puede cambiar con el tiempo. Estas referencias no tienen sentido en SE, edite su respuesta e incluya un enlace a la respuesta a la que se refería.

Respuesta

Existe un problema fundamental con su solicitud que hace que sea casi imposible de lograr: git es un proceso secundario del shell en este caso, y los procesos secundarios no pueden modificar el entorno principal en la mayoría de los sistemas operativos. , la única forma de hacerlo sería desde el lado del shell, implementando un alias o una función.

Puede encontrar detalles adicionales aquí: https://stackoverflow.com/questions/2375003/how-do-i-set-the-working-directory-of-the-parent-process

Respuesta

No lo recomendaría, pero podría utilizar esta frase:

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

Respuesta

Incluya esto en su shell:

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

Esto funciona obteniendo subrepticiamente el objetivo de clonación del error estándar de git y cd «ing en el objetivo si (y solo si) la clonación fue un éxito.

Acepta todos los argumentos y opciones que el git clone normal acepta.

O puede usar el contenedor de git y no tener que preocuparse por sus terminaciones, o puede deshacerse del contenedor de git y volver a cablear sus git clone terminaciones a git-clone.

Respuesta

He hecho esto basado en @ frederik-deweerdt respuesta.

Para que el usuario simplemente clone en clone el enlace del repositorio que está en el portapapeles, si informa al repositorio, clona y luego ingresa.

Es necesario instalar xclip.

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

Respuesta

Otra implementación, también maneja argumentos adicionales para el comando git clone.

Correctamente cd «s en la carpeta proporcionada o en el nombre del repositorio de git predeterminado.

Uso

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

Función 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"; }  

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *