Skip to main content
Glama
MementoRC

MCP Git Server

by MementoRC

git_reset

Unstage all staged changes in a Git repository. Use this tool to revert files in the staging area to their previous state, ensuring clarity in your next commit. Requires specifying the repository path for operation.

Instructions

Unstages all staged changes

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
repo_pathYes

Implementation Reference

  • Core handler function implementing git reset with support for soft, mixed, hard modes, optional target (commit/branch), and specific files. Includes validation, status reporting, and error handling.
    def git_reset(
        repo: Repo,
        mode: str | None = None,
        target: str | None = None,
        files: list[str] | None = None,
    ) -> str:
        """Reset repository with advanced options (--soft, --mixed, --hard)"""
        try:
            # Validate reset mode
            valid_modes = ["soft", "mixed", "hard"]
            if mode and mode not in valid_modes:
                return (
                    f"❌ Invalid reset mode '{mode}'. Valid modes: {', '.join(valid_modes)}"
                )
    
            # Build git reset command
            reset_args = []
    
            # Add mode flag if specified
            if mode:
                reset_args.append(f"--{mode}")
    
            # Add target if specified
            if target:
                # Validate target exists
                try:
                    repo.git.rev_parse(target)
                except GitCommandError:
                    return f"❌ Target '{target}' does not exist"
                reset_args.append(target)
    
            # Add files if specified
            if files:
                # Validate files exist
                for file in files:
                    if not os.path.exists(os.path.join(repo.working_dir, file)):
                        return f"❌ File '{file}' does not exist"
                reset_args.extend(files)
    
            # Special handling for file-specific reset
            if files and not mode and not target:
                # Default to mixed reset for files
                reset_args.insert(0, "HEAD")
    
            # Get status before reset for informative message
            status_before = ""
            if mode in ["mixed", "hard"] or not mode:
                try:
                    staged_files = [
                        item.a_path for item in repo.index.diff("HEAD") if item.a_path
                    ]
                    if staged_files:
                        status_before = f"staged files: {', '.join(staged_files[:5])}"
                        if len(staged_files) > 5:
                            status_before += f" (and {len(staged_files) - 5} more)"
                except Exception:
                    pass
    
            if mode == "hard":
                try:
                    modified_files = [
                        item.a_path for item in repo.index.diff(None) if item.a_path
                    ]
                    if modified_files:
                        mod_status = f"modified files: {', '.join(modified_files[:5])}"
                        if len(modified_files) > 5:
                            mod_status += f" (and {len(modified_files) - 5} more)"
                        status_before = (
                            f"{status_before}, {mod_status}"
                            if status_before
                            else mod_status
                        )
                except Exception:
                    pass
    
            # Execute reset
            if reset_args:
                repo.git.reset(*reset_args)
            else:
                repo.git.reset()
    
            # Build success message
            if files:
                return f"✅ Reset {len(files)} file(s): {', '.join(files)}"
            elif mode == "soft":
                return f"✅ Soft reset to {target if target else 'HEAD'} - keeping changes in index"
            elif mode == "mixed" or not mode:
                target_msg = f" to {target}" if target else ""
                return f"✅ Mixed reset{target_msg} - {status_before if status_before else 'no staged changes'}"
            elif mode == "hard":
                target_msg = f" to {target}" if target else ""
                return f"✅ Hard reset{target_msg} - {status_before if status_before else 'no changes'} discarded"
            else:
                # Fallback return (should not reach here)
                return "✅ Reset completed"
    
        except GitCommandError as e:
            return f"❌ Reset failed: {str(e)}"
        except Exception as e:
            return f"❌ Reset error: {str(e)}"
  • Pydantic input schema/model for the git_reset tool defining parameters: repo_path, mode (soft/mixed/hard), target, files.
    class GitReset(BaseModel):
        repo_path: str
        mode: str | None = None  # --soft, --mixed, --hard
        target: str | None = None  # commit hash, branch, tag
        files: list[str] | None = None  # specific files to reset
  • Registration of the git_reset tool handler using _create_git_handler wrapper with repo requirement.
    ),
    "git_reset": self._create_git_handler(git_reset, requires_repo=True),
  • Tool definition and registration in the ToolRegistry for 'git_reset' (RESET enum) with schema GitReset and Git category.
    ToolDefinition(
        name=GitTools.RESET,
        category=ToolCategory.GIT,
        description="Unstage all staged changes",
        schema=GitReset,
        handler=placeholder_handler,
        requires_repo=True,
    ),
  • Protected wrapper for git_reset that adds repository binding validation and remote integrity checks before calling the core git_reset function.
    async def protected_git_reset(
        self, repo_path: str, mode: str = "mixed", target: str | None = None
    ) -> str:
        """Git reset with repository binding protection."""
        validated_path = await self._validate_and_prepare_operation(repo_path)
        repo = Repo(validated_path)
        return git_reset(repo, mode, target)
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. 'Unstages all staged changes' implies a mutation operation but doesn't specify whether it's reversible, what permissions are needed, or if it affects the working directory. It lacks details on error conditions (e.g., no staged changes), side effects, or output format. For a mutation tool with zero annotation coverage, this is inadequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence ('Unstages all staged changes') that is front-loaded and wastes no words. It directly conveys the core action without unnecessary elaboration, making it easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (a mutation operation with no annotations, 1 parameter at 0% coverage, and no output schema), the description is incomplete. It doesn't cover behavioral aspects like safety, reversibility, or error handling, nor does it explain the parameter or return values. For a Git reset tool, more context is needed to use it effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds no meaning beyond the input schema, which has 1 parameter (repo_path) with 0% schema description coverage. It doesn't explain what repo_path represents (e.g., file path, directory, URL), its format, or default behavior. With low coverage, the description fails to compensate, leaving the parameter poorly documented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Unstages all staged changes' clearly states the verb ('Unstages') and resource ('all staged changes'), making the purpose immediately understandable. It distinguishes from siblings like git_add (which stages changes) and git_commit (which commits staged changes), though it doesn't explicitly name these alternatives. The description is specific but could be more precise about scope (e.g., whether it affects the entire repository or specific files).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing staged changes), exclusions (e.g., not for discarding unstaged changes), or related tools like git_checkout (for discarding changes) or git_reset with modes (e.g., --hard). Usage is implied from the action but lacks explicit context for decision-making.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MementoRC/mcp-git'

If you have feedback or need assistance with the MCP directory API, please join our Discord server