<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Troubleshooting on kenji.blog</title><link>http://kenji.blog/es/tags/troubleshooting/</link><description>Recent content in Troubleshooting on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>es</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 17:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/es/tags/troubleshooting/index.xml" rel="self" type="application/rss+xml"/><item><title>Colección de errores comunes y comandos de solución para principiantes de Git (resolución de conflictos, etc.)</title><link>http://kenji.blog/es/p/git-beginners-mistakes-and-solutions/</link><pubDate>Sat, 12 Sep 2026 17:00:00 +0900</pubDate><guid>http://kenji.blog/es/p/git-beginners-mistakes-and-solutions/</guid><description>&lt;img src="http://kenji.blog/p/git-beginners-mistakes-and-solutions/img/eyecatch.jpg" alt="Featured image of post Colección de errores comunes y comandos de solución para principiantes de Git (resolución de conflictos, etc.)" />&lt;h1 id="colección-de-errores-comunes-y-comandos-de-solución-para-principiantes-de-git-resolución-de-conflictos-etc">Colección de errores comunes y comandos de solución para principiantes de Git (resolución de conflictos, etc.)
&lt;/h1>&lt;h2 id="1-introducción-por-qué-cometemos-errores-en-git">1. Introducción: ¿Por qué cometemos errores en Git?
&lt;/h2>&lt;p>En el desarrollo de software, Git se ha convertido en algo tan indispensable como el aire o el agua. Sin embargo, para muchos principiantes (y a veces incluso para los expertos), Git puede parecer una &amp;ldquo;caja negra mágica y aterradora&amp;rdquo;. Los commits desaparecen, subes un montón de cambios en la rama equivocada o mensajes de error de conflictos que nunca has visto antes llenan la pantalla&amp;hellip; Cuando caes en estas &amp;ldquo;trampas de Git&amp;rdquo;, el progreso de tu trabajo se detiene por completo y, en el peor de los casos, te invade el miedo de haber destruido el código fuente.&lt;/p>
&lt;p>¿Por qué Git es tan difícil y propenso a inducir errores? La razón principal es que &amp;ldquo;usamos comandos superficiales de memoria sin entender lo que está sucediendo dentro de Git&amp;rdquo;. Git se basa en una filosofía de diseño robusta como un Sistema de Control de Versiones Distribuido (DVCS), pero su interfaz (CLI) no siempre es intuitiva.&lt;/p>
&lt;p>En este artículo, clasificaremos los &amp;ldquo;errores comunes&amp;rdquo; que los principiantes de Git encuentran frecuentemente en el trabajo en múltiples casos y proporcionaremos los comandos específicos para resolver cada uno de ellos. Sin embargo, no será una simple lista de comandos (hoja de trucos). Profundizaremos en &amp;ldquo;por qué ocurre ese error&amp;rdquo; y &amp;ldquo;cómo se mueven los datos dentro de Git cuando ejecutas ese comando&amp;rdquo; a lo largo de más de 10,000 caracteres, incluyendo la estructura del directorio &lt;code>.git&lt;/code>, el trasfondo matemático del algoritmo Diff que se ejecuta en segundo plano y diagramas usando Mermaid.&lt;/p>
&lt;p>Cuando termines de leer este artículo hasta el final, te liberarás del sentimiento de que &amp;ldquo;Git da miedo&amp;rdquo; y, en cambio, estarás seguro de que &amp;ldquo;no hay un compañero más confiable que Git&amp;rdquo;. Entonces, sumerjámonos en el profundo mundo de Git.&lt;/p>
&lt;hr>
&lt;h2 id="2-el-abismo-de-git-entendiendo-la-estructura-interna-del-directorio-git">2. El abismo de Git: Entendiendo la estructura interna del directorio &lt;code>.git&lt;/code>
&lt;/h2>&lt;p>El primer paso para facilitar la resolución de muchos problemas es saber cómo Git guarda los datos. La carpeta oculta &lt;code>.git&lt;/code> que se encuentra en el directorio raíz de tu proyecto es el corazón de Git. Git no es un sistema que simplemente registra las diferencias (parches) de los archivos en orden, sino que gestiona los datos como un &lt;strong>flujo de instantáneas (snapshots)&lt;/strong>.&lt;/p>
&lt;h3 id="21-modelo-de-objetos-blob-tree-commit">2.1 Modelo de objetos: Blob, Tree, Commit
&lt;/h3>&lt;p>Git utiliza principalmente 3 objetos para representar el estado del repositorio. Estos objetos se guardan en &lt;code>.git/objects&lt;/code>.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Blob (Binary Large Object)&lt;/strong>
Es el objeto que guarda el contenido del archivo en sí. La información como el nombre del archivo y los permisos no se incluyen aquí. Es puramente una secuencia de bytes comprimida con zlib y se identifica mediante un valor hash SHA-1 (un número hexadecimal de 40 caracteres).&lt;/li>
&lt;li>&lt;strong>Tree&lt;/strong>
Es el objeto que representa la estructura del directorio. Un objeto Tree contiene punteros (valores hash SHA-1) a otros objetos Tree (subdirectorios) y objetos Blob (archivos), así como sus nombres de archivo y permisos de acceso. Desempeña un papel similar a un directorio de UNIX.&lt;/li>
&lt;li>&lt;strong>Commit&lt;/strong>
Contiene un puntero al objeto Tree de nivel superior de todo el repositorio en un momento dado, metadatos (autor, fecha y hora del commit, mensaje del commit) y un puntero al commit inmediatamente anterior (commit padre).&lt;/li>
&lt;/ol>
&lt;pre class="mermaid">
graph TD
Commit1[&amp;#34;Commit (Hash: 9f8a)&amp;#34;] --&amp;gt; Tree1[&amp;#34;Tree (Hash: 4b82)&amp;#34;]
Tree1 --&amp;gt; Blob1[&amp;#34;Blob (Hash: 8d7e) : index.js&amp;#34;]
Tree1 --&amp;gt; Tree2[&amp;#34;Tree (Hash: 3a2c) : src/&amp;#34;]
Tree2 --&amp;gt; Blob2[&amp;#34;Blob (Hash: 5f1b) : app.js&amp;#34;]
&lt;/pre>
&lt;h3 id="22-la-verdadera-naturaleza-de-head-y-las-referencias-refs">2.2 La verdadera naturaleza de HEAD y las referencias (Refs)
&lt;/h3>&lt;p>Al trabajar con Git, verás frecuentemente la palabra &lt;code>HEAD&lt;/code>. Esto es una &lt;strong>referencia simbólica (Symbolic Reference)&lt;/strong> que apunta a la rama (o commit) que tienes actualmente verificada (checked out).
Si abres el archivo &lt;code>.git/HEAD&lt;/code> con un editor de texto, verás una cadena como esta:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">ref: refs/heads/main
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Esto significa que &amp;ldquo;el estado actual se encuentra en la punta de la rama &lt;code>main&lt;/code>&amp;rdquo;. Y si abres &lt;code>.git/refs/heads/main&lt;/code>, verás escrito un hash SHA-1 de 40 caracteres, que apunta al objeto Commit más reciente.
Una rama de Git es simplemente un puntero ligero (un archivo) que apunta a un commit específico. Solo con saber este hecho, el miedo de que &amp;ldquo;si elimino la rama, se borrarán todos los archivos&amp;rdquo; desaparece.&lt;/p>
&lt;hr>
&lt;h2 id="3-descifrando-git-con-matemáticas-el-algoritmo-diff-y-las-funciones-hash">3. Descifrando Git con matemáticas: El algoritmo Diff y las funciones hash
&lt;/h2>&lt;p>Cuando Git detecta un conflicto o muestra la diferencia entre archivos, se están ejecutando algoritmos avanzados internamente.&lt;/p>
&lt;h3 id="31-algoritmo-diff-de-myers">3.1 Algoritmo Diff de Myers
&lt;/h3>&lt;p>El algoritmo de detección de diferencias predeterminado de Git es un algoritmo ideado por Eugene W. Myers. Cuando hay dos archivos de texto $A$ y $B$, el problema de encontrar la &amp;ldquo;secuencia mínima de ediciones (inserciones y eliminaciones)&amp;rdquo; para convertir $A$ en $B$ se puede modelar como un problema de la ruta más corta en la teoría de grafos.&lt;/p>
&lt;p>Sean las longitudes de las cadenas $N$ y $M$ respectivamente, y la suma sea $V = N + M$. En el algoritmo de Myers, se busca la distancia de edición (Edit Distance) $D$. La complejidad temporal de este algoritmo se expresa con la siguiente fórmula:&lt;/p>
$$ \mathcal{O}(V \cdot D) $$&lt;p>Aquí, si la diferencia entre los archivos es pequeña (es decir, $D$ es pequeña), el algoritmo se ejecuta a una velocidad muy alta $\mathcal{O}(V)$. Sin embargo, si los archivos son completamente diferentes, $D \approx V$, y la complejidad temporal en el peor de los casos es $\mathcal{O}(V^2)$.&lt;/p>
&lt;h3 id="32-patience-diff-e-histogram-diff">3.2 Patience Diff e Histogram Diff
&lt;/h3>&lt;p>El algoritmo de Myers es excelente, pero cuando se cambia significativamente el orden de funciones o clases, puede generar diferencias que no son intuitivas (no tienen sentido) para los humanos. Para solucionar esto, Git implementa &lt;code>Patience Diff&lt;/code> e &lt;code>Histogram Diff&lt;/code>.&lt;/p>
&lt;p>Patience Diff se centra en las &amp;ldquo;líneas únicas que aparecen solo una vez en ambos archivos&amp;rdquo; y encuentra la subsecuencia común más larga (Longest Common Subsequence: LCS) de esas líneas. Si el número de elementos únicos es $U$, el cálculo de LCS se puede resolver con la siguiente complejidad computacional:&lt;/p>
$$ \mathcal{O}(U \log U) $$&lt;p>Cuando sientas que la resolución de un conflicto es difícil, una opción es usar &lt;code>git diff --histogram&lt;/code> o especificar este algoritmo en la estrategia de fusión (&lt;code>git merge -s recursive -X histogram&lt;/code>).&lt;/p>
&lt;h3 id="33-sha-1-y-la-probabilidad-de-colisiones">3.3 SHA-1 y la probabilidad de colisiones
&lt;/h3>&lt;p>Git gestiona todos los objetos con valores hash SHA-1. El tamaño del espacio hash es $2^{160}$. Si aproximamos la probabilidad de colisión de hash $p$ (que contenidos diferentes tengan el mismo valor hash) usando la paradoja del cumpleaños (Birthday Paradox), el número de objetos $k$ necesarios para que la probabilidad de colisión sea del 50% es el siguiente:&lt;/p>
$$ k \approx \sqrt{2 \ln(2)} \cdot 2^{80} \approx 1.2 \times 2^{80} $$&lt;p>Este es un número astronómico, y la probabilidad de que ocurra una colisión involuntaria en el desarrollo de software normal es prácticamente cero. Por lo tanto, Git funciona confiando en el valor hash como una &amp;ldquo;ID única absoluta&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="4-estudio-de-caso-1-he-hecho-un-commit-en-la-rama-equivocada">4. Estudio de caso 1: ¡He hecho un commit en la rama equivocada!
&lt;/h2>&lt;p>&lt;strong>【Situación】&lt;/strong>
Sin darte cuenta de que estabas trabajando en la rama &lt;code>main&lt;/code>, escribiste mucho código para una nueva función y, para colmo, hiciste un &lt;code>git commit&lt;/code>. ¡Se suponía que debías crear una rama llamada &lt;code>feature/login&lt;/code> y trabajar allí!&lt;/p>
&lt;h3 id="solución-git-reset-y-crear-una-rama">Solución: &lt;code>git reset&lt;/code> y crear una rama
&lt;/h3>&lt;p>En Git, los commits son objetos independientes y las ramas son solo punteros. Por lo tanto, puedes resolver esto al instante con la operación de &amp;ldquo;crear una nueva rama y luego retroceder el puntero de la rama actual&amp;rdquo;.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. Crear una nueva rama que apunte al commit actual (el commit hecho por error)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git branch feature/login
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. Retroceder el puntero de la rama main al commit anterior (HEAD~1)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Usando --keep, puedes restablecer de forma segura manteniendo los cambios no confirmados (uncommitted) en el directorio de trabajo.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git reset --keep HEAD~1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. Cambiar a la rama correcta&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git checkout feature/login
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="ilustración-qué-pasó-internamente">Ilustración: ¿Qué pasó internamente?
&lt;/h3>&lt;p>Visualicemos el movimiento de los punteros de rama en este momento usando &lt;code>gitGraph&lt;/code> de Mermaid.&lt;/p>
&lt;pre class="mermaid">
gitGraph
commit id: &amp;#34;Initial commit&amp;#34;
commit id: &amp;#34;Bugfix&amp;#34;
commit id: &amp;#34;Mistaken Commit&amp;#34; type: HIGHLIGHT
branch feature/login
checkout feature/login
checkout main
&lt;/pre>
&lt;p>Al principio, &lt;code>main&lt;/code> y &lt;code>HEAD&lt;/code> apuntaban a &amp;ldquo;Mistaken Commit&amp;rdquo;, pero con &lt;code>git branch feature/login&lt;/code>, se crea un nuevo puntero allí. Luego, con &lt;code>git reset&lt;/code>, solo el puntero &lt;code>main&lt;/code> vuelve a la posición &amp;ldquo;Bugfix&amp;rdquo;. No se ha eliminado ningún objeto en sí.&lt;/p>
&lt;hr>
&lt;h2 id="5-estudio-de-caso-2-quiero-deshacer-un-commit-que-ya-ha-sido-empujado-pushed">5. Estudio de caso 2: ¡Quiero deshacer un commit que ya ha sido empujado (pushed)!
&lt;/h2>&lt;p>&lt;strong>【Situación】&lt;/strong>
Cometiste un código lleno de errores escrito durante la madrugada impulsado por la tensión y, además, lo publicaste en el repositorio remoto con &lt;code>git push origin main&lt;/code>. Te das cuenta de un error crítico y palideces.&lt;/p>
&lt;h3 id="solución-1-git-revert-para-anular-la-historia-recomendado-y-seguro">Solución 1: &lt;code>git revert&lt;/code> para anular la historia (Recomendado y Seguro)
&lt;/h3>&lt;p>En el desarrollo en equipo, está estrictamente prohibido alterar el historial de commits ya empujados con comandos como &lt;code>git reset&lt;/code>. Incoherencias surgirán con los repositorios locales de otros desarrolladores. El enfoque correcto es &lt;strong>&amp;ldquo;crear un nuevo commit inverso que anule por completo los cambios del commit equivocado&amp;rdquo;&lt;/strong>. Esto es &lt;code>git revert&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Crear un commit que anule el último commit&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git revert HEAD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>main 7f3a8b2&lt;span class="o">]&lt;/span> Revert &lt;span class="s2">&amp;#34;Mensaje del commit equivocado&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="m">1&lt;/span> file changed, &lt;span class="m">1&lt;/span> insertion&lt;span class="o">(&lt;/span>+&lt;span class="o">)&lt;/span>, &lt;span class="m">10&lt;/span> deletions&lt;span class="o">(&lt;/span>-&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Empujar al remoto&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git push origin main
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;pre class="mermaid">
gitGraph
commit id: &amp;#34;Commit A&amp;#34;
commit id: &amp;#34;Commit B (Mistake)&amp;#34;
commit id: &amp;#34;Revert Commit B&amp;#34; type: REVERSE
&lt;/pre>
&lt;p>La historia sigue avanzando y solo el estado del código vuelve a su estado anterior.&lt;/p>
&lt;h3 id="solución-2-alterar-la-historia-con-git-push---force-with-lease">Solución 2: Alterar la historia con &lt;code>git push --force-with-lease&lt;/code>
&lt;/h3>&lt;p>Si acabas de empujar a una rama que solo tú estás usando, alterar la historia es aceptable.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Restablecer el commit localmente y arreglarlo&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git reset --hard HEAD~1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git add .
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git commit -m &lt;span class="s2">&amp;#34;Correct implementation&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Sobrescribir forzadamente el historial del remoto&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git push origin feature/login --force-with-lease
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;code>--force-with-lease&lt;/code> es un push forzado seguro para evitar el accidente de sobrescribir el trabajo de otra persona por error.&lt;/p>
&lt;hr>
&lt;h2 id="6-estudio-de-caso-3-quiero-cambiar-a-otra-rama-mientras-trabajo-la-magia-de-stash">6. Estudio de caso 3: Quiero cambiar a otra rama mientras trabajo (La magia de Stash)
&lt;/h2>&lt;p>&lt;strong>【Situación】&lt;/strong>
Estás implementando una nueva función en la rama &lt;code>feature/A&lt;/code>, pero el código fuente está a medias y ni siquiera compila. De repente, tu jefe te ordena: &amp;ldquo;¡Hay un error urgente en el entorno de producción en la rama &lt;code>main&lt;/code>, arréglalo ahora mismo!&amp;rdquo;.&lt;/p>
&lt;h3 id="solución-guardar-los-cambios-con-git-stash">Solución: Guardar los cambios con &lt;code>git stash&lt;/code>
&lt;/h3>&lt;p>&lt;code>git stash&lt;/code> es un comando que guarda los cambios no confirmados (uncommitted) en un área temporal.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. Guardar los cambios en los que estás trabajando&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git stash push -m &lt;span class="s2">&amp;#34;WIP: feature A partially implemented&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. Ahora es posible cambiar a la rama main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git checkout main
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ... (Realizas el trabajo de corrección de errores urgentes, commit, push) ...&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. Volver a la rama original cuando termines&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git checkout feature/A
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 4. Restaurar los cambios guardados&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git stash pop
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Cuando ejecutas &lt;code>git stash&lt;/code>, Git crea internamente dos objetos de commit especiales y los guarda en una referencia llamada &lt;code>refs/stash&lt;/code>. Es decir, al fin y al cabo, un Stash también es &amp;ldquo;un commit temporal sin nombre&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="7-estudio-de-caso-4-el-aterrador-estado-de-detached-head">7. Estudio de caso 4: El aterrador estado de &amp;ldquo;Detached HEAD&amp;rdquo;
&lt;/h2>&lt;p>&lt;strong>【Situación】&lt;/strong>
Querías comprobar el código de un punto específico en el pasado y ejecutaste &lt;code>git checkout 9f8a7b6&lt;/code>. Entonces apareció el mensaje &lt;code>You are in 'detached HEAD' state.&lt;/code>. Hiciste un commit así sin más, pero cuando cambiaste de rama, ¡el commit desapareció!&lt;/p>
&lt;h3 id="el-mecanismo-de-detached-head">El mecanismo de Detached HEAD
&lt;/h3>&lt;p>Normalmente, &lt;code>HEAD&lt;/code> apunta a una rama como &lt;code>refs/heads/main&lt;/code>. Sin embargo, si verificas (checkout) directamente un commit específico, &lt;code>HEAD&lt;/code> apuntará directamente al objeto del commit. A esto se le llama &lt;strong>Detached HEAD (HEAD separado o desprendido)&lt;/strong>.&lt;/p>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;Commit A&amp;#34;] --&amp;gt; B[&amp;#34;Commit B&amp;#34;]
B --&amp;gt; C[&amp;#34;Commit C&amp;#34;]
C --&amp;gt; D[&amp;#34;Commit D&amp;#34;]
BranchMain[&amp;#34;Rama: main&amp;#34;] --&amp;gt; D
HEAD[&amp;#34;HEAD&amp;#34;] --&amp;gt; B
style HEAD fill:#f9f,stroke:#333,stroke-width:4px
&lt;/pre>
&lt;p>Incluso si apilas commits en este estado, ninguna rama seguirá esos nuevos commits. En el momento en que cambies a otra rama, los nuevos commits se perderán.&lt;/p>
&lt;h3 id="solución-guardar-como-una-nueva-rama">Solución: Guardar como una nueva rama
&lt;/h3>&lt;p>Se soluciona creando una nueva rama en el lugar donde te encuentras actualmente.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Crear una nueva rama en la posición actual de HEAD y cambiar a ella&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git checkout -b feature/recovered-work
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="8-estudio-de-caso-5-resolución-de-conflictos-en-merge-y-rebase">8. Estudio de caso 5: Resolución de conflictos en Merge y Rebase
&lt;/h2>&lt;p>&lt;strong>【Situación】&lt;/strong>
Ejecutaste &lt;code>git merge&lt;/code> o &lt;code>git rebase&lt;/code> y apareció el mensaje &lt;code>CONFLICT (content)&lt;/code>, y el proceso se interrumpió.&lt;/p>
&lt;h3 id="la-diferencia-entre-merge-fusión-y-rebase-reestructuración">La diferencia entre Merge (Fusión) y Rebase (Reestructuración)
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>Merge (Fusión)&lt;/strong>
Realiza una fusión a tres bandas (3-way merge) utilizando los últimos commits de las dos ramas y un ancestro común, creando un commit de fusión.&lt;/li>
&lt;li>&lt;strong>Rebase (Reestructuración)&lt;/strong>
Guarda temporalmente los commits de la rama actual y los vuelve a aplicar en la punta del objetivo. La historia se vuelve lineal.&lt;/li>
&lt;/ol>
&lt;pre class="mermaid">
gitGraph
commit id: &amp;#34;M1&amp;#34;
commit id: &amp;#34;M2&amp;#34;
branch feature
checkout feature
commit id: &amp;#34;F1&amp;#34;
commit id: &amp;#34;F2&amp;#34;
checkout main
commit id: &amp;#34;M3&amp;#34;
merge feature
&lt;/pre>
&lt;h3 id="método-de-resolución-de-conflictos">Método de resolución de conflictos
&lt;/h3>&lt;p>En los archivos donde ocurrió un conflicto, se insertan marcadores como los siguientes:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span> &lt;span class="nx">HEAD&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">apiUrl&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://api.production.example.com&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">=======&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">apiUrl&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://api.staging.example.com&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span> &lt;span class="nx">feature&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="nx">api&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>El procedimiento de resolución es extremadamente simple.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Eliminar los marcadores y corregir con el código correcto.&lt;/strong>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">apiUrl&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">process&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">env&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">NODE_ENV&lt;/span> &lt;span class="o">===&lt;/span> &lt;span class="s1">&amp;#39;production&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">?&lt;/span> &lt;span class="s2">&amp;#34;https://api.production.example.com&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;https://api.staging.example.com&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>&lt;strong>Añadir el archivo resuelto al área de preparación (staging).&lt;/strong>
&lt;code>git add&lt;/code> tiene el papel de &amp;ldquo;decirle a Git que has resuelto el conflicto&amp;rdquo;.
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ git add index.js
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>&lt;strong>Completar el proceso.&lt;/strong>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># En el caso de merge&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git commit -m &lt;span class="s2">&amp;#34;Resolve merge conflict in index.js&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># En el caso de rebase&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git rebase --continue
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;/ol>
&lt;p>Si entras en pánico, siempre puedes cancelar con &lt;code>$ git merge --abort&lt;/code> o &lt;code>$ git rebase --abort&lt;/code>.&lt;/p>
&lt;hr>
&lt;h2 id="9-estudio-de-caso-6-el-historial-de-commits-es-un-desastre-git-rebase--i">9. Estudio de caso 6: ¡El historial de commits es un desastre! &lt;code>git rebase -i&lt;/code>
&lt;/h2>&lt;p>&lt;strong>【Situación】&lt;/strong>
Se han generado muchos commits pequeños como &amp;ldquo;Corrección de error tipográfico&amp;rdquo;, &amp;ldquo;Corrección de nuevo&amp;rdquo;, &amp;ldquo;Añadir prueba&amp;rdquo;, etc. Si fusionas a &lt;code>main&lt;/code> tal como está, el historial se ensuciará.&lt;/p>
&lt;h3 id="solución-rebase-interactivo">Solución: Rebase interactivo
&lt;/h3>&lt;p>Al usar &lt;code>git rebase -i&lt;/code> (interactive), puedes cambiar el orden de los commits pasados, combinar múltiples commits en uno (squash) o modificar el mensaje de un commit.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Organizar los últimos 3 commits&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git rebase -i HEAD~3
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Se abrirá un editor y se mostrará lo siguiente:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">pick 1a2b3c4 Corrección de error tipográfico
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pick 2b3c4d5 Corrección de nuevo
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pick 3c4d5e6 Añadir prueba
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Lo reescribes de la siguiente manera:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">pick 1a2b3c4 Implementación de la función X
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">squash 2b3c4d5 Corrección de nuevo
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">squash 3c4d5e6 Añadir prueba
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Cuando lo guardes y cierres, estos 3 commits se integrarán hermosamente en uno solo.&lt;/p>
&lt;hr>
&lt;h2 id="10-estudio-de-caso-7-no-sé-cuándo-se-introdujo-el-error-git-bisect">10. Estudio de caso 7: ¡No sé cuándo se introdujo el error! &lt;code>git bisect&lt;/code>
&lt;/h2>&lt;p>&lt;strong>【Situación】&lt;/strong>
Hay un error en la rama &lt;code>main&lt;/code> actual, pero todo era normal en el lanzamiento de hace un mes. Quieres identificar en qué commit se introdujo el error, ¡pero hay más de 100 commits y es imposible hacerlo manualmente!&lt;/p>
&lt;h3 id="solución-identificar-el-error-mediante-búsqueda-binaria">Solución: Identificar el error mediante búsqueda binaria
&lt;/h3>&lt;p>Git tiene una herramienta incorporada para encontrar el commit donde se introdujo un error utilizando una búsqueda binaria matemática (Binary Search). La complejidad temporal es $\mathcal{O}(\log N)$, por lo que, aunque haya 1000 commits, se puede identificar con unas 10 pruebas.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Iniciar la búsqueda&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git bisect start
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># El commit actual tiene el error (bad)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git bisect bad
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Hace un mes (por ejemplo, el hash era a1b2c3d) era normal (good)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git bisect good a1b2c3d
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Git revisará (checkout) automáticamente el commit intermedio, así que ejecutas tu prueba&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Si la prueba es exitosa:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git bisect good
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Si la prueba falla:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git bisect bad
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Simplemente repitiendo esto, Git te dirá exactamente &amp;ldquo;Este es el primer commit defectuoso (Bad commit)&amp;rdquo;. Cuando termines, vuelve al estado original con &lt;code>$ git bisect reset&lt;/code>.&lt;/p>
&lt;hr>
&lt;h2 id="11-la-red-de-seguridad-definitiva-git-reflog">11. La red de seguridad definitiva: &lt;code>git reflog&lt;/code>
&lt;/h2>&lt;p>La técnica final para cualquier &amp;ldquo;metedura de pata&amp;rdquo; en Git es &lt;code>git reflog&lt;/code>. Git registra todo el historial de operaciones locales (historial de movimientos de HEAD) durante un período de tiempo determinado. Incluso si has borrado una rama o has hecho un restablecimiento (reset) incorrecto, puedes encontrar el hash pasado con &lt;code>git reflog&lt;/code> y restaurarlo simplemente haciendo &lt;code>git reset --hard&lt;/code> allí.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ git reflog
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">9f8a7b6 &lt;span class="o">(&lt;/span>HEAD -&amp;gt; main&lt;span class="o">)&lt;/span> HEAD@&lt;span class="o">{&lt;/span>0&lt;span class="o">}&lt;/span>: commit: Add new feature
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1a2b3c4 HEAD@&lt;span class="o">{&lt;/span>1&lt;span class="o">}&lt;/span>: reset: moving to HEAD~1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="12-conclusión">12. Conclusión
&lt;/h2>&lt;p>Hemos explicado con gran detalle los errores comunes en los que suelen caer los principiantes de Git, los mecanismos de Git detrás de ellos y cómo resolverlos. Commits en la rama equivocada, anular commits ya empujados, aprovechar Stash, sobrevivir a Detached HEAD y resolver conflictos. Lo importante en todo esto es imaginar &amp;ldquo;qué objetos y punteros está manipulando Git en segundo plano&amp;rdquo;.&lt;/p>
&lt;p>La diferencia de los archivos se calcula mediante un riguroso algoritmo Diff expresado en fórmulas matemáticas, y la integridad de la historia está garantizada por funciones hash criptográficas. Si entiendes esta hermosa filosofía de diseño, te darás cuenta de que Git no es en absoluto una &amp;ldquo;caja negra incomprensible&amp;rdquo;, sino el escudo más fuerte para proteger firmemente tu código fuente.&lt;/p>
&lt;p>La próxima vez que pienses &amp;ldquo;¡Metí la pata!&amp;rdquo;, en lugar de entrar en pánico y cerrar la terminal, respira hondo y escribe &lt;code>git status&lt;/code>. Git siempre te ofrecerá pistas para la recuperación.&lt;/p></description></item></channel></rss>