Módulo 8: Proyecto final colaborativo y evaluación
Unidad: GIT-10
Nivel: tronco, inicial–intermedio
Duración orientativa: 4–5 horas
Público: alumnado de DAW, DAM, ASIR y grados de informática.
Itinerario: cierre del tronco, tras fundamentos, ramas, remotos, recuperación y entrega.
Prerrequisitos: módulos 1 a 7 completos.
Objetivo observable: entregar, en equipo, un repositorio en GitHub con una versión etiquetada y documentada; cada persona debe poder explicar su historial, la integración de su contribución y una decisión segura de recuperación.
Fuente técnica: documentación oficial de Git, especialmente branches, merge, push y tag, y la documentación de pull requests de GitHub.
Reto
Construid un pequeño proyecto colaborativo: una aplicación o sitio estático de agenda de actividades. El valor funcional es secundario: se evalúa el uso razonado de Git, no la calidad del producto.
El repositorio debe incluir:
README.mdcon objetivo, instalación/uso, estructura, integrantes y flujo de trabajo..gitignoreadecuado al editor, al sistema y a la tecnología empleada (módulo 4).- Al menos tres funcionalidades separables en ramas de tarea.
- Una integración mediante
mergecon un conflicto real, resuelto y explicado (módulo 5). - Un tag anotado
v1.0.0publicado (módulo 7). - Un historial legible, sin commits de archivos generados, secretos ni dependencias instaladas.
- Evidencia individual de contribución y explicación técnica.
No son requisito ni Git LFS, ni hooks, ni CI/CD, ni rebase, ni push --force. Pueden usarse solo como ampliación documentada, y los tres primeros se tratan en los módulos 10 y 11.
Organización
Equipos de 2–4 personas. Cada integrante asume una funcionalidad y rota, al menos una vez, el papel de integrador/a: quien revisa y acepta el trabajo de otra persona. Las tareas se registran como issues en GitHub.
Flujo mínimo por tarea:
- Poner
mainal día:git switch main && git fetch origin && git merge origin/main. - Crear una rama:
feat/nombre-corto,fix/nombre-cortoodocs/nombre-corto. - Hacer commits pequeños, coherentes y verificables.
- Publicar la rama con
git push -u origin <rama>y abrir una pull request en GitHub. - Otra persona revisa, comenta y aprueba.
- Integrar y borrar la rama.
Al final del proyecto: preparar el README, crear el tag anotado y publicar la versión.
Git aporta ramas, commits, remotos y merges. La pull request, las aprobaciones y la protección de ramas son funciones de GitHub, no de Git (módulo 5).
Preparar el repositorio en GitHub
Una persona del equipo crea el repositorio y añade al resto como colaboradores. Después, cada integrante lo clona:
git clone https://github.com/<organizacion>/<repositorio>.git
cd <repositorio>
git config user.name "Nombre Apellido"
git config user.email "correo@ejemplo.es"Configurar la identidad por repositorio (sin --global) evita el error clásico de entregar commits firmados con el nombre de otra persona o con el del ordenador del aula. Compruébalo antes del primer commit:
git config user.name
git log -1 --format="%an <%ae>"Se recomienda proteger main en la configuración del repositorio para que solo se pueda modificar mediante pull request. Es opcional para el proyecto y se trata a fondo en el módulo 11.
Demostración práctica
La siguiente secuencia usa un remoto local para poder ensayar el flujo completo sin depender de la red. En el proyecto real, ../agenda-remoto.git se sustituye por la URL de GitHub y el paso de integración por una pull request.
Arranque y primera funcionalidad
mkdir proyecto-agenda
cd proyecto-agenda
git init -b main
printf "# Agenda de actividades\n" > README.md
printf "node_modules/\n.env\n.DS_Store\n" > .gitignore
git add README.md .gitignore
git commit -m "chore: crea estructura inicial"
git init --bare ../agenda-remoto.git
git remote add origin ../agenda-remoto.git
git push -u origin main
git switch -c feat/listado-actividades
printf "<h1>Próximas actividades</h1>\n" > index.html
git add index.html
git commit -m "feat: añade listado de actividades"
git push -u origin feat/listado-actividades[main (root-commit) ebdeab7] chore: crea estructura inicial
2 files changed, 4 insertions(+)
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.
[feat/listado-actividades 76085b4] feat: añade listado de actividades
1 file changed, 1 insertion(+)
* [new branch] feat/listado-actividades -> feat/listado-actividadesRevisar antes de integrar
Este es el trabajo del integrador, y el detalle importa:
git fetch origin
git log --oneline --graph --decorate --all
git diff --stat main...origin/feat/listado-actividadesTres puntos, no dos. main...rama compara la rama contra el punto en que ambas se separaron, que es la pregunta de una revisión: «¿qué ha hecho esta rama?». Con dos puntos obtendrías además, invertidos, los cambios que main haya sumado por su cuenta. En una revisión real eso aparece como si la contribución borrase archivos que nunca tocó:
# git diff --stat main..origin/feat/inscripciones ← DOS puntos, engañoso
README.md | 4 ----
inscripcion.html | 1 +
# git diff --stat main...origin/feat/inscripciones ← TRES puntos, correcto
inscripcion.html | 1 +fetch descarga referencias sin modificar tu rama (módulo 5). No trates git pull como una acción opaca: es fetch más una integración.
Integrar y publicar la versión
git switch main
git merge --no-ff feat/listado-actividades -m "merge: integra listado de actividades"
git tag -a v1.0.0 -m "Versión inicial de Agenda"
git push origin main --tags
git ls-remote --tags originMerge made by the 'ort' strategy.
index.html | 1 +
ebdeab7..7979a5a main -> main
* [new tag] v1.0.0 -> v1.0.0
5104d6d61d6ce3c460213b3ece000cce93f93525 refs/tags/v1.0.0
7979a5a2218e30661f75998add2b6caae9a9e1df refs/tags/v1.0.0^{}--no-ff deja constancia en el historial de que hubo una rama, que es lo que se quiere en un proyecto evaluado. Las dos líneas del tag en ls-remote son la firma de un tag anotado (módulo 7).
El conflicto obligatorio
El enunciado exige un conflicto real. La forma limpia de provocarlo es que dos ramas modifiquen la misma línea:
git switch -c feat/horarios
printf "<h1>Próximas actividades</h1>\n<p>Horario: mañanas</p>\n" > index.html
git add index.html && git commit -m "feat: añade horario de mañanas"
git switch main
printf "<h1>Próximas actividades</h1>\n<p>Horario: tardes</p>\n" > index.html
git add index.html && git commit -m "feat: añade horario de tardes"
git merge feat/horariosCONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.La resolución es una decisión de equipo, no una elección mecánica entre las dos versiones:
printf "<h1>Próximas actividades</h1>\n<p>Horario: mañanas y tardes</p>\n" > index.html
git add index.html
git commitAquí ninguna de las dos versiones era correcta: la agenda abre en ambos turnos. Esa justificación es lo que se evalúa, más que el comando.
Qué cambia en cada paso:
| Comando | Efecto |
|---|---|
git add |
Actualiza el área de preparación |
git commit |
Crea historial local |
git push |
Publica commits y referencias en el remoto |
git merge |
Integra en el historial local; el remoto no cambia hasta el push |
git tag -a |
Crea la etiqueta local |
git push --tags |
Publica las etiquetas |
Errores frecuentes
- Trabajar directamente en
main: comprueba congit branch --show-currentantes de tocar archivos. Si ya has hecho commits,git switch -c feat/tarealos conserva (módulo 5). - Commits con la identidad equivocada: en un aula con equipos compartidos es lo más habitual. Configura
user.nameyuser.emailpor repositorio y verifica congit log -1 --format="%an <%ae>"antes de acumular trabajo. La rúbrica evalúa la contribución individual y se lee del historial. - Subir archivos innecesarios o sensibles: si
git statusmuestranode_modules,.envo archivos generados, faltan reglas en.gitignore. Añádelas antes del primer commit de esos archivos: una vez confirmado un secreto, elrevertno lo borra del historial (módulo 6). - Intentar publicar sin integrar: el push se rechaza con
(fetch first).git fetch, revisar, integrar y volver a publicar (módulo 5). - Revisar con
git diff main..rama: usa tres puntos. Con dos, la revisión muestra como borrados los cambios quemainsumó por su cuenta. - Resolver un conflicto a ciegas: lee las dos versiones, comprueba el resultado y justifica la decisión. Si no tienes información,
git merge --aborty pregunta. - Usar
reset --hardpara corregir la entrega: puede descartar trabajo sin confirmar. Prefiererestore,reverto una rama de seguridad; si pierdes un commit,git reflog(módulo 6). - Usar
push --forcesobre una rama compartida: sobrescribe trabajo ajeno. No se permite en el proyecto final salvo autorización expresa del profesorado, y con justificación de recuperación.
Entrega
Cada equipo entrega la URL del repositorio de GitHub con la versión etiquetada v1.0.0 publicada. Cada integrante adjunta una nota breve —máximo 200 palabras— que responda:
- Qué rama creó y qué aportó.
- Qué commit considera más representativo y por qué.
- Qué integración o conflicto revisó o resolvió, y con qué criterio.
- Qué comando usaría ante un error propio ya publicado, y por qué ese y no otro.
La cuarta pregunta es la que separa el aprobado del notable: la respuesta correcta es revert, y hay que saber decir por qué no reset (módulo 6).
Rúbrica
| Criterio | Evidencia | Puntos |
|---|---|---|
| Estructura y documentación | README útil, .gitignore pertinente y proyecto reproducible |
1,5 |
| Historia local | Commits pequeños, mensajes comprensibles y cambios revisables | 2,0 |
| Ramas e integración | Ramas de tarea, merge correcto y conflicto resuelto y explicado | 2,0 |
| Remoto y sincronización | Publicación de ramas, uso correcto de fetch/push y sin sobrescrituras |
1,5 |
| Entrega de versión | Tag anotado v1.0.0 publicado y estado final coherente |
1,0 |
| Seguridad y recuperación | Decisión razonada entre restore, revert, reset o reflog |
1,0 |
| Defensa individual | Explica con precisión su contribución y el estado local/remoto | 1,0 |
Total: 10 puntos. Criterio de superación: 5/10, sin obtener 0 en historia local, en ramas e integración ni en seguridad y recuperación. La calificación es individual, aunque el repositorio sea compartido.
Cómo se comprueba cada criterio
Para que la evaluación sea reproducible, estas son las comprobaciones sobre el repositorio entregado:
git log --oneline --graph --all # ramas, merges y legibilidad
git log --format="%an" | sort | uniq -c # reparto real de la contribución
git ls-remote --tags origin # tag publicado
git log -S "<<<<<<<" --oneline # marcadores de conflicto confirmados
git log --diff-filter=A --name-only --format="" | sort -u # qué se llegó a añadirLa cuarta detecta el error más penalizado de todos: confirmar un archivo con los marcadores de conflicto dentro. La quinta revela dependencias o secretos que llegaron al historial aunque después se borraran.
Qué debe saber hacer el alumnado
Al terminar, debe poder organizar un trabajo en ramas, revisar e integrar contribuciones ajenas, sincronizar un remoto sin sobrescribir trabajo, preparar una versión etiquetada y justificar una decisión segura ante un error propio ya publicado.
Estado editorial: listo.
Registro de revisión técnica
Revisado el 4 de agosto de 2026 con Git 2.47.1. La demostración se ha reproducido íntegra desde una carpeta vacía, con identidad de práctica y configuración aislada. Se ha comprobado que:
- La secuencia de arranque, publicación de la rama,
merge --no-ff, tag anotado ygit push origin main --tagsfunciona tal cual: un solo comando publica la rama y la etiqueta, ygit ls-remote --tagsdevuelve las dos líneas propias de un tag anotado. - El conflicto de integración se provoca de forma fiable haciendo que las dos ramas escriban la misma línea de
index.html, y se cierra congit add+git commit.
Corrección aplicada. El borrador indicaba revisar la contribución con git diff main..origin/feat/listado-actividades, con dos puntos. Reproducido con main avanzada por su cuenta, ese comando informa de README.md | 4 ----: presenta como si la rama borrara un archivo que nunca tocó, que es justo el falso negativo capaz de hundir una revisión. Con tres puntos (main...rama) el resultado es el correcto, solo inscripcion.html. Se ha corregido y explicado en el propio módulo y en los errores frecuentes, en coherencia con lo que ya enseña el módulo 5.
Decisiones incorporadas. La forja es GitHub, así que se han sustituido las referencias genéricas a «la forja elegida» por instrucciones concretas: creación del repositorio, alta de colaboradores, clonado y flujo de pull request. Se ha añadido la configuración de identidad por repositorio, que en aulas con equipos compartidos es la causa habitual de que la contribución individual no se pueda leer del historial —y la rúbrica la califica individualmente—. Se han añadido también los comandos de comprobación de la rúbrica y enlaces cruzados a los módulos 4, 5, 6 y 7.
Pendiente al disponer del repositorio del curso: ensayar el flujo completo de pull request con dos cuentas y decidir si la protección de main se exige o se deja como recomendación.