SVN: ¿Hay alguna forma de marcar un archivo como "no confirmar"?

153

Con TortoiseSVN, puedo mover un archivo a la lista de cambios ignorar al confirmar, para que cuando confirme un árbol completo, los cambios en ese archivo no se confirmen.

¿Hay alguna manera de hacer algo así usando la herramienta de línea de comandos svn?

EDITAR: Gracias por las sugerencias para usar svn:ignore, pero eso no hace exactamente lo que estaba buscando.

svn:ignoreafecta cosas como svn add& svn import. Le da una lista de patrones de nombre de archivo para ignorar.

Tengo un archivo que ya está bajo control de origen, pero quiero hacer cambios temporales en ese archivo que no quiero confirmar más adelante cuando confirmo todo el árbol de origen. Estoy haciendo muchos otros cambios y podría pegar una nota en mi monitor diciéndome que revierta ese archivo antes de confirmar el árbol, pero sería bueno si svn pudiera omitir ese archivo automáticamente.

Ferruccio
fuente
1
Hay una manera de usar la rama personal y cambiar el estado. [Vea mi otra publicación sobre este tema.] [1] [1]: stackoverflow.com/questions/862950/…
ptitpion

Respuestas:

120

Subversion no tiene una función incorporada "no confirmar" / "ignorar al confirmar", a partir de febrero de 2016 / versión 1.9. Esta respuesta es una solución alternativa de línea de comandos no ideal

Como dice el OP, TortoiseSVN tiene una lista de cambios incorporada, "ignore-on-commit", que se excluye automáticamente de los commits. El cliente de línea de comandos no tiene esto, por lo que debe usar varias listas de cambios para lograr este mismo comportamiento (con advertencias) :

  • uno para el trabajo que quieres comprometer [trabajo]
  • uno para las cosas que desea ignorar [ignorar al confirmar]

Como hay un precedente con TortoiseSVN, uso "ignore-on-commit" en mis ejemplos para los archivos que no quiero comprometer. Usaré "trabajo" para los archivos que hago, pero puedes elegir el nombre que quieras.

Primero, agregue todos los archivos a una lista de cambios llamada "trabajo". Esto debe ejecutarse desde la raíz de su copia de trabajo:

svn cl work . -R

Esto agregará todos los archivos de la copia de trabajo de forma recursiva a la lista de cambios denominada "trabajo". Hay una desventaja en esto: a medida que se agregan nuevos archivos a la copia de trabajo, deberá agregar específicamente los nuevos archivos o no se incluirán. En segundo lugar, si tiene que ejecutar esto nuevamente, deberá volver a agregar todos sus archivos "ignorar al confirmar" nuevamente. No es ideal: podría comenzar a mantener su propia lista de "ignorar" en un archivo como lo han hecho otros.

Luego, para los archivos que desea excluir:

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

Debido a que los archivos solo pueden estar en una lista de cambios, la ejecución de esta adición después de su agregado "trabajo" anterior eliminará el archivo que desea ignorar de la lista de cambios "trabajo" y lo colocará en la lista de cambios "ignorar al confirmar".

Cuando esté listo para confirmar sus archivos modificados que desea, simplemente agregue "--cl work" a su confirmación:

svn commit --cl work -m "message"

Así es como se ve un ejemplo simple en mi 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.

Una alternativa sería simplemente agregar cada archivo que desea comprometer a una lista de cambios de 'trabajo', y ni siquiera mantener una lista de ignorados, pero esto también es mucho trabajo. Realmente, la única solución simple e ideal es si / cuando esto se implementa en SVN. Hay un problema de larga data sobre esto en el rastreador de problemas de Subversion, SVN-2858 , en caso de que esto cambie en el futuro.

Joshua McKinnon
fuente
1
He agregado dos archivos con el comando que ha mencionado: $svn st --- Changelist 'ignore-on-commit': M database.php M config.php y aún así, se han enviado al repositorio en commit. ¿Alguna idea de qué hice mal?
Attila Fulop
77
Agregar archivos a la lista de cambios 'ignore-on-commit' en sí mismo no evita que los archivos se confirmen. TortoiseSVN (un cliente de la GUI de Windows) se ha creado con respecto a "ignorar al confirmar", pero la línea de comando svn no. La única sugerencia que tuve en mi respuesta original fue agregar los archivos que desea enviar a una lista de cambios, y decirle que lo haga
Joshua McKinnon
77
ignore-on-commit es definitivamente una lista reservada de Tortoise. Todo lo que está haciendo es evitar que los elementos se verifiquen en la GUI de forma predeterminada, por lo que es una característica específica de Tortoise GUI. No necesita usar la línea de comando para agregar a la lista si usa la GUI. Simplemente menú contextual en los elementos de la lista de confirmación y en la parte inferior puede moverlos a una lista de cambios e ignorar al confirmar ya está definido. tortoisesvn.net/docs/release/TortoiseSVN_en/…
tjmoore
Esto no hizo Jack. comprometió todo.
ahnbizcad
No funciona, la pregunta específicamente sobre una solución de línea de comando, no GUI.
riv
26

También me he encontrado constantemente en esta situación: y las listas de cambios no funcionan para mí: quiero hacer una breve lista de archivos que no quiero comprometer, en lugar de mantener una lista masiva de archivos que quiero ¡comprometerse!

Trabajo en la línea de comandos de Linux: así que mi solución es crear un script / usr / bin / svnn (¡sí, con dos 'n's!) De la siguiente manera:

#! /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, esto se adapta a mi situación, pero solo cambia DIR e IGNORE_FILES para adaptarlo a tu configuración de desarrollo. Recuerde cambiar el script a ejecutable con:

sudo chmod +x /usr/bin/svnn

..entonces simplemente usa "svnn" en lugar de "svn" para ejecutar subversion sin temor a registrar cambios locales en los archivos de la lista IGNORE_FILES. ¡Espero que esto ayude!

usuario88044
fuente
Finalmente, esta respuesta es realmente correcta. Necesitas escribir alguna herramienta. Esto es realmente imperfecto, porque quiero tener una opción dinámica, como svnn ignore configs/*- con comodines, y campanas y silbatos. ¡Creo que escribo algo así y luego vuelvo aquí!
Tomasz Gandor
¡esto es genial! Aún mejor, cree un alias en .bashrc para svn -> svnn. Aún mejor, en lugar de especificar los archivos a ignorar dentro del comando, podría comportarse como git, verificaría un archivo .ignore dentro de la carpeta e ignoraría cada archivo que coincida con el patrón.
Tarek
En lugar de tener que volver a aprender a escribir svnn, considere llamarlo svny colocar este script en algo que pueda estar al comienzo de su RUTA, como ${HOME}/bin. Desde el script en sí, entonces llamarías /usr/bin/svn.
Joost
17

No creo que haya una manera de ignorar un archivo en el repositorio. A menudo nos encontramos con esto con web.config y otros archivos de configuración.

Aunque no es perfecta, la solución que veo y uso con mayor frecuencia es tener un archivo .default y una tarea ingeniosa para crear copias locales.

Por ejemplo, en el repositorio hay un archivo llamado web.config.defaultque tiene valores predeterminados. Luego, cree una tarea ingenua que cambie el nombre de todos los web.config.defaultarchivos a los web.configque luego se puede personalizar con valores locales. Esta tarea debe llamarse cuando se recupera una nueva copia de trabajo o se ejecuta una compilación.

También deberá ignorar el web.configarchivo creado para que no se confirme en el repositorio.

Steven Lyons
fuente
8

Consulte las listas de cambios , que pueden proporcionarle una opción para filtrar los archivos que ha cambiado pero que no desea confirmar. SVN no omitirá automáticamente un archivo a menos que usted lo indique, y la forma en que le dice que este archivo es de alguna manera diferente a otros archivos es ponerlo en una lista de cambios.

Requiere más trabajo para usted, y solo puede aplicar la lista de cambios a su copia de trabajo (obviamente, ¡imagine el caos que se produciría si pudiera aplicar una propiedad 'nunca actualizar' a una revisión!).

gbjbaanb
fuente
1
Pero eso es exactamente lo que queremos. Por ejemplo, un archivo fuente que necesita establecer defaultUserId = yourId, en lugar del predeterminado del sistema.
pez orb
4

Llegué a este hilo en busca de una forma de realizar una confirmación "atómica" de solo algunos archivos y, en lugar de ignorar algunos archivos en la confirmación, fui hacia el otro lado y solo confirmé los archivos que quería:

svn ci filename1 filename2

Tal vez, ayudará a alguien.

Radek
fuente
Su respuesta es solo una sugerencia adecuada en este hilo. svn cies simplemente un alias de svn commit. El comando Commit permite realizar una confirmación particular de los archivos especificados
oxfn
3

Chicos, acabo de encontrar una solución. Dado que TortoiseSVN funciona de la manera que queremos, traté de instalarlo en Linux, lo que significa que se ejecuta en Wine. ¡Sorprendentemente funciona! Todo lo que tienes que hacer es:

  1. Agregue los archivos que desea omitir confirmando ejecutando: "svn changelist 'ignore-on-commit'".
  2. Use TortoiseSVN para confirmar: "~ / .wine / drive_c / Programme \ Files / TortoiseSVN / bin / TortoiseProc.exe / command: commit / path: '
  3. Los archivos excluidos estarán desmarcados para confirmar de forma predeterminada, mientras que otros archivos modificados serán verificados. Esto es exactamente lo mismo que en Windows. ¡Disfrutar!

(La razón por la que es necesario excluir archivos por CLI es porque no se encontró la entrada del menú para hacerlo, no estoy seguro de por qué. De cualquier manera, ¡esto funciona muy bien!)

James Fu
fuente
2

Los archivos en conflicto no pueden ser confirmados. Puede aprovechar esto para mantener sus cambios privados fuera del repositorio. Esto funciona mejor con una pequeña cantidad de archivos.

Para obtener un conflicto a-file, su copia de trabajo (WC) no tiene la actualización a-filedel repositorio y que a-fileen su WC tiene cambios que están en la misma ubicación que los cambios en el repositorio (cambios que no actualizó a todavía). Si no desea esperar las condiciones anteriores, puede crear un conflicto a-filecomo este:
en la copia de trabajo 1 (WC1), agregue una línea de texto en la parte superior a-file, como "haga un conflicto aquí" . Use la sintaxis necesaria para no romper el repositorio. Comprometerse a-filedesde WC1. En WC2, agregue una línea de texto diferente en la parte superior a-file, como "quiero un conflicto" . Actualice desde WC2, y ahora el archivo a debería estar en conflicto.

fi
fuente
1

En cambio, escribiría una secuencia de comandos bash auxiliar que se ejecute svn commiten todos los archivos que necesita y ninguno de los que no necesita. De esta manera tienes mucho más control.

Por ejemplo, con una línea, puede confirmar todos los archivos con extensión .hy .cppa los que realizó cambios (y que no causarían un conflicto):

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

Cambiar / agregar extensiones a la [h|cpp]pieza. Agregue un mensaje de registro entre comillas -m ""si es necesario.

Alan Turing
fuente
1

Algunas de las ideas propuestas pueden implementarse así:

En Windows en PowerShell

agregar todo a la lista predeterminada.ps1

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

agregar 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

Ahora, puede usar un alias svn ci --changelist defaultpara no tener que especificarlo cada vez. El beneficio adicional es que puede almacenar la lista de ignorar al confirmar (si lo desea) en el repositorio.

Hago esto para algunos archivos que se regeneran constantemente pero que rara vez se cambian a mano. Por ejemplo, agrego un número de revisión a mis archivos de configuración en marcadores de posición específicos para que los archivos se cambien en cada confirmación, pero el cambio manual es raro.

majkinetor
fuente
1

Me cansé de esperar a que esto se incorpore a SVN. Estaba usando tortoiseSVN con ignore-on-commit, pero aparece un cuadro de diálogo de usuario que no puede suprimir desde la línea de comandos, y cuando ejecuto mi script de compilación y voy y hago una taza de té, odio cuando Regreso para descubrir que está esperando la entrada del usuario el 10% del camino.

Así que aquí hay un script de Windows PowerShell que confirma solo los archivos que no están en una lista de cambios:

# 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
fuente
1

Actualización del script de user88044.

La idea es insertar los archivos en la lista de cambios de no comprometer y ejecutar el script malvado.

El script extrae los archivos de no confirmación del comando: svn status --changelist 'do-not-commit'

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

IGNORE_FILES = "$ (svn status --changelist 'do-not-commit' | tail -n +3 | grep -oE '[^] + $')"

para i en $ IGNORE_FILES; hacer mv $ DIR / $ i $ DIR / "$ i" _; hecho;

svn "$ @";

para i en $ IGNORE_FILES; hacer mv $ DIR / "$ i" _ $ DIR / $ i; hecho;

El script se coloca en / usr / bin / svnn (sudo chmod + x / usr / bin / svnn)

estado de svnn, compromiso de svnn, etc.

Nicolas F.
fuente
1

Puede configurar la lista de cambios "ignorar al confirmar" directamente con TortoiseSVN. No es necesario configurar ninguna otra lista de cambios, incluidos todos los demás archivos

1) Haga clic en "SVN Commit ..." (no nos comprometeremos, solo una forma de encontrar un menú gráfico para la lista de cambios) 2) En la lista, haga clic derecho en el archivo que desea excluir. 3) Menú: mover a la lista de cambios> ignorar al confirmar

La próxima vez que realice una confirmación SVN ... Los archivos aparecerán sin marcar al final de la lista, en la categoría ignorar-en-confirmación.

Probado con: TortoiseSVN 1.8.7, Build 25475 - 64 Bit, 05/05/2014 20:52:12, Subversion 1.8.9, -lanzamiento

luney
fuente
1
youps, acabo de ver los comentarios de tjmoore, que ya da la buena información para el usuario de tortoiseSVN ... sin línea de comando tortoisesvn.net/docs/release/TortoiseSVN_en/…
luney
¿Está roto en 1.9?
Jake Hm
1

Esto es tarde para el juego, pero encontré el comando de línea de comando más impresionante para este problema. Hecho usando bash. Disfrutar.

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

Ok, entonces aquí hay una explicación del comando. Algunas cosas deberán cambiarse según su caso de uso.

svn status

Me sale una lista de todos los archivos. Todos comenzarán con esos caracteres de estado (?,!, A, etc.). Cada uno está en sus propias líneas.

grep -v excluding

Yo uso grep para filtrar la lista. Se puede usar normalmente (para incluir) o con el indicador -v (para excluir). En este caso, se está utilizando para excluir, con una frase "excluyente" que será lo que se excluirá.

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

Ahora elimino el carácter de estado y el espacio en blanco al comienzo de cada línea, y luego cito cada línea, usando sed. Algunos de mis nombres de archivo tienen espacios en ellos, de ahí la cita.

tr '\n' ' '

Usando tr, reemplazo todas las líneas nuevas con espacios. Ahora toda mi lista de archivos para confirmar está en una línea.

xargs svn commit -m "My Message"

Por último, uso xargs para ejecutar mi comando de confirmación con el mensaje. Realiza la confirmación y elimina mi lista de archivos citados como último argumento.

El resultado es que, en última instancia, todo funciona como yo quiero. Todavía odio a svn por obligarme a saltar a través de estos malditos aros, pero puedo vivir con esto. Supongo.

usuario2223059
fuente
0

Como me enfrentaba exactamente al mismo problema, y ​​mi búsqueda en Google no me daba nada, creo que encontré una solución. Esto es lo que hice, parece funcionar para mí, pero como estoy atascado con una versión anterior de SVN (<1.5, ya que no tiene la opción --keep-local) y no soy un experto en ello. , No puedo estar seguro de que sea una solución universal. Si también funciona para usted, ¡hágamelo saber!

Estaba tratando con una instalación de Prestashop que obtuve de SVN, ya que otras personas ya habían comenzado a trabajar en ella. Como la configuración de la base de datos se realizó para otro servidor, la cambié en algún archivo en la carpeta / config. Como esta carpeta ya estaba versionada, configurarla en svn: ignore no evitaría que se confirmen mis modificaciones locales. Esto es lo que hice:

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)

Ahora puedo ejecutar svn add --force. en la raíz del repositorio sin agregar mi configuración, incluso si no coincide con la versión del repositorio (supongo que tendría que pasar por todo esto nuevamente si lo modificara una vez más, no lo hice). También puedo actualizar sin tener que sobrescribir mis archivos u obtener ningún error.

neemzy
fuente
0

Una solución que no ignora los cambios en las propiedades del directorio.

Traté de usar la solución basada en changelist, pero tengo un par de problemas con ella. Primero, mi repositorio tiene miles de archivos, por lo que la lista de cambios para confirmar es enorme, y mi svn statussalida se hizo demasiado larga y necesitaba ser analizada para que fuera útil. Lo más importante es que quería cometer cambios que vinieron de una fusión, lo que significa que incluyen cambios de propiedad. Al confirmar una lista de cambios, las propiedades svn adjuntas al directorio no se confirman, por lo que tuve que hacer una confirmación adicional:

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

Puede que tenga que hacer eso para varios directorios (aquí registro las propiedades de DIRy del directorio actual .), básicamente aquellos con un Men la segunda columna al emitir el svn statuscomando.

Solución

Usé parches y svn patch. En pseudocó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

Al igual que otros carteles, termino usando un script para mantener la lista de archivos a ignorar:

#! /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 "$@"

Normalmente lo uso con ciy revert -R ..

P. Le Sager
fuente
-1

svn:ignore es tu respuesta

Ejemplo:

$ svn propset svn:ignore -F .cvsignore .
property 'svn:ignore' set on '.'
Manuel Ferreria
fuente
1
Tenga en cuenta que el ejemplo anterior muestra cómo usar un archivo cvsignore configurado previamente como entrada a su propiedad svnignore.
Ben Hoffstein
1
no svn: ignore es solo para archivos de conversión. no funciona con archivos de versión
Sérgio
1
Y tampoco es local. Es un cambio de propiedad que se cometerá por sí mismo.
Adam Badura
-9
svn propset "svn:ignore" "*.xml" .

el *.xmles el patrón de archivos a ignorar; puedes usar nombres de directorio aquí también.

Casas2001
fuente
3
-1 porque no puedes ignorar un archivo que es parte del repositorio.
zellus