git自动压缩提交的脚本

可以将当前未提交的代码自动执行

  • git add
  • git commit
  • git squash

Git 命令安装指南

1. 创建脚本目录

如果目录不存在,创建它:

bash 复制代码
mkdir -p ~/.local/bin

2. 创建脚本文件

bash 复制代码
vim ~/.local/bin/git-squash

将完整的脚本代码复制到此文件中。

3. 设置脚本权限

bash 复制代码
chmod +x ~/.local/bin/git-squash

4. 配置 PATH

编辑 shell 配置文件(根据你使用的 shell 选择):

bash 复制代码
# 对于 bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc

# 或对于 zsh
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc

重新加载配置:

bash 复制代码
source ~/.bashrc  # 或 source ~/.zshrc

5. 创建 Git 别名

bash 复制代码
git config --global alias.allen-squash '!git-squash'

6. 验证安装

检查脚本是否可执行:

bash 复制代码
ls -l ~/.local/bin/git-squash

检查脚本是否在 PATH 中:

bash 复制代码
which git-squash

检查 git 别名是否设置成功:

bash 复制代码
git config --get-regexp alias.*squash

7. 使用方法

可以通过以下两种方式使用:

bash 复制代码
# 直接使用脚本
git-squash

# 或使用 git 别名
git allen-squash

8. 常见问题排查

命令未找到

  1. 检查 PATH:
bash 复制代码
echo $PATH | grep -o ~/.local/bin
  1. 检查脚本权限:
bash 复制代码
ls -l ~/.local/bin/git-squash
  1. 检查 git 别名:
bash 复制代码
git config --list | grep allen-squash

管理别名

bash 复制代码
# 删除别名
git config --global --unset alias.allen-squash

# 修改别名
git config --global alias.allen-squash '!git-squash'

编辑脚本

bash 复制代码
vim ~/.local/bin/git-squash

9. 备份建议

建议进行以下备份:

bash 复制代码
# 备份脚本
cp ~/.local/bin/git-squash ~/.local/bin/git-squash.backup

# 备份 git 配置
cp ~/.gitconfig ~/.gitconfig.backup

10. 更新脚本

如需更新脚本:

bash 复制代码
# 编辑脚本
vim ~/.local/bin/git-squash

# 确保权限正确
chmod +x ~/.local/bin/git-squash

注意事项

  1. 确保 ~/.local/bin 目录存在并在 PATH 中
  2. 确保脚本具有可执行权限
  3. 重启终端或重新加载配置文件后更改才会生效
  4. 建议在使用前先进行配置备份
  5. 如果遇到权限问题,检查用户权限和文件权限

故障排除

如果命令不能正常工作,请按以下步骤检查:

  1. 确认脚本位置:

    • 检查 ~/.local/bin/git-squash 是否存在
    • 确认文件权限是否正确
  2. 检查 PATH 设置:

    • 确认 ~/.local/bin 在 PATH 中
    • 检查 shell 配置文件是否正确加载
  3. 验证 git 别名:

    • 检查别名是否正确设置
    • 确认 git 配置文件是否正确

脚本内容

sh 复制代码
#!/bin/bash

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 全局变量
COMMITS_TO_SQUASH=0

# 错误处理函数
handle_error() {
    echo -e "${RED}Error: $1${NC}"
    exit 1
}

# 获取与main分支的距离和可压缩提交数量
get_commit_info() {
    # 获取当前分支名
    current_branch=$(git branch --show-current)
    
    # 获取当前分支的总提交数
    total_commits=$(git rev-list HEAD --count)
    
    # 尝试获取与main分支的距离
    if git rev-parse --verify main >/dev/null 2>&1; then
        commits_from_main=$(git rev-list --count main..HEAD)
        echo -e "\n${YELLOW}Commit information:${NC}"
        echo -e "Current branch: ${GREEN}$current_branch${NC}"
        echo -e "Total commits in current branch: ${GREEN}$total_commits${NC}"
        echo -e "Commits ahead of main: ${GREEN}$commits_from_main${NC}"
        echo -e "Maximum commits that can be squashed: ${GREEN}$commits_from_main${NC}"
    else
        echo -e "\n${YELLOW}Commit information:${NC}"
        echo -e "Current branch: ${GREEN}$current_branch${NC}"
        echo -e "Total commits in current branch: ${GREEN}$total_commits${NC}"
        echo -e "Main branch not found - cannot calculate distance from main"
        echo -e "Maximum commits that can be squashed: ${GREEN}$total_commits${NC}"
    fi
}

# 显示最近的提交历史并获取压缩数量
show_recent_commits() {
    echo -e "\n${YELLOW}Recent commits:${NC}"
    git --no-pager log --oneline -n 5
    
    # 计算与main分支的距离
    commits_ahead=$(git rev-list --count main..HEAD)
    
    echo -e "\n${YELLOW}Valid squash range:${NC}"
    echo -e "Minimum commits: ${GREEN}2${NC}"
    echo -e "Maximum commits: ${GREEN}$commits_ahead${NC} (number of commits ahead of main)"
    
    while true; do
        echo -e "\n${YELLOW}How many commits do you want to squash? (${GREEN}2${NC} to ${GREEN}$commits_ahead${NC})${NC}"
        read -r commits_count
        
        # 验证输入是否在有效范围内
        if [[ "$commits_count" =~ ^[0-9]+$ ]] && [ "$commits_count" -ge 2 ] && [ "$commits_count" -le "$commits_ahead" ]; then
            COMMITS_TO_SQUASH=$commits_count
            break
        else
            echo -e "${RED}Please provide a number between 2 and $commits_ahead${NC}"
        fi
    done
}

# 创建备份分支
create_backup() {
    current_branch=$(git branch --show-current)
    backup_branch="${current_branch}_backup_$(date +%Y%m%d_%H%M%S)"
    git branch $backup_branch || handle_error "Failed to create backup branch"
    echo -e "${GREEN}Created backup branch: $backup_branch${NC}"
}

# 执行squash操作
do_squash() {
    local commits_count=$1
    
    echo -e "\n${YELLOW}Will squash last $commits_count commits:${NC}"
    git --no-pager log --oneline -n "$commits_count"
    
    echo -e "\n${YELLOW}Do you want to continue? (y/n)${NC}"
    read -r response
    if [[ ! "$response" =~ ^[Yy]$ ]]; then
        echo "Operation cancelled"
        exit 0
    fi
    
    # 创建备份
    create_backup
    
    # 执行交互式rebase
    echo -e "\n${YELLOW}Starting interactive rebase...${NC}"
    echo -e "${YELLOW}In the editor:${NC}"
    echo -e "1. Leave the first 'pick' as is"
    echo -e "2. Change 'pick' to 's' or 'squash' for all other commits"
    echo -e "3. Save and close the editor"
    echo -e "4. In the next editor, write your combined commit message"
    
    if ! git rebase -i HEAD~"$commits_count"; then
        echo -e "${RED}Rebase failed. Restoring from backup...${NC}"
        git rebase --abort
        handle_error "Rebase failed"
    fi
}

# 推送更改
push_changes() {
    echo -e "\n${YELLOW}Do you want to push changes to remote? (y/n)${NC}"
    read -r response
    if [[ "$response" =~ ^[Yy]$ ]]; then
        current_branch=$(git branch --show-current)
        echo -e "${YELLOW}Using force push with lease for safety...${NC}"
        if git push origin "$current_branch" --force-with-lease; then
            echo -e "${GREEN}Successfully pushed changes${NC}"
        else
            handle_error "Push failed"
        fi
    fi
}

# 主函数
main() {
    # 检查是否在git仓库中
    git rev-parse --git-dir > /dev/null 2>&1 || handle_error "Not in a git repository"
    
    # 检查是否有改动需要提交
    if git diff-index --quiet HEAD -- && [ -z "$(git ls-files --others --exclude-standard)" ]; then
        echo -e "\n${YELLOW}No changes to stage or commit, skipping...${NC}"
    else
        # 添加新的暂存和提交步骤
        echo -e "\n${YELLOW}Staging all changes...${NC}"
        git add . || handle_error "Failed to stage changes"
        
        echo -e "${GREEN}Successfully staged all changes${NC}"
        
        echo -e "\n${YELLOW}Creating stage commit...${NC}"
        git commit -m "stage commit" || handle_error "Failed to create commit"
        
        echo -e "${GREEN}Successfully created stage commit${NC}"
    fi
    
    # 显示提交信息
    get_commit_info
    
    # 显示当前提交历史并获取要压缩的提交数
    show_recent_commits
    
    # 执行squash操作
    do_squash "$COMMITS_TO_SQUASH"
    
    # 推送更改
    push_changes
    
    echo -e "\n${GREEN}All operations completed successfully${NC}"
}

# 执行主函数
main
相关推荐
leisoo80974 小时前
100GBA股股票数据怎么存ClickHouseRedisMySQLJSON完整对比
大数据·linux·服务器·开发语言·python
AI产品测评官5 小时前
突破系统割裂困局:2026企业级AI招聘架构如何迈向“原生全流程”?
大数据·微服务·架构
梦梦代码精5 小时前
连锁品牌数字化:从门店扩张到用户资产运营的技术底座
大数据·人工智能·低代码·docker·开源·代码规范
沐梯子8 小时前
具身智能爆发前夜的“数据饥渴”:2026机器人数据采集产业链选型解析
大数据·人工智能·机器人
ltqvibe8 小时前
企业数智化中台的五层架构——AI框架为什么需要纵向贯通
大数据·人工智能·架构
吴free9 小时前
现代软件工程新范式:Harness、LOOP与Graph工程深度解析
大数据·软件工程
MuMuMu122310 小时前
工业园区 VOCs 绿岛集中治理:越华环保集团项目技术方案与工程实践
大数据·运维
AI大模型-小雄11 小时前
Codex写分页接口为什么越翻越慢?用Cursor Pagination解决重复与漏数据
大数据·数据库·elasticsearch·搜索引擎·chatgpt·后端开发·codex
品牌测评11 小时前
大模型推理算力平台推荐分享|六家平台计费与架构拆解
大数据·人工智能·架构
LedgerNinja11 小时前
WEEX 真实情况如何?交易平台如何判断是否可靠
大数据·人工智能·区块链