2009-05-14 23 views
35

Tengo una copia de trabajo de Subversion en la que realicé algunas modificaciones locales en un archivo. Las modificaciones solo son relevantes para mí, no quiero comprometerlas. (La versión en el repositorio contiene algunos valores predeterminados que son adecuados para los demás usuarios, pero no para mí, por lo que quiero sobrescribirlos localmente).Subversion: ¿evita que se realicen modificaciones locales en un archivo?

Tenga en cuenta que aunque no deseo confirmar mis cambios, I do quiero recibir las actualizaciones realizadas en el repositorio cuando lo hago svn update. Además, es solo en mi copia de trabajo que no quiero confirmar los cambios en ese archivo, los otros usuarios no deberían verse afectados. Entonces, svn:ignore o commit hooks no se ajustan a mi propósito.

Actualmente, hago simplemente:

svn commit file1 file2... 

donde especificar explícitamente los archivos que tienen cambios excluyendo el archivo particular que no quiero cometer.

Sin embargo, mientras estoy trabajando, tengo el hábito de escribir simplemente:

svn commit -m "Log of what I just did" 

y temo que sin querer voy a cometer el archivo "prohibido" utilizando el comando anterior en un momento cuando No estoy atento.

En resumen, lo que estoy buscando es simplemente una forma de "marcar" un archivo en una copia de trabajo que evita que Subversion cometa los cambios en ese archivo (no tiene que ser una exclusión automática, incluso si Acabo de recibir un error cuando intento enviar todos los archivos, está bien). Algo así como marcar archivos en un estado de "conflicto" ...

¿Existe tal cosa?

Actualización: akent, gracias por señalar este very similar question.

+0

¿Podría ser algo que su ide podría hacer por usted? – Josh

+0

u obtén tortoisesvn, te permite elegir qué archivos comprometer –

+4

qué IDE? :-) Usualmente uso svn desde la línea de comando. –

Respuesta

17

Ha habido algunas respuestas que pueden trabajar:

  1. Crear un pre-commit script gancho que rechazan el compromiso al que se añade una propiedad específica. A continuación, puede agregar esta propiedad a los archivos en la copia de trabajo para evitar confirmaciones.
  2. TortoiseSVN excluirá los archivos en la lista de cambios especial "ignorar-en-comprometer". Sin embargo, esto no es respetado por el cliente de línea de comandos SVN.

CoverosGene sugirió que los comandos predeterminados, tales como svn commit operan en una lista de cambios por defecto, de manera que se puede excluir un archivo si lo ha asignado a otra lista de cambios, pero no puedo encontrar ninguna referencia de que en la documentación, y en mi prueba esto no funciona.

Como no hay una buena solución para el cliente de línea de comandos SVN, he abierto una solicitud de mejora here. La solicitud sugiere que el cliente de línea de comandos también podría cumplir la lista de cambios "ignorar en el compromiso".

Actualización: Esto es ahora issue 2858 y hay una feature outline para manejarlo con una propiedad svn:hold.

2

Lock ciertamente no es lo que quieres, y no creo que ninguna de las funciones integradas lo haga por ti.

Dependiendo del entorno en el que se está trabajando, me gustaría escribir un script que:

  1. obtiene la lista de archivos
  2. Elimina los que no quiero cometer
  3. compromete a las
  4. archivos

Algo a lo largo de las líneas de:

svn status | grep ^M | grep -v exclude.c | awk -F' ' '{print $2}' | xargs svn ci -m "I'm committing something" 

O si la lista de archivos es realmente estática, ¡solo arregle la lista!

8

Entiendo el problema que tiene; probablemente este archivo "prohibido" contenga ajustes de configuración y similares que solo son relevantes para su entorno de compilación local. No he encontrado ninguna manera directa de decirle a SVN solo para ignorar los cambios en un archivo versionado, pero aquí hay una solución que he usado en el pasado.

Suponiendo que se llama a su archivo, por ejemplo, "build.conf". Nombre el archivo versionado SVN algo así como build.conf.example.Luego, en su script Makefile o compilación o lo que sea, puede copiar automáticamente build.conf.example al real build.conf, que permanece sin versión. Luego svn ignora build.conf y cada desarrollador puede hacer los cambios locales que necesite.

Pero "tiene que haber una mejor manera" ...

Editar: pregunta casi idéntica aquí: SVN: Is there a way to mark a file as "do not commit"?

+1

Aparentemente, esta también es la respuesta de las preguntas frecuentes. Sin embargo, esta es una molestia y pasa por alto un punto muy importante: cada vez que el archivo "prohibido" se actualiza en el repositorio, quiero que svn combine los cambios remotos con mis modificaciones locales (y señalice un conflicto si es necesario). Con un archivo no versionado, debe hacerlo manualmente, lo que significa que su build.conf probablemente se desactualice en comparación con build.conf.example. –

+0

De acuerdo, no ideal. La respuesta de CoverosGene parece ser "la mejor manera". Solo en versiones recientes (1.5+) de SVN, parece. – akent

2

Esta pregunta está en el Subversion FAQ. Pero la respuesta no es muy útil si no controlas el repositorio.

Quizás intente administrar su copia local con git encima de la subversión. Hay un simple course for git disponible. A continuación, puede usar git-svn para rastrear cambios en el repositorio svn y para comprometer sus cambios. Necesitará algo de aprendizaje y entrenamiento a través de.

8

Cree un changelist con ese archivo y luego simplemente no preste atención a la lista de cambios. El archivo se quedará ahí esperando ser confirmado, pero sus confirmaciones regulares, que funcionan en la lista de cambios predeterminada, nunca lo recogerán.

svn changelist mylocal file1 

creará una lista de cambios llamada mylocal y asignar el archivo file1 a ella.

+0

Buena solución, pero solo funciona por desarrollador; no es algo que pueda configurar para todos los que verifiquen el repositorio. Además, solo está disponible en versiones SVN> 1.5. – akent

+8

Las listas de cambios parecen ser geniales, pero lo que dices no es del todo correcto: cuando creo una lista de cambios "mylocal", entonces "svn commit" seguirá teniendo en cuenta todos los archivos modificados. Por lo que veo, no hay mención de la lista de cambios "predeterminada" en la documentación. –

+0

@akent: per-working-copy es exactamente lo que quiero –

0

Puede usar un gancho precompromiso. En el gancho use svnlook author para ver si usted es el que está realizando los cambios. Si es así, use svnlook changed para ver si está cambiando uno de los archivos prohibidos.

3

Desde mi experiencia: no pongas ese archivo bajo control de versiones y usas svn: ignore en él.

Al principio es un poco difícil, ya que no puede ignorar un archivo que ya está bajo control de versión y no puede eliminar un archivo del control de versión sin eliminarlo del disco duro (y de cada copia de trabajo en la siguiente actualización. ..). Pero cuando finalmente logras configurar el repositorio correctamente, funciona como el encanto. No olvide agregar una plantilla genérica en lugar de su archivo de configuración original (para que todos conozcan las nuevas variables de configuración, etc.).

Para nueva operación:

mkdir config 
svn add config 
svn propset svn:ignore '*.conf' config 

Para repo existente: estar seguro, para tener una copia de seguridad de su configuración en cada copia de trabajo, a continuación, quitar (SVN del) config desde el repositorio, comprometerse (por favor tenga en cuenta: el archivo se eliminará en cada copia de trabajo en la próxima actualización! debe tener una copia de seguridad) y luego restaurar el archivo y establecer la propiedad de ignorar.

Otra forma es un candado. Garantiza que nadie confíe el archivo, pero dará lugar a un error en cada confirmación. no muy bueno.

Y la tercera forma - changesets, una nueva característica en clientes SVN 1.5. Esto es claro, pero solo está relacionado con una copia de trabajo, no con un repositorio global. Y tiene que configurarlos manualmente, agregar cada nuevo archivo, es difícil de mantener.

4

Hablando de Tortoisesvn y listas de cambios, ya viene con una lista de cambios llamada ignore-on-committ, que hace lo que estás buscando.

5

En realidad, un script de precompilación podría hacer el trabajo.

Escriba un script precompromiso que ejecute 'svnlook diff' y rechace el compromiso si hay una propiedad llamada 'nocommit' que se establece en el conjunto de cambios.

Luego, en su copia de trabajo, puede simplemente establecer una propiedad 'no comprometer' en cualquier archivo que no se debe confirmar. Cualquier confirmación subsiguiente fallará si algún archivo tiene la propiedad 'no comprometer'. Si luego necesita verificar los cambios en el archivo, todo lo que tiene que hacer es eliminar la propiedad 'no comprometer' de su copia de trabajo.

+0

Fallar no es una opción. Ignorar es lo que se necesita hacer. – majkinetor

3

Durante los últimos años he estado usando una solución simple que logra exactamente lo que está buscando. Se llama la palabra clave NOCOMMIT.

Lo que hago es que tengo un gancho precompromiso en mi repositorio SVN que comprueba si algún archivo contiene la cadena NOCOMMIT y, de ser así, falla la confirmación. Entonces, cuando un programador realiza una modificación que no debe comprometerse (por ejemplo, cambiaron la cadena de conexión de base de datos de todo el proyecto del servidor de prueba local a su propio servidor de prueba local o agregaron declaraciones de diagnóstico de depuración que enviarán spam al registro con miles de líneas por segundo), le añaden un comentario //NOCOMMIT, y no tienen que preocuparse de haberlo cometido accidentalmente. Cuando llegue el momento de cometer, se les impide, por lo que se ven obligados a cualquiera:

  • movimiento que presentar a su lista de cambios que no desean comprometerse, o
  • búsqueda de NOCOMMIT y eliminar cualquier ocurrencia de la misma, con la esperanza de arreglar el código al que lo habían adjuntado.

Personalmente, creo que la palabra clave NOCOMMIT tan útil que lo uso, incluso cuando se trabaja en proyectos favoritos de la mina, donde obviamente, yo soy el único programador en el equipo.

Si está utilizando Windows, puede pegar el siguiente texto en el archivo llamado pre-commit.bat en la carpeta hooks de su repositorio SVN.

:: Stops commits that contain the NOCOMMIT keyword. 
setlocal 
set REPOS=%1 
set TXN=%2   
SVNLook diff %REPOS% -t %TXN% | findstr /I /M /L NOCOMMIT > nul 
if %errorlevel% gtr 0 (
    exit 0 
) else (
    echo Your commit has been blocked because it contains the keyword NOCOMMIT. 1>&2 
    exit 1 
) 

En los sistemas Unix, algo como lo siguiente debe hacer el truco, aunque Tenga en cuenta que no he probado.

#!/bin/sh 
REPOS="$1" 
TXN="$2" 
SVNLOOK=/usr/local/bin/svnlook 
$SVNLOOK diff -t "$TXN" "$REPOS" | grep -i "NOCOMMIT" > /dev/null && { echo "Your commit has been blocked because it contains the keyword NOCOMMIT." 1>&2; exit 1; } 
0

Puede usar una rama personal y cambiar ese archivo para este efecto. De esta manera:

svn cp ^/trunk ^/branches/your_name -m "Creating a personal branch."  
cd working_copy_of_trunk/sub_path/ 
svn switch ^/branches/your_name/sub_path/your_file your_file 

Tenga en cuenta que:

  1. se puede comprobar el estado de conmutación de la 'S' que aparece en la quinta columna con el comando: svn status
  2. Nunca se va a trabajar en la rama , su working_copy_of_trunk aún está sincronizado con el directorio troncal del repositorio excepto los archivos que ha cambiado, por lo que siempre que realice cambios en su_archivo, las confirmaciones para ese archivo se realizarán en su sucursal y no en el enlace troncal.
  3. La copia se ha realizado del lado del servidor completo, y esta es la forma recomendada con svn. La copia completa del lado del servidor es instantánea y no gastará espacio adicional en el servidor. Sin embargo, también se recomienda que las personas no revisen el directorio superior que contiene trunk/tags/y branches/pero directamente trunk/de lo contrario todos los archivos se duplicarán localmente al actualizar desde este directorio superior. Si este es el caso en lugar subtitute el primer comando con:

    cp SVN --parents ^/trunk/sub_path/your_file ^/ramas/su_nombre/sub_path/your_file

    Por último, si por alguna razón no quieren para copiar su archivo en otro lugar en su servidor de repositorio, entonces aún puede combinar este enfoque con un servidor externo y svn: palabras clave externas (no muy recomendadas).

+0

Seguro que funciona, pero: 1. necesita trash el depósito con una bifurcación adicional, 2. obtiene una copia de trabajo incoherente. 3. Todavía escribiendo mucho, rara vez vale la pena el problema. –

1

Agregue todos los archivos a una lista de cambios y luego elimine los archivos que no desea confirmar. Finalmente cometer la lista de cambios como se muestra a continuación:

$ svn status 
M file01 
M ... 
M file100 
M file_not_ready_for_commit 

// This will add all working copy files, can be adjusted to add only relevant files 
$ svn changelist mychangelist -R . 

// Remove the nascent one(s) 
$ svn changelist mychangelist --remove file_not_ready_for_commit 

// Commit only the files in the changelist 
$ svn commit --changelist mychangelist 

Fuente de información anterior es este blog que también tiene un enlace a http://svnbook.red-bean.com para más detalles. Todos los créditos para el autor del blog.

Cuestiones relacionadas