Intelligente Lösungen
in neuer Dimension

Linux - Git-Verzeichnis bereinigen

Mein Git-Verzeichnis ist mittlerweile richtig groß geworden: Über 65GB. Ich weiß, dass da viel Schrott dabei ist, den ich so nicht mehr benötige. Konkret gibt es viele Git-Clones von Git-Servern, die längst nicht mehr zur Verfügung stehen. Hier beschreibe ich, wie ich diese Clones finde und bereinige.

Randbedingungen

Bei mir gilt:

  • Alle Git-Projekte liegen unterhalb von “$HOME/git”
  • Alle Git-Projekte sind in einem Backup gesichert. ich kann also relativ offensiv löschen
  • Alle Git-Projekte enthalten keine merkwürdigen Zeichen wie Leerzeichen im Verzeichnisnamen
  • Alle Git-Servernamen (git remotes) enthalten keine merkwürdigen Zeichen wie Leerzeichen

Git-Projektverzeichnisse finden

Unterhalb von “$HOME/git” liegen die Git-Projekte. Diese sind teilweise in Unterverzeichnissen. Also Ziel 1: Ermutteln der Git-Projektverzeichnisse:

1
2
3
4
5
6
7
8
9
$ find "${HOME}/git" -name ".git" -type d|xargs -n1 dirname|tee /tmp/git-projects
/home/uli/git/john-eastfield
/home/uli/git/g3
/home/uli/git/vorlagen
/home/uli/git/virus-checker-verification
/home/uli/git/sandbox
/home/uli/git/uli-gradle
/home/uli/git/dp-flot
...

Git-Projektverzeichnisse mit Problemen finden

Nun möchte ich mit Ziel 2 ermitteln, welche Git-Projektverzeichnisse Probleme mit ihren hinterlegten Git-Servern haben:

1
2
3
4
5
6
7
8
9
$ cat /tmp/git-projects|while read d; do ( cd "$d"; if git remote -v update >/dev/null 2>&1; then echo "OK: $d"; else echo "KO: $d"; fi ); done |tee /tmp/git-projects-status
OK: /home/uli/git/john-eastfield
OK: /home/uli/git/g3
OK: /home/uli/git/vorlagen
OK: /home/uli/git/virus-checker-verification
KO: /home/uli/git/sandbox
OK: /home/uli/git/uli-gradle
KO: /home/uli/git/dp-flot
...

Die Zeilen, die mit “KO:” beginnen, zeigen Git-Projektverzeichnisse an, die mit Problemen kämpfen.

Komplettes Kommando:

1
find "${HOME}/git" -name ".git" -type d|xargs -n1 dirname|while read d; do ( cd "$d"; if git remote -v update >/dev/null 2>&1; then echo "OK: $d"; else echo "KO: $d"; fi ); done

Git-Server mit Problemen ermitteln

Ziel 3: Alle problematischen Git-Projektverzeichnisse sichten und jeweils ermitteln, ob alle hinterlegten Git-Server Probleme haben:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ cat /tmp/git-projects-status          \
|grep "^KO:"                            \
|cut -d " " -f 2-                       \
|while read d; do (                     \
    STATUS=KO;                          \
    REMOTE_STATUS=;                     \
    cd "$d";                            \
    for r in $(git remote); do          \
      if git remote -v update "${r}" >/dev/null 2>&1; then\
        REMOTE_STATUS="${REMOTE_STATUS} ${r}:OK";\
        STATUS=OK;                      \
      else                              \
        REMOTE_STATUS="${REMOTE_STATUS} ${r}:KO";\
      fi;                               \
    done;                               \
    echo "${STATUS}: ${d} ${REMOTE_STATUS}";\
 ); done | tee /tmp/git-remotes-status
KO: /home/uli/git/sandbox  origin:KO
KO: /home/uli/git/dp-flot  origin:KO
...
OK: /home/uli/git/dp-gitea/dp-browser  gitbucket:KO origin:OK
OK: /home/uli/git/dp-gitea/dp-octopress  intern:KO origin:OK
OK: /home/uli/git/dp-gitea/dp-verwaltung  gitbucket:KO origin:OK
...

Die Zeilen, die mit “KO:” beginnen, zeigen Git-Projektverzeichnisse an, die keinen funktionierenden Git-Server hinterlegt haben. Ich denke, diese werde ich löschen!

Die Zeilen, die mit “OK:” beginnen, zeigen Git-Projektverzeichnisse an, die mindestens einen nucht funktionierenden Git-Server hinterlegt haben. Ich denke, diese ich werde ich bereinigen!

Komplettes Kommando:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
find "${HOME}/git" -name ".git" -type d \
|xargs -n1 dirname                      \
|while read d; do (                     \
    cd "$d";                            \
    if git remote -v update >/dev/null 2>&1; then \
      echo "OK: $d";                    \
    else                                \
      echo "KO: $d";                    \
    fi                                  \
 ); done                                \
|grep "^KO:"                            \
|cut -d " " -f 2-                       \
|while read d; do (                     \
    STATUS=KO;                          \
    REMOTE_STATUS=;                     \
    cd "$d";                            \
    for r in $(git remote); do          \
      if git remote -v update "${r}" >/dev/null 2>&1; then\
        REMOTE_STATUS="${REMOTE_STATUS} ${r}:OK";\
        STATUS=OK;                      \
      else                              \
        REMOTE_STATUS="${REMOTE_STATUS} ${r}:KO";\
      fi;                               \
    done;                               \
    echo "${STATUS}: ${d} ${REMOTE_STATUS}";\
 ); done

Git-Projektverzeichnisse bereinigen

Diejenigen Git-Projektverzeichnisse, bei denen nicht erreichbare Git-Server hinterlegt sind, werden bereinigt. Ich lösche die nicht erreichbaren Git-Server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ cat /tmp/git-remotes-status \
|grep "^OK: "                 \
|cut -d " " -f 2              \
|while read d; do test -d "${d}" && echo "${d}"; done\
|while read d; do (           \
   cd "${d}" || exit 0;       \
   for r in $(git remote); do \
     git remote -v update "${r}" >/dev/null 2>&1 || echo "( cd '$(pwd)'; git remote remove '${r}' )"; \
   done                       \
 ); done | tee /tmp/git-remove-remotes
( cd '/home/uli/git/dpserver'; git remote remove 'gitbucket' )
( cd '/home/uli/git/forked/mdwiki'; git remote remove 'ciel' )
( cd '/home/uli/git/forked/dl'; git remote remove 'origin' )
...

Es werden die Befehle ausgegeben, die zum Löschen der nicht erreichbaren Git-Server ausgeführt werden müssen. Befehle sichten und ausführen!

Komplettes Kommando:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
find "${HOME}/git" -name ".git" -type d \
|xargs -n1 dirname                      \
|while read d; do (                     \
    cd "$d";                            \
    if git remote -v update >/dev/null 2>&1; then \
      echo "OK: $d";                    \
    else                                \
      echo "KO: $d";                    \
    fi                                  \
 ); done                                \
|grep "^KO:"                            \
|cut -d " " -f 2-                       \
|while read d; do (                     \
    STATUS=KO;                          \
    REMOTE_STATUS=;                     \
    cd "$d";                            \
    for r in $(git remote); do          \
      if git remote -v update "${r}" >/dev/null 2>&1; then\
        REMOTE_STATUS="${REMOTE_STATUS} ${r}:OK";\
        STATUS=OK;                      \
      else                              \
        REMOTE_STATUS="${REMOTE_STATUS} ${r}:KO";\
      fi;                               \
    done;                               \
    echo "${STATUS}: ${d} ${REMOTE_STATUS}";\
 ); done                                \
|grep "^OK: "                           \
|cut -d " " -f 2                        \
|while read d; do test -d "${d}" && echo "${d}"; done\
|while read d; do (                     \
   cd "${d}" || exit 0;                 \
   for r in $(git remote); do           \
     git remote -v update "${r}" >/dev/null 2>&1 || echo "( cd '$(pwd)'; git remote remove '${r}' )"; \
   done                                 \
 ); done

Git-Projektverzeichnisse löschen

Diejenigen Git-Projektverzeichnisse, bei nur nicht erreichbare Git-Server hinterlegt sind, werden gelöscht:

1
2
3
4
5
6
7
8
9
$ cat /tmp/git-remotes-status \
|grep "^KO: "                 \
|cut -d " " -f 2              \
|while read d; do \
   test -d "${d}" && echo "rm -rf '${d}'";\
 done | tee /tmp/git-remove
rm -rf '/home/uli/git/sandbox'
rm -rf '/home/uli/git/dp-flot'
...

Es werden die Befehle ausgegeben, die zum Löschen der kaputten Git-Projektverzeichnisse ausgeführt werden müssen. Befehle sichten und ausführen!

Komplettes Kommando:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
find "${HOME}/git" -name ".git" -type d \
|xargs -n1 dirname                      \
|while read d; do (                     \
    cd "$d";                            \
    if git remote -v update >/dev/null 2>&1; then \
      echo "OK: $d";                    \
    else                                \
      echo "KO: $d";                    \
    fi                                  \
 ); done                                \
|grep "^KO:"                            \
|cut -d " " -f 2-                       \
|while read d; do (                     \
    STATUS=KO;                          \
    REMOTE_STATUS=;                     \
    cd "$d";                            \
    for r in $(git remote); do          \
      if git remote -v update "${r}" >/dev/null 2>&1; then\
        REMOTE_STATUS="${REMOTE_STATUS} ${r}:OK";\
        STATUS=OK;                      \
      else                              \
        REMOTE_STATUS="${REMOTE_STATUS} ${r}:KO";\
      fi;                               \
    done;                               \
    echo "${STATUS}: ${d} ${REMOTE_STATUS}";\
 ); done                                \
|grep "^OK: "                           \
|cut -d " " -f 2                        \
|while read d; do test -d "${d}" && echo "${d}"; done\
|while read d; do (                     \
   cd "${d}" || exit 0;                 \
   for r in $(git remote); do           \
     git remote -v update "${r}" >/dev/null 2>&1 || echo "( cd '$(pwd)'; git remote remove '${r}' )"; \
   done                                 \
 ); done

Git-Projektverzeichnisse komprimieren

1
2
3
4
5
6
7
8
$ find "${HOME}/git" -name ".git" -type d \
|xargs -n1 dirname                      \
|while read d; do (                     \
    set -x;                             \
    cd "$d";                            \
    git reflog expire --expire-unreachable=now --all; \
    git gc --prune=now                  \
 ); done

Platzbedarf

Zeitpunkt GB Bytes Anmerkung
Beginn 73G 76129180 Ausgangslage
DP-Server bereinigt 73G 76128152 … hat wenig gebracht!
Gelöscht 54G 56187800 … immerhin grob 20G weniger
Komprimiert 52G 54397904 … nochmal 2G weniger

Historie

  • 2023-11-26: Erste Version