Skip to content

Clarification on closed issue 1238 - adaptation of pre-commit hook - Add (optional) auto-git-add to pre-commit #1239

@de-hru

Description

@de-hru

Dear asottile,

I'm sorry for bothering you, but I think, I was misunderstood.

Many thanks for your quick response. I really appreciate it.

As #1238 was closed and the conversation there has been locked and limited to collaborators, I'm not able to reply there.


#1238 (comment) : there's already an opt in command for that called git add -p

I'm aware of it. My issue (FR) was not about git add -p


#1238 (comment) : this is also completely the wrong project and you would have found duplicates there

I still think, my FR is related to pre-commit.


#1238 (comment) : also ai slop issues are not acceptable

Yes, you're right. I have used AI to create a FR which sounds professionaly and is easy to understand.
But, I've prompted the AI agent we're using at Mercedes-Benz several times, and checked the generated content until I was happy with it.


Here is the additional description and also some screenshots which should demonstrate what I tried to explain.

At the end, you'll find my adapted pre-commit hook I used to demonstrate the behaviour I described in my FR:

I have adapted my .git/hooks/pre-commit, so that it automatically detects if any unstaged/untracked files exist in my repo clone when I try to commit.
If so, the CLI displays a message "Unstaged/untracked files detected"
And, it asks me, if I would like to get all unstaged/untracked files staged so that I would not need to run git add . manually.
If I confirm (y/Y/ENTER), unstaged/untracked files are staged automatically before pre-commit runs.
If I do NOT confirm, nothing ist staged and pre-commit runs, stashes the unstaged files, and restore them when pre-commit finishes.


Screenshot with unstaged AND untracked files -> confirmed to stage them -> they were staged

Image

Screenshot with unstaged files only -> confirmed to stage them -> they were staged

Image

Screenshot with untracked files only -> decline to stage them -> they were not staged

Image

My (adapted) pre-commit hook I used to demonstrate the behaviour I described in my FR:

#!/bin/sh
#!/usr/bin/env bash
# File generated by pre-commit: https://pre-commit.com
# ID: 138fd403232d2ddd5efb44317e38bf03

# === CUSTOM: Unstaged file detection ===
# Colors
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# Get repository root directory
REPO_ROOT=$(git rev-parse --show-toplevel)

# Check for unstaged tracked changes (modified/deleted)
HAS_UNSTAGED=false
if ! git diff --quiet; then
    HAS_UNSTAGED=true
fi

# Check for untracked files
HAS_UNTRACKED=false
if [ -n "$(git ls-files --others --exclude-standard)" ]; then
    HAS_UNTRACKED=true
fi

# If we have either unstaged or untracked files, prompt user
if [ "$HAS_UNSTAGED" = true ] || [ "$HAS_UNTRACKED" = true ]; then
    echo -e "${YELLOW}⚠ Uncommitted files detected!${NC}"
    echo -e "${YELLOW}Pre-commit hooks work on staged files only!${NC}\n"

    # Show unstaged tracked files if they exist
    if [ "$HAS_UNSTAGED" = true ]; then
        echo -e "${BLUE}=== Modified/deleted but unstaged files ===${NC}"
        git diff --name-status
        echo ""
    fi

    # Show untracked files if they exist
    if [ "$HAS_UNTRACKED" = true ]; then
        echo -e "${CYAN}=== Untracked files ===${NC}"
        git ls-files --others --exclude-standard
        echo ""
    fi

    # Ask appropriate question based on what we found
    if [ "$HAS_UNSTAGED" = true ] && [ "$HAS_UNTRACKED" = true ]; then
        echo -n "Would you like to stage all unstaged and untracked files? [Y/n]: "
    elif [ "$HAS_UNSTAGED" = true ]; then
        echo -n "Would you like to stage all unstaged files? [Y/n]: "
    else
        echo -n "Would you like to stage all untracked files? [Y/n]: "
    fi

    read -r REPLY < /dev/tty

    if [[ $REPLY =~ ^[Yy]$ ]] || [[ -z $REPLY ]]; then
        echo -e "${GREEN}Staging files...${NC}"

        # Stage based on what we found
        if [ "$HAS_UNSTAGED" = true ] && [ "$HAS_UNTRACKED" = true ]; then
            # Stage everything: tracked changes + untracked files
            git -C "$REPO_ROOT" add -A
            echo -e "${GREEN}✓ All unstaged and untracked files staged${NC}\n"
        elif [ "$HAS_UNSTAGED" = true ]; then
            # Stage only tracked changes
            git -C "$REPO_ROOT" add -u
            echo -e "${GREEN}✓ All unstaged files staged${NC}\n"
        else
            # Stage only untracked files
            git -C "$REPO_ROOT" add .
            echo -e "${GREEN}✓ All untracked files staged${NC}\n"
        fi
    else
        echo -e "${YELLOW}⚠ Proceeding with only currently staged files${NC}\n"
    fi
fi

# Check if there are any staged changes to commit
if git diff --cached --quiet; then
    echo -e "${YELLOW}⚠ No staged changes to commit${NC}"
    echo "Aborting commit."
    exit 1
fi
# === END CUSTOM ===

# start templated
INSTALL_PYTHON='C:\Program Files\Python310\python.exe'
ARGS=(hook-impl --config=.pre-commit-config.yaml --hook-type=pre-commit)
# end templated

HERE="$(cd "$(dirname "$0")" && pwd)"
ARGS+=(--hook-dir "$HERE" -- "$@")

if [ -x "$INSTALL_PYTHON" ]; then
    exec "$INSTALL_PYTHON" -mpre_commit "${ARGS[@]}"
elif command -v pre-commit > /dev/null; then
    exec pre-commit "${ARGS[@]}"
else
    echo '`pre-commit` not found.  Did you forget to activate your virtualenv?' 1>&2
    exit 1
fi

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions