From 67eb6fb6d1710b387f8f2cf807be8a8a7c6d4a6b Mon Sep 17 00:00:00 2001 From: Jonathan Teran Carballo Date: Sat, 26 Sep 2026 17:38:05 -0300 Subject: [PATCH] feature: show commit lists in merge and rebase in a table --- src/git_flow/command/base.py | 51 +++++++++++++++++++++++++++++++++ src/git_flow/command/merge.py | 10 +------ src/git_flow/command/release.py | 10 +------ 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/git_flow/command/base.py b/src/git_flow/command/base.py index 7a4ae7b..7c3b0c4 100644 --- a/src/git_flow/command/base.py +++ b/src/git_flow/command/base.py @@ -1,8 +1,11 @@ +import re +import time from os.path import isfile import questionary import rich import rich.panel +from rich.table import Table from git_flow import ( BRANCH_TYPES, @@ -162,6 +165,54 @@ def get_commit_message(commit_types: list[str] = COMMIT_TYPES) -> str: return commit_type + ": " + commit_message +# [(alcance)][!]: , para no confundir "Merge pull request 'feature: ...'" con un tipo +COMMIT_SUBJECT_RE = re.compile(r"^(\w+)(?:\([^)]*\))?!?:\s*(.*)$") + + +def show_commits(title: str, revision_range: str): + """Muestra en una tabla los commits del rango (fecha relativa, tipo y mensaje). + Si no hay commits aborta, ya que no hay nada para mergear.""" + # fecha de autor: la de commit cambia al hacer rebase (por ejemplo, en release) + lines = Git("log", revision_range, format="%at%x09%s").lines() + + if not lines: + raise GitFlowError("No hay cambios a mergear.") + + table = Table(title=title, title_justify="left", title_style="bold") + table.add_column("Fecha", style="dim", no_wrap=True) + table.add_column("Tipo", style="cyan", no_wrap=True) + table.add_column("Mensaje") + + now = time.time() + + for line in lines: + timestamp, subject = line.split("\t", 1) + match = COMMIT_SUBJECT_RE.match(subject) + commit_type, message = match.groups() if match else ("-", subject) + table.add_row(format_time_ago(now - int(timestamp)), commit_type, message) + + console.print(table) + + +def format_time_ago(seconds: float) -> str: + units = [ + (365 * 24 * 3600, "año", "años"), + (30 * 24 * 3600, "mes", "meses"), + (7 * 24 * 3600, "semana", "semanas"), + (24 * 3600, "día", "días"), + (3600, "hora", "horas"), + (60, "minuto", "minutos"), + ] + + for size, singular, plural in units: + amount = int(seconds // size) + + if amount >= 1: + return f"hace {amount} {singular if amount == 1 else plural}" + + return "hace un momento" + + def io_error(message: str, title: str | None = None): _io_status(message, "✖ Error: ", "red", title) diff --git a/src/git_flow/command/merge.py b/src/git_flow/command/merge.py index 2f0efee..454d4eb 100644 --- a/src/git_flow/command/merge.py +++ b/src/git_flow/command/merge.py @@ -71,15 +71,7 @@ def run_local(branch: str, target: str): def show_commits_to_merge(target): - commits = Git("log", target + "..", format="%s").lines() - - if not commits: - raise GitFlowError("No hay cambios a mergear.") - - print("Cambios a mergear:") - - for commit in commits: - print("- " + commit) + base.show_commits("Cambios a mergear", target + "..") def check_merge_conflicts(target: str): diff --git a/src/git_flow/command/release.py b/src/git_flow/command/release.py index 45e91a9..b0556d4 100644 --- a/src/git_flow/command/release.py +++ b/src/git_flow/command/release.py @@ -32,15 +32,7 @@ def release(): ) fork_point = Git.get_first_fork_point(branch, env) - commits = Git("log", fork_point + "..", format="%s").lines() - - if not commits: - raise GitFlowError("No hay cambios a mergear.") - - print("Cambios a pasar al proximo entorno:") - - for commit in commits: - print("- " + commit) + base.show_commits("Cambios a pasar al próximo entorno", fork_point + "..") if has_remote and Git.get_tracking_branch(next_env): Git("switch", next_env).exec(print="Cambiando a la rama objetivo")