{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Trabajar en dos cosas a la vez\n",
    "\n",
    "Las ramas, que son mucho más simples de lo que parecen\n",
    "\n",
    "Cuaderno de soluciones del capítulo 10 de **Git desde cero**, de Miss Yera.\n",
    "\n",
    "Corre de arriba abajo. Si lo abres en Google Colab no necesitas instalar nada.\n",
    "\n",
    "Capítulo completo: https://missyera.com/guias/git-desde-cero/ramas/\n",
    "\n",
    "Este es el cuaderno de **soluciones**. Trae el código de cada ejercicio, la\n",
    "explicación de la trampa y la respuesta del quiz. Si vienes del cuaderno de\n",
    "práctica sin haberlo intentado, vuelve 🙂"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Antes de empezar\n",
    "\n",
    "Este capítulo son comandos de terminal, no Python. La celda de abajo baja el\n",
    "ayudante que los ejecuta y que **recuerda en qué carpeta quedaste**, que es lo\n",
    "que hace falta para que un `cd` de una celda siga valiendo en la siguiente.\n",
    "\n",
    "A partir de ahí, cada celda de comandos empieza por `%%consola`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import urllib.request\n",
    "\n",
    "# El ayudante de los cuadernos. Trae la corrección de los ejercicios y, en los\n",
    "# capítulos de consola, la celda mágica que ejecuta los comandos. Se baja en\n",
    "# vez de venir pegado aquí para que siempre sea el último.\n",
    "urllib.request.urlretrieve(\n",
    "    \"https://missyera.com/static/cuadernos/revisa.py\", \"revisa.py\")\n",
    "import revisa\n",
    "revisa.carga({}, lenguaje=\"bash\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Para qué sirven"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Estás con el reporte nuevo y llega un arreglo urgente. Con una sola rama\n",
    "tienes las dos cosas mezcladas en la misma carpeta y no puedes entregar una sin\n",
    "la otra.\n",
    "\n",
    "Con ramas trabajas en dos líneas de tiempo distintas y saltas entre ellas."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "mkdir tienda\n",
    "cd tienda\n",
    "git init -q\n",
    "printf 'ciudad,monto\\nLima,1200\\n' > ventas.csv\n",
    "git add ventas.csv\n",
    "git commit -q -m \"Primeras ventas de Lima\"\n",
    "git branch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Una sola rama, `main`, y el asterisco dice que estás en ella."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Crear y entrar, en un solo movimiento"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "git switch -c reporte-por-canal\n",
    "git branch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "El `-c` es de crear. Ojo con esto porque es donde más gente se\n",
    "tropieza: `git branch nombre` crea la rama pero **no te lleva a\n",
    "ella**, y terminas haciendo los commits en el sitio equivocado.\n",
    "\n",
    "Trabajo aquí:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "printf 'canal\\nbodega\\n' > canales.csv\n",
    "git add canales.csv\n",
    "git commit -q -m \"Se agrega el catalogo de canales\"\n",
    "git log --oneline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Y ahora el salto"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "git switch main\n",
    "ls\n",
    "git log --oneline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Aquí está la magia: `canales.csv` **no está**. No se\n",
    "borró, está en la otra rama. Tu carpeta cambia de contenido según dónde estés\n",
    "parada, y por eso hay que mirar en qué rama estás antes de empezar a trabajar 🧭\n",
    "\n",
    "Hago el arreglo urgente aquí, tranquila:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "printf 'Arequipa,890\\n' >> ventas.csv\n",
    "git add ventas.csv\n",
    "git commit -q -m \"Urgente, entran las ventas de Arequipa\"\n",
    "git log --all --oneline --graph"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dos líneas de tiempo que salieron del mismo punto. Juntarlas es el capítulo\n",
    "11."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Borrar una rama"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "git switch -c prueba\n",
    "git switch main\n",
    "git branch -d prueba\n",
    "git branch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Se borró sin quejarse porque no tenía nada que perder. Pero si la rama tiene\n",
    "commits que no están en ningún otro sitio, Git se planta:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Esto revienta a propósito**, y de eso va. La celda te muestra la queja igual que te la mostraría tu terminal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "git branch -d reporte-por-canal"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y la queja que tiene que salir es esta:\n",
    "\n",
    "```\n",
    "error: the branch 'reporte-por-canal' is not fully merged.\n",
    "If you are sure you want to delete it, run 'git branch -D reporte-por-canal'\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Not fully merged*: ahí dentro hay trabajo que no está en `main`.\n",
    "Ese aviso ha salvado muchísimo trabajo, y por eso la `-D` mayúscula\n",
    "conviene tratarla con el mismo respeto que `reset --hard`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### La trampa\n",
    "\n",
    "Te piden un cambio urgente en el reporte de ventas mientras estás a medias con otra cosa. Creas la rama para el arreglo urgente y te pones a trabajar.\n",
    "\n",
    "```\n",
    "$ git branch arreglo-urgente\n",
    "$ nano reporte.py         # haces el arreglo\n",
    "$ git add reporte.py\n",
    "$ git commit -m \"Arreglo urgente del reporte\"\n",
    "$ git branch\n",
    "\n",
    "  arreglo-urgente\n",
    "* main\n",
    "```\n",
    "\n",
    "**Qué está mal**\n",
    "\n",
    "El commit se fue a `main`, no a la rama 🌿\n",
    "\n",
    "`git branch` **crea** la rama pero no te lleva a ella. Es la diferencia entre poner un marcador en el mapa y caminar hasta ahí. Fíjate en el asterisco de la salida: sigue en `main`.\n",
    "\n",
    "Por eso en este libro siempre uso `git switch -c`, que crea y entra en el mismo movimiento. `git branch` a secas lo dejo solo para listar.\n",
    "\n",
    "Si ya te pasó no perdiste nada: el commit existe, solo está en la rama equivocada. Con lo del capítulo 7 y una rama nueva se mueve de sitio."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Comprueba que se entendió"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Comprueba que lo tienes\n",
    "\n",
    "Estás en una rama, haces `git switch main` y un archivo tuyo desaparece de la carpeta. ¿Qué pasó?\n",
    "\n",
    "a) Se borró y hay que recuperarlo\n",
    "\n",
    "b) Está en la otra rama, vuelve y aparece\n",
    "\n",
    "c) Git lo mandó al stash\n",
    "\n",
    "d) Hay que hacer un merge para recuperarlo\n",
    "\n",
    "---\n",
    "\n",
    "**La correcta es la b.**\n",
    "\n",
    "*a)* No se borró nada. Está guardado en el commit de la otra rama, esperando a que vuelvas.\n",
    "\n",
    "*c)* El stash solo guarda lo que tú le mandas a mano. Cambiar de rama no lo usa para nada.\n",
    "\n",
    "*d)* El merge sirve para juntar las dos ramas. Para volver a ver el archivo basta con volver a su rama.\n",
    "\n",
    "Tu carpeta enseña la rama donde estás parada, no todo lo que existe 🌳"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ejercicios"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Vuelve a tu rama y comprueba\n",
    "\n",
    "Regresa a la rama del reporte y mira que el archivo está."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "git switch reporte-por-canal\n",
    "ls"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "Switched to branch 'reporte-por-canal'\n",
    "canales.csv\n",
    "ventas.csv\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ahí estaba, sano y salvo. Cambiar de rama es gratis y no pierde nada, y eso\n",
    "es lo que hay que interiorizar."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Y que aquí falta lo urgente\n",
    "\n",
    "Mira el CSV de ventas en esta rama."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "cat ventas.csv"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "ciudad,monto\n",
    "Lima,1200\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Arequipa no está, porque ese commit vive en `main`. Las dos ramas\n",
    "tienen versiones distintas del mismo archivo y las dos son correctas."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Una rama por cada cosa\n",
    "\n",
    "Crea una tercera rama para el catálogo de clientes y haz un\n",
    "commit ahí."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "git switch main\n",
    "git switch -c catalogo-clientes\n",
    "printf 'bodega,ciudad\\nBodega Sol,Lima\\n' > clientes.csv\n",
    "git add clientes.csv\n",
    "git commit -q -m \"Se agrega el catalogo de bodegas\"\n",
    "git branch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "Switched to branch 'main'\n",
    "Switched to a new branch 'catalogo-clientes'\n",
    "* catalogo-clientes\n",
    "  main\n",
    "  reporte-por-canal\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tres ramas, tres asuntos separados. Este es el flujo normal de cualquier\n",
    "proyecto con más de una persona."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. Mira el árbol completo\n",
    "\n",
    "Dibuja todas las ramas a la vez."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "git log --all --oneline --graph"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "* 4152b62 Se agrega el catalogo de bodegas\n",
    "* 1976933 Urgente, entran las ventas de Arequipa\n",
    "| * c516683 Se agrega el catalogo de canales\n",
    "|/  \n",
    "* 54da6e2 Primeras ventas de Lima\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Se ve el tronco común y de dónde sale cada rama. Este dibujo es lo que uso\n",
    "para explicarle Git a alguien en dos minutos 🎨"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5. En qué rama estoy\n",
    "\n",
    "Pregunta solo el nombre de la rama actual."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "git branch --show-current"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "catalogo-clientes\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Un comando de una línea que evita la mitad de los accidentes. Yo lo tengo\n",
    "puesto en la propia terminal para verlo siempre."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6. Qué ramas ya están juntas con main\n",
    "\n",
    "Lista las ramas cuyo trabajo ya está en la rama actual."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "git switch main\n",
    "git branch --merged"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "Switched to branch 'main'\n",
    "* main\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solo aparece `main`, porque las otras dos tienen commits propios.\n",
    "Este comando dice cuáles se pueden borrar sin pensarlo."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 7. Intenta borrar una rama con trabajo dentro\n",
    "\n",
    "Prueba a borrar la del catálogo de clientes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "git branch -d catalogo-clientes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "error: the branch 'catalogo-clientes' is not fully merged.\n",
    "If you are sure you want to delete it, run 'git branch -D catalogo-clientes'\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Git te frena y te dice cómo insistir si de verdad quieres. Ese \"si estás\n",
    "segura\" es de las mejores cosas que tiene 🛑"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lo que te llevas"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Una rama es un nombre que apunta a un commit. Cambiar de rama no\n",
    "copia nada, mueve un puntero.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preguntas frecuentes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "¿Qué es una rama en Git?Una línea de trabajo paralela. Te llevas una copia de la historia, trabajas ahí sin tocar lo que funciona, y cuando está listo se junta.\n",
    "\n",
    "¿Cómo creo una rama?Con git switch -c y el nombre. La versión antigua es git checkout -b y hace lo mismo.\n",
    "\n",
    "¿Qué hace git merge?Junta el trabajo de una rama con otra. Si las dos tocaron la misma línea, aparece un conflicto y hay que decidir a mano cuál se queda.\n",
    "\n",
    "¿Cuál es la diferencia entre git pull y git fetch?fetch trae lo que hay en el remoto y no toca tus archivos. pull hace lo mismo y además lo junta con lo tuyo. Cuando algo sale raro, fetch primero y mirar."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "Ese era el capítulo 10 de **Git desde cero**. El texto completo, con las salidas de cada bloque, está en https://missyera.com/guias/git-desde-cero/ramas/\n",
    "\n",
    "Que tengas lindo día! 🌸"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
