git push
Remote-Refs samt zugehöriger Objekte aktualisieren
Der Befehl 'git push' lädt Inhalte aus dem lokalen Repository in ein Remote-Repository hoch. Er überträgt Commits und Branch-Updates (und Tags, wenn du sie mit --tags oder --follow-tags anforderst) von deinem lokalen Repo zu einem Remote, sodass deine Änderungen für andere verfügbar werden. Mit Push teilst du deine Arbeit – nach dem lokalen Commit pushst du, um dich mit dem Team zu synchronisieren. Standardmäßig (push.default=simple) aktualisiert git push nur den Upstream-Branch des aktuellen Branches, der existieren und gleich heißen muss, und nur bei einem Fast-Forward (der Remote-Branch ist also ein Vorfahre deines lokalen Branches).
Syntax
git push [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [-f | --force] [-d | --delete] [--prune] [-q | --quiet] [-v | --verbose] [-u | --set-upstream] [-o <string>] [--force-with-lease[=<refname>[:<expect>]] [--force-if-includes]] [--no-verify] [<repository> [<refspec>...]]Optionen
Die richtige Option wählen
Die Sicherheitsleiter für Force-Push
Wenn du die Remote-Historie überschreiben musst, wähle die sicherste Option, die für deine Lage funktioniert
| Befehl | Risiko | Prüft Remote | Wann es scheitert | Anwendungsfall |
|---|---|---|---|---|
git push | Sicher | ✓ Nur Fast-Forward | Wenn das Remote neue Commits hat | Normaler Alltag |
git push --force-with-lease --force-if-includes | Sicherstes Erzwingen | ✓ Remote-Spitze in lokaler Historie | Wenn du die Remote-Änderungen nicht integriert hast | Nach einem Rebase, wenn andere gepusht haben könnten |
git push --force-with-lease | Sichereres Erzwingen | ✓ Remote seit dem Fetch unverändert | Wenn sich das Remote seit dem letzten Fetch geändert hat | Nach einem Rebase auf einem persönlichen Branch |
git push --force | Gefährlich | ✗ Überschreibt blind | Nie (außer der Server lehnt ab) | Nur, wenn du dir sicher bist, oder allein auf dem Branch |
Was gepusht wird
Den Umfang dessen steuern, was du zum Remote sendest
| Befehl | Pusht | Mit Tags | Typische Nutzung |
|---|---|---|---|
git push origin main | Ein Branch | ✗ | Einen bestimmten Branch pushen |
git push -u origin branch | Ein Branch + setzt Tracking | ✗ | Erster Push eines neuen Branches |
git push --all | Alle Branches | ✗ | Alle lokalen Branches synchronisieren |
git push --tags | Nur Tags (keine Branches) | ✓ Alle Tags | Versions-Tags pushen |
git push --follow-tags | Aktueller Branch | ✓ Nur erreichbare annotierte | Mit den passenden Release-Tags pushen |
git push --mirror | Alles | ✓ Alles | Exakter Klon auf dem Remote (löscht Refs, die nur remote existieren) |
Ausgabe und Rückmeldung
Ausführlichkeit und Ausgabeformat an deinen Bedarf anpassen
| Befehl | Ausgabeumfang | Zeigt Fortschritt | Maschinenlesbar | Am besten für |
|---|---|---|---|---|
git push | Standard | Nur im Terminal | ✗ | Normale interaktive Nutzung |
git push --verbose | Ausführlich | ✓ | ✗ | Push-Probleme debuggen |
git push --quiet | Nur Fehler | ✗ | ✗ | Skripte, CI-Pipelines |
git push --progress | Standard + erzwungener Fortschritt | ✓ Immer | ✗ | Skripte, die Fortschritt im Log brauchen |
git push --porcelain | Strukturiert | ✗ | ✓ Tabulatorgetrennt | Push-Ergebnisse in Skripten auswerten |
Sicherheit und Überprüfung
Prüfungen vor dem Push und Kontrolloptionen
| Befehl | Führt Hooks aus | Prüft | Erzeugt Commit | Wann verwenden |
|---|---|---|---|---|
git push | ✓ pre-push | Remote akzeptiert | N/A | Normaler Workflow |
git push --dry-run | ✓ pre-push | Was passieren würde | ✗ Nur Vorschau | Vor wichtigen Pushes |
git push --atomic | ✓ | Alle Refs oder keine | Alles oder nichts | Mehrere Branches zusammen pushen |
git push --no-verify | ✗ Überspringt lokales pre-push (Server-Hooks laufen weiter) | Remote akzeptiert | N/A | Notfall, wenn Hooks dich blockieren |
git push --signed | ✓ | GPG-Signatur | Kryptografisch signiert | Hochsichere Repos, Identität nachweisen |
Remote- und Branch-Verwaltung
Optionen zum Verwalten von Remote-Refs und Branch-Beziehungen
| Befehl | Aktion | Wirkt auf Remote | Anwendungsfall |
|---|---|---|---|
git push -u origin branch | Push + Upstream setzen | Fügt Branch hinzu | Erster Push, richtet Tracking ein |
git push origin --delete branch | Remote-Branch löschen | Entfernt Branch | Gemergte Branches aufräumen |
git push --prune | Remote-Branches löschen, die du lokal gelöscht hast (braucht --all oder eine Wildcard-Refspec) | Entfernt Branches | Löschungen aufs Remote übertragen |
git push --repo=<url> | Zu einem bestimmten Remote pushen | Ziel-Remote | Zu einer anderen Remote-URL pushen |
Workflow-Beispiele
git remote add origin https://github.com/user/repo.gitDie URL des Remote-Repositorys hinzufügen
git push -u origin mainDen main-Branch pushen und ihn origin/main folgen lassen
git statusPrüfen, dass du auf dem richtigen Branch bist und Commits zum Pushen hast
git pushZum verfolgten Upstream-Branch pushen
git checkout featureAuf deinen Feature-Branch wechseln
git rebase mainAuf main rebasen (schreibt die Commit-Historie um)
git push --force-with-leaseSicher force-pushen – scheitert, wenn jemand anderes gepusht hat
git checkout -b feature/new-loginNeuen Branch anlegen und dorthin wechseln
git add . && git commit -m "Add new login"Änderungen machen und committen
git push -u origin feature/new-loginPushen und Upstream-Tracking einrichten
git push origin --delete feature/old-branchDen Remote-Branch löschen
git branch -d feature/old-branchAuch den lokalen Branch löschen
git push --all originAlle Branches unter refs/heads/ pushen
git push --tags originOptional auch alle Tags pushen
Fehlerbehebung
! [rejected] main -> main (fetch first) / (non-fast-forward)
Ursache: Der Remote-Branch hat Commits, die dein lokaler Branch nicht hat. Jemand anderes hat Änderungen gepusht, oder du hast bereits gepushte Commits gerebast/geamendet.
Hole zuerst die Remote-Änderungen mit 'git pull --rebase' oder 'git pull --no-rebase', löse eventuelle Konflikte und pushe dann erneut. Erzwinge (am besten mit '--force-with-lease') nur, wenn du sicher bist, dass niemand sonst den Branch nutzt.
git pull --rebase && git pushgit@github.com: Permission denied (publickey)
Ursache: Die SSH-Anmeldung ist gescheitert: Kein Schlüssel ist geladen, oder dein öffentlicher Schlüssel ist nicht in deinem Konto hinterlegt. (Fehlende Schreibrechte führen zu einem anderen Fehler, „Permission to ... denied“.)
Prüfe, ob dein SSH-Schlüssel in deinem GitHub-/GitLab-Konto hinterlegt ist. Teste mit 'ssh -T git@github.com'. Bei HTTPS stelle sicher, dass du die richtigen Zugangsdaten nutzt.
ssh -T git@github.comfatal: No configured push destination
Ursache: Das Repository hat überhaupt kein Remote konfiguriert. (Gibt es ein Remote, aber der Branch hat keinen Upstream, erscheint stattdessen „The current branch ... has no upstream branch“.)
Füge mit 'git remote add origin <url>' ein Remote hinzu und pushe dann mit gesetztem Upstream per 'git push -u origin <branch>'.
git push -u origin mainYour branch is behind 'origin/main'
Ursache: Der Remote-Branch hat neuere Commits als dein lokaler Branch. Du musst diese Änderungen integrieren, bevor du pushst.
Hole die Remote-Änderungen und merge oder rebase sie vor dem Pushen in deinen lokalen Branch.
git pull origin main && git pushrefusing to update checked out branch
Ursache: Du versuchst, in ein Nicht-Bare-Repository zu pushen, in dem dieser Branch gerade ausgecheckt ist. Das könnte dessen Arbeitsverzeichnis inkonsistent machen.
Pushe in ein Bare-Repository oder lass den Empfänger zuerst einen anderen Branch auschecken. Das passiert meist bei eigenen Servern, nicht bei GitHub/GitLab.
git config receive.denyCurrentBranch updateInsteaderror: failed to push some refs to '<remote-url>'
Ursache: Allgemeiner Fehler mit mehreren möglichen Ursachen: Non-Fast-Forward-Updates, fehlgeschlagene Hooks oder Rechteprobleme. Sieh dir die ausführliche Fehlermeldung über dieser Zeile an.
Lies die vollständige Fehlerausgabe. Meist ist es ein Non-Fast-Forward-Problem (erst pullen) oder ein fehlgeschlagener pre-push-Hook (behebe, was der Hook meldet).
git pull --rebase && git pushpre-push-Hook fehlgeschlagen
Ursache: Ein pre-push-Hook (Tests, Linting usw.) hat Probleme gefunden und den Push blockiert.
Behebe die vom Hook gemeldeten Probleme. Umgehe ihn mit '--no-verify' nur, wenn es wirklich nötig ist und du die Folgen verstehst.
git push --no-verifyremote: Repository not found
Ursache: Die Repository-URL ist falsch, das Repository wurde gelöscht oder umbenannt, oder du hast keinen Zugriff.
Prüfe die Repository-URL mit 'git remote -v'. Stelle sicher, dass das Repository existiert und du Zugriff hast. Passe die URL bei Bedarf an.
git remote set-url origin https://github.com/user/correct-repo.gitTipps & Stolperfallen
Best Practices
- ✓Immer vor dem Push pullen: Führe vor dem Pushen 'git pull' aus (oder 'git fetch' mit anschließendem Merge oder Rebase), damit du die neuesten Remote-Änderungen hast und abgelehnte Pushes vermeidest.
- ✓--force-with-lease statt --force nutzen: Wenn du erzwingen musst, ist --force-with-lease sicherer, weil es scheitert, wenn seit deinem letzten Fetch jemand anderes gepusht hat (für zusätzliche Sicherheit --force-if-includes ergänzen).
- ✓Beim ersten Push den Upstream setzen: Nutze 'git push -u origin branch-name' beim Pushen eines neuen Branches, um das Tracking einzurichten. Danach reicht ein einfaches 'git push'.
- ✓Nie auf geteilte Branches force-pushen: Ein Force-Push auf main, master oder develop kann die Arbeit anderer zerstören. Nutze Revert-Commits statt die Historie umzuschreiben.
- ✓Branch-Schutzregeln nutzen: Konfiguriere dein Repository so, dass Force-Pushes auf wichtige Branches verhindert und Reviews für Pull Requests verlangt werden.
- ✓Oft pushen, um deine Arbeit zu sichern: Regelmäßige Pushes von Feature-Branches dienen als Backup und zeigen anderen deinen Fortschritt.
- ✓Vor dem Pushen prüfen: Mit 'git push --dry-run' siehst du, was gepusht würde, ohne tatsächlich zu pushen. Ideal zum Gegenprüfen.
- ✓Remote-Branches aufräumen: Lösche gemergte Feature-Branches mit 'git push origin --delete branch-name', damit das Remote-Repository ordentlich bleibt.
- ✓Atomare Pushes für zusammenhängende Änderungen: Wenn du mehrere voneinander abhängige Branches pushst, sorgt '--atomic' dafür, dass alle durchgehen oder keiner.
- ✓Wichtige Pushes signieren: In sicherheitskritischen Repositories signiert '--signed' deine Pushes mit GPG zur Überprüfung (der Server muss signierte Pushes unterstützen, sonst scheitert der Push).
Häufige Fehler
- ✗Pushen, ohne vorher zu pullen: Hat das Remote neue Commits, wird dein Push abgelehnt. Führe immer zuerst 'git pull' aus (oder fetch, dann merge/rebase), um Remote-Änderungen aufzunehmen.
- ✗--force auf geteilten Branches nutzen: Ein Force-Push schreibt die Historie um und kann die Arbeit anderer zerstören. Nutze stattdessen --force-with-lease oder vermeide Force-Pushes auf geteilte Branches am besten ganz.
- ✗Vergessen, mit -u den Upstream zu setzen: Nutze beim ersten Push eines neuen Branches 'git push -u origin branch-name', um das Tracking einzurichten. Sonst musst du Remote und Branch jedes Mal angeben.
- ✗Auf den falschen Branch pushen: Prüfe vor dem Push mit 'git branch' deinen aktuellen Branch. Nutze zur Sicherheit eine ausdrückliche Syntax wie 'git push origin feature:feature'.
- ✗Abgelehnte Pushes nicht verstehen: 'non-fast-forward'-Fehler bedeuten, dass das Remote Commits hat, die du lokal nicht hast. Pulle und merge/rebase vor dem Pushen – erzwinge nicht einfach.
FAQ
'git push' lädt deine lokalen Commits in ein Remote-Repository hoch und macht deine Änderungen für andere verfügbar. 'git pull' lädt Commits von einem Remote herunter und mergt sie in deinen lokalen Branch. Push schickt Daten raus; Pull holt Daten rein.
Einen Push kann man nicht wirklich „rückgängig“ machen, da er geteilte Historie ist. Sicher zurücknehmen kannst du ihn mit 'git revert HEAD', das einen neuen Commit erzeugt, der die Änderungen aufhebt – dann erneut pushen. Vermeide 'git reset' + Force-Push auf geteilten Branches, da es Historie umschreibt, die andere vielleicht schon gepullt haben.
Die Option -u richtet eine Tracking-Beziehung zwischen deinem lokalen Branch und dem Remote-Branch ein. Nach 'git push -u origin feature' reichen 'git push' und 'git pull', ohne jedes Mal Remote und Branch anzugeben.
Force-Push (--force) sollte nur auf Branches genutzt werden, an denen du allein arbeitest, etwa persönliche Feature-Branches nach einem Rebase. Force-pushe nie auf geteilte Branches wie main oder develop. Wenn es sein muss, nutze zur Sicherheit --force-with-lease.
Nutze die Refspec-Syntax: 'git push origin local-branch:remote-branch'. Zum Beispiel pusht 'git push origin feature:experiment' deinen lokalen Branch 'feature' auf einen Remote-Branch namens 'experiment'.
Meist, weil das Remote Commits hat, die du lokal nicht hast (non-fast-forward). Führe 'git pull' aus, um diese Änderungen zu holen und zu mergen, löse eventuelle Konflikte und pushe dann erneut. Erzwinge nichts, außer du bist sicher, dass es gefahrlos ist.
Nutze 'git push --all origin', um alle lokalen Branches zum Remote zu pushen. Tags brauchen einen eigenen Befehl, weil sich '--all' und '--tags' nicht kombinieren lassen: 'git push --tags origin'.
'--force' überschreibt den Remote-Branch blind, egal in welchem Zustand er ist. '--force-with-lease' überschreibt nur, wenn sich das Remote seit deinem letzten Fetch nicht geändert hat – es scheitert, wenn jemand anderes gepusht hat, und schützt so dessen Arbeit. Achtung: Ein Fetch (auch ein Hintergrund-Fetch deiner IDE) frischt diese Prüfung auf, also ergänze --force-if-includes, um zusätzlich zu verlangen, dass du das Geholte integriert hast.
Nutze 'git push origin --delete branch-name' oder die Kurzform 'git push origin :branch-name'. Beide entfernen den Branch aus dem Remote-Repository.
Ein einfaches 'git push' funktioniert nur, wenn für den aktuellen Branch ein Upstream-Branch konfiguriert ist. Bei neuen Branches brauchst du zuerst 'git push -u origin branch-name'. Prüfe die Tracking-Beziehungen mit 'git branch -vv'.