En BASH ¿Cómo se puede copyr recursivamente solo la versión del contenido? ¿Controlado por Git?

¿Hay alguna forma de copyr un recursivo de masa del terminal de bash (equivalente cp -rf ) de un subdirectory a otro, preservando la estructura del directory pero SÓLO copyr los files / directorys está controlado por la versión de git ?

La estrategia ingenua sería …

 cp -rf <targetDir> variantDir/; git add variantDir; 

… pero eso recogería un montón de files que son files de datos eliminados por el IDE, etc. Estoy trabajando con files que actualmente no están controlados por la versión en <targetDir> .


Como background, tengo la siguiente estructura de directory:

 ${baseDir}/ ${baseDir}/variantA 

Básicamente, ${baseDir}/ contiene todo el contenido controlado de la versión original, y ${baseDir}/variantA contiene el contenido que difiere para una variante específica. Para la carpeta de destino original ${baseDir}/variantA se ignora. Para el segundo objective, se incluye la variantA carpeta variantA , que reemplaza efectivamente cualquier contenido que concuerde con otra parte que no sea la parte variantA de la ruta.

es decir, si tuviera:

 ${baseDir}/someFolder/someStuff.cpp ${baseDir}/variantA/someFolder/someStuff.cpp 

Usaría la segunda ruta para el segundo objective y la primera ruta para el primer objective.

Ahora agrego variantB y es una variante completa (a diferencia de la variante variantA que tiene algunos problemas con los files del objective base). Está más cerca de variantA así que variantA quiero copyr todo en la carpeta base, luego copyr todo en la subcarpeta variantA a la subcarpeta variantB … así tengo una nueva copy de todo el contenido (incluidos los fall through) a la versión commit, con una preference para variantA versiones de file, cuando tal superposition existe.

Usaría el fragment ingenuo anterior, pero tengo un problema más fundamental que mi IDE ha eliminado *.xml y otros files no deseados que git es de alguna manera lo suficientemente inteligente como para marcar como contenido no comprometido (probablemente específico del idioma), pero que cp ignoraría . Creo que git copyría estos files si se lo pidiera EXPLÍCITAMENTE, así que, por lo tanto, quiero excluir todo el contenido no controlado por git , mientras uso la estrategia general establecida anteriormente.

 git ls-files | tar Tc - | tar Cx /path/to/destination 

esto toma lo que está en tu lugar actual en el tree de trabajo. Para usar un subdirectory de una confirmación, use la solución de git archive @Charles Duffy mencionó ,

 git archive master:path/to/subdir | tar Cx /path/to/destination 

y para trabajar con su contenido actualmente agregado pero no comprometido puede sustituir $(git write-tree) para el master anterior.

¿Por qué no simplemente crear un tree de trabajo nuevo (que obviamente solo tendrá files controlados por el origen, ya que se genera a partir del control de origen)?

Hay algunas maneras de hacer esto (con clones o treees de trabajo) pero pensaría

 git worktree add -b variantB path/where/variantB/will/be/created master 

te ayudaría a comenzar con los files relevantes (los que están bajo el control de la fuente). Luego copie la path/where/variant/B/will/be/created/variantA sobre la path/where/variant/B/will/be/created

Y debido a la opción -b , ya está en una nueva sucursal, que es la forma en que es probable que desee mantener esta variación de todos modos, ya que es un reemploop completo. (Para varientA es discutible, ya que quiere que la variante A se mantenga actualizada con los cambios de línea base en los files, no varía …)

Pero si no quieres mantener una nueva sucursal para esto, no es gran cosa. Utilice un clon o un command de agregar tree de trabajo (sin -b ) para crear una image de tree de trabajo de la variante B como se muestra arriba, pero luego mueva los files resultantes a su tree de trabajo pnetworkingeterminado en un directory … / variantB

Para copyr solo files bajo el control de origen de variantA a variantB:

 cd variantA rsync --files-from <(git ls-files .) . ../variantB 

Esto funciona al include solo los files devueltos por git ls-files .

Editar: la syntax <() se llama sustitución de process .

Si tiene GNU cp , puede usar la opción --parents :

 mkdir variantB cd variantA cp --parents $(git ls-files .) ../variantB