2008-09-18 10 views
31

Así que si estoy usando ramas que son ramas remotas (con seguimiento), y quiero obtener las últimas, todavía no estoy claro si debería estar haciendo git pull o git rebase. Pensé que había leído que al hacer git rebase cuando trabajaba en una sucursal con otros usuarios, puede arruinarlos cuando extraen o vuelven a tener una base. ¿Es eso cierto? ¿Deberíamos todos estar usando git pull?Git - ¿es pull o rebase cuando se trabaja en ramas con otras personas?

Respuesta

48

Git tirón es una combinación de 2 comandos

  • git fetch (sincroniza tu repositorio local con el nuevo material en el control remoto)
  • git merge (combina los cambios de la rama distante, en su caso, en su sucursal de seguimiento local)

git rebase es solo un equivalente aproximado de git merge. No capta nada de forma remota. De hecho, tampoco realiza una combinación adecuada, sino que reproduce las confirmaciones de la rama en la que se encuentra después de las nuevas confirmaciones de una segunda rama.

Su propósito es principalmente permitirle tener un historial más limpio. Muchas personas no necesitan muchas fusiones antes de que la historia pasada en gitk se vuelva terriblemente espaguetis.

La mejor explicación gráfica se puede ver en los primeros 2 gráficos here. Pero déjame explicarte aquí con un ejemplo.

Tengo 2 sucursales: master y mybranch. Al estar de pie en MyBranch puedo correr

git rebase master 

y voy a conseguir nada nuevo en el master se inserta delante de mis más recientes comete en MyBranch. Esto es perfecto, porque si ahora fusiono o rebase las cosas de mybranch en master, mis nuevas confirmaciones se agregan linealmente justo después de las confirmaciones más recientes.

El problema al que se refiere ocurre si rebase en la dirección "incorrecta". Si acabo de recibir la más reciente principal (con nuevos cambios) y de maestro que rebase así (antes de sincronizar mi sucursal):

git rebase mybranch 

Ahora lo que he hecho es que he insertado mis nuevos cambios en alguna parte en el pasado de maestro .La línea principal de confirmaciones ha cambiado. Y debido a la forma en que git funciona con los identificadores de commit, todos los commits (desde el máster) que se repitieron sobre mis nuevos cambios tienen nuevos ids.

Bueno, es un poco difícil de explicar sólo con palabras ... Espero que esto tiene un poco de sentido :-)

De todos modos, mi propio flujo de trabajo es la siguiente:

  • 'git pull' nuevos cambios de control remoto del interruptor
  • a MyBranch
  • 'git rebase master' para traer nuevos cambios de maestría en mi cometer historia interruptor
  • volver a dominar
  • 'git merge MyBranch', que sólo avanza rápidamente cuando todo en el maestro es también en MyBranch (evitando así el problema de cometer reordenamiento en una rama pública)
  • 'git push'

Una última palabra. Recomiendo usar rebase cuando las diferencias sean triviales (por ejemplo, personas que trabajan en archivos diferentes o al menos en líneas diferentes). Tiene el gotcha que traté de explicar justo arriba, pero hace una historia mucho más limpia.

Tan pronto como pueda haber conflictos importantes (por ejemplo, un compañero de trabajo ha cambiado el nombre de un grupo de archivos), recomiendo fusionar. En este caso, se te pedirá que resuelvas el conflicto y luego confirmes la resolución. En el lado positivo, una fusión es mucho más fácil de resolver cuando hay conflictos. La desventaja es que su historia puede ser difícil de seguir si mucha gente se funde todo el tiempo :-)

¡Buena suerte!

+1

Me parece que debería haber dicho: 'git _merge_ mybranch', que solo avanza rápidamente cuando todo en master también está en mybranch (evitando así el problema de reordenamiento de commit en una rama pública) –

+0

'git rebase mybranch' definitivamente debería leer 'git merge mybranch'. –

6

git pull realiza una combinación si tiene commits que no están en la rama remota. git rebase reescribe cualquier confirmación existente que tiene que ser relativa a la punta de la rama remota. Son similares en que ambos pueden causar conflictos, pero creo que usar git rebase si puede permite una colaboración más fluida. Durante la operación de rebase puede refinar sus confirmaciones para que se vean como si se hubieran aplicado recientemente a la última revisión de la rama remota. Una combinación es quizás más apropiada para ciclos de desarrollo más largos en una rama que tiene más historial.

Como la mayoría de las otras cosas en git, hay una gran cantidad de funcionalidad que se superpone para adaptarse a diferentes estilos de trabajo.

0

Si desea extraer la fuente sin afectar ramas remotas y sin ningún cambio en su copia local, lo mejor es usar git pull.

Creo que si tienes una rama activa a la que hayas realizado cambios, usa git rebase para cambiar la base de esa rama para que sea la última maestra remota, mantendrás todos los cambios de rama, sin embargo la rama ahora estará que se ramifica desde la ubicación principal, en lugar de desde donde anteriormente se ramificó.

10

Git rebase es una reescritura de la historia. Nunca debe hacer esto en sucursales que son "públicas" (es decir, sucursales que comparte con otros). Si alguien clona su sucursal y luego vuelve a establecer la base de esa sucursal, entonces ya no podrá extraer/fusionar los cambios de su sucursal, tendrá que tirar la anterior y volver a tirar.

Este artículo en packaging software with git es una lectura muy útil. Se trata más de gestionar las distribuciones de software, pero es bastante técnico y habla de cómo se pueden usar/administrar/compartir las sucursales. Hablan sobre cuándo volver a establecer la base y cuándo extraer, y cuáles son las diversas consecuencias de cada una.

En resumen, ambos tienen su lugar, pero es necesario realmente asimilar la diferencia.

+0

¿Es esto cierto, @Pat? En el caso de una extracción --rebase, ¿no estás reordenando tus compromisos locales para estar al tanto de lo que sacaste? Dado que esos fueron compromisos locales, y aún no se publicaron, ¿cómo van a romper a alguien que intenta tirar después de que 'tire --rebase''edó? –

+1

El problema es si alguien más extrae de una sucursal que luego vuelve a establecer. Está bien si saco de 'A' a 'local' y luego rebase 'local', y alguien más saca de' A'. No está bien si saco de 'A', alguien más saca de' local', luego rebase 'local'. –

+1

En resumen, no rebase las confirmaciones que vivan en otros repositorios. – Ikke

Cuestiones relacionadas