Como cd automaticamente após o git clone?

29

Eu quero automaticamente cd para o diretório criado pelo comando clone depois que eu git clone d algo.

Importante: Eu não quero alterar a sintaxe do comando (por exemplo, usar um alias / função) porque isso quebraria as conclusões do zsh que recebo automaticamente do projeto Pretzo .

EDITAR : A razão pela qual eu não escolhi nenhuma resposta como correta, é porque nenhuma resposta foi dada que cumpriu a condição acima.

Eu uso o ZSH, mas uma resposta em qualquer outro shell também é aceitável.

    
por Cat Boss 28.10.2013 / 15:10

8 respostas

15

git clone recebe um argumento adicional: o diretório a ser usado. Você pode fazê-lo clonar no diretório de trabalho atual com git clone URL . . Então, não há necessidade de alterar o diretório de trabalho; você já está lá.

Se você realmente quer que o comando git altere o diretório de trabalho, você pode mudá-lo para uma função que chama o% realgit quando necessário:

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
}
    
por 28.10.2013 / 19:20
15

Crie uma função:

gclonecd() {
  git clone "$1" && cd "$(basename "$1")"
}
    
por 28.10.2013 / 15:21
6

Se você fornecer o nome local do repo, é muito fácil usar $ _ :

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

Mas se você não quiser redigitar nomes longos, é um pouco feio, mas é possível com o sed:

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

EDIT: Bem, eu ia agradecer Manav (comentário abaixo) para o conciso

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

mas não funciona em zsh (algo sobre como o zsh faz expansões faz com que não trate o primeiro comando como entrada para !$ ). Eu tive que procurar o que !$:t fez ( Avançando na Bash Shell | $ {me: -qualquer } ). !$ pega a última parte do comando anterior e :t "Remove todos os componentes de nome de arquivo principais, deixando a cauda." Boa informação, mas gostaria de poder fazê-lo funcionar com o zsh (tentei noglob sem sucesso).

EDIT: Em vez de usar sed ou !$:t (que não funciona em zsh, para mim de qualquer maneira), encontrei duas outras opções (uma adaptando link com link ' s comentário):

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

ou

git clone [email protected]:npm/npm.git && cd ${${_%%.git*}##*/}
    
por 28.06.2014 / 01:46
2

Aqui está uma adaptação da resposta acima para OSX

  • mktemp requer um parâmetro adicional
  • git clone escreve para STDERR por padrão (consulte this )

Função:

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
}
    
por 21.09.2015 / 12:13
1

Uma solução simples para qualquer shell POSIX é especificar o diretório para clonar explicitamente (qualquer caminho do sistema de arquivos) e reutilizá-lo:

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

e

cd -

quando estiver pronto.

    
por 14.04.2016 / 16:01
0

Eu não recomendaria isso, mas você poderia usar este verso:

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

    
por 26.09.2014 / 01:22
0

Você pode fazer 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)

É bastante simplista. É um precmd hook (executado antes de cada prompt), que verifica se a última linha de comando se parece com git clone .../something ou git clone .../something dir , adivinhe o diretório e copie para ele.

Não funciona se você inseriu git clone foo; whatever ou whatever; git clone foo ou git clone --option repo ...

    
por 14.04.2016 / 16:31
0

Inclua isso no seu 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"
}

Isso funciona sub-repticiamente captando o alvo de clonagem do erro padrão do git e cd 'no alvo se (e somente se) a clonagem for um sucesso.

Aceita todos os argumentos e opções que o git clone regular faz.

Você pode usar o wrapper git e não precisar se preocupar com suas conclusões, ou pode se livrar do wrapper git e reconectar seus git clone completions a git-clone .

    
por 14.04.2016 / 16:48

Tags