Como usar o SVN CLI efetivamente

7

Como posso me tornar mais produtivo com o SVN CLI? Eu preciso completar tarefas repetitivas como estas:

  • encontre arquivos modificados no diretório
  • confirmar apenas ALGUNS
    • selecionando-os de alguma forma, depois lembrando seus nomes
  • lista de arquivos não versionados
    • adicione apenas alguns usando de algum modo efetivo outro então lembrando deles
  • reverter apenas alguns arquivos em determinado diretório

Eu estava acostumado com o TortoiseSVN no Windows, mas uma mudança para o OSX (que é bem similar ao Linux) me forçou a usar o CLI do SVN, já que outros clientes são ruins ou realmente caros.

    
por Tomáš Fejfar 31.10.2011 / 13:12

2 respostas

4

Eu me deparo com problemas semelhantes. Minha abordagem tem sido escrever aliases ou funções de shell para as ações mais comuns que tomo. Para referência, estas são funções do shell ZSH. As próprias funções devem funcionar no bash também, mas o material de conclusão do shell seria diferente.

Ao analisar seu uso, a ação "selecionar alguns" que você deseja executar varia de acordo com meu uso e não há provisão para isso. Na verdade, sugiro que você modifique seu uso do controle de revisão para realizar confirmações mais frequentes e tirar proveito de várias cópias ou ramificações de trabalho em um repositório para acompanhar conjuntos de mudanças seletivas. Se você estiver trabalhando em um diretório, tudo o que você fizer lá deve ser confirmado ou revertido de forma seletiva, mas não muito deve ser deixado por aí. Comprometer o que você tem a qualquer momento e usar recursos de controle de revisão para lidar com o que entra ou não no produto.

Para que isso funcione, você deve colocar o código no seu arquivo ~/.zshrc (ou ~/.bashrc para o bash).

Aqui está a função principal que uso (todos os dias):

function svnlist () {
    if [ -z "$2" ]; then
        case $1 in
            clobered)
                svn status | grep '^~' | cut -c9-
                ;;
            missing)
                svn status | grep '^\!' | cut -c0-
                ;;
            unknown)
                svn status | grep '^\?' | cut -c9-
                ;;
            conflicted)
                svn status | grep '^C' | cut -c9-
                ;;
        esac
    else
        case $2 in
            add)
                $0 unknown | xargs -iX svn add "X"
                ;;
            del)
                $0 missing | xargs -iX svn del "X"
                ;;
            revert) $0 conflicted | xargs -iX svn revert "X"
                ;;
            resolved) $0 conflicted | xargs -iX svn resolved "X"
                ;;
            unclober)
                mkdir _tmp
                $0 clobered | while read item; do
                    mv "$item" _tmp
                    svn del "$item"
                done
                svn ci -m "Unclobering files. (removing old)"
                mv _tmp/* .
                rmdir _tmp
                $0 unknown add
                svn ci -m "Unclobering files. (adding new)"
                ;;
        esac
    fi
}

alias svndiff="svn diff -x -b | colordiff"
compctl -x 'p[1]' -k '(missing unknown conflicted clobered)' - 'p[2]' -k '(add del revert resolved)' -- svnlist

Isso deve permitir que você execute algo como svnlist unknown para localizar todos os arquivos no diretório atual que não tenham sido modificados e svnlist unknown add para incluí-los como opção. svnlist clobered revert encontraria todos os arquivos que foram corrigidos após uma atualização e os reverterá. svnlist conflicted resolved marcaria todos os conflitos como resolvidos. svnlist missing del marcaria todos os arquivos ausentes em ação como excluídos no repositório.

Além disso, se você topar com ele, aqui está um para editar a mensagem de log de uma revisão específica. Eu não uso mais isso, mas cometi muitos erros desde o início e preferi manter as mensagens de log em ordem:

function svneditlog () {
    rev=$1
    if ! echo $rev | pcregrep '^[0-9]+$'; then
        echo "Invalid usage. svneditlog REV"
        return
    fi
    svn info | grep ^URL: | awk '{print $2}' | read url
    svn propedit -r $rev --revprop svn:log $url
}

Ao olhar para este código, ele realmente mostra que escrevi isso há muitos anos, quando eu estava começando a usar o controle de versão e não era muito gracioso em um shell, mas ele ainda deveria funcionar.

    
por 31.10.2011 / 22:08
4

Aproveite a conclusão do seu shell. O Bash tem alguma conclusão para svn , o zsh é significativamente melhor. Por exemplo, em zsh, svn add <TAB> completa apenas os arquivos que ainda não estão registrados, svn commit <TAB> lista apenas os arquivos registrados e com alterações, e assim por diante. Isso por si só deve lhe dar a maior parte do que você está perguntando:

  • encontre arquivos modificados no diretório → svn status ou svn commit <TAB>
  • confirmar apenas ALGUNS deles → svn commit <TAB>
  • listar arquivos não versionados → svn status ou svn add <TAB>
  • adicione apenas alguns → svn add <TAB>
  • reverter apenas alguns arquivos em determinado diretório → svn revert <TAB>

Defina aliases e funções para os comandos que você usa com mais frequência. Aqui estão alguns que eu uso em zsh (note que estou mudando para aliases agnósticos de VC; estes são atalhos específicos do svn, análogos aos atalhos do CVS que eu tenho usado por uma década ou mais).

## Show file status (excluding non-controlled files)
alias svns='svn status > >(grep -v "^?")'
## Show the status of modified files (in particular, to notice potential conflicts in the next update)
svnm () {
  [[ $# -ne 0 ]] || set .
  svn merge -r BASE:HEAD --dry-run "$@" | sed -e '/^-/d'
  return $pipestatus[1]
}

## log (in chronological order)
svnl () {
  local since="1" cmd arg= ret=0
  if [[ $1 = <1900->-<1-12>-<1-31> ]]; then
    since="{$1}"
    shift
  elif [[ $1 = <1-> ]]; then
    since=$1
    shift
  fi
  cmd=(svn log -r$since:HEAD)
  while [[ $1 = -* ]]; do
    cmd=($cmd $1)
    shift
  done
  if [[ $# -ne 0 ]]; then
    for arg; do
      $cmd[@] $1
      ret=$((ret > $? ? $ret : $?))
    done
    return $ret
  else
    $cmd[@]
  fi
}
## log (from the start of the present branch or the last move)
alias svnlb='svnl --stop-on-copy'

Você pode incluir algumas informações de controle de versão em seu prompt, com do zsh vcsinfo .

    
por 02.11.2011 / 00:23