From eed5b606fb1a65bddb9a3c26c0a6d16d19855d55 Mon Sep 17 00:00:00 2001 From: Jonathan Teran Carballo Date: Wed, 30 Sep 2026 23:53:18 -0300 Subject: [PATCH] refactor: update merge conflict detection strategy (merge --no-commit to merge-tree --write-tree) --- src/git_flow/command/merge.py | 11 +++-------- src/git_flow/git.py | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/git_flow/command/merge.py b/src/git_flow/command/merge.py index 6539bde..be32156 100644 --- a/src/git_flow/command/merge.py +++ b/src/git_flow/command/merge.py @@ -75,17 +75,12 @@ def show_commits_to_merge(target): def check_merge_conflicts(target: str): - merge_conflicts = Git("merge", target, ff=False, commit=False).code( - print="Realizando merge de prueba para verificar conflictos" - ) - - # Si el merge no llegó a realizarse (por ejemplo, "Already up to date") no hay nada que abortar - if Git.is_merging(): - Git("merge", abort=True).exec(print="Abortando merge de prueba") + merge_conflicts = Git.get_merge_conflicts(target, print="Verificando conflictos de merge") if merge_conflicts: + files = "\n".join(" - " + file for file in merge_conflicts) base.io_error( - f"La rama actual tiene conflictos con {target}.\n" + f"La rama actual tiene conflictos con {target}:\n{files}\n\n" f"Se recomienda mergear {target} a la rama actual, resolver los conflictos localmente,\n" "y ejecutar nuevamente este comando", title="Conflictos de merge", diff --git a/src/git_flow/git.py b/src/git_flow/git.py index d54965c..e4c99b0 100644 --- a/src/git_flow/git.py +++ b/src/git_flow/git.py @@ -64,9 +64,19 @@ class Git: return Git._get_references("heads/" + prefix) @staticmethod - def is_merging() -> bool: - """Indica si hay un merge en curso (existe MERGE_HEAD), con o sin conflictos.""" - return Git("rev-parse", "MERGE_HEAD", quiet=True, verify=True).code() == 0 + def get_merge_conflicts(target: str, print: str | None = None) -> list[str]: + """Archivos con conflictos al mergear target en HEAD. El merge se resuelve en memoria con + merge-tree, sin tocar el índice ni el worktree.""" + process = Git( + "merge-tree", "HEAD", target, write_tree=True, name_only=True, messages=False + )._get(print, check=False) + + # 0: sin conflictos, 1: con conflictos, otro: error (por ejemplo, historias sin relación) + if process.returncode not in (0, 1): + process.check_returncode() + + # Primera línea: OID del árbol resultante, luego los archivos en conflicto + return [l for l in process.stdout.splitlines()[1:] if l] @staticmethod def status():