Git Repository Struktur: Ein vollständiger technischer Leitfaden
Git ist ein verteiltes Versionskontrollsystem, das den Projektverlauf als gerichteten azyklischen Graphen (DAG) aus unveränderlichen Snapshot-Objekten speichert. Jedes Git-Repository besteht aus drei logischen Zonen — dem Arbeitsverzeichnis, dem Staging-Index und dem Objektspeicher innerhalb von .git/ — sowie einer Reihe von leichtgewichtigen Zeigern (Branches, Tags, Remotes), die durch diese Historie navigieren. Das Verständnis, wie diese Schichten zusammenwirken, ist der Unterschied zwischen mechanischer und präziser Nutzung von Git.
Wenn Sie Ihre Repositories auf einem VPS selbst hosten, ermöglicht Ihnen die Beherrschung dieser internen Struktur, sich von Katastrophen zu erholen, effiziente CI/CD-Pipelines zu entwerfen und jeden Byte der Historie Ihres Projekts zu prüfen, ohne auf eine Drittanbieter-Plattform angewiesen zu sein.
Das Drei-Zonen-Modell: Wie Git Daten bewegt
Bevor wir uns mit einzelnen Komponenten befassen, sollten Sie das Datenflusskmodell verinnerlichen, das jeden Git-Vorgang steuert:
Working Directory --> Staging Area (Index) --> .git/ Object Store
(edit) (git add) (git commit)Änderungen fließen von links nach rechts, wenn Sie einen Commit erstellen, und von rechts nach links, wenn Sie wiederherstellen oder zurücksetzen. Jeder Git-Befehl ist im Wesentlichen ein Lese- oder Schreibvorgang auf einer oder mehreren dieser Zonen.
Arbeitsverzeichnis
Das Arbeitsverzeichnis (auch als Working Tree bezeichnet) ist die Dateisystemansicht Ihres Projekts in einem bestimmten Checkout-Zustand. Wenn Sie git clone oder git checkout ausführen, rekonstruiert Git Dateien aus komprimierten Objekten in .git/objects/ und schreibt sie in dieses Verzeichnis.
Dateien im Arbeitsverzeichnis befinden sich in einem von vier Zuständen:
- Unverfolgt — Git hat diese Datei noch nie gesehen; sie existiert nur auf der Festplatte.
- Verfolgt, unverändert — die Datei stimmt exakt mit dem zuletzt committeten Snapshot überein.
- Verfolgt, geändert — die Datei unterscheidet sich vom zuletzt committeten Snapshot, wurde aber noch nicht gestagt.
- Verfolgt, gelöscht — die Datei wurde von der Festplatte entfernt, aber die Löschung wurde noch nicht gestagt.
Eine wichtige Nuance, die viele Entwickler verwirrt: Das Arbeitsverzeichnis ist keine einfache Kopie des Repositorys. Git rekonstruiert es, indem es Tree-Objekte liest und Blob-Objekte dekomprimiert. Wenn .git/ intakt ist, können Sie das Arbeitsverzeichnis jederzeit von Grund auf neu generieren — umgekehrt gilt das nicht.
Sparse Checkout für große Monorepos
Bei Repositories mit Zehntausenden von Dateien (häufig in Monorepo-Architekturen) können Sie einschränken, welche Pfade Git im Arbeitsverzeichnis materialisiert:
git sparse-checkout init --cone
git sparse-checkout set services/api services/authDies ist auf einem VPS mit begrenztem Festplatten-I/O äußerst wertvoll, da Git das Dekomprimieren von Blobs für Pfade außerhalb des Kegels überspringt.
Staging-Bereich (Index)
Der Staging-Bereich, intern als Index bezeichnet, ist eine Binärdatei unter .git/index. Er fungiert als vorgeschlagener nächster Commit — ein veränderbarer Snapshot, der zwischen Ihrem Arbeitsverzeichnis und dem permanenten Objektspeicher liegt.
git add <file> # Stage a specific file
git add -p # Interactively stage hunks within a file
git add -u # Stage all tracked modifications and deletions
git status # Compare working directory and index against HEAD
git diff --cached # Show diff between index and HEADWarum der Index existiert
Der Index löst ein Problem, das einfachere VCS-Tools ignorieren: partielle Commits. Sie haben möglicherweise fünf Dateien geändert, möchten aber nur drei davon im nächsten Commit haben. Der Index ermöglicht es Ihnen, genau den Snapshot zusammenzustellen, den Sie aufzeichnen möchten, unabhängig davon, was Ihr Editor geöffnet hat.
Sonderfall — Index-Korruption: Wenn ein Systemabsturz ein git add unterbricht, kann die Index-Datei beschädigt werden. Symptome sind, dass git status hängt oder seltsame Ausgaben liefert. Wiederherstellung:
rm .git/index
git resetGit baut den Index aus HEAD neu auf, ohne Ihr Arbeitsverzeichnis zu berühren.
Der Index als Merge-Konflikt-Register
Während eines Merge-Konflikts speichert der Index drei Versionen jeder konfliktbehafteten Datei gleichzeitig (Stufen 1, 2 und 3 — Basis, unsere, ihre). Deshalb zeigt git diff --cached mitten in einem Konflikt nichts Nützliches; Sie benötigen git diff --cc oder ein Merge-Tool, um alle drei Stufen zu inspizieren.
Das .git/-Verzeichnis: Anatomie des Objektspeichers
Das .git/-Verzeichnis ist das Repository. Alles andere — das Arbeitsverzeichnis, Remote-Klone — wird daraus abgeleitet. Das Löschen von .git/ verwandelt ein Repository in ein einfaches Verzeichnis ohne Historie.
.git/
├── HEAD
├── config
├── description
├── index
├── COMMIT_EDITMSG
├── hooks/
├── info/
├── logs/
│ ├── HEAD
│ └── refs/
├── objects/
│ ├── info/
│ └── pack/
└── refs/
├── heads/
├── remotes/
└── tags/HEAD
HEAD ist eine einfache Textdatei, die entweder eine symbolische Referenz (die auf einen Branch zeigt) oder einen rohen SHA-1-Hash (Detached-HEAD-Zustand) enthält.
cat .git/HEAD
# ref: refs/heads/main <-- on a branch
# a3f1c9d... <-- detached HEADDetached HEAD ist kein Fehlerzustand — er ist beabsichtigt, wenn Sie einen Tag oder einen bestimmten Commit zur Inspektion auschecken. Die Gefahr besteht darin, Commits im Detached-HEAD-Zustand zu erstellen: Diese Commits sind nur über den Reflog erreichbar, bis Sie sie an einen Branch anhängen.
git checkout -b rescue-branch # Attach detached commits to a new branchconfig
Die lokale Repository-Konfigurationsdatei. Sie überschreibt globale (~/.gitconfig) und System- (/etc/gitconfig) Einstellungen. Häufige Einträge:
[core]
repositoryformatversion = 0
filemode = true
bare = false
[remote "origin"]
url = git@github.com:user/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/mainAuf einem selbst gehosteten Server werden Sie diese Datei häufig direkt bearbeiten, wenn Sie Remote-URLs rotieren oder uploadpack.allowReachableSHA1InWant für partielle Klone konfigurieren.
refs/
Das refs/-Verzeichnis enthält einfache Textdateien, die jeweils einen einzelnen SHA-1-Hash enthalten. Sie sind die benannten Zeiger, die Gits DAG navigierbar machen.
| Ref-Typ | Pfad | Beschreibung |
|---|---|---|
| Lokaler Branch | refs/heads/<name> | Zeigt auf den Tip-Commit eines Branches |
| Remote-Tracking-Branch | refs/remotes/<remote>/<name> | Lokaler Cache des Tip eines Remote-Branches |
| Leichtgewichtiger Tag | refs/tags/<name> | Zeigt direkt auf ein Commit-Objekt |
| Annotierter Tag | refs/tags/<name> | Zeigt auf ein Tag-Objekt, das auf einen Commit zeigt |
| Stash | refs/stash | Zeigt auf den Stash-Commit |
Aus Leistungsgründen packt Git Refs in .git/packed-refs, sobald sich in einem Repository viele davon angesammelt haben. Überprüfen Sie beim Scripting gegen Refs immer beide Speicherorte.
Git-Objekte: Der unveränderliche Kern
Alles, was in .git/objects/ gespeichert ist, ist inhaltsadressiert: Der Dateiname ist der SHA-1- (oder SHA-256 in neueren Git-Versionen) Hash des Inhalts des Objekts. Dies macht Git inhärent manipulationssicher — das Ändern eines Bytes ändert den Hash und bricht die Kette.
Die vier Objekttypen
| Objekttyp | Was gespeichert wird | Zeigt auf |
|---|---|---|
| Blob | Roher Dateiinhalt (kein Dateiname, keine Berechtigungen) | Nichts |
| Tree | Verzeichnislisting: Dateinamen, Berechtigungen, Blob/Tree-SHAs | Blobs und andere Trees |
| Commit | Autor, Committer, Zeitstempel, Nachricht, übergeordnete SHA(s) | Ein Tree + null oder mehr übergeordnete Commits |
| Tag | Tagger-Identität, Zeitstempel, Nachricht, GPG-Signatur | Normalerweise ein Commit |
Objekte direkt inspizieren
# Show the type of any object
git cat-file -t a3f1c9d
# Show the content of any object
git cat-file -p a3f1c9d
# Show the tree of the current HEAD commit
git ls-tree HEAD
# Show a specific blob's content
git show HEAD:src/main.pyLose Objekte vs. Pack-Dateien
Anfangs wird jedes Objekt als einzelne komprimierte Datei unter .git/objects/<2-char-prefix>/<38-char-suffix> gespeichert. Dies sind lose Objekte. Mit der Zeit führt Git git gc (Garbage Collection) aus, um lose Objekte in Pack-Dateien (.git/objects/pack/*.pack) mit einem entsprechenden Index (.pack.idx) zu bündeln.
Pack-Dateien verwenden Delta-Komprimierung — sie speichern den Unterschied zwischen ähnlichen Objekten anstatt vollständiger Kopien. Ein Repository mit Tausenden ähnlicher Textdateien kann nach dem Packen erheblich schrumpfen. Auf einem VPS mit begrenzter NVMe-Kapazität ist das Ausführen von git gc --aggressive auf großen Repositories vor der Archivierung gängige Praxis.
git count-objects -vH # Show loose object count and disk usage
git gc --aggressive # Repack aggressively (CPU-intensive)
git verify-pack -v .git/objects/pack/*.idx | sort -k3 -n | tail -20
# Find the 20 largest objects in the packCommit-Historie: Der gerichtete azyklische Graph
Jedes Commit-Objekt enthält genau einen Zeiger auf ein Tree-Objekt (den Root-Verzeichnis-Snapshot) und null oder mehr Zeiger auf übergeordnete Commits. Dies bildet einen DAG, bei dem:
- Null Eltern = der initiale Commit (Root-Commit)
- Ein Elternteil = ein normaler Commit
- Zwei Elternteile = ein Merge-Commit
- Drei oder mehr Elternteile = ein Octopus-Merge (selten, wird zum gleichzeitigen Integrieren vieler Feature-Branches verwendet)
git log --oneline --graph --all # Visualize the full DAG
git log --format="%H %P" # Show each commit's SHA and parent SHA(s)Commit-Unveränderlichkeit und Umschreiben der Historie
Da der SHA eines Commits aus seinem Inhalt (einschließlich der übergeordneten SHAs) abgeleitet wird, erstellt jedes Umschreiben einen neuen Commit mit einem neuen SHA. Operationen wie git rebase, git commit --amend und git filter-repo ändern die Historie nicht — sie erstellen eine parallele Historie. Die alten Commits verbleiben im Objektspeicher, bis sie durch Garbage Collection entfernt werden.
Deshalb ist das erzwungene Pushen umgeschriebener Historie in einen gemeinsam genutzten Branch destruktiv: Die lokalen Branches der Mitarbeiter zeigen weiterhin auf die alte Commit-Kette.
Branches: Leichtgewichtige Zeiger
Ein Branch ist nichts weiter als eine 41-Byte-Datei, die einen SHA-1-Hash enthält. Das Erstellen eines Branches ist unabhängig von der Repository-Größe sofort möglich, da Git nur eine kleine Datei schreibt.
git branch feature/auth # Create branch at current HEAD
git checkout -b feature/auth # Create and switch in one step
git switch -c feature/auth # Modern equivalent (Git 2.23+)
git branch -d feature/auth # Delete (safe: refuses if unmerged)
git branch -D feature/auth # Delete (force: regardless of merge status)Branch-Interna
cat .git/refs/heads/main
# a3f1c9d8e2b1f4c7d9e0a1b2c3d4e5f6a7b8c9d0Wenn Sie auf einem Branch committen, schreibt Git den neuen Commit-SHA in diese Datei. Das ist die Gesamtheit des „Vorrückens eines Branch-Zeigers”.
Tracking-Branches und Upstream-Konfiguration
Eine Tracking-Beziehung teilt Git mit, gegen welchen Remote-Branch ein lokaler Branch für die git status-Divergenzberichterstattung und das git pull-Verhalten verglichen werden soll.
git branch --set-upstream-to=origin/main main
git branch -vv # Show tracking relationships and ahead/behind countsTags: Permanente Markierungen in der Historie
Tags markieren bestimmte Commits als bedeutsam — typischerweise Software-Releases. Im Gegensatz zu Branches werden Tags nicht durch neue Commits verschoben.
| Merkmal | Leichtgewichtiger Tag | Annotierter Tag |
|---|---|---|
| Speicherung | Eine Ref-Datei, die auf einen Commit zeigt | Ein Tag-Objekt im Objektspeicher |
| Metadaten | Keine | Tagger-Name, E-Mail, Datum, Nachricht |
| GPG-Signierung | Nicht möglich | Unterstützt über git tag -s |
| Empfohlen für Releases | Nein | Ja |
Übertragung mit git push --tags | Ja | Ja |
git tag v2.1.0 # Lightweight tag at HEAD
git tag -a v2.1.0 -m "Release 2.1.0" # Annotated tag
git tag -s v2.1.0 -m "Signed release" # GPG-signed annotated tag
git push origin --tags # Push all tags to remote
git push origin v2.1.0 # Push a specific tagKritische Falle: git push pusht standardmäßig keine Tags. Teams vergessen dies häufig und veröffentlichen Release-Notes, die auf einen Tag verweisen, der auf dem Remote nicht existiert.
Remotes: Verteilte Zusammenarbeit
Ein Remote ist eine benannte URL, die in .git/config gespeichert ist. Remote-Tracking-Branches (unter refs/remotes/) sind lokale schreibgeschützte Snapshots der Branches des Remotes, die nur aktualisiert werden, wenn Sie explizit fetchen.
git remote add origin git@github.com:user/repo.git
git remote -v # List remotes with URLs
git remote set-url origin <new-url> # Change a remote URL
git fetch origin # Update remote-tracking branches
git fetch --prune # Remove stale remote-tracking branches
git push origin main # Push local main to remote
git push -u origin feature/auth # Push and set upstream trackingMehrere Remotes
Ein einzelnes Repository kann mehrere Remotes verfolgen — üblich, wenn ein Fork neben dem Upstream gepflegt wird:
git remote add upstream git@github.com:original/repo.git
git fetch upstream
git merge upstream/mainWenn Sie bare Repositories auf einem dedizierten Server für Ihr Team selbst hosten, fügt jeder Entwickler den Server als Remote hinzu und verwendet SSH-Schlüssel-Authentifizierung für Push-Zugriff.
Hooks: Automatisierte Durchsetzung bei jedem Git-Ereignis
Hooks sind ausführbare Skripte in .git/hooks/. Git ruft sie an definierten Punkten im Workflow auf. Sie werden nicht durch git clone oder git push übertragen — jeder Entwickler (oder Server) muss sie unabhängig installieren. Dies ist eine häufige Quelle der Verwirrung in Team-Umgebungen.
Client-seitige Hooks
| Hook | Auslöser | Häufige Verwendung |
|---|---|---|
pre-commit | Vor der Commit-Nachricht-Eingabeaufforderung | Linting, Secret-Scanning, Testausführung |
prepare-commit-msg | Nach Erstellung der Standardnachricht | Branch-Namen in Nachricht einfügen |
commit-msg | Nachdem der Benutzer die Nachricht geschrieben hat | Conventional-Commit-Format durchsetzen |
post-commit | Nachdem der Commit aufgezeichnet wurde | Lokale Benachrichtigungen |
pre-push | Bevor git push ausgeführt wird | Vollständige Testsuite ausführen |
pre-rebase | Bevor Rebase beginnt | Rebase veröffentlichter Branches verhindern |
Server-seitige Hooks
| Hook | Auslöser | Häufige Verwendung |
|---|---|---|
pre-receive | Bevor Refs aktualisiert werden | Branch-Schutz durchsetzen, Force-Push ablehnen |
update | Pro Ref während des Empfangs | Branch-spezifische Richtliniendurchsetzung |
post-receive | Nachdem alle Refs aktualisiert wurden | CI/CD auslösen, Benachrichtigungen senden |
Beispiel: Pre-commit-Hook zur Secret-Erkennung
#!/usr/bin/env bash
# .git/hooks/pre-commit
if git diff --cached --name-only | xargs grep -lE '(AKIA|passwords*=|api_keys*=)' 2>/dev/null; then
echo "ERROR: Potential secret detected in staged files. Commit aborted."
exit 1
fi
exit 0Ausführbar machen:
chmod +x .git/hooks/pre-commitFür teamweite Hook-Verteilung verwenden Sie ein Tool wie Husky (Node.js-Projekte) oder speichern Sie Hooks in einem hooks/-Verzeichnis im Repository-Root und verlinken Sie sie während der Projekteinrichtung symbolisch.
Reflog: Das Sicherheitsnetz
Der Reflog zeichnet jede Bewegung von HEAD und Branch-Zeigern auf, einschließlich Operationen, die scheinbar die Historie zerstören (Hard-Resets, Rebases, geänderte Commits). Er wird in .git/logs/ gespeichert.
git reflog # Show HEAD movement history
git reflog show main # Show movement history for a specific branch
git checkout HEAD@{3} # Check out the state HEAD was in 3 moves ago
git branch recovered HEAD@{5} # Recover commits by branching from a reflog entryReflog-Einträge laufen standardmäßig nach 90 Tagen ab (gc.reflogExpire). Auf einem Produktionsserver sollten Sie dies verlängern:
git config gc.reflogExpire 180
git config gc.reflogExpireUnreachable 30Bare Repositories: Server-seitiges Hosting
Ein bare Repository hat kein Arbeitsverzeichnis. Es enthält nur den Inhalt von .git/ auf der Root-Ebene. Bare Repositories sind das richtige Format für zentralisiertes Hosting — sie akzeptieren Pushes ohne die Komplikationen eines ausgecheckten Branches.
git init --bare /srv/repos/myproject.gitWenn Sie zu GitHub, GitLab oder einem selbst gehosteten Git-Server pushen, pushen Sie in ein bare Repository. Wenn Sie Ihren eigenen Git-Server auf einem VPS mit cPanel oder einem reinen Linux-VPS hosten, sind bare Repositories unter /srv/repos/ mit SSH-Zugang die Standardarchitektur.
Initialisierung eines gemeinsam genutzten bare Repositorys
# On the server
git init --bare --shared=group /srv/repos/project.git
chown -R git:developers /srv/repos/project.git
# On a developer's machine
git remote add origin git@yourserver.com:/srv/repos/project.git
git push -u origin mainGit-Objektspeicher: Größe, Integrität und Wartung
Repository-Gesundheit prüfen
git fsck --full # Verify object integrity (finds dangling and corrupt objects)
git fsck --lost-found # Write dangling objects to .git/lost-found/Große Objekte finden und entfernen
Versehentlich committete große Binärdateien sind eine häufige Ursache für aufgeblähte Repositories. Identifizieren Sie sie, bevor Sie git filter-repo verwenden, um sie zu entfernen:
# Find the 10 largest objects by compressed size
git verify-pack -v .git/objects/pack/*.idx
| sort -k3 -rn
| head -10
| awk '{print $1}'
| xargs -I{} git cat-file -p {}# Remove a file from all history (requires git-filter-repo)
git filter-repo --path path/to/large-file.bin --invert-pathsNach dem Filtern müssen alle Mitarbeiter neu klonen — ihre lokalen Repositories referenzieren SHA-Hashes, die in der umgeschriebenen Historie nicht mehr existieren.
Vergleich: Wichtige Git-Repository-Konzepte
| Konzept | Typ | Veränderbar | Gespeichert in | Übertragen durch Push/Fetch |
|---|---|---|---|---|
| Blob | Objekt | Nein | .git/objects/ | Ja (wenn erreichbar) |
| Tree | Objekt | Nein | .git/objects/ | Ja (wenn erreichbar) |
| Commit | Objekt | Nein | .git/objects/ | Ja (wenn erreichbar) |
| Annotierter Tag | Objekt | Nein | .git/objects/ | Nur mit --tags |
| Branch | Ref | Ja | .git/refs/heads/ | Ja |
| Remote-Tracking-Branch | Ref | Ja (beim Fetch) | .git/refs/remotes/ | Nein (lokaler Cache) |
| Leichtgewichtiger Tag | Ref | Nein | .git/refs/tags/ | Nur mit --tags |
| HEAD | Symref/Hash | Ja | .git/HEAD | Nein |
| Index | Binärdatei | Ja | .git/index | Nein |
| Hooks | Skripte | Ja | .git/hooks/ | Nein |
| Reflog | Log | Ja (läuft automatisch ab) | .git/logs/ | Nein |
Praktische Entscheidungsmatrix und wichtige Erkenntnisse
Verwenden Sie diese Checkliste beim Einrichten oder Prüfen eines Git-Repositorys auf Ihrer Infrastruktur:
Repository-Initialisierung
- Verwenden Sie
git init --bare --shared=groupfür jedes Repository, das Pushes von mehreren Benutzern empfangen wird. - Speichern Sie bare Repositories außerhalb von web-zugänglichen Verzeichnissen (niemals unter
/var/www/).
Objektspeicher-Gesundheit
- Führen Sie
git fsck --fullnach jedem Speichervorfall oder Dateisystemfehler aus. - Planen Sie
git gcregelmäßig für langlebige Repositories; automatisieren Sie es über Cron auf Ihrem Server. - Überwachen Sie die Pack-Dateigröße mit
git count-objects -vH; untersuchen Sie, wenn die Anzahl loser Objekte 1.000 überschreitet.
Branch- und Ref-Hygiene
- Löschen Sie zusammengeführte Branches umgehend; veraltete Refs häufen sich an und verlangsamen
git fetch --prune-Operationen. - Verwenden Sie
git fetch --prunein CI-Pipelines, um nicht auf gelöschte Remote-Branches zu reagieren.
Hook-Bereitstellung
- Verlassen Sie sich niemals auf
.git/hooks/für teamweite Richtlinien — Hooks werden nicht geklont. Verwenden Sie stattdessen server-seitigepre-receive-Hooks oder ein CI-Gate. - Prüfen Sie server-seitige Hooks nach jedem Git-Server-Upgrade; Hook-Interpreter-Pfade können sich ändern.
Sicherheit auf selbst gehosteten Servern
- Beschränken Sie SSH-Zugang auf den
git-Benutzer mit erzwungenen Befehlen (command=inauthorized_keys). - Verwenden Sie
git-shellals Login-Shell für dengit-Benutzer, um beliebige Befehlsausführung zu verhindern. - Kombinieren Sie Ihren Repository-Server mit einem gültigen SSL-Zertifikat, wenn Sie eine Web-Oberfläche (Gitea, GitLab, cgit) bereitstellen.
Umschreiben der Historie
- Schreiben Sie niemals die Historie auf Branches um, die mit anderen geteilt werden, ohne einen koordinierten Migrationsplan.
- Nach
git filter-repomüssen alle Mitarbeiter neu klonen; aktualisieren Sie CI/CD-Remote-URLs sofort.
Notfallwiederherstellung
- Verlängern Sie die Reflog-Ablaufzeit auf Produktionsservern (
gc.reflogExpire = 180). - Halten Sie einen sekundären bare Klon auf einem separaten Host als Backup; ein einfaches
git fetchvom primären Server ist ausreichend.
FAQ
Was ist der Unterschied zwischen einem bare und einem nicht-bare Git-Repository?
Ein nicht-bare Repository hat ein Arbeitsverzeichnis, in dem Dateien ausgecheckt sind, plus ein .git/-Unterverzeichnis, das den Objektspeicher enthält. Ein bare Repository enthält nur den Objektspeicher in seinem Root (kein Arbeitsverzeichnis) und ist das richtige Format für einen gemeinsam genutzten Server, der Pushes empfängt.
Kann ich Commits nach dem Ausführen von git reset --hard wiederherstellen?
Ja, solange die Commits nicht durch Garbage Collection entfernt wurden. Führen Sie git reflog aus, um den SHA des Commits zu finden, den Sie wiederherstellen möchten, dann git checkout -b recovery-branch <SHA>, um ihn an einen neuen Branch anzuhängen. Reflog-Einträge werden standardmäßig 90 Tage lang aufbewahrt.
Warum überträgt git push meine Tags nicht?
Standardmäßig überträgt git push nur Commits, die von den Refs erreichbar sind, die Sie explizit pushen. Tags sind separate Refs und müssen mit git push origin --tags (alle Tags) oder git push origin <tagname> (ein bestimmter Tag) gepusht werden.
Was passiert mit dem Index während eines Merge-Konflikts?
Der Index speichert alle drei Versionen jeder konfliktbehafteten Datei gleichzeitig: Stufe 1 (gemeinsamer Vorfahre/Basis), Stufe 2 (Ihre Version) und Stufe 3 (deren Version). Normales git add schreibt nur Stufe 0 (aufgelöst). Bis alle Konflikte aufgelöst und gestagt sind, wird git commit die Ausführung verweigern.
Wie unterscheiden sich Git-Hooks zwischen client-seitigen und server-seitigen Bereitstellungen?
Client-seitige Hooks laufen auf dem Rechner des Entwicklers und werden nicht zentral durchgesetzt — jeder Entwickler kann sie umgehen, indem er die Hook-Datei löscht. Server-seitige Hooks (pre-receive, update, post-receive) laufen auf dem Hosting-Server und können vom Client nicht umgangen werden, was sie zum richtigen Durchsetzungspunkt für Branch-Schutzrichtlinien, Code-Review-Anforderungen und CI/CD-Auslöser macht.
bei allen Hosting-Diensten