Machen Sie den aktuellen Git-Zweig zu einem Master-Zweig

1657

Ich habe ein Repository in Git. Ich habe eine Verzweigung vorgenommen und dann einige Änderungen sowohl am Master als auch an der Verzweigung vorgenommen.

Dann, zehn Commits später, wurde mir klar, dass sich der Zweig in einem viel besseren Zustand befindet als der Master. Daher möchte ich, dass der Zweig zum Master wird und die Änderungen am Master ignoriert.

Ich kann es nicht zusammenführen, da ich die Änderungen nicht auf dem Master behalten möchte. Was sollte ich tun?

Extra : In diesem Fall wurde der 'alte' Master bereits pushin ein anderes Repository wie GitHub verschoben. Wie ändert sich das?

Karel Bílek
quelle
2
Überprüfen Sie die Antworten auf die sehr ähnliche Frage stackoverflow.com/q/2862590/151641
mloskot
4
Hatte das gleiche Problem, aber ich entfernte einfach den Master und benannte einen anderen Zweig in Master um: stackoverflow.com/a/14518201/189673
jayarjo
10
@ jayarjo Sie sollten dies vermeiden, wenn Sie können, da es den Verlauf neu schreibt und Probleme für alle anderen verursacht, wenn sie das nächste Mal versuchen, den Master zu ziehen.
Joelittlejohn
3
Deshalb liebe ich die Antwort von @Jefromi. Es findet keine Dekonstruktion der Archivgeschichte statt.
Froggythefrog

Antworten:

2134

Das Problem mit den beiden anderen Antworten ist, dass der neue Meister den alten Meister nicht als Vorfahren hat. Wenn Sie ihn also drücken, werden alle anderen durcheinander gebracht. Folgendes möchten Sie tun:

git checkout better_branch
git merge --strategy=ours master    # keep the content of this branch, but record a merge
git checkout master
git merge better_branch             # fast-forward master up to the merge

Wenn Sie möchten, dass Ihr Verlauf etwas klarer wird, würde ich empfehlen, der Merge-Commit-Nachricht einige Informationen hinzuzufügen, um zu verdeutlichen, was Sie getan haben. Ändern Sie die zweite Zeile in:

git merge --strategy=ours --no-commit master
git commit          # add information to the template merge message
Cascabel
quelle
25
Hinweis zu Git's Merge "Strategien": --strategy=oursunterscheidet sich von --strategy=recursive -Xours. Dh "unsere" kann eine Strategie für sich sein (Ergebnis ist der aktuelle Zweig, egal was passiert) oder als Option an die "rekursive" Strategie übergeben werden (Änderungen anderer Zweige einbringen und Änderungen des aktuellen Zweigs automatisch bevorzugen, wenn ein Konflikt vorliegt ).
Kelvin
5
Ich musste die zweite Zeile machen, git merge --strategy=ours master -m "new master"damit es funktionierte.
Glühlampenmann
5
@Johsm Genau darum geht es im ersten Satz meiner Antwort. Wenn Sie dies tun, hat der neue Master nicht die gleiche Historie wie der alte Master, was sehr schlecht ist, wenn Sie drücken / ziehen möchten. Sie müssen gemeinsame Vorfahren haben, damit dies ordnungsgemäß funktioniert. Wenn Sie stattdessen tun, was Sie sagen, dann scheitert es einfach, wenn Sie versuchen, es zu drücken, es sei denn, Sie erzwingen es (weil dies schlecht ist und versucht, Sie aufzuhalten), und wenn Sie es erzwingen, dann jeder, der anschließend zieht wird versuchen, den alten und den neuen Meister zusammenzuführen, was wahrscheinlich ein Zugunglück sein wird.
Cascabel
4
Wenn der vi-Editor während des Zusammenführens angezeigt wird, geben Sie Folgendes ein: w (zum Speichern): q (zum Beenden von vi)
Tomas Kubes,
9
Diese Antwort funktioniert hervorragend. Ich wollte nur hinzufügen (für die Leute, die neu oder unsicher sind), dass Sie gleich danach ein tun müssen, git pushwenn Sie möchten, dass Ihr Code auf Remote übertragen wird. Möglicherweise wird eine Warnung wie Your branch is ahead of 'origin/master' by 50 commits.diese angezeigt . Schieben Sie es einfach! : D
Kapellensaft
388

Stellen Sie sicher, dass alles in Ihr Remote-Repository (GitHub) übertragen wird:

git checkout master

Überschreiben Sie "master" mit "better_branch":

git reset --hard better_branch

Erzwingen Sie den Push in Ihr Remote-Repository:

git push -f origin master
Brandon Howard
quelle
81
Dies ist wahrscheinlich die Antwort, nach der die meisten Menschen suchen. Alle anderen Antworten mit der Zusammenführung der BS-Strategie ersetzen den Zweig nicht vollständig. Dies machte alles so, wie ich es wollte, überschrieb einfach den Zweig und drückte ihn nach oben.
Gubatron
31
Obwohl dies in der Tat das ist, wonach viele suchen, sollte beachtet werden, dass alle anderen lokalen Kopien des Repos das git reset --hard origin/masternächste Mal benötigt werden, wenn sie ziehen möchten, andernfalls wird git versuchen, die Änderungen in ihre (jetzt) ​​divergierenden lokalen zu integrieren. Die Gefahren davon werden in dieser Antwort
näher
3
Bitte beachten Sie auch, dass Sie Push in das Repository erzwingen müssen müssen - z. B. in einer Geschäftsumgebung funktioniert dies nicht
inetphantom
Der Vorteil hier kann auch ein Nachteil sein, je nachdem, was die Leute wollen. Wenn Sie so weit gehen möchten, die Geschichte des Masters durch die Geschichte des anderen Zweigs zu ersetzen, ist dies Ihre Antwort.
15.
75

Edit: Du hast nicht gesagt, dass du zu einem öffentlichen Repo gedrängt hast! Das macht einen großen Unterschied.

Es gibt zwei Möglichkeiten, die "schmutzige" und die "saubere". Angenommen, Ihr Zweig heißt benannt new-master. Das ist der saubere Weg:

git checkout new-master
git branch -m master old-master
git branch -m new-master master
# And don't do this part.  Just don't.  But if you want to...
# git branch -d --force old-master

Dadurch werden die Konfigurationsdateien so geändert, dass sie mit den umbenannten Zweigen übereinstimmen.

Sie können dies auch auf schmutzige Weise tun, wodurch die Konfigurationsdateien nicht aktualisiert werden. Dies ist eine Art, was unter der Haube der oben genannten passiert ...

mv -i .git/refs/new-master .git/refs/master
git checkout master
Dietrich Epp
quelle
2
Vielen Dank. Noch eine Frage. Ich drücke es auf Github. Was passiert dort, wenn ich das mache?
Karel Bílek
3
@Karel: Es wird ein bisschen Chaos für andere Benutzer schaffen; Sie müssen ihren Master auf den Github-Master zurücksetzen. Wenn Sie vermeiden möchten, dass sie Probleme bekommen, schauen Sie sich meine Antwort an.
Cascabel
6
@Dietrick Epp: Ich bin mir nicht sicher, ob es eine gute Idee ist, den schmutzigen Weg überhaupt vorzuschlagen. Es wird Remote Tracking, Reflogs durcheinander bringen ... ich kann mir keinen Grund vorstellen, warum Sie es jemals tun würden.
Cascabel
2
Ah, das ist ein guter Punkt. Sie können es jedoch in beide Richtungen haben : git branch old-master master; git branch -f master new-master. Erstellen Sie den Sicherungszweig neu und verschieben Sie den Master direkt in den neuen Master. (Und entschuldigen Sie die falsche Schreibweise Ihres Namens, habe das gerade bemerkt)
Cascabel
2
@FakeName Ich bin nicht zu dem Schluss gekommen, dass es keinen Grund dafür gibt, nur dass es keinen Grund gibt, es auf schmutzige Weise zu tun . Sie können dies mit normalen Befehlen tun (wie in meinem vorherigen Kommentar) und das gleiche Ergebnis erzielen, außer wenn die Reflogs intakt sind und keine Chance besteht, Dinge zu stören. Und es funktioniert garantiert, da Sie sich nicht mit Implementierungsdetails herumschlagen.
Cascabel
46

Benennen Sie den Zweig um in master:

git branch -M branch_name master
Alan Haggai Alavi
quelle
11
Leider verfolgt git keine Umbenennungen von Zweigen. Wenn Sie also Ihr Repo bereits auf eine Fernbedienung übertragen haben und andere lokale Änderungen an ihrem lokalen alten Hauptzweig vorgenommen haben, treten Probleme auf.
thSoft
Gibt es einen Unterschied zwischen diesem und git checkout master&&git reset --hard better_branch?
Wotanii
26

Soweit ich weiß, können Sie den aktuellen Zweig in einen vorhandenen Zweig verzweigen. Im Wesentlichen wird dies mit allem überschrieben, masterwas Sie in der aktuellen Verzweigung haben:

git branch -f master HEAD

Sobald Sie dies getan haben, können Sie normalerweise Ihren lokalen masterZweig verschieben, wobei möglicherweise auch hier der Force- Parameter erforderlich ist :

git push -f origin master

Keine Zusammenführungen, keine langen Befehle. Einfach branchund push- aber ja, dies wird die Geschichte der masterBranche neu schreiben. Wenn Sie also in einem Team arbeiten, müssen Sie wissen, was Sie tun.




Alternativ habe ich festgestellt, dass Sie jeden Zweig an einen beliebigen Remote-Zweig senden können, also:

# This will force push the current branch to the remote master
git push -f origin HEAD:master

# Switch current branch to master
git checkout master

# Reset the local master branch to what's on the remote
git reset --hard origin/master
fregante
quelle
Sehr einfach und hat perfekt funktioniert! Zwei einfache und leicht verständliche Git-Befehle. Mein Git Repo ist gespeichert und sieht jetzt super sauber aus. Vielen Dank!
Thehelix
16

Ich fand die gewünschte Antwort im Blog-Beitrag. Ersetzen Sie den Hauptzweig durch einen anderen Zweig in git :

git checkout feature_branch
git merge -s ours --no-commit master
git commit      # Add a message regarding the replacement that you just did
git checkout master
git merge feature_branch

Es ist im Wesentlichen dasselbe wie Cascabels Antwort . Abgesehen davon, dass die "Option", die er unter seiner Lösung hinzugefügt hat, bereits in meinen Hauptcodeblock eingebettet ist.

Es ist einfacher, diesen Weg zu finden.

Ich füge dies als neue Antwort hinzu, denn wenn ich diese Lösung später benötige, möchte ich den gesamten Code, den ich verwenden werde, in einem Codeblock haben.

Ansonsten kann ich copy-paste, dann Details lesen Sie unten die Linie zu sehen , dass ich sollte geändert haben - nachdem ich es bereits ausgeführt.

SherylHohman
quelle
14

Die hier angegebenen Lösungen (Umbenennen des Zweigs in 'master') bestehen nicht auf den Konsequenzen für das Remote-Repo (GitHub):

    -f
    --Macht

Normalerweise weigert sich der Befehl, eine Remote-Referenz zu aktualisieren, die kein Vorfahr der lokalen Referenz ist, die zum Überschreiben verwendet wurde. Dieses Flag deaktiviert die Prüfung. Dies kann dazu führen, dass das Remote-Repository Commits verliert. Verwenden Sie es mit Vorsicht.

Wenn andere Ihr Repo bereits abgerufen haben, können sie diesen neuen Master-Verlauf nicht abrufen, ohne ihren eigenen Master durch diesen neuen GitHub-Master-Zweig zu ersetzen (oder sich mit vielen Zusammenführungen zu befassen).
Es gibt Alternativen zu einer Git-Push-Force für öffentliche Repos .
Jefromis Antwort (Zusammenführen der richtigen Änderungen zum ursprünglichen Master) ist eine davon.

VonC
quelle
14

Ich fand diese einfache Methode am besten. Der Verlauf wird nicht neu geschrieben, und alle vorherigen Eincheckvorgänge der Zweigstelle werden an den Master angehängt. Es geht nichts verloren und Sie können deutlich sehen, was im Festschreibungsprotokoll passiert ist.

Ziel: Machen Sie den aktuellen Status von "Branch" zum "Master"

Wenn Sie an einem Zweig arbeiten, schreiben Sie Ihre Änderungen fest und übertragen Sie sie, um sicherzustellen, dass Ihre lokalen und Remote-Repositorys auf dem neuesten Stand sind:

git checkout master      # Set local repository to master
git reset --hard branch  # Force working tree and index to branch
git push origin master    # Update remote repository

Danach ist Ihr Master der genaue Status Ihres letzten Commits der Verzweigung und Ihr Master-Commit-Protokoll zeigt alle Check-Ins der Verzweigung an.

Mark Dietel
quelle
10

Man kann auch alle Dateien aus dem anderen Zweig in den Master auschecken:

git checkout master
git checkout better_branch -- .

und dann alle Änderungen festschreiben.

user2064284
quelle
5

Um Jefromis Antwort zu ergänzen: Wenn Sie keine bedeutungslose Zusammenführung in den Verlauf der sourceVerzweigung einfügen möchten , können Sie eine temporäre Verzweigung für die oursZusammenführung erstellen und diese dann wegwerfen:

git checkout <source>
git checkout -b temp            # temporary branch for merge
git merge -s ours <target>      # create merge commit with contents of <source>
git checkout <target>           # fast forward <target> to merge commit
git merge temp                  # ...
git branch -d temp              # throw temporary branch away

Auf diese Weise existiert das Zusammenführungs-Commit nur in der Geschichte des targetZweigs.

Wenn Sie überhaupt keine Zusammenführung erstellen möchten, können Sie alternativ einfach den Inhalt von abrufen sourceund ihn für ein neues Commit verwenden für target:

git checkout <source>                          # fill index with contents of <source>
git symbolic-ref HEAD <target>                 # tell git we're committing on <target>
git commit -m "Setting contents to <source>"   # make an ordinary commit with the contents of <source>
staafl
quelle
3

Für mich wollte ich, dass mein Entwickler zurück zum Meister ist, nachdem er voraus war.

Während der Entwicklung:

git checkout master
git pull

git checkout develop
git pull

git reset --hard origin/master
git push -f
Braden Borman
quelle
2

Meine Art, Dinge zu tun, ist die folgende

#Backup branch
git checkout -b master_backup
git push origin master_backup
git checkout master
#Hard Reset master branch to the last common commit
git reset --hard e8c8597
#Merge
git merge develop
ar-g
quelle
2

Wenn Sie eGit in Eclipse verwenden :

  • Klicken Sie mit der rechten Maustaste auf den Projektknoten.
  • Wählen Sie Team → dann Erweitert → und dann Zweig umbenennen
  • Erweitern Sie dann den Remote-Tracking- Ordner.
  • Wählen Sie den Zweig mit dem falschen Namen aus, klicken Sie auf die Schaltfläche zum Umbenennen und benennen Sie ihn in einen beliebigen neuen Namen um.
  • Wählen Sie den neuen Master aus und benennen Sie ihn in Master um.
Junchen Liu
quelle
Ich habe das getan, bin mir aber nicht sicher, ob es funktioniert hat. Auf Github hat sich nichts geändert, aber auf Git-Erweiterungen kann ich sehen, dass der Zweig umbenannt wurde.
Pramod
0

Die folgenden Schritte werden im Git-Browser ausgeführt, der von Atlassian (Bitbucket-Server) unterstützt wird.

{Current-branch} als machen master

  1. Machen Sie einen Zweig daraus masterund nennen Sie ihn "Master-Duplikat".
  2. Machen Sie aus {current-branch} einen Zweig und nennen Sie ihn "{current-branch} -copy".
  3. Ändern Sie in der Repository-Einstellung (Bitbucket) "Standardzweig" in "Master-Duplikat" (ohne diesen Schritt können Sie den Master nicht löschen - "Im nächsten Schritt").
  4. "Master" -Zweig löschen - Ich habe diesen Schritt aus dem Quellbaum ausgeführt (Sie können dies über die CLI oder den Git-Browser tun).
  5. Benennen Sie "{current-branch}" in "master" um und verschieben Sie es in das Repository (dadurch wird ein neuer "master" -Zweig erstellt, der noch "{current-branch}" enthält).
  6. Ändern Sie in den Repository-Einstellungen "Standardzweig" so, dass er auf "Master" zeigt.
Purushothaman
quelle