SVN: Existe uma maneira de marcar um arquivo como "não confirmar"?

153

Com o TortoiseSVN, eu posso mover um arquivo para a lista de alterações ignorar ao confirmar, para que quando eu confirmar uma árvore inteira, as alterações nesse arquivo não sejam confirmadas.

Existe uma maneira de fazer algo assim usando a ferramenta de linha de comando svn?

EDIT: Obrigado pelas sugestões de uso svn:ignore, mas isso não faz exatamente o que eu estava procurando.

svn:ignoreafeta coisas como svn add& svn import. Ele fornece uma lista de padrões de nome de arquivo a serem ignorados.

Eu tenho um arquivo que já está sob controle de origem, mas quero fazer alterações temporárias nesse arquivo que não quero ser confirmadas mais tarde, quando confirmar a árvore de origem inteira. Estou fazendo muitas outras alterações e pude colocar uma nota no meu monitor dizendo para reverter esse arquivo antes de confirmar a árvore, mas seria bom se o svn pudesse pular esse arquivo automaticamente.

Ferruccio
fonte
1
Existe uma maneira de usar o ramo pessoal e o status do switch. [Veja meu outro post sobre esse assunto.] [1] [1]: stackoverflow.com/questions/862950/…
ptitpion

Respostas:

120

O Subversion não possui um recurso interno "não confirmar" / "ignorar ao confirmar", a partir de fevereiro de 2016 / versão 1.9. Esta resposta é uma solução alternativa da linha de comando não ideal

Como o OP afirma, o TortoiseSVN possui uma lista de alterações incorporada, "ignorar na confirmação", que é automaticamente excluída das confirmações. O cliente da linha de comando não possui isso; portanto, você precisa usar várias listas de alterações para realizar esse mesmo comportamento (com ressalvas) :

  • um para o trabalho que você deseja confirmar [trabalho]
  • um para coisas que você deseja ignorar [ignorar ao confirmar]

Como existe um precedente no TortoiseSVN, uso "ignorar na confirmação" nos meus exemplos para os arquivos que não quero confirmar. Usarei "trabalho" para os arquivos que faço, mas você pode escolher qualquer nome que desejar.

Primeiro, adicione todos os arquivos a uma lista de alterações denominada "trabalho". Isso deve ser executado a partir da raiz da sua cópia de trabalho:

svn cl work . -R

Isso adicionará todos os arquivos da cópia de trabalho recursivamente à lista de alterações denominada "trabalho". Há uma desvantagem nisso - à medida que novos arquivos são adicionados à cópia de trabalho, você precisará adicionar especificamente os novos arquivos ou eles não serão incluídos. Segundo, se você precisar executar isso novamente, precisará adicionar novamente todos os seus arquivos "ignorar ao confirmar" novamente. Não é o ideal - você pode começar a manter sua própria lista de 'ignorados' em um arquivo, como outros fizeram.

Em seguida, para os arquivos que você deseja excluir:

svn cl ignore-on-commit path\to\file-to-ignore

Como os arquivos podem estar apenas em uma lista de alterações, a execução dessa adição após a adição "trabalho" anterior removerá o arquivo que você deseja ignorar da lista de alterações "trabalho" e o colocará na lista de alterações "ignorar ao confirmar".

Quando você estiver pronto para confirmar seus arquivos modificados que deseja confirmar, basta adicionar "--cl work" ao seu commit:

svn commit --cl work -m "message"

Aqui está como é um exemplo simples na minha máquina:

D:\workspace\trunk>svn cl work . -R
Skipped '.'
Skipped 'src'
Skipped 'src\conf'
A [work] src\conf\db.properties
Skipped 'src\java'
Skipped 'src\java\com'
Skipped 'src\java\com\corp'
Skipped 'src\java\com\corp\sample'
A [work] src\java\com\corp\sample\Main.java
Skipped 'src\java\com\corp\sample\controller'
A [work] src\java\com\corp\sample\controller\Controller.java
Skipped 'src\java\com\corp\sample\model'
A [work] src\java\com\corp\sample\model\Model.java
Skipped 'src\java\com\corp\sample\view'
A [work] src\java\com\corp\sample\view\View.java
Skipped 'src\resource'
A [work] src\resource\icon.ico
Skipped 'src\test'

D:\workspace\trunk>svn cl ignore-on-commit src\conf\db.properties
D [work] src\conf\db.properties
A [ignore-on-commit] src\conf\db.properties

D:\workspace\trunk>svn status

--- Changelist 'work':
        src\java\com\corp\sample\Main.java
        src\java\com\corp\sample\controller\Controller.java
        src\java\com\corp\sample\model\Model.java
M       src\java\com\corp\sample\view\View.java
        src\resource\icon.ico

--- Changelist 'ignore-on-commit':
M       src\conf\db.properties

D:\workspace\trunk>svn commit --cl work -m "fixed refresh issue"
Sending        src\java\com\corp\sample\view\View.java
Transmitting file data .done
Committing transaction...
Committed revision 9.

Uma alternativa seria simplesmente adicionar todos os arquivos que você deseja confirmar a uma lista de alterações 'trabalho' e nem mesmo manter uma lista de ignorados, mas isso também é muito trabalhoso. Realmente, a única solução ideal e simples é se / quando isso for implementado no próprio SVN. Há um problema antigo sobre isso no rastreador de problemas do Subversion, SVN-2858 , caso isso mude no futuro.

Joshua McKinnon
fonte
1
Adicionei dois arquivos com o comando que você mencionou: $svn st --- Changelist 'ignore-on-commit': M database.php M config.php e ainda assim, eles foram enviados para o repositório no commit. Alguma idéia do que eu fiz de errado?
Attila Fulop
7
Adicionar arquivos à lista de alterações 'ignorar ao confirmar', por si só, não impede que os arquivos sejam confirmados. O TortoiseSVN (um cliente da GUI do Windows) foi construído com respeito a "ignorar na confirmação", mas a linha de comando svn não. A única sugestão que eu tinha em minha resposta original para adicionar os arquivos que você deseja comprometer-se a uma lista de alterações, e contá-la a cometer esse
Joshua McKinnon
7
ignore-on-commit é definitivamente uma lista reservada do Tortoise. Tudo o que está fazendo é impedir que os itens sejam verificados na GUI por padrão, por isso é um recurso específico da GUI do Tortoise. Você não precisa usar a linha de comando para adicionar à lista se usar a GUI. Apenas o menu de contexto nos itens da lista de confirmação e, na parte inferior, você pode movê-los para uma lista de alterações e ignorar na confirmação já está definido. tortoisesvn.net/docs/release/TortoiseSVN_en/…
tjmoore
isso não deu certo. comprometeu tudo.
Ahnbizcad
Não funcionando, a pergunta feita especificamente sobre uma solução de linha de comando, não sobre a GUI.
riv
26

Eu também sempre me encontrei nessa situação: e as listas de alterações não funcionam para mim - quero fazer uma pequena lista de arquivos que não quer se comprometer, em vez de manter uma enorme lista de arquivos que eu faço falta comprometer-se!

Eu trabalho na linha de comando do linux: portanto, minha solução é criar um script / usr / bin / svnn (sim, com dois 'n's!) Da seguinte maneira:

#! /bin/bash
DIR=/home/mike/dev/trunk

IGNORE_FILES="\
        foo/pom.xml \
        foo/src/gwt/App.gwt.xml \
        foo/src/main/java/gwt/Common.gwt.xml \
        foo/src/main/resources/context/datasource/local.xml \
        foo/src/main/resources/context/environment/local.xml"

for i in $IGNORE_FILES; do mv $DIR/$i $DIR/"$i"_; done;

svn "$@"

for i in $IGNORE_FILES; do mv $DIR/"$i"_ $DIR/$i; done;

Obviamente, isso é adaptado à minha situação - mas apenas altere DIR e IGNORE_FILES para se adequar à sua configuração de desenvolvedor. Lembre-se de alterar o script para executável com:

sudo chmod +x /usr/bin/svnn

.. então você apenas usa "svnn" em vez de "svn" para executar o subversion sem medo de verificar mudanças locais nos arquivos da lista IGNORE_FILES. Eu espero que isso ajude!

user88044
fonte
Finalmente, esta resposta está realmente correta. Você precisa escrever alguma ferramenta. Isso é realmente imperfeito, porque eu quero ter uma opção dinâmica, como svnn ignore configs/*- com curingas, sinos e assobios. Acho que escrevo algo assim e volto aqui!
Tomasz Gandor
isso é ótimo! Melhor ainda, crie um alias em .bashrc para svn -> svnn. Melhor ainda, em vez de especificar os arquivos a serem ignorados dentro do comando, ele pode se comportar como git, verificaria um arquivo .ignore dentro da pasta e ignoraria todos os arquivos que correspondam ao padrão.
Tarek
Em vez de ter que aprender novamente a digitar svnn, considere chamá-lo svne colocar esse script em algo que possa estar no início do seu PATH, como ${HOME}/bin. A partir do próprio script, você chamaria /usr/bin/svn.
Joost
17

Não acredito que haja uma maneira de ignorar um arquivo no repositório. Frequentemente, encontramos isso com o web.config e outros arquivos de configuração.

Embora não seja perfeita, a solução que costumo ver e usar é ter um arquivo .default e uma tarefa importante para criar cópias locais.

Por exemplo, no repositório é um arquivo chamado web.config.defaultque possui valores padrão. Em seguida, crie uma tarefa nant que renomeie todos os web.config.defaultarquivos para web.configque possam ser personalizados para valores locais. Essa tarefa deve ser chamada quando uma nova cópia de trabalho é recuperada ou uma compilação é executada.

Você também precisará ignorar o web.configarquivo que é criado para que não seja confirmado no repositório.

Steven Lyons
fonte
8

Confira as listas de alterações , que podem fornecer uma opção para filtrar os arquivos que você alterou, mas que não deseja confirmar. O SVN não pulará automaticamente um arquivo, a menos que você o diga - e a maneira como você diz que esse arquivo é de alguma forma diferente de outros arquivos é colocá-lo em uma lista de alterações.

Requer mais trabalho para você, e você só pode aplicar a lista de alterações à sua cópia de trabalho (obviamente, imagine o caos que poderia ocorrer se você pudesse aplicar uma propriedade 'nunca atualizar' a uma revisão!).

gbjbaanb
fonte
1
Mas é exatamente isso que queremos. Por exemplo, um arquivo de origem que você precisa definir como defaultUserId = yourId, em vez do padrão do sistema.
orbfish
4

Cheguei a esse segmento procurando uma maneira de fazer um commit "atômico" de apenas alguns arquivos e, em vez de ignorar alguns arquivos no commit, segui o caminho contrário e apenas comitei os arquivos que queria:

svn ci filename1 filename2

Talvez ajude alguém.

Radek
fonte
Sua resposta é apenas uma sugestão adequada neste tópico. svn cié simplesmente alias para svn commit. O comando commit permite fazer um commit específico dos arquivos especificados
oxfn
3

Gente, acabei de encontrar uma solução. Dado que o TortoiseSVN funciona da maneira que queremos, tentei instalá-lo no Linux - o que significa, rodando no Wine. Surpreendentemente, funciona! Tudo o que tem a fazer é:

  1. Adicione os arquivos que você deseja pular o commit executando: "svn changelist 'ignore-on-commit'".
  2. Use o TortoiseSVN para confirmar: "~ / .wine / drive_c / Program \ Files / TortoiseSVN / bin / TortoiseProc.exe / command: commit / path: '
  3. Os arquivos excluídos serão desmarcados para confirmação por padrão, enquanto outros arquivos modificados serão verificados. É exatamente o mesmo que no Windows. Aproveitar!

(A razão pela qual a necessidade de excluir arquivos pela CLI é porque a entrada do menu para fazer isso não foi encontrada, não sei por quê. De qualquer forma, isso funciona muito bem!)

James Fu
fonte
2

Arquivos em conflito não podem ser confirmados. Você pode tirar proveito disso para manter suas alterações privadas fora do repositório. Isso funciona melhor com um pequeno número de arquivos.

Para obter um conflito a-file, sua cópia de trabalho (WC) não possui as informações atualizadas a-filedo repositório e as a-filealterações no seu WC estão no mesmo local das alterações no repositório (alterações que você não atualizou ainda). Se você não quiser esperar pelas condições acima, poderá criar um conflito a-filecomo este:
Na cópia de trabalho 1 (WC1), adicione uma linha de texto na parte superior a-file, como "faça um conflito aqui" . Use a sintaxe necessária para não quebrar o repositório. Confirme a a-filepartir do WC1. No WC2, adicione uma linha de texto diferente na parte superior a-file, como "eu quero um conflito" . Atualização do WC2 e agora um arquivo deve estar em conflito.

phi
fonte
1

Em vez disso, eu escreveria um script de ajuda do bash que é executado svn commitem todos os arquivos que você precisa e em nenhum deles. Dessa forma, você tem muito mais controle.

Por exemplo, com uma linha, você pode confirmar todos os arquivos com extensão .he .cppnos quais você fez alterações (e que não causariam conflito):

svn commit -m "" `svn status | grep "^M.*[h|cpp]$" | awk '{print $2}' | tr "\\n" " "`

Altere / adicione extensões à [h|cpp]peça. Adicione uma mensagem de log entre as aspas, -m ""se necessário.

Alan Turing
fonte
1

Algumas das idéias propostas podem ser implementadas assim:

No Windows no PowerShell

adicione tudo ao list.ps1 padrão

dir -Recurse | ? { -not $_.PSIsContainer } | % { svn cl default $_.FullName }

adicione para ignorar list.ps1

 dir file1 ... filN  % { $_.FullName } > ignore-on-commit
 cat .\ignore-on-commit | % { svn cl ignore-on-commit $_ }
 svn add ignore-on-commit

Agora, você pode usar svn ci --changelist defaulto alias para não precisar especificá-lo sempre. O benefício adicional é que você pode armazenar a lista de ignorar ao confirmar (se desejar) no repositório.

Eu faço isso para alguns arquivos que são constantemente regenerados, mas que raramente são alterados manualmente. Por exemplo, adiciono número de revisão aos meus arquivos de configuração em espaços reservados específicos para que os arquivos sejam alterados a cada confirmação, mas as alterações manuais são raras.

majkinetor
fonte
1

Eu cansei de esperar que isso fosse incorporado ao SVN. Eu estava usando o tortoiseSVN com ignorar ao confirmar, mas isso abre uma caixa de diálogo do usuário que você não pode suprimir na linha de comando, e quando executo meu script de construção e faço uma xícara de chá, odeio quando Volto para descobrir que está aguardando a entrada do usuário em 10% do caminho.

Então, aqui está um script do Windows PowerShell que confirma apenas os arquivos que não estão em uma lista de alterações:

# get list of changed files into targets
[XML]$svnStatus = svn st -q --xml C:\SourceCode\Monad
# select the nodes that aren't in a changelist
$fileList = $svnStatus.SelectNodes('/status/target/entry[wc-status/@item != "unversioned"]') | Foreach-Object {$_.path};
# create a temp file of targets
$fileListPath =  [IO.Path]::GetTempFileName();
$fileList | out-file $fileListPath -Encoding ASCII
# do the commit
svn commit --targets $fileListPath -m "Publish $version" --keep-changelists 
# remove the temp file
Remove-Item $filelistPath
Ben Curthoys
fonte
1

Atualização do script de user88044.

A idéia é enviar os arquivos na lista de alterações não confirmar e executar o script maligno.

O script extrai os arquivos do-not-commit do comando: svn status --changelist 'do-not-commit'

#! / bin / bash DIR = "$ (pwd)"

IGNORE_FILES = "$ (status svn - lista de alterações 'não confirmar' | tail -n +3 | grep -oE '[^] + $')"

para i em $ IGNORE_FILES; mv $ DIR / $ i $ DIR / "$ i" _; feito;

svn "$ @";

para i em $ IGNORE_FILES; mv $ DIR / "$ i" _ $ DIR / $ i; feito;

O script é colocado em / usr / bin / svnn (sudo chmod + x / usr / bin / svnn)

status svnn, svnn commit, etc ...

Nicolas F.
fonte
1

Você pode configurar a lista de alterações "ignorar na confirmação" diretamente com o TortoiseSVN. Não há necessidade de configurar nenhuma outra lista de alterações, incluindo todos os outros arquivos

1) Clique em "SVN Commit ..." (não confirmaremos, apenas uma maneira de encontrar um menu gráfico para a lista de alterações) 2) Na lista Clique com o botão direito do mouse no arquivo que você deseja excluir. 3) Menu: vá para lista de alterações> ignorar ao confirmar

Na próxima vez que você fizer um SVN Commit ... Os arquivos aparecerão desmarcados no final da lista, na categoria ignorar ao confirmar.

Testado com: TortoiseSVN 1.8.7, Build 25475 - 64 Bit, 05/05/2014 20:52:12, Subversion 1.8.9, -release

luney
fonte
1
ups, eu acabei de ver os comentários de tjmoore, já dando as boas informações para o usuário tortoiseSVN ... nenhuma linha de comando tortoisesvn.net/docs/release/TortoiseSVN_en/…
luney 18/16
Isso está quebrado em 1.9?
Jake Hm
1

Está atrasado para o jogo, mas encontrei o comando de linha de comando mais impressionante para esse problema. Feito usando o bash. Aproveitar.

svn status | grep -v excluding | sed 's/^A */"/g; s/$/"/g' | tr '\n' ' ' | xargs svn commit -m "My Message"

Ok, então aqui está uma explicação do comando. Algumas coisas precisarão ser alteradas com base no seu caso de uso.

svn status

Eu recebo uma lista de todos os arquivos. Todos eles começarão com esses caracteres de status (?,!, A, etc). Cada um está em suas próprias linhas

grep -v excluding

Eu uso grep para filtrar a lista. Pode ser usado normalmente (para incluir) ou com o sinalizador -v (para excluir). Nesse caso, ele está sendo usado para excluir, com a frase "exclusão" sendo o que será excluído.

sed 's/^. */"/g; s/$/"/g'

Agora, removo o caractere de status e os espaços em branco no início de cada linha e depois cito cada linha, usando sed. Alguns dos meus nomes de arquivos têm espaços neles, daí a citação.

tr '\n' ' '

Usando tr, substituo todas as novas linhas por espaços. Agora minha lista inteira de arquivos a serem confirmados está em uma linha.

xargs svn commit -m "My Message"

Por fim, uso xargs para executar meu comando de confirmação com a mensagem Ele faz o commit e descarta minha lista de arquivos citados como o último argumento.

O resultado é que tudo funciona da maneira que eu quero. Eu ainda meio que odeio svn por me forçar a pular por esses malditos aros, mas posso viver com isso. Eu acho.

user2223059
fonte
0

Como eu estava enfrentando exatamente o mesmo problema, e meu Google continuava me dando nada, acho que encontrei uma solução alternativa. Aqui está o que eu fiz, parece funcionar para mim, mas como estou preso a uma versão antiga do SVN (<1.5, pois ele não tem a opção --keep-local) e não sou especialista nisso , Não posso ter certeza de que é uma solução universal. Se funcionar para você também, por favor me avise!

Eu estava lidando com uma instalação do Prestashop que recebi do SVN, já que outras pessoas já começaram a trabalhar nela. Como as configurações do banco de dados foram feitas para outro servidor, eu as alterei em algum arquivo na pasta / config. Como esta pasta já estava com controle de versão, defini-la em svn: ignore não impediria que minhas modificações locais fossem confirmadas. Aqui está o que eu fiz:

cp config ../cfg_bkp              # copy the files out of the repo
svn rm config                     # delete files both from svn and "physically"
svn propset svn:ignore "config" . # as the files no longer exists, I can add my ignore rule and then...
mv ../cfg_bkp config              # ...bring'em back
svn revert --recursive config     # make svn forget any existing status for the files (they won't be up for deletion anymore)

Agora eu posso executar o svn add --force. na raiz do repositório sem adicionar minha configuração, mesmo que não corresponda à versão do repositório (acho que teria que passar por tudo isso novamente se o modificasse mais uma vez, não testasse). Também posso atualizar o svn sem que meus arquivos sejam substituídos ou sem erros.

neemzy
fonte
0

Uma solução que não ignora alterações nas propriedades do diretório

Tentei usar a solução com base changelist, mas tenho alguns problemas com ela. Primeiro, meu repositório possui milhares de arquivos, portanto a lista de alterações a ser comprometida é enorme, e minha svn statussaída ficou muito longa e precisava ser analisada para ser útil. O mais importante é que eu queria confirmar alterações que vieram de uma mesclagem, o que significa que elas incluem alterações de propriedade. Ao confirmar uma lista de alterações, as propriedades svn anexadas ao diretório não são confirmadas, então tive que fazer uma confirmação extra:

svn ci --cl work -m "this commits files from the work changelist only"
svn up
svn ci --depth empty DIR . -m "record merge properties"

Você pode ter que fazer isso em vários diretórios (aqui, registro as propriedades de DIRe do diretório atual .), basicamente aqueles com um Mna segunda coluna ao emitir o svn statuscomando.

Solução

Eu usei patches e svn patch. No pseudo-código:

svn diff $IGNORE_FILES > MYPATCH   # get the mods to ignore
svn patch --reverse-diff MYPATCH   # remove the mods
svn ci -m "message"                # check-in files and directory properties
svn patch MYPATCH                  # re-apply the mods

Como outros pôsteres, acabo usando um script para manter a lista de arquivos a serem ignorados:

#! /usr/bin/env bash

finish() {
    svn patch MYPATCH               # re-apply the mods
}
trap finish EXIT

IGNORE_FILES="\
sources/platform/ecmwf-cca-intel-mpi.xml \
runtime/classic/platform/ecmwf-cca.job.tmpl \
runtime/classic/platform/ecmwf-cca-intel.xml"

svn diff $IGNORE_FILES > MYPATCH # get the mods to ignore
svn patch --reverse-diff MYPATCH # remove the mods

svn "$@"

Eu normalmente o usei com cie revert -R ..

P. Le Sager
fonte
-1

svn:ignore é a sua resposta.

Exemplo:

$ svn propset svn:ignore -F .cvsignore .
property 'svn:ignore' set on '.'
Manuel Ferreria
fonte
1
Observe que o exemplo acima mostra como usar um arquivo cvsignore configurado anteriormente como entrada para sua propriedade svnignore.
21119 Ben Hoffstein
1
no svn: ignore é apenas para arquivos de versão. não funciona com arquivos de versão
Sérgio
1
E também não é local. É uma alteração de propriedade que será confirmada por si só.
Adam Badura
-9
svn propset "svn:ignore" "*.xml" .

o *.xmlé o padrão dos arquivos a serem ignorados; você também pode usar nomes de diretório aqui.

Casas2001
fonte
3
-1 porque você não pode ignorar um arquivo que faz parte do repositório.
Zellus