如何批量检查Git仓库的未提交变更及远程同步状态?
Hey there! Let's break down these two common multi-repo Git checks with practical, actionable scripts—they'll save you a ton of manual work.
If you've got a predefined list of repos you need to audit, a simple bash script can automate the process. The key steps are: fetch the latest remote data (without messing with your local workspace), then compare your local branch's commit ID to the corresponding remote branch.
Here's the script:
# Define your list of repository paths REPOS=( "/home/you/projects/repo-a" "/home/you/projects/repo-b" "/home/you/projects/repo-c" ) for repo in "${REPOS[@]}"; do echo "=== Checking $repo ===" # Skip if we can't access the repo cd "$repo" || { echo "⚠️ Could not access $repo"; echo ""; continue; } # Fetch remote updates quietly git fetch --quiet # Get current branch and its remote counterpart CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) REMOTE_BRANCH="origin/$CURRENT_BRANCH" # Grab commit IDs for local and remote LOCAL_COMMIT=$(git rev-parse HEAD) REMOTE_COMMIT=$(git rev-parse "$REMOTE_BRANCH") # Compare and report status if [ "$LOCAL_COMMIT" = "$REMOTE_COMMIT" ]; then echo "* $CURRENT_BRANCH is fully synced with $REMOTE_BRANCH" else if git merge-base --is-ancestor "$LOCAL_COMMIT" "$REMOTE_BRANCH"; then echo "* $CURRENT_BRANCH is behind $REMOTE_BRANCH (needs a pull)" elif git merge-base --is-ancestor "$REMOTE_COMMIT" "$LOCAL_COMMIT"; then echo "* $CURRENT_BRANCH is ahead of $REMOTE_BRANCH (needs a push)" else echo "* $CURRENT_BRANCH and $REMOTE_BRANCH have diverged (resolve conflicts first)" fi fi echo "" done
Just update the REPOS array with your actual repo paths. The script will tell you if each repo is synced, behind, ahead, or has diverged from its remote.
For a directory full of repos (each with both Github and Gitlab remotes), we can loop through every Git repo, check for uncommitted changes, then verify sync status with both remotes.
First, make sure each repo has both remotes set up (you can add the Gitlab remote with git remote add gitlab <gitlab-repo-url> if you haven't already). Then use this script:
# Navigate to the parent directory containing all your repos cd "/home/you/all-git-repos" || exit # Loop through all subdirectories that are Git repos (identified by .git folder) for repo_dir in */; do # Check if this is a Git repo if [ -d "$repo_dir/.git" ]; then echo "=== Checking ${repo_dir%/} ===" cd "$repo_dir" || { echo "⚠️ Could not access ${repo_dir%/}"; echo ""; cd ..; continue; } # Check for uncommitted changes (workspace + staging area) echo -n "Uncommitted changes: " if git status --porcelain | grep -q .; then echo "* Found uncommitted changes (run `git status` for details)" else echo "* No uncommitted changes" fi # Fetch latest updates from all remotes git fetch --all --quiet # Check sync status with Github (origin remote) CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) echo -n "Github sync status (origin/$CURRENT_BRANCH): " if git rev-parse --verify "origin/$CURRENT_BRANCH" >/dev/null 2>&1; then LOCAL_COMMIT=$(git rev-parse HEAD) REMOTE_COMMIT=$(git rev-parse "origin/$CURRENT_BRANCH") if [ "$LOCAL_COMMIT" = "$REMOTE_COMMIT" ]; then echo "* Fully synced" elif git merge-base --is-ancestor "$LOCAL_COMMIT" "origin/$CURRENT_BRANCH"; then echo "* Local is behind Github (needs pull)" elif git merge-base --is-ancestor "$REMOTE_COMMIT" "$LOCAL_COMMIT"; then echo "* Local has commits not pushed to Github (needs push)" else echo "* Local and Github have diverged" fi else echo "* Github remote branch not found" fi # Check sync status with Gitlab (gitlab remote) echo -n "Gitlab sync status (gitlab/$CURRENT_BRANCH): " if git rev-parse --verify "gitlab/$CURRENT_BRANCH" >/dev/null 2>&1; then LOCAL_COMMIT=$(git rev-parse HEAD) GITLAB_COMMIT=$(git rev-parse "gitlab/$CURRENT_BRANCH") if [ "$LOCAL_COMMIT" = "$GITLAB_COMMIT" ]; then echo "* Fully synced" elif git merge-base --is-ancestor "$LOCAL_COMMIT" "gitlab/$CURRENT_BRANCH"; then echo "* Local is behind Gitlab (needs pull)" elif git merge-base --is-ancestor "$GITLAB_COMMIT" "$LOCAL_COMMIT"; then echo "* Local has commits not pushed to Gitlab (needs push)" else echo "* Local and Gitlab have diverged" fi else echo "* Gitlab remote branch not found" fi echo "" cd .. fi done
This script automatically detects all Git repos in the parent directory, checks for any uncommitted changes (using git status --porcelain which gives a clean, parseable output), then verifies sync status with both Github and Gitlab remotes.
内容的提问来源于stack exchange,提问作者a06e

