paul-gauthier / aider

aider is AI pair programming in your terminal
https://aider.chat/
Apache License 2.0
18.37k stars 1.71k forks source link

[Q/FR] Is there an easy way to squash commits? #822

Open NightMachinery opened 2 months ago

NightMachinery commented 2 months ago

Is there an easy way to squash commits?

The AI keeps committing for each message, and this litters the history. Having /squash 3 which automatically generates a prompt message using AI and squashes would be good.

paul-gauthier commented 2 months ago

Thanks for trying aider and filing this issue.

I've been thinking about this lately and laying some groundwork for a squash feature.

paul-gauthier commented 2 months ago

In the meantime you could do:

/git reset --soft HEAD~3
/commit

This will squash the last 3 commits with an appropriate commit message.

nevercast commented 2 months ago

I don't know if this is on topic or not here, but something I've been really wanting is a smart squash that uses fixup for fixes, squash where it makes sense, and generally just rewrites history to make it pretty.

Then slaps new commit messages on top.

paul-gauthier commented 2 months ago

That's what I've been thinking about. I've been making some design notes and laying groundwork.

The recent feature to do multiple /undo commands was working towards this.

Roald87 commented 1 month ago

An idea for the workflow would be to start with a command /new_feat or /tdd. Then you start implementing the feature or unit test step by step. When finished you say /done or /finish and it automatically merges all the commits made from the time the first command was given.

GeoffMillerAZ commented 3 weeks ago

Enhanced Labeling Functionality with AI Capabilities

Proposal Overview

I'd like to propose an enhancement to the labeling system within the Aider AI coding assistant to improve version control workflows. This feature would introduce a flexible labeling mechanism, allowing developers to mark specific points in their development process. These labels could then be used in conjunction with various commands to manage and manipulate the Git history more effectively.

Command #5 suggested below is the squash command. Should I make this it's own post? I originally just wanted to give a few more suggestions for possible names to @Roald87 's suggestion, which I liked. But then I got to thinking about it and wrote this more detailed proposal which incorporates potential for a lot more features from a similar idea. edit I did make it's own post: #1172

Persistent Labels

To ensure that labels remain consistent and accessible across sessions, the labels would be stored persistently in the .aider meta files within the workspace. This allows labels to be saved, loaded, and referenced even after the coding assistant or workspace is restarted. This persistence ensures that developers can rely on labels to maintain continuity in their workflow, making it easier to manage and navigate the project over time.

Key Benefits:

Proposed Commands

  1. /set \<label> [commit_id]

    • Function: Sets a label at the current commit, or optionally at a specified commit if the commit_id is provided. This label can then be referenced by other commands.
    • Default Behavior: A label is required for this command. If no commit ID is provided, the label is set at the current commit.
    • Proposed Alternatives:
      • /mark \<label> [commit_id]
      • /stage \<label> [commit_id]
      • /initiate \<label> [commit_id]
      • /pin \<label> [commit_id]
      • /checkpoint \<label> [commit_id]
      • /stamp \<label> [commit_id]
    • AI Enhancement: After setting the label, AI could suggest potential next steps based on the current context (e.g., "Would you like to create a branch from this label?").
    • Persistence: The label is saved in the .aider meta file, ensuring it remains accessible across sessions.
  2. /diff \<label>

    • Function: Displays the difference between the current state and the state at the specified label.
    • Default Behavior: If no label is provided, the command compares the current state with the last set label. If no labels exist, the command will not execute.
    • AI Enhancement:
      • Git Command Output: In addition to showing the diffs, the command could print the exact git diff command used, enabling easy replication in the terminal.
      • AI Summary: The AI could provide a plain-language summary of the code changes, such as "Refactored function X for performance improvements" or "Added validation checks to input processing."
  3. /log \<label>

    • Function: Outputs the commit history starting from the specified label to the current commit.
    • Default Behavior: If no label is provided, the command defaults to showing the commit history from the last set label to the current state. If no labels exist, the entire commit history is shown.
    • AI Enhancement:
      • Commit Categorization: AI could categorize commits based on their content (e.g., "Bug fixes," "Feature additions," "Refactoring") and provide a summarized log view.
  4. /save \<label>

    • Function: Saves the current state as a stash (similar to git stash), labeled with the custom name.
    • Default Behavior: If no label is provided, the current state is stashed with a generic label (e.g., "auto-stash"). If no previous label exists, a default stash is created without a label.
    • AI Enhancement:
      • Stash Suggestion: AI could suggest a suitable label based on recent changes (e.g., "save-before-major-refactor").
  5. /squash \<label>

    • Function: Squashes all commits from the current state back to the commit where the specified label was set. An AI-generated aggregated commit message is used.
    • Default Behavior: If no label is provided, the command squashes all commits back to the most recent label. If no labels exist, the command will not execute.
    • AI Enhancement:
      • Commit Message Generation: AI could generate a concise, informative commit message that reflects the overall purpose and key changes of the squashed commits, offering multiple suggestions for the user to choose from.
      • Change Summary: AI could generate a high-level summary of what the squash achieves, such as "Consolidated 15 commits: refactoring, bug fixes, and feature completion."
  6. /info \<label>

    • Function: Retrieves detailed information about the commit where the specified label was set, including the commit hash, message, author, date, and a summary of changes.
    • Default Behavior: If no label is provided, the command defaults to providing information about the most recent label. If no labels exist, the command will not execute.
  7. /search \<label>

    • Function: Allows users to use plain language to find the commit where a specific change happened within the range of commits from the current state back to the specified label.
    • Default Behavior: If no label is provided, the command defaults to searching from the most recent label. If no labels exist, the command will not execute.
    • AI Enhancement:
      • Plain Language Query: Users can describe what they are looking for (e.g., "When was the validation added to the input function?"), and AI will identify the relevant commit within the specified range.
      • Commit Information: The AI would return detailed information about the identified commit, including the commit hash, message, author, and a summary of the changes.
  8. /cost \<mylabel> [myotherlabel]

    • Function: Tracks the cost associated with using the large language model (LLM) AI coder.
    • Default Behavior: If no label is provided, it returns the cost since the last label.
    • One Label Provided: Returns the cost since the specified label.
    • Two Labels Provided: Returns the cost between the two specified labels.
    • Example Usage:
      • /cost: "Cost since last label: $12.34"
      • /cost featureX: "Cost since featureX: $45.67"
      • /cost featureX featureY: "Cost between featureX and featureY: $23.45"
    • Tracking Consideration: If the API key does not provide the necessary granularity, cost information might need to be tracked in the .aider meta files within the workspace to ensure accurate cost reporting.
    • Benefit: Helps users monitor and manage AI-related expenses during different phases of development.

Enhanced Labeling System with Automatic and Reserved Labels

This proposal introduces a sophisticated labeling system to efficiently track key events and manage commit history in a structured way. The system leverages automatic labels, reserved labels, and sublabels, which together provide developers with powerful tools for maintaining a clean, navigable, and organized codebase.

Concept of Automatic and Reserved Labels

Automatic labels are labels that the system creates without user intervention, marking significant events in the development process. These labels are similar to the latest tag in containers or release management, automatically updating to point to the most recent state of a specific event, such as a successful lint or test pass.

Reserved labels are a specific type of automatic label that are always active, ensuring that critical moments in the development cycle are consistently tracked, regardless of user-defined labels.

Example Reserved Labels:

These labels allow developers to easily revert to or squash commits back to key milestones in their codebase, ensuring stability and consistency.

Application at the Sublabel and Label Levels

Automatic and reserved labels can be applied at both the sublabel level (within a specific development phase) and the label level (across the entire project timeline).

  1. Automatic Sublabels:

    • Linting Sublabels: Automatically adds a sublabel like mylabel.linted whenever all files pass linting under a specific label.
    • Testing Sublabels: Adds a sublabel like mylabel.passed each time tests pass successfully under a specific label.

    Usage Examples:

    • /undo mylabel.passed: Reverts to the last commit where tests passed under the mylabel label.
    • /diff mylabel.passed: Describes all changes since the last time tests passed under the mylabel label.
  2. Reserved Automatic Labels:

    • These labels are not tied to any specific user-defined label and are automatically created whenever the associated event occurs, such as linted and passed.
    • They provide a broader scope of tracking, marking the latest occurrence of linting or testing success across the entire project.

    Usage Examples:

    • /undo passed: Reverts the repository to the last commit where all tests passed, regardless of any specific label.
    • /squash linted: Squashes commits back to the last time the code passed linting, ensuring a clean codebase.

Summary of Benefits

See my other issue for how this could tie into cost tracking and aider contribution percentage tracking...

1139