2011-06-09 34 views
10

Estoy tratando de mantener 2 proyectos de sitio web en un repositorio. Estos sitios web son básicamente los mismos excepto los archivos de plantilla (html, css) y algunos archivos de configuración. El sitio principal (que es mi opinión Supersite) está en la rama principal. El segundo sitio está en la rama secondarySite. Cada vez, cuando desarrollo alguna característica nueva en la rama principal, quiero fusionarla en secondarySite, pero quiero excluir la fusión de los archivos de plantillas.git - cómo excluir archivos de la fusión

He encontrado solución parcial aquí How do I tell git to always select my local version for conflicted merges on a specific file? pero sólo funciona cuando cambio archivo de plantilla en ambas ramas y conflicto se produce. Cuando no hay conflictos, solo usa la versión remota más nueva del archivo.

¿Cómo puedo decirle a git siempre dejar los archivos locales especificados sin cambios, incluso si no hay ningún conflicto.

¿O tal vez utilizo un enfoque totalmente incorrecto para el problema?

Gracias de antemano por cualquier ayuda.

+0

¿alguna vez encontró una solución a esto? – pvinis

Respuesta

3

¿Has probado a usar .gitignore? Detalles disponibles en la documentación de git here

+3

Gracias por su sugerencia. El problema es que necesito rastrear archivos en ambas ramas, solo quiero mantener estos archivos "específicos de la rama". – Marcin

6

Como se menciona en my answer on merge drivers, son útiles en caso de conflicto solamente.
Eso applies to a merge=ours in a .gitattributes file: vea Merge strategies.

Una opción muy útil es decirle a Git que no trate de combinar archivos específicos cuando tienen conflictos, pero en lugar de usar su lado de la fusión sobre otra persona.

Este recent thread (2012) lo confirma:

¿Hay una manera de combinar de branchA a branchB y desde branchB a branchA, ignorando por completo los cambios en un archivo que se hace un seguimiento y existe en tanto ramas?

Nº Fundamentalmente, un objeto comprometerse en git consiste en un estado contenido (es decir, un puntero a un objeto árbol) y un puntero a toda la historia anterior (es decir, cero o más "padre" punteros para cometer objetos).
La semántica de un objeto de confirmación se puede considerar como "He examinado todo el historial en todas las confirmaciones principales, y el estado que contiene mi puntero de árbol las reemplaza a todas".

por lo que podría hacer que se funden en BA, pero mantener copia del archivo A 's (por ejemplo, utilizando la estrategia de 'ours'). Pero eso significa que usted consideró el estado de A y B, y decidió que la versión de A reemplaza lo que sucedió en B. Si luego desea fusionar desde A a B, la versión del archivo B ni siquiera se considerará como un resultado para la fusión.

No hay realmente una manera inteligente de evitar esto mediante una estrategia de combinación diferente; es un aspecto fundamental de la estructura de datos de git para almacenar el historial.

Si esas plantillas están en un subdirectorio, es mejor aislarlas en un repositorio git propio, para incluir ese repositorio como un submódulo.

Si no es así, entonces usted necesita para revertir los archivos de forma incorrecta se fusionó antes de comprometerse (como en this thread):

git merge --no-commit other 
git checkout HEAD XYZ # or 'git rm XYZ' if XYZ does not exist on master 
git commit 
2

Aquí git-update-índice - Registre el contenido del archivo en el directorio de trabajo para el índice.

git update-index --assume-unchanged <PATH_OF_THE_FILE> 

Ejemplo: -

git update-index --assume-unchanged somelocation/pom.xml

o

Añadir rutas de archivos en .gitignore

1

O tal vez utilizar el enfoque totalmente equivocado a la pr ¿Oblem?

Estás usando totalmente el enfoque equivocado a este problema :)

La cuestión es que las ramas y las herramientas que les rodea, están destinadas a mantener diferentes versiones de la misma cosa subyacente .

Pero sus dos sitios web no son realmente la misma cosa subyacente, son dos cosas diferentes con algo en común, y usted tiene que abusar de git porque le está mintiendo sobre su relación.

Sus opciones sanas son:

  1. hacer su cesión temporal representan el universo de todos (bueno, dos) sitios. Entonces, ambos son visibles en la misma estructura de directorio y usan diferentes nombres de ruta. Ellos podrían tener ramas de desarrollo y liberación separadas, pero es opcional. Si los dos sitios tienen algo en común, esto solo puede ser en forma de archivos compartidos.

    por ejemplo.

    repo/supersite 
    repo/secondsite 
    repo/common 
    
  2. haga un repositorio separado para cada sitio, y duplique los archivos comunes. Puede simplemente copiar los cambios

  3. hacer un repositorio por separado para cada sitio, y un tercer repositorio por las cosas comunes, y usar submódulos para combinar supersite + común en un lugar, y segundosite + común en otro.

    por ejemplo.

    super-repo/site # super site content 
    super-repo/common # common repo as submodule 
    second-repo/site # second site content 
    second-repo/common # same common repo as submodule 
    

    Nota los submódulos se refieren al mismo repo, pero cada instancia puede estar actualmente en una rama diferente o cometer

Hasta cierto punto, la elección correcta depende de la cantidad de los dos sitios varían de forma independiente , y con qué frecuencia cambian los bits compartidos, y si está bien obligar a ambos sitios a usar la misma versión de los bits compartidos, y qué fracción del contenido total se comparte frente a único, etc. etc.

1

En cada de sus ramas, agregue el archivo .gitattributes in roo t.

Para cada rama, se especifica que los archivos sean ignorados en la fusión de la siguiente manera:

filename merge=ours 

y no se olvide de activar el controlador para que:

git config --global merge.ours.driver true 

Pruebe la fusión, se le ver que los archivos especificados en .gitattributes en cada rama no se tocarán mientras ocurre la fusión.

Cuestiones relacionadas