git push: So laden Sie Änderungen ins Remote-Repository hoch
git push überträgt die lokalen Commits des aktuellen Branches ins Remote-Repository und verschiebt dort den Branch-Zeiger. Beim ersten Mal veröffentlichen Sie einen Branch mit git push -u origin branch-name, danach genügt git push. Liegen auf dem Server fremde Commits, holen Sie diese zuerst per git pull, statt einen Force-Push zu machen.
Was macht git push?
Der Befehl git push nimmt die Commits Ihres lokalen Branches, die es auf dem Server noch nicht gibt, überträgt sie ins Remote-Repository (meist heißt es origin) und setzt dort den Branch-Zeiger auf Ihren letzten Commit. Die Dateien im Arbeitsverzeichnis und nicht committete Änderungen gehen dabei nirgendwohin: Übertragen wird nur die Historie, also die Commits.
Wichtig: Push ist keine „Synchronisation“. Er funktioniert nur in eine Richtung – vom lokalen ins Remote-Repository. Um die Änderungen anderer zu bekommen, brauchen Sie git fetch oder git pull. Wer diese Richtungen verwechselt, landet bei fast allen Problemen, mit denen Einsteiger zum Mentor kommen.
Noch eine Git-Regel: Standardmäßig ist ein Push nur als „Vorspulen“ (Fast-Forward) erlaubt. Der Server nimmt Ihre Commits an, wenn sie die Historie fortsetzen, die dort bereits liegt. Hat jemand vor Ihnen seine Commits gepusht, wird Ihr Push abgelehnt – und das ist ein Schutzmechanismus, kein Fehler.
Syntax des Befehls
git push [<remote>] [<lokaler-branch>[:<remote-branch>]]
Rufen Sie git push ohne Argumente auf, nimmt Git den aktuellen Branch und pusht ihn in den als Upstream (Tracking-Branch) eingetragenen Branch. Die explizite Form ist nützlich, wenn noch kein Upstream eingerichtet ist oder Sie den Branch unter einem anderen Namen pushen wollen:
git push origin main # lokalen main nach origin/main pushen
git push origin feature/login # Branch feature/login pushen
git push origin fix:hotfix-123 # lokalen fix auf dem Server als hotfix-123 pushen
git push origin HEAD # aktuellen Branch unter gleichem Namen pushen
Änderungen zum ersten Mal pushen
Der typische Weg von einem neuen Projekt bis zum Code auf GitHub oder GitLab sieht so aus. Zuerst legen Sie auf dem Server ein leeres Repository an, dann verknüpfen Sie es mit dem lokalen und pushen den Branch.
git init
git add .
git commit -m "Erster Commit"
git branch -M main
git remote add origin git@github.com:user/project.git
git push -u origin main
Die Option -u (Langform --set-upstream) verknüpft den lokalen Branch main mit dem Remote-Branch origin/main. Danach genügt in diesem Branch einfach git push und git pull, und git status zeigt an, wie viele Commits Sie dem Server voraus sind oder hinterherhinken.
Wohin das Remote zeigt, prüfen Sie mit git remote -v. Ist die Adresse falsch, korrigieren Sie sie mit git remote set-url origin <neue-adresse>, statt das Repository zu löschen und neu anzulegen.
Einen neuen Branch pushen
Sie haben einen Branch für eine Aufgabe angelegt, Commits gemacht und tippen git push. Git antwortet:
fatal: The current branch feature/login has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin feature/login
Das ist kein Fehler, sondern ein Hinweis: Der Branch hat auf dem Server noch kein Gegenstück. Führen Sie den vorgeschlagenen Befehl aus oder die Kurzform git push -u origin feature/login. Damit Git das bei allen neuen Branches automatisch erledigt, aktivieren Sie diese Einstellung (verfügbar ab Git 2.37):
git config --global push.autoSetupRemote true
git push rejected: Was tun bei non-fast-forward?
Die häufigste Situation bei der Teamarbeit:
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'github.com:user/project.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally.
Ein Kollege hat seine Commits vor Ihnen gepusht. Ihre Historie und die auf dem Server haben sich auseinanderentwickelt, und würde Git Ihren Push annehmen, gingen die Commits des Kollegen verloren. Die richtige Lösung: zuerst die Änderungen holen und Ihre eigenen darauf aufbauen.
git pull --rebase # fremde Commits holen und eigene darauf setzen
# bei Konflikten: Dateien korrigieren, git add, git rebase --continue
git push
Statt --rebase können Sie auch ein normales git pull machen – dann entsteht ein Merge-Commit. Beide Varianten sind korrekt; in den meisten Teams bevorzugt man für eigene lokale Commits rebase, damit die Historie linear bleibt. Entscheidend ist, die Ablehnung nicht mit --force zu „lösen“.
git push --force und --force-with-lease
Ein erzwungener Push ist nötig, wenn Sie die Historie Ihres Branches bewusst umgeschrieben haben: mit git commit --amend, git rebase oder durch Zusammenfassen von Commits vor dem Review. Ein normaler Push wird einen solchen Branch nicht annehmen, weil die alten Commits auf dem Server keine Vorfahren der neuen mehr sind.
git push --force-with-lease
--force-with-lease überschreibt den Branch auf dem Server nur, wenn er dort noch genau da steht, wo Ihr lokales Git ihn zuletzt gesehen hat (laut Referenz origin/<branch>). Hat ein Kollege inzwischen etwas gepusht, verweigert der Befehl den Push, und Sie löschen seine Arbeit nicht. Ein einfaches --force (-f) prüft nichts und überschreibt alles stillschweigend.
Eine Feinheit: Führen Sie vorher git fetch aus, wird die Referenz origin/<branch> aktualisiert, und der Schutz greift nicht mehr – Git nimmt an, Sie hätten die fremden Commits „gesehen“. Machen Sie daher kein fetch direkt vor einem Force-Push, ohne sich anzusehen, was angekommen ist.
| Befehl | Was er macht | Wann verwenden |
|---|---|---|
git push | Nur Fast-Forward | Immer, standardmäßig |
git push --force-with-lease | Überschreiben mit Prüfung | Eigener Branch nach rebase oder amend |
git push --force | Überschreiben ohne Prüfung | Fast nie; niemals in gemeinsame Branches |
In gemeinsame Branches (main, develop) darf man keinen Force-Push machen: Bei allen, die die alte Historie schon geholt haben, weicht sie dann von der auf dem Server ab. Meist sind solche Branches zusätzlich durch Repository-Einstellungen geschützt, und der Server antwortet mit protected branch hook declined.
Tags pushen
Ein normales git push überträgt keine Tags. Sie müssen sie explizit pushen:
git tag -a v1.2.0 -m "Release 1.2.0"
git push origin v1.2.0 # ein Tag
git push --tags # alle lokalen Tags
git push --follow-tags # Commits und die annotierten Tags, die darauf zeigen
--follow-tags ist praktischer als --tags: Es pusht keine versehentlichen lokalen Lightweight-Tags, sondern nur annotierte, und nur solche, die von den gepushten Commits aus erreichbar sind.
Remote-Branch löschen
Auch das Löschen läuft über push:
git push origin --delete feature/login
# alte Syntax, macht dasselbe:
git push origin :feature/login
Der lokale Branch bleibt dabei erhalten, löschen können Sie ihn mit git branch -d feature/login. Bei Kollegen hängt die Referenz origin/feature/login noch so lange herum, bis sie git fetch --prune ausführen.
Nützliche Optionen von git push
| Option | Zweck |
|---|---|
-u, --set-upstream | Remote-Branch als Upstream speichern |
-n, --dry-run | Anzeigen, was gepusht würde, ohne etwas zu übertragen |
--all | Alle lokalen Branches pushen |
--tags / --follow-tags | Tags pushen |
-d, --delete | Branch oder Tag auf dem Server löschen |
--force-with-lease | Historie sicher überschreiben |
-v, --verbose | Ausführliche Ausgabe |
--no-verify | pre-push-Hook überspringen (nur bewusst einsetzen) |
Typische Fehler bei git push und ihre Lösung
Permission denied (publickey)
Der Server hat Ihren SSH-Schlüssel nicht akzeptiert. Prüfen Sie, ob der Schlüssel existiert (ls ~/.ssh), ob der öffentliche Teil im Account hinterlegt ist und ob die Verbindung funktioniert: ssh -T git@github.com. Ist das Remote per HTTPS eingetragen, fragt Git nach Benutzername und Token statt nach dem Schlüssel – sehen Sie sich git remote -v an.
Authentication failed über HTTPS
GitHub und viele andere Dienste akzeptieren über HTTPS schon lange kein Account-Passwort mehr. Sie brauchen ein Personal Access Token oder steigen auf SSH um. Speichern lässt sich das Token mit einem Credential Helper: git config --global credential.helper store (speichert im Klartext) oder mit dem Anmeldedaten-Manager Ihres Betriebssystems.
src refspec main does not match any
Einen Branch mit diesem Namen gibt es bei Ihnen nicht. Meist wurde im leeren Repository noch kein einziger Commit gemacht, oder der Branch heißt master. Prüfen Sie git branch und machen Sie einen Commit oder benennen Sie den Branch um: git branch -M main.
Everything up-to-date, obwohl es Änderungen gibt
Sie haben vergessen zu committen. git push überträgt Commits, keine Dateien. Führen Sie git status aus, dann git add und git commit. Zweite Möglichkeit: Sie sind nicht in dem Branch, den Sie auf dem Server erwarten.
Datei zu groß
Hoster begrenzen die Dateigröße (bei GitHub 100 MB). Ist eine solche Datei schon in der Historie, reicht es nicht, sie mit einem neuen Commit zu löschen: Sie müssen die Historie umschreiben oder die Datei aus den noch nicht gepushten Commits entfernen (git reset --soft, dann neu committen). Für große Binärdateien nutzt man Git LFS.
Der Arbeitsablauf mit git push
git switch -c feature/x– Branch für die Aufgabe.- Commits in kleinen, logischen Schritten.
git fetchundgit rebase origin/main– aktuellen Haupt-Branch einbeziehen.git push -u origin feature/x– Branch veröffentlichen.- Pull Request öffnen, nach dem Review weitere Commits und normales
git push. - Musste die Historie umgeschrieben werden –
git push --force-with-lease.
Vor dem Push lohnt ein Blick darauf, was genau auf den Server geht: git log origin/main..HEAD --oneline zeigt die Commits, die es dort noch nicht gibt.
Einmal einrichten und Ruhe haben
Ein paar globale Einstellungen ersparen Ihnen die meisten Überraschungen beim Pushen. push.default legt fest, was git push ohne Argumente überträgt. Standard in aktuellen Versionen ist simple: Gepusht wird nur der aktuelle Branch und nur in den gleichnamigen Upstream-Branch. Ändern muss man das meist nicht, aber prüfen Sie, ob in einer alten Konfiguration nicht noch matching steht – das pusht alle namensgleichen Branches auf einmal.
git config --global push.default simple
git config --global push.autoSetupRemote true
git config --global push.followTags true
git config --global pull.rebase true
push.followTags macht --follow-tags zum Standardverhalten, und pull.rebase erspart überflüssige Merge-Commits, wenn ein Push abgelehnt wurde und Sie erst die fremden Änderungen holen müssen.
Der pre-push-Hook
Die Datei .git/hooks/pre-push wird vor dem Push ausgeführt. Endet sie mit einem Exit-Code ungleich null, findet der Push nicht statt. Teams lassen darin oft Tests oder einen Linter laufen, damit kaputter Code nicht auf den Server gelangt. Den Hook mit --no-verify zu umgehen, ist nur sinnvoll, wenn Sie genau wissen, warum er fehlschlägt.
Fazit
git push veröffentlicht Ihre Commits im Remote-Repository und arbeitet nur in eine Richtung. Den ersten Push eines Branches machen Sie mit -u, bei einer Ablehnung holen Sie zuerst die fremden Änderungen per pull, und eine umgeschriebene Historie Ihres eigenen Branches pushen Sie ausschließlich mit --force-with-lease. Die Arbeit mit Remote-Repositories, push, pull und SSH-Schlüsseln wird im Git-Kurs praktisch geübt.
Häufige Fragen
Überträgt git push auch nicht committete Änderungen?
Nein. Push überträgt nur Commits; Änderungen im Arbeitsverzeichnis und im Index bleiben lokal, bis Sie sie committen.
Wie macht man einen git push rückgängig?
Im eigenen Branch können Sie den Commit lokal zurücksetzen (git reset) und mit git push --force-with-lease pushen. In einem gemeinsamen Branch ist es sicherer, mit git revert einen Gegen-Commit zu erzeugen und normal zu pushen.
Kann man nur einen einzelnen Commit pushen?
Ja, über seinen Hash: git push origin abc1234:main überträgt die gesamte Historie bis einschließlich dieses Commits, aber keine späteren. Einen Commit ohne seine Vorfahren zu pushen, ist nicht möglich.
Was ist der Unterschied zwischen git push und git push origin main?
Ohne Argumente verwendet Git den eingerichteten Upstream des aktuellen Branches, die explizite Form gibt Remote und Branch direkt an und funktioniert auch ohne Upstream.
Wie pusht man in zwei Repositories gleichzeitig?
Fügen Sie ein zweites Remote hinzu und pushen Sie gezielt in beide, oder hinterlegen Sie für origin zwei Push-Adressen mit git remote set-url --add --push origin adresse (für beide Adressen ausführen, auch die ursprüngliche, sonst geht der Push nur an die zweite).
Dieses Thema wird im Kurs „Git vom Anfänger zum versierten Entwickler“ ausführlich mit Praxis behandelt.
Zum Kurs