git: determina si hay un file que no está en el repository, pero debe agregarse

Tengo un repository donde Git muestra que:

$ git status # On branch develop # Your branch is up-to-date with 'origin/develop'. # # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: pom.xml # # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: src/main/java/fr/SomeClass.java # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # README.md # 

Me gustaría saber de una manera razonablemente rápida si:

  • hay files en etapas para commit (aquí: pom.xml )
  • no organizado para commit (aquí: SomeClass.java )
  • files sin README.md (aquí: README.md )

Estoy usando el siguiente command para el primer caso:

  git diff --no-ext-diff --quiet --exit-code 2> /dev/null || w='*' git diff --no-ext-diff --quiet --exit-code HEAD 2> /dev/null || h='+' 

Pero cuando solo un file no está en etapas, w y h se completan con * y + .

 $ git status --porcelain M pom.xml M src/main/java/fr/SomeClass.java ?? toto 

Funcionaría, pero imprime mucho, y estoy buscando algo que simplifique la printing de una serie de elementos, como:

 1 1 1 

Donde cada número es, respectivamente, organizado, no organizado y sin seguimiento.

Mi propósito aquí es imprimir si se cambian mis repositorys y qué se cambia. No quiero analizar todo el resultado (eso funcionaría con grep y tal, pero quiero evitar eso).

Ah, y lo etiqueté con Windows porque estoy buscando una solución que funcione en Linux pero también en Windows con git-bash. La solución basada en Bash 4, sin una forma explícita de hacerlo en Bash 3, no me ayudará mucho.

 #!/bin/bash let untracked_count=0 worktree_count=0 staged_count=0 other_count=0 git status -z --porcelain > status.tmp while IFS= read -n 2 stat; IFS= read -d '' line; do case "$stat" in (\?\?) (( untracked_count++ )) ;; (\ ?) (( worktree_count++ )) ;; (?\ ) (( staged_count++ )) ;; (M?) (( worktree_count++ )) ; (( staged_count++ )) ;; *) (( other_count++ )) ;; esac done < status.tmp 

Lee el git status -z --porcelain salida de git status -z --porcelain con read git status -z --porcelain bash para captar la información que nos importa y luego count lo que vemos. IFS en la primera lectura es necesario para evitar que el shell arroje espacios iniciales o finales. IFS en la segunda lectura no es estrictamente necesario en este caso, pero es el patrón de "lectura de input por líneas" que uso.

El uso de bash 4 permitiría un set less duplicado de tags de casos (mediante el uso de ;;& ).

Nota al pie: en Linux, se puede hacer así:

 while IFS= read -n 2 stat; IFS= read -d '' line; do .. done < <(git status -z --porcelain) 

Pero el <(...) redirect no está implementado en Git Bash en Windows.