Alexander Mills
Alexander Mills

Reputation: 100320

Command line tool to check if any git repos have uncommitted code?

Is there a command line tool that can look through a directory recursively for all the .git repos and check for uncommitted code? The use case is I have a machine at work and one at home and sometimes I forget to push code to Github before I go home after work. Does such a tool exist that can do this? Perhaps git itself can do this?

I might want to write something like this myself just for fun - does anyone know how to inspect a .git repo for uncommitted code? I supposed I could run the git command and collect the results somehow.

Upvotes: 1

Views: 479

Answers (4)

danialk
danialk

Reputation: 1463

Shell script below to list out repos with changes, stashes and commits not present in remote.

Note this skips submodules and bare repos, to include those, modify the find command per this question's answer.

#!/usr/bin/env bash

# Usage:
# - Save this file as e.g. find-repos.sh
# - Give execute permissions with `chmod +x find-repos.sh`
# - Run the script with optional path to repos (default to current directory), e.g. `./find-repos.sh ~/my-projects`

# Store current working directory to switch back to later on
PWD_PATH=$(pwd)

# Fetch source path to scan from argument, if unset use current directory
SOURCE_PATH="${1:-$PWD_PATH}"

# Ensure ~ is expanded to an absolute path
PATH_TO_SCAN=$(eval echo "${SOURCE_PATH}")

echo "Scanning for repos with changes and stashes in ${PATH_TO_SCAN}"

# Set up counters
REPO_COUNT=0
REPO_WITH_CHANGES_COUNT=0

# Loop through all directories and check git
for GIT_DIRECTORY in $(find "${PATH_TO_SCAN}" -type d -name '*.git');
do
  REPO_DIRECTORY=$(dirname "${GIT_DIRECTORY}")

  # Change in to directory
  cd ${REPO_DIRECTORY}

  # Check for any modified or untracked files
  GIT_STATUS=$(git status --porcelain)
  if [ -n "$GIT_STATUS" ]; then
    echo "Found changes in repo: ${REPO_DIRECTORY}"
    echo "$GIT_STATUS"
    ((REPO_WITH_CHANGES_COUNT++))
    echo "---"
  fi

  # Check for any stashes
  GIT_STASH_LIST=$(git stash list)
  if [ -n "$GIT_STASH_LIST" ]; then
    echo "Found stashes in repo: ${REPO_DIRECTORY}"
    echo "$GIT_STASH_LIST"
    ((REPO_WITH_CHANGES_COUNT++))
    echo "---"
  fi

  # Check for branches not in remote
  GIT_BRANCHES_NOT_REMOTE=$(git log --oneline --branches --not --remotes)
  if [ -n "$GIT_BRANCHES_NOT_REMOTE" ]; then
    echo "Found local commits not available in remote: ${REPO_DIRECTORY}"
    echo "$GIT_BRANCHES_NOT_REMOTE"
    ((REPO_WITH_CHANGES_COUNT++))
    echo "---"
  fi

  ((REPO_COUNT++))
done

# Change back to original working directory
cd "${PWD_PATH}"

# Print summary
echo "Processed ${REPO_COUNT} repos, ${REPO_WITH_CHANGES_COUNT} repos to review"

Upvotes: 1

HelloPablo
HelloPablo

Reputation: 625

I had the same problem/requirement and ended up using eapen/ucommitted, which works very well.

Of course, writing a script as you/others mentioned would be straightforward, and a great learning exercise!

Upvotes: 1

CodeWizard
CodeWizard

Reputation: 142542

Lets explain how git works (in general).

Git has something called as 3 states.
The 3 states are a very basic piece of git, and the changes you make are reflected in this structure.


3 states

enter image description here

To simplify it look on it like this:
In each project you have 1 of each.

  • The working directory is your file system, where you wrote your code.
  • The statging area is where you add your files before commiting it.
  • The repository is where you commit and store all your changes,

As mentioned before each project has 1 of each and as a result every time you switch to a different branch all the content form the working directory & staging are is "moving" and will appear on every branch until you commit it.

So once we understand what is going on the answer to your question is simple:

You need to find out which content is not commited yet. You do it with git status command.


git status

enter image description here

Upvotes: 2

qHack
qHack

Reputation: 332

git status --s

gets you something like

M includes/angular/settingsCtrl.js
M index.php
M templates/views/settings/profile.php
?? vendor/apache/

Which are all the new /modified files in your current working dir

You can feed those results into git add then run git commit, then git push

You should be able to do this with a shell script

Upvotes: 1

Related Questions