tag remove remota rama que para crear cambiar git merge patch

remove - Git: ¿Cómo crear parches para una fusión?



git tag (5)

A partir de la solución de Philippe De Muyter, hice una versión que formatea los parches de la misma manera que git-format-patch (por lo que puedo decir). Simplemente configure RANGO en el rango deseado de confirmaciones (por ejemplo, origen ... HEAD) y vaya:

LIST=$(git log --oneline --first-parent --reverse ${RANGE}); I=0; IFS=$''/n''; for ITEM in ${LIST}; do NNNN=$(printf "%04d/n" $I); COMMIT=$(echo "${ITEM}" | sed ''s|^/([^ ]*/) /(.*/)|/1|''); TITLE=$(echo "${ITEM}" | sed ''s|^/([^ ]*/) /(.*/)|/2|'' | sed ''s|[ -/~]|-|g'' | sed ''s|--*|-|g'' | sed ''s|^/(./{52/}/).*|/1|''); FILENAME="${NNNN}-${TITLE}.patch"; echo "${FILENAME}"; git log -p --pretty=email --stat -m --first-parent ${COMMIT}~1..${COMMIT} > ${FILENAME}; I=$(($I+1)); done

Tenga en cuenta que si está utilizando esto con git-quiltimport, deberá excluir cualquier confirmación de fusión vacía o aparecerá el error "El parche está vacío. ¿Se dividió mal?"

Cuando uso git format-patch , no parece incluir combinaciones. ¿Cómo puedo realizar una combinación y luego enviarla por correo electrónico a alguien como un conjunto de parches?

Por ejemplo, digamos que fusiono dos ramas y realizo otra confirmación en la parte superior de la combinación:

git init echo "initial file" > test.txt git add test.txt git commit -m "Commit A" git checkout -b foo master echo "foo" > test.txt git commit -a -m "Commit B" git checkout -b bar master echo "bar" > test.txt git commit -a -m "Commit C" git merge foo echo "foobar" > test.txt git commit -a -m "Commit M" echo "2nd line" >> test.txt git commit -a -m "Commit D"

Esto crea el siguiente árbol:

B / / A M - D / / C

Ahora trato de verificar la confirmación inicial y reproducir los cambios anteriores:

git checkout -b replay master git format-patch --stdout master..bar | git am -3

Esto produce un conflicto de fusión. En este escenario, git format-patch master..bar solo produce 3 parches, omitiendo "Commit M". ¿Cómo trato con esto?

-Geoffrey Lee


Ampliando la respuesta de sun , llegué a un comando que puede producir una serie de parches similares a los que git format-patch produciría si pudiera, y que puede alimentar a git am para producir un historial con las confirmaciones individuales:

git log -p --pretty=email --stat -m --first-parent --reverse origin/master..HEAD | / csplit -b %04d.patch - ''/^From [a-z0-9]/{40/} .*$/'' ''{*}'' rm xx0000.patch

Los parches se xx0001.patch a xxLAST.patch


Parece que no hay una solución que produzca confirmaciones individuales para el git format-patch , pero FWIW, puede formatear un parche que contenga la confirmación de fusión efectiva, adecuada / compatible con git am :

Al parecer, la guía de referencia de Git proporciona la primera pista:

git log -p muestra el parche introducido en cada confirmación

[...] Eso significa que para cualquier confirmación puede obtener el parche que se introdujo en el proyecto. Puede hacer esto ejecutando git show [SHA] con una confirmación específica SHA, o puede ejecutar git log -p , que le dice a Git que coloque el parche después de cada confirmación. [...]

Ahora, la página de manual de git-log da la segunda pista:

git log -p -m --first-parent

... Muestra el historial, incluidos los cambios de diferencias, pero solo desde la perspectiva de la "rama principal", omitiendo confirmaciones que provienen de las ramas fusionadas y mostrando las diferencias completas de los cambios introducidos por las combinaciones. Esto tiene sentido solo cuando se sigue una política estricta de fusionar todas las ramas temáticas al permanecer en una sola rama de integración.

Lo que a su vez significa en pasos concretos:

# Perform the merge: git checkout master git merge feature ... resolve conflicts or whatever ... git commit # Format a patch: git log -p --reverse --pretty=email --stat -m --first-parent origin/master..HEAD > feature.patch

Y esto se puede aplicar según lo previsto:

git am feature.patch

Nuevamente, esto no contendrá los compromisos individuales, pero produce un parche git am compatible con un compromiso de combinación.

Por supuesto, si no necesitas un parche compatible con git am en primer lugar, entonces es mucho más sencillo:

git diff origin/master > feature.patch

Pero supongo que ya lo pensó, y si llegó a esta página aquí, en realidad está buscando la solución / solución que he descrito anteriormente. ;)


Si examinas el contenido de los dos primeros parches, verás el problema:

diff --git a/test.txt b/test.txt --- a/test.txt +++ b/test.txt @@ -1 +1 @@ -initial file +foo diff --git a/test.txt b/test.txt index 7c21ad4..5716ca5 100644 --- a/test.txt +++ b/test.txt @@ -1 +1 @@ -initial file +bar

Desde la perspectiva de la rama en la que estaba trabajando en ese momento (foo y bar), ambas de estas confirmaciones han eliminado la línea del "archivo inicial" y la han reemplazado con algo completamente distinto. AFAIK, no hay forma de evitar este tipo de conflicto cuando genera un parche de una progresión no lineal con cambios superpuestos (su rama confirma B y C en este caso).

La gente normalmente usa parches para agregar una única característica o corrección de errores de un buen estado de trabajo anterior: el protocolo de parches simplemente no es lo suficientemente sofisticado para manejar el historial de fusión como lo hace Git de forma nativa. Si desea que alguien vea su combinación, entonces necesita empujar / tirar entre las ramas para no dejar atrás el parche / dif.


Tenga en cuenta que un simple git log -p no mostrará ningún contenido de parche para la confirmación de fusión "M", pero el uso de git log -p -c no lo convence. Sin embargo, git format-patch no acepta ningún argumento análogo al -c (o --combined , -cc ) aceptado por git log .

Yo también me quedo perplejo.