2012-05-18 17 views
16

Estoy teniendo algunos problemas para entender los conceptos básicos de git:/Git ignorar archivos siendo rastreado sin eliminarlos

estoy probando en mi máquina local de Windows antes de intentar algunas cosas en mi sitio git-controlado.

que tengo:

gittesting/repo1: 
    file.txt 
    ignoreme: 
     ignore.txt 

y

gittesting/repo2 
    file.txt 
    ignoreme: 
     ignore.txt 

repo2 es una copia de repo1 y ignoreme ya está siendo rastreado. El archivo ignore.txt cambia en repo2, pero quiero dejar de seguirlo y que git lo ignore por completo. El problema es que si creo un archivo .gitignore y agrego ignoreme, es demasiado tarde porque ya está siendo rastreado, así que tendría que hacer git rm --cached ignore, pero luego se marca como eliminado y si saqué el commit para repo1, el directorio sería eliminada en lugar de quedarse solo ..

Para resumir:

  1. el ignore.txt tienen un contenido diferente entre los dos repositorios.
  2. quiero el contenido ignore.txt permanezcan como están y ser completamente ignorado por git

He mirado en línea, pregunte en el IRC, y miré las preguntas muy relacionados, pero no puede encuentra una manera de hacer esto. Sé que el ejemplo parece trivial, pero es exactamente lo que tengo que hacer en mi sitio, donde el directorio es Foro/caché en su lugar.


edición:

Esto es un poco de un truco y yo preferiría una mejor respuesta, pero terminó haciendo:

cd repo2 
echo "ignoreme" > .gitignore 
echo "ignoreme/*" > .gitignore 
git rm --cache -r ignoreme 
git commit -m "Should ignore now" 
cd ../repo1 
mv ignoreme ignoreme2 
git pull ../repo2 
mv ignoreme2 ignoreme 

Respuesta

7

Si entiendo correctamente su pregunta, quiere que repo2 conozca el directorio , pero no desea que a Git le importen las modificaciones al directorio. Y git rm --cached no lo ayudará porque le está diciendo a Git que deje de seguir este contenido a partir de ahora.

La solución de Git para realizar un seguimiento del contenido, pero corregida en un cierto punto, es a través de submódulos. Esta excepción de la Git Book explica (énfasis añadido):

Aunque rack es un subdirectorio en el directorio de trabajo, Git lo ve como un submódulo y no realizar un seguimiento de su contenido cuando no estás en ese directorio. En cambio, Git lo registra como una confirmación particular de ese repositorio.

Usted podría intentar lo siguiente:

  1. Copiar el directorio ignoreme/ a una nueva ubicación, y convertirlo en un repositorio git

  2. agregarlo de nuevo como un submódulo en repo2:

    git submodule add file:///path/to/ignoreme ignoreme 
    git commit -m"Add ignoreme/ as a submodule" 
    

El submódulo ignoreme ahora está fijado a una confirmación concreta. repo2 sigue rastreando el contenido que esté dentro del submódulo, pero los cambios a los archivos en ignoreme/ no se rastrearán en repo2 a menos que los especifique en el submódulo. Digamos ignoreme/ignore.txt fue modificado de alguna manera:

$ git status 
# On branch master 
# Changes not staged for commit: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# (commit or discard the untracked or modified content in submodules) 
# 
#  modified: ignoreme (modified content) 
# 
no changes added to commit (use "git add" and/or "git commit -a") 

Incluso si ejecuta git add ., los cambios en ignoreme/ignore.txt no será añadido al índice a menos que se cometen al submódulo de este modo:

$ cd ignoreme 
$ git commit -am"Time to change ignore.txt" 
$ cd .. 
$ git add . 
$ git status 
# On branch master 
# Changes to be committed: 
# (use "git reset HEAD <file>..." to unstage) 
# 
#  modified: ignoreme 
# 

Sin embargo, si desea olvidar las modificaciones locales en el submódulo:

$ cd ignoreme 
$ git reset --hard 
$ cd .. 
1

Git no almacena los directorios. Si desea mantener un directorio vacío en Git, la convención es poner allí un archivo vacío llamado .keepme, y confirmarlo.

En cuanto a la pregunta, no serás capaz de ocultar un archivo en una rama ascendente desde su clon, según mi leal saber y entender. Esto no es algo para lo que Git está diseñado. Considere otras opciones, como dividir en dos repositorios (y, tal vez, usar subárbol o submódulos). O mantenga una rama separada en sentido ascendente para realizar un seguimiento en sentido descendente, y filtre el ignore.txt desde esa rama mediante un enlace posterior a la recepción.

Cuéntanos más de por qué quieres hacer esto, tal vez hay una mejor manera.

De todos modos, espero que no intenta ocultar este archivo por razones de "seguridad" - de lo contrario las cosas serían mucho más complicado (por ejemplo, hay que borrarlo de toda la historia, etc.)

+2

Siempre prefiero poner '.gitignore' dentro del directorio para directorios" vacíos ". – meagar

+0

El enfoque personalizado consiste en enviar un archivo '.gitkeep' vacío. El motivo es el prefijo breve e inequívoco: '. * # Ignore dotfiles''! .git * # pero no los que configuran el repositorio, es decir .gitignore, .gitkeep' –

+0

'.keepme' es una expresión muy utilizada. Como es habitual con la expresión idiomática, puedes ir contra la corriente y hacerlo a tu manera, pero bajo tu propio riesgo. –

0

El registro de salida una confirmación que tenga ese archivo lo reemplazará, y la transición de una confirmación con ella a una confirmación sin ella la eliminará. Git no pudo hacer otra cosa sanamente. .gitignore no anula el repositorio, es una conveniencia mantener la fluff fuera de sus informes de estado.

Puede hacer que el archivo sea un enlace simbólico a un lugar fuera del territorio de git, que hace que la recuperación del daño se realice mediante la verificación del historial incorrecto. Si esa no es una opción, hay una rama de filtro.

18

probar este

git update-index --assume-unchanged ignoreme/ignore.txt 

Git ignorará cualquier cambio futuro a este archivo sin cambiar el repositorio. Para iniciar el seguimiento de los cambios de nuevo, utilizar

git update-index --no-assume-unchanged ignoreme/ignore.txt 

Tenga en cuenta que esto sólo tiene efecto para la copia de trabajo actual, por lo que tendría que hacer esto cada vez se clona el repositorio.

+1

Todavía cambió el archivo :( – mowwwalker

+1

Esto no impedirá que se modifique el archivo. Simplemente evitará que git muestre el archivo como cambiado. Si desea evitar cambios en el archivo por completo, puede configurarlo como leído- only. –

+2

Usar '--assume-unchanged' solo es legal si no cambias el archivo. Si lo cambias, estás mintiendo a git y eso nunca termina bien. –

0

Git solo aplica ignorar patrones a los archivos sin seguimiento. No puede usar patrones de ignorar para ignorar los cambios en los archivos que ya han sido rastreados por git. Aún así, vea https://gist.github.com/1423106 para conocer las formas en que las personas han solucionado el problema.

Nota: si le preocupa .gitignore en sí mismo, puede intentar usar .git/info/excludes para un archivo .gitignore local-repo-only.Tenga en cuenta que esto no resolver el problema de cambiar los archivos rastreados, solo le dan .gitombreres suplementarios que no serán rastreados.

Cuestiones relacionadas