Definición de "aguas abajo" y "aguas arriba"


902

He comenzado a jugar con Git y he encontrado los términos "upstream" y "downstream". Los he visto antes pero nunca los entendí completamente. ¿Qué significan estos términos en el contexto de SCM ( herramientas de gestión de configuración de software ) y el código fuente?


13
Hay dos contextos diferentes para upstream / downstream en git: controles remotos y tiempo / historia. En sentido ascendente / descendente con respecto a los controles remotos, el repositorio descendente se extraerá del repositorio ascendente (los cambios fluirán en sentido descendente naturalmente). Río arriba / río abajo con respecto al tiempo / historia puede ser confuso, porque río arriba en el tiempo significa río abajo en la historia, y viceversa (la terminología de la genealogía funciona mucho mejor aquí - padre / ancestro / hijo / descendiente).
charlesreid1


55
Relacionado: Diferencia entre origen y upstream en gitHub
RBT

Respuestas:


703

En términos de control de fuente, está " aguas abajo " cuando copia (clona, ​​finaliza la compra, etc.) desde un repositorio. La información fluyó "aguas abajo" hacia usted.

Cuando realiza cambios, generalmente desea enviarlos de vuelta "en sentido ascendente " para que lleguen a ese repositorio de modo que todos los que extraen de la misma fuente estén trabajando con los mismos cambios. Esto es principalmente una cuestión social de cómo todos pueden coordinar su trabajo en lugar de un requisito técnico de control de fuente. Desea obtener sus cambios en el proyecto principal para no seguir líneas de desarrollo divergentes.

A veces leerá acerca de los administradores de paquetes o versiones (las personas, no la herramienta) hablando sobre cómo enviar cambios a "upstream". Eso generalmente significa que tuvieron que ajustar las fuentes originales para poder crear un paquete para su sistema. No quieren seguir haciendo esos cambios, por lo que si los envían "aguas arriba" a la fuente original, no deberían tener que lidiar con el mismo problema en la próxima versión.


116
"Descargar" y "subir" son verbos. "Upstream" y "downstream" describen una posición relativa.
brian d foy

2
Diría que aguas arriba y aguas abajo son adjetivos
Crt

8
Son adjetivos cuando se usan como modificadores, pero esos términos a menudo se usan como sustantivos.
brian d foy

2
Las palabras @MycrofD se pueden usar como adjetivos y sustantivos según el contexto
reggaeguitar

1
Esto es principalmente un problema social más que un requisito técnico . Entonces, ¿por qué hay una opción -ucomo git push --set-upstream origin mastersi no es un requisito técnico ? Podemos push -u origino no push origin, por lo que es un requisito tecnológico. Pero cual es la diferencia?
Verde

249

Cuando lees en la git tagpágina man :

Un aspecto importante de git es que está distribuido, y estar distribuido en gran medida significa que no hay un "flujo ascendente" o "flujo descendente" inherente en el sistema.

, eso simplemente significa que no hay un repositorio absoluto ascendente o un repositorio descendente.
Esas nociones son siempre relativas entre dos repositorios y dependen de la forma en que fluyen los datos:

Si "yourRepo" ha declarado "otherRepo" como uno remoto, entonces :

  • está tirando de "otherRepo" aguas arriba ("otherRepo" es "aguas arriba de usted" y está "aguas abajo de otherRepo").
  • está presionando hacia arriba ("otherRepo" todavía está "arriba", donde la información ahora vuelve a).

Tenga en cuenta el "desde" y "para": usted no es sólo "aguas abajo", usted es "aguas abajo de / para ", de ahí el aspecto relativo.


El giro del DVCS (Sistema de control de versiones distribuido) es: no tiene idea de qué es realmente en sentido descendente, además de su propio repositorio en relación con los repositorios remotos que ha declarado.

  • usted sabe qué es aguas arriba (los repositorios de los que está tirando o empujando)
  • no sabes de qué está hecho aguas abajo (los otros repositorios se mueven o empujan hacia tu repositorio ).

Básicamente:

En términos de " flujo de datos ", su repositorio está en la parte inferior ("aguas abajo") de un flujo que proviene de repositorios ascendentes ("pull from") y regresa a (el mismo u otro) repositorios ascendentes ("push to" )


Puede ver una ilustración en la git-rebasepágina del manual con el párrafo "RECUPERANDO DE LA REEMBOLSO DE UPSTREAM":

Significa que se está retirando de un repositorio "en sentido ascendente" donde se realizó un rebase , y usted (el repositorio "en sentido descendente" está atascado con la consecuencia (muchos commits duplicados, porque la rama rebaseada en sentido ascendente recreó los commits de la misma rama que usted) tener localmente).

Eso es malo porque para un repositorio "ascendente", puede haber muchos repositorios descendentes (es decir, repos que se extraen del repositorio ascendente, con la rama rebaseada), todos ellos potencialmente teniendo que lidiar con los commits duplicados.

Nuevamente, con la analogía del "flujo de datos", en un DVCS, un comando incorrecto "aguas arriba" puede tener un " efecto dominó " aguas abajo.


Nota: esto no se limita a los datos.
También se aplica a los parámetros , ya que los comandos git (como los de "porcelana") a menudo llaman internamente otros comandos git (los de "plomería"). Ver rev-parsepágina del manual :

Muchos comandos de git porcelainish toman una mezcla de banderas (es decir, parámetros que comienzan con un guión ' -') y parámetros destinados al subyacentegit rev-list comando que usan internamente y indicadores y parámetros para los otros comandos que usan aguas abajogit rev-list . Este comando se usa para distinguir entre ellos.


15
que tire de aguas arriba, y que empuja a aguas arriba. empujar hacia abajo me suena muy mal
knittl

1
@knittl: tienes razón. He reformulado mi respuesta para ilustrar mejor el papel del repositorio "ascendente" en relación con su propio repositorio local (y "descendente").
VonC

85

Seguimiento ascendente (en relación con)

El término upstream también tiene un significado inequívoco en el conjunto de herramientas GIT, especialmente en relación con el seguimiento

Por ejemplo :

   $git rev-list --count --left-right "@{upstream}"...HEAD
   >4   12

imprimirá (el último valor almacenado en caché) el número de confirmaciones detrás (izquierda) y delante (derecha) de su rama de trabajo actual, en relación con la rama remota ( si la hay ) que actualmente rastrea para esta rama local. De lo contrario, imprimirá un mensaje de error:

    >error: No upstream branch found for ''
  • Como ya se ha dicho, puede tener cualquier número de controles remotos para un repositorio local, por ejemplo, si bifurca un repositorio desde github, luego emite una 'solicitud de extracción', seguramente tendrá al menos dos: origin(su repositorio bifurcado en github) y upstream(el repositorio en github que bifurcó). Esos son solo nombres intercambiables, solo la url 'git @ ...' los identifica.

Sus .git/configlecturas:

   [remote "origin"]
       fetch = +refs/heads/*:refs/remotes/origin/*
       url = git@github.com:myusername/reponame.git
   [remote "upstream"]
       fetch = +refs/heads/*:refs/remotes/upstream/*
       url = git@github.com:authorname/reponame.git
  • Por otro lado, el significado de @ {upstream} para GIT es único:

es 'la rama' (si la hay) en 'dicho control remoto' , que está rastreando la 'rama actual' en su 'repositorio local' .

Es la rama de la que obtiene / extrae cada vez que emite un simple git fetch/ git pull, sin argumentos.

Digamos que desea establecer el origen / maestro de la sucursal remota para que sea la rama de seguimiento de la sucursal maestra local que ha extraído. Solo emite:

   $ git branch --set-upstream  master origin/master
   > Branch master set up to track remote branch master from origin.

Esto agrega 2 parámetros en .git/config :

   [branch "master"]
       remote = origin
       merge = refs/heads/master

ahora intente (siempre que el control remoto 'ascendente' tenga una rama 'dev')

   $ git branch --set-upstream  master upstream/dev
   > Branch master set up to track remote branch dev from upstream.

.git/config ahora lee:

   [branch "master"]
       remote = upstream
       merge = refs/heads/dev

git-push(1) Página manual :

   -u
   --set-upstream

Para cada rama que esté actualizada o que se haya enviado correctamente, agregue una referencia ascendente (seguimiento) , utilizada por git-pull (1) sin argumentos y otros comandos. Para más información, verbranch.<name>.merge en git-config (1).

git-config(1) Página manual :

   branch.<name>.merge

Define, junto con branch.<name>.remote, el rama ascendente para la rama dada. Le dice a git fetch / git pull / git rebase qué rama fusionar y también puede afectar a git push (ver push.default). \ (...)

   branch.<name>.remote

Cuando está en la rama <nombre>, le dice a git fetch y git push qué control remoto debe buscar / empujar a. El valor predeterminado es el origen si no hay ningún control remoto configurado. origen también se usa si no está en ninguna rama.

Upstream y Push (Gotcha)

echa un vistazo a la git-config(1)página del manual

   git config --global push.default upstream
   git config --global push.default tracking  (deprecated)

Esto es para evitar empujes accidentales a las ramas que aún no estás listo para empujar.


44
Extracto de a git branch --helppartir de 2018:As this option had confusing syntax, it is no longer supported. Please use --track or --set-upstream-to instead.
zezollo

59

Eso es un poco de terminología informal.

En lo que respecta a Git, cualquier otro repositorio es solo un control remoto.

En términos generales, aguas arriba es donde clonaste (el origen). Downstream es cualquier proyecto que integre su trabajo con otros trabajos.

Los términos no están restringidos a los repositorios de Git.

Por ejemplo, Ubuntu es un derivado de Debian, por lo que Debian está en sentido ascendente para Ubuntu.


51

Aguas arriba llamado nocivo

Hay, por desgracia, otro uso de "aguas arriba" al que las otras respuestas aquí no están llegando, es decir, para referirse a la relación padre-hijo de los compromisos dentro de un repositorio. Scott Chacon en el libro Pro Git es particularmente propenso a esto, y los resultados son desafortunados. No imites esta forma de hablar.

Por ejemplo, dice de una fusión que resulta en un avance rápido de que esto sucede porque

el compromiso señalado por la rama en la que se fusionó estaba directamente aguas arriba del compromiso en el que está

Quiere decir que cometer B es el único hijo del único hijo de ... del único hijo de cometer A, por lo que para fusionar B en A es suficiente mover la referencia A para señalar el compromiso B. ¿Por qué esta dirección? debería llamarse "aguas arriba" en lugar de "aguas abajo", o por qué la geometría de un gráfico de línea recta tan pura debe describirse "directamente aguas arriba", es completamente confusa y probablemente arbitraria. (La página del manual para git-mergehace un trabajo mucho mejor al explicar esta relación cuando dice que "el jefe de la sucursal actual es un antepasado del commit nombrado". Ese es el tipo de cosas que Chacon debería haber dicho).

De hecho, el propio Chacon parece usar "aguas abajo" más adelante para significar exactamente lo mismo, cuando habla de reescribir todas las confirmaciones secundarias de una confirmación eliminada:

Debe reescribir todas las confirmaciones posteriores de 6df76 para eliminar completamente este archivo de su historial de Git

Básicamente, parece no tener una idea clara de lo que quiere decir "aguas arriba" y "aguas abajo" cuando se refiere a la historia de los compromisos a lo largo del tiempo. Este uso es informal, entonces, y no debe fomentarse, ya que es confuso.

Está perfectamente claro que cada commit (excepto uno) tiene al menos un padre, y que los padres de los padres son antepasados; y en la otra dirección, los commits tienen hijos y descendientes. Esa es la terminología aceptada, y describe la direccionalidad del gráfico de manera inequívoca, por lo que esa es la forma de hablar cuando desea describir cómo se relacionan los commits entre sí dentro de la geometría del gráfico de un repositorio. No utilice "aguas arriba" o "aguas abajo" sin apretar en esta situación.

[Nota adicional: He estado pensando en la relación entre la primera oración de Chacon que cito arriba y la git-mergepágina del manual, y se me ocurre que la primera puede estar basada en un malentendido de la segunda. La página de manual continúa describiendo una situación en la que el uso de "upstream" es legítimo: el avance rápido a menudo ocurre cuando "está rastreando un repositorio de upstream, no ha cometido cambios locales y ahora desea actualizar a uno más nuevo revisión aguas arriba ". Entonces quizás Chacon usó "río arriba" porque lo vio aquí en la página del manual. Pero en la página del manual hay un repositorio remoto; no hay un repositorio remoto en el ejemplo citado de Chacon de avance rápido, solo un par de sucursales creadas localmente.]


14
La página de manual de git-rebase también sufre de esta sobrecarga: el commit que se desprotege antes de rebase se denomina "upstream". Esto también puede haber afectado el uso de Chacon.
outis

@outis strange: en la documentación de git html, la rama se desprotegió antes de referirse a rebase <branch>.
Jesper Matthiesen

Buen punto. Sería un poco útil reunir "terminología git" común en alguna parte. Especialmente para novatos (o personas que contribuyen a git). Me hubiera ahorrado un buen tiempo acostumbrarme a la redacción de las páginas de manual de git.
SebNag


1
Vine aquí desde los git-rebasedocumentos porque estaba totalmente confundido por qué una referencia de confirmación se llamaría "ascendente" allí (de hecho, dudaba de mí mismo ya que no había visto esta terminología antes). ¡Gracias @outis y @matt por aclarar las cosas!
Borek Bernard

-1

En general;

  • aguas arriba es hacia la fuente
  • aguas abajo es hacia el fregadero o destino

Esto se aplica a todos los sistemas en forma de árbol, incluidos los sistemas de control de origen.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.