Lista Todos os Repositórios com Arquivos Modificados

Publish date: Nov 19, 2020
Tags: git, cli, linux, bash, scripting

Motivação

Como eu estou usando mais de uma máquina em minha casa, frequentemente eu esqueço de subir algum código para o repositório remoto. Isso pode ser um grande inconveniente quando eu já desliguei o computador com o código original.

A Solução

A solução pra mim é manter o histórico de quais repositórios eu fiz modificações. No meu caso isso é suficiente porque eu costumo subir o código imediatamente após comitar.

Low Tech

Para a tarefa eu escolhi uma abordagem simples: um script bash que busca todos os repositórios com modificações pendentes de commit. Estou usando: find, sed, git ls-files e um simples for-loop.

Implementação e comentários

modified-repos.sh

#!/usr/bin/env bash

if [ -n "$1" ]; then DIR="$1"; else DIR="$HOME"; fi
if [ "$1" == "help" ];
then
    echo 'Usage:   $ ./modified-repos.sh [directory-name]'
    echo '         directory-name: optional parameters, defaults to $HOME'
    echo 'Example: $ ./modified-repos.sh .'
    exit 0;
fi

for f in $(find $DIR -name .git -type d -not -name 'node_modules' 2> /dev/null | sed 's/\/.git$/'/)
do
    if [ $(git -C $f ls-files -m | wc -l) -ne 0 ]; then echo "$f"; fi
done

Argumentos

Aceita: o diretório base ou “help” Se nada for passado usa o diretório do usuário $HOME como base

Comando find

Uso o comando find para buscar pelo diretório .git com a opção -not -name para excluir os diretórios com node_modules no nome. Para ignorar os erros de permissão eu direciono o stderr para /dev/null.

Comando sed

Remove a parte .git do nome do diretório e fica apenas como o nome do diretório da raiz do repositório.

Comando git ls-files

A linha if [ $(git -C $f ls-files -m | wc -l) -ne 0 ]; then echo "$f"; fi é a mais interessante. Segue análise de suas partes:

git -C <directory-name>: permite que eu execute o comando git à partir de um outro diretório. ls-files -m: o comando lista todos os arquivos controlados pelo git que foram modificados depois do último commit. wc -l: conta o número de linhas na saída de ls-files -m

Se o número de linhas modificadas for maior do que zero, o nome do diretório é exibido, senão é ignorado.

O Resultado Esperado

$ ./modified-repos.sh .

Deve resultar em algo como:

./elisp/emacs-bitbucket
./elisp/mosql
./elisp/company-sql
./elisp/mopomo