add reset to commit from history tab
This commit is contained in:
parent
8d1d712785
commit
ad4fe4cf44
@ -137,6 +137,7 @@ class GitSvnSyncApp:
|
||||
merge_local_branch_cb=self.merge_local_branch,
|
||||
compare_branch_with_current_cb=self.compare_branch_with_current,
|
||||
view_commit_details_cb=self.view_commit_details,
|
||||
reset_to_commit_cb=self.repository_handler.handle_reset_to_commit if self.repository_handler else None,
|
||||
config_manager_instance=self.config_manager,
|
||||
profile_sections_list=self.config_manager.get_profile_sections(),
|
||||
)
|
||||
@ -178,6 +179,8 @@ class GitSvnSyncApp:
|
||||
self.main_frame.tags_tab.create_tag_callback = self.repository_handler.create_tag
|
||||
self.main_frame.tags_tab.checkout_tag_callback = self.repository_handler.checkout_tag
|
||||
self.main_frame.tags_tab.revert_to_tag_callback = self.repository_handler.revert_to_tag
|
||||
|
||||
self.main_frame.history_tab.reset_to_commit_callback = self.repository_handler.handle_reset_to_commit
|
||||
|
||||
self.main_frame.branch_tab.create_branch_callback = self.repository_handler.create_branch
|
||||
self.main_frame.branch_tab.checkout_branch_callback = self.repository_handler.checkout_branch
|
||||
|
||||
@ -20,7 +20,7 @@ import re
|
||||
from gitutility.logging_setup import log_handler
|
||||
from gitutility.commands.git_commands import GitCommandError
|
||||
from gitutility.async_tasks import async_workers
|
||||
from gitutility.config.config_manager import DEFAULT_REMOTE_NAME
|
||||
from ..core.wiki_updater import WikiUpdateStatus
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..app import GitSvnSyncApp
|
||||
@ -80,7 +80,7 @@ class AsyncResultHandler:
|
||||
"clone_remote": self._handle_clone_remote_result,
|
||||
"checkout_tracking_branch": self._handle_checkout_tracking_branch_result,
|
||||
"get_commit_details": self._handle_get_commit_details_result,
|
||||
"update_wiki": self._handle_generic_result,
|
||||
"update_wiki": self._handle_update_wiki_result,
|
||||
"revert_to_tag": self._handle_revert_to_tag_result,
|
||||
"analyze_history": self._handle_analyze_history_result,
|
||||
"purge_history": self._handle_purge_history_result,
|
||||
@ -92,6 +92,7 @@ class AsyncResultHandler:
|
||||
"init_submodules": self._handle_init_submodules_result,
|
||||
"force_clean_submodule": self._handle_force_clean_submodule_result,
|
||||
"clean_submodule": self._handle_clean_submodule_result,
|
||||
"reset_to_commit": self._handle_reset_to_commit_result,
|
||||
}
|
||||
|
||||
handler_method = handler_map.get(task_context)
|
||||
@ -107,6 +108,14 @@ class AsyncResultHandler:
|
||||
if should_trigger_refreshes:
|
||||
self.app._trigger_post_action_refreshes(post_action_sync_refresh_needed)
|
||||
|
||||
def _handle_reset_to_commit_result(self, result_data: Dict[str, Any], context: Dict[str, Any]) -> Tuple[bool, bool]:
|
||||
if result_data.get("status") == "success":
|
||||
self.main_frame.show_info("Operation Successful", result_data.get("message"))
|
||||
return True, True
|
||||
else:
|
||||
self.main_frame.show_error("Reset to Commit Error", f"Failed:\n{result_data.get('message')}")
|
||||
return False, False
|
||||
|
||||
def _handle_refresh_tags_result(self, result_data: Dict[str, Any], context: Dict[str, Any]) -> Tuple[bool, bool]:
|
||||
if result_data.get("status") == "success":
|
||||
self.main_frame.tags_tab.update_tag_list(result_data.get("result", []))
|
||||
@ -599,4 +608,24 @@ class AsyncResultHandler:
|
||||
statuses = result_data.get("result", {})
|
||||
self.main_frame.submodules_tab.update_remote_statuses(statuses)
|
||||
|
||||
return False, False
|
||||
|
||||
def _handle_update_wiki_result(self, result_data: Dict[str, Any], context: Dict[str, Any]) -> Tuple[bool, bool]:
|
||||
"""Handles the result of the update_wiki_from_docs async task."""
|
||||
status = result_data.get("status")
|
||||
message = result_data.get("message", "Wiki operation finished.")
|
||||
|
||||
if status == "success":
|
||||
# In our new implementation, 'success' is for both actual updates and no-changes scenarios
|
||||
self.main_frame.show_info("Wiki Update", message)
|
||||
# We only need to trigger a full refresh if something actually changed.
|
||||
# The result object from the worker now contains the detailed status.
|
||||
update_result = result_data.get("result")
|
||||
if update_result and update_result.status == WikiUpdateStatus.SUCCESS:
|
||||
return True, True
|
||||
elif status == "warning":
|
||||
self.main_frame.show_warning("Wiki Update Info", message)
|
||||
elif status == "error":
|
||||
self.main_frame.show_error("Wiki Update Error", f"Failed:\n{message}")
|
||||
|
||||
return False, False
|
||||
@ -13,7 +13,7 @@ from ..commands.git_commands import GitCommands, GitCommandError
|
||||
from ..core.action_handler import ActionHandler
|
||||
from ..core.backup_handler import BackupHandler
|
||||
from ..core.remote_actions import RemoteActionHandler
|
||||
from ..core.wiki_updater import WikiUpdater
|
||||
from ..core.wiki_updater import WikiUpdater, WikiUpdateStatus
|
||||
from ..core.history_cleaner import HistoryCleaner
|
||||
from ..core.submodule_handler import SubmoduleHandler
|
||||
|
||||
@ -1040,17 +1040,27 @@ def run_update_wiki_async(
|
||||
"status": "error",
|
||||
"message": "Wiki update failed.",
|
||||
"exception": None,
|
||||
"result": False,
|
||||
"result": None,
|
||||
}
|
||||
try:
|
||||
success, message = wiki_updater.update_wiki_from_docs(
|
||||
update_result = wiki_updater.update_wiki_from_docs(
|
||||
main_repo_path=main_repo_path,
|
||||
main_repo_remote_url=main_repo_remote_url,
|
||||
)
|
||||
result_payload["status"] = "success" if success else "error"
|
||||
result_payload["message"] = message
|
||||
result_payload["result"] = success
|
||||
log_handler.log_info(f"[Worker] Wiki update result: {message}", func_name=func_name)
|
||||
|
||||
# The status for the queue can be 'success', 'warning', or 'error'
|
||||
# We map our detailed status to one of these
|
||||
if update_result.status in [WikiUpdateStatus.SUCCESS, WikiUpdateStatus.NO_CHANGES]:
|
||||
queue_status = "success"
|
||||
elif update_result.status in [WikiUpdateStatus.DOC_NOT_FOUND]:
|
||||
queue_status = "warning"
|
||||
else:
|
||||
queue_status = "error"
|
||||
|
||||
result_payload["status"] = queue_status
|
||||
result_payload["message"] = update_result.message
|
||||
result_payload["result"] = update_result # Pass the whole result object
|
||||
log_handler.log_info(f"[Worker] Wiki update result: {update_result.message}", func_name=func_name)
|
||||
|
||||
except Exception as e:
|
||||
log_handler.log_exception(f"[Worker] UNEXPECTED EXCEPTION during wiki update: {e}", func_name=func_name)
|
||||
@ -1092,6 +1102,36 @@ def run_revert_to_tag_async(
|
||||
except Exception as qe:
|
||||
log_handler.log_error(f"[Worker] Failed to put result in queue for {func_name}: {qe}", func_name=func_name)
|
||||
log_handler.log_debug(f"[Worker] Finished: Revert to Tag '{tag_name}'", func_name=func_name)
|
||||
|
||||
def run_reset_to_commit_async(
|
||||
action_handler: ActionHandler,
|
||||
repo_path: str,
|
||||
commit_hash: str,
|
||||
results_queue: queue.Queue[Dict[str, Any]],
|
||||
) -> None:
|
||||
"""Worker to perform a hard reset to a specific commit asynchronously."""
|
||||
func_name = "run_reset_to_commit_async"
|
||||
log_handler.log_debug(f"[Worker] Started: Reset to Commit '{commit_hash}' in '{repo_path}'", func_name=func_name)
|
||||
result_payload: Dict[str, Any] = {
|
||||
"status": "error", "result": False, "message": f"Failed to reset to commit '{commit_hash[:7]}'.", "exception": None,
|
||||
}
|
||||
try:
|
||||
# Directly call the git_reset_hard from action_handler's git_commands
|
||||
action_handler.git_commands.git_reset_hard(repo_path, commit_hash)
|
||||
result_payload["status"] = "success"
|
||||
result_payload["result"] = True
|
||||
result_payload["message"] = f"Repository successfully reset to commit '{commit_hash[:7]}'."
|
||||
log_handler.log_info(f"[Worker] {result_payload['message']}", func_name=func_name)
|
||||
except (GitCommandError, ValueError, Exception) as e:
|
||||
log_handler.log_exception(f"[Worker] EXCEPTION resetting to commit: {e}", func_name=func_name)
|
||||
result_payload["exception"] = e
|
||||
result_payload["message"] = f"Error resetting to commit '{commit_hash[:7]}': {e}"
|
||||
finally:
|
||||
try:
|
||||
results_queue.put(result_payload)
|
||||
except Exception as qe:
|
||||
log_handler.log_error(f"[Worker] Failed to put result in queue for {func_name}: {qe}", func_name=func_name)
|
||||
log_handler.log_debug(f"[Worker] Finished: Reset to Commit '{commit_hash}'", func_name=func_name)
|
||||
|
||||
def run_analyze_repo_for_purge_async(
|
||||
history_cleaner: HistoryCleaner,
|
||||
|
||||
@ -905,6 +905,32 @@ class GitCommands:
|
||||
raise e
|
||||
|
||||
# --- History / Log ---
|
||||
def reset_hard(self, working_directory: str, commit_hash: str) -> None:
|
||||
"""
|
||||
Performs a git reset --hard to the specified commit hash.
|
||||
|
||||
Args:
|
||||
working_directory (str): Path to the repository.
|
||||
commit_hash (str): The commit hash to reset to.
|
||||
"""
|
||||
func_name = "reset_hard"
|
||||
log_handler.log_warning(
|
||||
f"Performing a destructive 'git reset --hard' to '{commit_hash}' in '{working_directory}'",
|
||||
func_name=func_name
|
||||
)
|
||||
if not commit_hash or commit_hash.isspace():
|
||||
raise ValueError("Commit hash cannot be empty.")
|
||||
|
||||
cmd = ["git", "reset", "--hard", commit_hash]
|
||||
try:
|
||||
self.log_and_execute(cmd, working_directory, check=True)
|
||||
log_handler.log_info(
|
||||
f"Successfully reset to commit '{commit_hash}'.", func_name=func_name
|
||||
)
|
||||
except GitCommandError as e:
|
||||
log_handler.log_error(f"Failed to 'git reset --hard': {e}", func_name=func_name)
|
||||
raise
|
||||
|
||||
def get_commit_log(
|
||||
self, working_directory: str, max_count: int = 200, branch: Optional[str] = None
|
||||
) -> List[str]:
|
||||
@ -2048,11 +2074,11 @@ class GitCommands:
|
||||
raise e
|
||||
|
||||
log_handler.log_warning(
|
||||
"Performing DESTRUCTIVE operation: git clean -fdx", func_name=func_name
|
||||
"Performing DESTRUCTIVE operation: git clean -fd", func_name=func_name
|
||||
)
|
||||
|
||||
# 2. Esegui git clean -fdx per rimuovere file non tracciati
|
||||
clean_cmd: List[str] = ["git", "clean", "-fdx"]
|
||||
# 2. Esegui git clean -fd per rimuovere file non tracciati
|
||||
clean_cmd: List[str] = ["git", "clean", "-fd"]
|
||||
try:
|
||||
self.log_and_execute(
|
||||
clean_cmd, working_directory, check=True, log_output_level=logging.INFO
|
||||
|
||||
@ -5,14 +5,33 @@ import shutil
|
||||
import tempfile
|
||||
import re
|
||||
import time
|
||||
from typing import Optional, Tuple
|
||||
from typing import Optional
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
from enum import Enum, auto
|
||||
from dataclasses import dataclass
|
||||
|
||||
from ..commands.git_commands import GitCommands, GitCommandError
|
||||
from ..logging_setup import log_handler
|
||||
|
||||
class WikiUpdateStatus(Enum):
|
||||
"""Represents the result of the wiki update operation."""
|
||||
SUCCESS = auto()
|
||||
NO_CHANGES = auto()
|
||||
URL_DERIVATION_FAILED = auto()
|
||||
CLONE_FAILED = auto()
|
||||
PUSH_FAILED = auto()
|
||||
COMMIT_FAILED = auto()
|
||||
DOC_NOT_FOUND = auto()
|
||||
BRANCH_NOT_FOUND = auto()
|
||||
GENERIC_ERROR = auto()
|
||||
|
||||
@dataclass
|
||||
class WikiUpdateResult:
|
||||
"""Holds the result of the wiki update operation."""
|
||||
status: WikiUpdateStatus
|
||||
message: str
|
||||
|
||||
class WikiUpdater:
|
||||
# ... (il resto della classe è invariato fino a update_wiki_from_docs)
|
||||
DEFAULT_WIKI_EN_FILENAME = "English-Manual.md"
|
||||
DEFAULT_WIKI_IT_FILENAME = "Italian-Manual.md"
|
||||
|
||||
@ -23,7 +42,6 @@ class WikiUpdater:
|
||||
log_handler.log_debug("WikiUpdater initialized.", func_name="__init__")
|
||||
|
||||
def _get_wiki_repo_url(self, main_repo_url: str) -> Optional[str]:
|
||||
# ... (codice invariato)
|
||||
if not main_repo_url:
|
||||
return None
|
||||
try:
|
||||
@ -52,7 +70,7 @@ class WikiUpdater:
|
||||
wiki_en_target_filename: Optional[str] = None,
|
||||
wiki_it_target_filename: Optional[str] = None,
|
||||
commit_message: str = "Update Wiki documentation from local files"
|
||||
) -> Tuple[bool, str]:
|
||||
) -> WikiUpdateResult:
|
||||
"""
|
||||
Clones the Gitea wiki repo, updates pages from local doc files, and pushes.
|
||||
"""
|
||||
@ -63,7 +81,7 @@ class WikiUpdater:
|
||||
if not wiki_url:
|
||||
msg = "Could not derive Wiki repository URL from main remote URL."
|
||||
log_handler.log_error(msg, func_name=func_name)
|
||||
return False, msg
|
||||
return WikiUpdateResult(status=WikiUpdateStatus.URL_DERIVATION_FAILED, message=msg)
|
||||
|
||||
log_handler.log_debug(f"Derived wiki URL: {wiki_url}", func_name=func_name)
|
||||
|
||||
@ -78,7 +96,7 @@ class WikiUpdater:
|
||||
if not en_exists and not it_exists:
|
||||
msg = f"Neither '{en_manual_filename}' nor '{it_manual_filename}' found in '{doc_path}'. Cannot update Wiki."
|
||||
log_handler.log_warning(msg, func_name=func_name)
|
||||
return False, msg
|
||||
return WikiUpdateResult(status=WikiUpdateStatus.DOC_NOT_FOUND, message=msg)
|
||||
|
||||
temp_dir: Optional[str] = None
|
||||
try:
|
||||
@ -93,7 +111,7 @@ class WikiUpdater:
|
||||
else:
|
||||
msg = f"Failed to clone Wiki repository '{wiki_url}'. Error: {stderr_msg.strip()}"
|
||||
log_handler.log_error(msg, func_name=func_name)
|
||||
return False, f"{msg} (Check authentication?)"
|
||||
return WikiUpdateResult(status=WikiUpdateStatus.CLONE_FAILED, message=f"{msg} (Check authentication?)")
|
||||
|
||||
log_handler.log_info("Wiki repository cloned successfully.", func_name=func_name)
|
||||
|
||||
@ -108,26 +126,24 @@ class WikiUpdater:
|
||||
if not self.git_commands.git_status_has_changes(temp_dir):
|
||||
msg = "Wiki content is already up-to-date with local doc files."
|
||||
log_handler.log_info(msg, func_name=func_name)
|
||||
return True, msg
|
||||
return WikiUpdateResult(status=WikiUpdateStatus.NO_CHANGES, message=msg)
|
||||
|
||||
# --- MODIFICA PER PROBLEMA COMMIT ---
|
||||
log_handler.log_info("Changes detected. Staging with --renormalize to handle line endings.", func_name=func_name)
|
||||
# Questo comando forza Git a ri-processare i file, risolvendo problemi di CRLF/LF
|
||||
self.git_commands.add_file(temp_dir, ".", renormalize=True)
|
||||
# Ora eseguiamo il commit, ma senza fare un altro 'add'
|
||||
|
||||
commit_success = self.git_commands.git_commit(temp_dir, commit_message, stage_all_first=False)
|
||||
# --- FINE MODIFICA ---
|
||||
|
||||
if not commit_success:
|
||||
msg = "Staged changes, but commit reported no changes to commit. Push will be skipped."
|
||||
log_handler.log_warning(msg, func_name=func_name)
|
||||
return True, msg # Consideriamo un "successo" perché non c'era nulla di sostanziale da pushare
|
||||
return WikiUpdateResult(status=WikiUpdateStatus.NO_CHANGES, message=msg)
|
||||
|
||||
log_handler.log_info("Wiki changes committed locally.", func_name=func_name)
|
||||
|
||||
current_wiki_branch = self.git_commands.get_current_branch_name(temp_dir)
|
||||
if not current_wiki_branch:
|
||||
return False, "Could not determine the current branch in the cloned wiki repository."
|
||||
msg = "Could not determine the current branch in the cloned wiki repository."
|
||||
log_handler.log_error(msg, func_name=func_name)
|
||||
return WikiUpdateResult(status=WikiUpdateStatus.BRANCH_NOT_FOUND, message=msg)
|
||||
|
||||
log_handler.log_info("Pushing wiki changes to remote...", func_name=func_name)
|
||||
push_result = self.git_commands.git_push(
|
||||
@ -140,30 +156,28 @@ class WikiUpdater:
|
||||
if push_result.returncode == 0:
|
||||
msg = "Wiki update pushed successfully to Gitea."
|
||||
log_handler.log_info(msg, func_name=func_name)
|
||||
return True, msg
|
||||
return WikiUpdateResult(status=WikiUpdateStatus.SUCCESS, message=msg)
|
||||
else:
|
||||
stderr_msg = push_result.stderr or "Unknown push error"
|
||||
msg = f"Failed to push Wiki updates. Error: {stderr_msg.strip()}"
|
||||
log_handler.log_error(msg, func_name=func_name)
|
||||
return False, msg
|
||||
return WikiUpdateResult(status=WikiUpdateStatus.PUSH_FAILED, message=msg)
|
||||
|
||||
except (GitCommandError, ValueError, IOError, Exception) as e:
|
||||
log_handler.log_exception(f"Error during wiki update process: {e}", func_name=func_name)
|
||||
return False, f"Wiki update failed: {e}"
|
||||
return WikiUpdateResult(status=WikiUpdateStatus.GENERIC_ERROR, message=f"Wiki update failed: {e}")
|
||||
|
||||
finally:
|
||||
# --- MODIFICA PER PROBLEMA PULIZIA ---
|
||||
if temp_dir and os.path.isdir(temp_dir):
|
||||
log_handler.log_debug(f"Attempting to clean up temporary directory: {temp_dir}", func_name=func_name)
|
||||
for attempt in range(3): # Prova fino a 3 volte
|
||||
for attempt in range(3):
|
||||
try:
|
||||
shutil.rmtree(temp_dir)
|
||||
log_handler.log_info(f"Cleanup of temporary directory successful.", func_name=func_name)
|
||||
break # Esci dal ciclo se la pulizia ha successo
|
||||
break
|
||||
except Exception as clean_e:
|
||||
log_handler.log_warning(f"Cleanup attempt {attempt + 1} failed for '{temp_dir}': {clean_e}", func_name=func_name)
|
||||
if attempt < 2:
|
||||
time.sleep(0.5) # Aspetta 500ms prima di riprovare
|
||||
time.sleep(0.5)
|
||||
else:
|
||||
log_handler.log_error(f"Final cleanup attempt failed for '{temp_dir}'.", func_name=func_name)
|
||||
# --- FINE MODIFICA ---
|
||||
@ -27,6 +27,7 @@ class HistoryTab(ttk.Frame):
|
||||
# Store callbacks
|
||||
self.refresh_history_callback = kwargs.get('refresh_history_cb')
|
||||
self.view_commit_details_callback = kwargs.get('view_commit_details_cb')
|
||||
self.reset_to_commit_callback = kwargs.get('reset_to_commit_cb')
|
||||
|
||||
# --- Get a reference to the main frame for shared components ---
|
||||
self.main_frame = self.master.master
|
||||
@ -97,7 +98,8 @@ class HistoryTab(ttk.Frame):
|
||||
tree_scrollbar_x.grid(row=1, column=0, columnspan=2, sticky="ew")
|
||||
|
||||
self.history_tree.bind("<Double-Button-1>", self._on_history_double_click)
|
||||
Tooltip(self.history_tree, "Double-click a commit line to view details.")
|
||||
self.history_tree.bind("<Button-3>", self._show_context_menu)
|
||||
Tooltip(self.history_tree, "Double-click a commit line to view details.\nRight-click for more options.")
|
||||
|
||||
def set_action_widgets_state(self, state: str) -> None:
|
||||
"""Sets the state of all action widgets in this tab."""
|
||||
@ -115,8 +117,10 @@ class HistoryTab(ttk.Frame):
|
||||
if self.history_tree and self.history_tree.winfo_exists():
|
||||
if state == tk.DISABLED:
|
||||
self.history_tree.unbind("<Double-Button-1>")
|
||||
self.history_tree.unbind("<Button-3>")
|
||||
else:
|
||||
self.history_tree.bind("<Double-Button-1>", self._on_history_double_click)
|
||||
self.history_tree.bind("<Button-3>", self._show_context_menu)
|
||||
|
||||
def update_history_display(self, log_lines: List[str]) -> None:
|
||||
"""Populates the history treeview with parsed log data."""
|
||||
@ -185,4 +189,59 @@ class HistoryTab(ttk.Frame):
|
||||
self.view_commit_details_callback(commit_hash)
|
||||
except Exception as e:
|
||||
log_handler.log_exception(f"Error handling history double-click: {e}", func_name=func_name)
|
||||
messagebox.showerror("Error", f"Could not process history selection:\n{e}", parent=self)
|
||||
messagebox.showerror("Error", f"Could not process history selection:\n{e}", parent=self)
|
||||
|
||||
def _show_context_menu(self, event: tk.Event) -> None:
|
||||
"""Displays a context menu on right-click."""
|
||||
# Select the item under the cursor
|
||||
iid = self.history_tree.identify_row(event.y)
|
||||
if not iid: # Clicked outside of any item
|
||||
return
|
||||
|
||||
self.history_tree.selection_set(iid)
|
||||
self.history_tree.focus(iid)
|
||||
|
||||
item_data = self.history_tree.item(iid)
|
||||
item_values = item_data.get("values")
|
||||
if not item_values or not str(item_values[0]).strip():
|
||||
return
|
||||
|
||||
commit_hash = str(item_values[0]).strip()
|
||||
|
||||
context_menu = tk.Menu(self, tearoff=0)
|
||||
context_menu.add_command(
|
||||
label=f"View Details for {commit_hash[:7]}...",
|
||||
command=lambda: self.view_commit_details_callback(commit_hash)
|
||||
)
|
||||
context_menu.add_separator()
|
||||
context_menu.add_command(
|
||||
label=f"Reset branch to this commit ({commit_hash[:7]}) ...",
|
||||
command=lambda: self._on_reset_to_commit(commit_hash)
|
||||
)
|
||||
|
||||
try:
|
||||
context_menu.tk_popup(event.x_root, event.y_root)
|
||||
finally:
|
||||
context_menu.grab_release()
|
||||
|
||||
def _on_reset_to_commit(self, commit_hash: str) -> None:
|
||||
"""Handles the 'Reset to commit' action from the context menu."""
|
||||
func_name = "_on_reset_to_commit"
|
||||
if not callable(self.reset_to_commit_callback):
|
||||
log_handler.log_warning("reset_to_commit_callback is not available.", func_name)
|
||||
return
|
||||
|
||||
title = "Confirm Destructive Action"
|
||||
message = (
|
||||
f"Are you sure you want to reset your current branch to commit {commit_hash[:7]}?"
|
||||
f"WARNING: This is a destructive operation!"
|
||||
f"- All commits made after this one will be permanently lost."
|
||||
f"- All uncommitted changes in your working directory will be permanently lost."
|
||||
f"This action cannot be undone. Proceed with caution."
|
||||
)
|
||||
|
||||
if messagebox.askokcancel(title, message, icon=messagebox.WARNING, parent=self):
|
||||
log_handler.log_warning(f"User confirmed reset to commit: '{commit_hash}'", func_name)
|
||||
self.reset_to_commit_callback(commit_hash)
|
||||
else:
|
||||
log_handler.log_info("User cancelled reset operation.", func_name)
|
||||
@ -407,4 +407,19 @@ class RepositoryHandler:
|
||||
worker_func=async_workers.run_get_commit_details_async,
|
||||
args_tuple=args,
|
||||
context_dict={"context": "get_commit_details", "status_msg": f"Loading details for commit {commit_hash_short}"}
|
||||
)
|
||||
|
||||
def handle_reset_to_commit(self, commit_hash: str):
|
||||
"""Handles the destructive 'Reset to Commit' action."""
|
||||
func_name = "handle_reset_to_commit"
|
||||
svn_path = self.app._get_and_validate_svn_path("Reset to Commit")
|
||||
if not svn_path or not self.app._is_repo_ready(svn_path):
|
||||
self.main_frame.show_error("Action Failed", "Repository is not ready.")
|
||||
return
|
||||
|
||||
args = (self.action_handler, svn_path, commit_hash)
|
||||
self.app._start_async_operation(
|
||||
worker_func=async_workers.run_reset_to_commit_async,
|
||||
args_tuple=args,
|
||||
context_dict={"context": "reset_to_commit", "status_msg": f"Resetting to commit '{commit_hash[:7]}'"},
|
||||
)
|
||||
Loading…
Reference in New Issue
Block a user