可以將當前未提交的代碼自動執行
- git add
- git commit
- git squash
Git 命令安裝指南
1. 創建腳本目錄
如果目錄不存在,創建它:
mkdir -p ~/.local/bin
2. 創建腳本文件
vim ~/.local/bin/git-squash
將完整的腳本代碼復制到此文件中。
3. 設置腳本權限
chmod +x ~/.local/bin/git-squash
4. 配置 PATH
編輯 shell 配置文件(根據你使用的 shell 選擇):
# 對于 bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc# 或對于 zsh
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
重新加載配置:
source ~/.bashrc # 或 source ~/.zshrc
5. 創建 Git 別名
git config --global alias.allen-squash '!git-squash'
6. 驗證安裝
檢查腳本是否可執行:
ls -l ~/.local/bin/git-squash
檢查腳本是否在 PATH 中:
which git-squash
檢查 git 別名是否設置成功:
git config --get-regexp alias.*squash
7. 使用方法
可以通過以下兩種方式使用:
# 直接使用腳本
git-squash# 或使用 git 別名
git allen-squash
8. 常見問題排查
命令未找到
- 檢查 PATH:
echo $PATH | grep -o ~/.local/bin
- 檢查腳本權限:
ls -l ~/.local/bin/git-squash
- 檢查 git 別名:
git config --list | grep allen-squash
管理別名
# 刪除別名
git config --global --unset alias.allen-squash# 修改別名
git config --global alias.allen-squash '!git-squash'
編輯腳本
vim ~/.local/bin/git-squash
9. 備份建議
建議進行以下備份:
# 備份腳本
cp ~/.local/bin/git-squash ~/.local/bin/git-squash.backup# 備份 git 配置
cp ~/.gitconfig ~/.gitconfig.backup
10. 更新腳本
如需更新腳本:
# 編輯腳本
vim ~/.local/bin/git-squash# 確保權限正確
chmod +x ~/.local/bin/git-squash
注意事項
- 確保
~/.local/bin
目錄存在并在 PATH 中 - 確保腳本具有可執行權限
- 重啟終端或重新加載配置文件后更改才會生效
- 建議在使用前先進行配置備份
- 如果遇到權限問題,檢查用戶權限和文件權限
故障排除
如果命令不能正常工作,請按以下步驟檢查:
-
確認腳本位置:
- 檢查
~/.local/bin/git-squash
是否存在 - 確認文件權限是否正確
- 檢查
-
檢查 PATH 設置:
- 確認
~/.local/bin
在 PATH 中 - 檢查 shell 配置文件是否正確加載
- 確認
-
驗證 git 別名:
- 檢查別名是否正確設置
- 確認 git 配置文件是否正確
腳本內容
#!/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; thencommits_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}"elseecho -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; doecho -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" ]; thenCOMMITS_TO_SQUASH=$commits_countbreakelseecho -e "${RED}Please provide a number between 2 and $commits_ahead${NC}"fidone
}# 創建備份分支
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=$1echo -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 responseif [[ ! "$response" =~ ^[Yy]$ ]]; thenecho "Operation cancelled"exit 0fi# 創建備份create_backup# 執行交互式rebaseecho -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"; thenecho -e "${RED}Rebase failed. Restoring from backup...${NC}"git rebase --aborthandle_error "Rebase failed"fi
}# 推送更改
push_changes() {echo -e "\n${YELLOW}Do you want to push changes to remote? (y/n)${NC}"read -r responseif [[ "$response" =~ ^[Yy]$ ]]; thencurrent_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; thenecho -e "${GREEN}Successfully pushed changes${NC}"elsehandle_error "Push failed"fifi
}# 主函數
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)" ]; thenecho -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_changesecho -e "\n${GREEN}All operations completed successfully${NC}"
}# 執行主函數
main