2016-06-30 24 views
1

Ich habe zwei Zweige develop und master. Es gibt viele Commits in Entwicklung, die noch nicht in master sind. Obwohl ich develop Zweig machen muss genau so aussehen wie master. Um alle Änderungen, die in develop passiert sind, zu erhalten, werde ich einen neuen Zweig von develop erstellen, damit all diese Änderungen nicht verloren gehen.git - Zweig wiederherstellen, um wie Master auszusehen?

Aber nach dem Kopieren von develop, wie kann ich sicher zurücksetzen oder wieder aussehen wie master?

sah ich dies: Git: reset/revert a whole branch to another branches state?

So zurückgesetzt, was ich tun kann:

git checkout develop 
git reset --hard master 

Aber das Problem ist develop Zweig bereits zu entfernten geschoben wird und dort andere, die develop bereits gezogen hatte.

Vielleicht gibt es einen sichereren Weg, dies zu tun, mit Rückstellung oder auf andere Weise? Aber ich möchte (wenn möglich) auf eine Weise wiederherstellen, die zu master Zustand zurückkehren würde, nicht manuell jedes Commit auswählen, da einige letzte Commits in develop gehalten werden müssen, weil sie von Master (Hotfixes) kamen.

So Geschichte der Commits auf develop sieht ungefähr so ​​aus (die meisten Top-Mittel spätestens Datum begehen):

commit hotfix2 - in both develop and master 
some other commits that are only in develop 
commit hotfix1 - in both develop and master 
some commits that are only in develop 
all commits that came when develop was created from master 
+0

Also, was wollen Sie tun, um alle Commits rückgängig machen, die nur gemacht wurden entwickelt? (z. B. die "einige Commits" und die "anderen Commits" aus Ihrer Geschichte rückgängig machen) – poke

+0

@pokes Nun ja, aber gibt es einen einfacheren Weg, als alle Commits zu durchlaufen und diejenigen auszuwählen, die ich rückgängig machen muss? Dies ist nur ein Beispiel, im realen Fall gibt es viele Commits, die rückgängig gemacht werden müssen und zwischen denen Commits gemacht werden müssen. Mit 'reset' ist es einfach, ich kann nur Verzweigung angeben und es wird zurückgesetzt, um genau wie' Master' zu aussehen. – Andrius

Antwort

2

Das Standardverfahren Commits in einer nicht-destruktive Weise rückgängig zu machen ist git revert zu verwenden. Dieser Befehl nimmt grundsätzlich den invertierten Unterschied eines Ziel-Commits und versucht ihn anzuwenden. Sie erhalten also ein neues Commit, das alle Änderungen rückgängig macht.

Um mehrere Commits gleichzeitig rückgängig zu machen, können Sie auch einen Commit-Bereich angeben. Da Sie nur zwei Bereiche haben, die Sie rückgängig machen möchten (die zwischen diesen Hotfixes), wäre dies tatsächlich überschaubar.

Sie können auch die Flagge --no-commit oder -n verwenden, um nicht automatisch eine Festschreibung erstellen. Dies ermöglicht es Ihnen, mehrere git revert -n <commit> Befehle nacheinander zu verketten, ohne dass für jedes ein rückgängig machendes Commit erstellt wird. Wenn Sie dann alle Commits oder Commit-Bereiche, die Sie rückgängig machen möchten, ausgewählt haben, können Sie einen einzigen Commit durchführen, der alle kombiniert.

In Ihrem Fall, da Sie einen anderen Zweig haben, der den genauen (Arbeitsverzeichnis) -Zustand hat, in den Sie Ihre develop Verzweigung einfügen möchten, ist es viel einfacher, das zu tun. Alles, was Sie tun müssen, ist, den Arbeitsbaum für master in Ihrem develop Zweig zu überprüfen und diesen Zustand auf den develop Zweig zu übertragen. Sie würden dies mit git checkout master -- . tun. Leider funktioniert dies nicht für Pfade, die dem Zweig master unbekannt sind. Wenn Sie also neue Dateien im Zweig develop hinzufügen, werden diese beibehalten und Sie müssen sie separat löschen.

Stattdessen starten wir eine neue Verzweigung master (die dann genau den gleichen Inhalt hat) und setzen diese Verzweigung so zurück, dass sie stattdessen auf develop basiert. Auf diese Weise behalten wir den Arbeitsverzeichnisstatus von master, aber ein Commit würde stattdessen develop folgen.Danach können wir schnell vor- develop, dass man begehen:

# checkout a new branch off master 
git checkout -b new-develop master 

# make a soft reset to develop 
git reset --soft develop 

# commit the changes 
git commit 

# get back to develop and fast forward 
git checkout develop 
git merge --ff-only new-develop 
git branch -d new-develop 

Das in der gleichen Sache führen Sie durch Verkettungs git revert -n mit allen Commits bekommen würde, die develop ausschließen. Es gibt ein paar andere Möglichkeiten, diesen Zustand zu erreichen, aber das ist wirklich am einfachsten.

Unabhängig davon, auf welche Weise Sie in diesen Zustand gelangen, sollten Sie im Nachhinein eine Zusammenführung in Betracht ziehen. Die Zusammenführung wird eigentlich nichts tun (da beide Zweige den gleichen Inhalt haben), aber es wird die Zweige in der Geschichte kombinieren, so dass Sie sehen, dass sie tatsächlich konvergieren.

So sieht ursprünglich wie dieses Recht, die Geschichte unter der Annahme:

     master 
         ↓ 
* ------------ h1 ------ h2 
\    \   \ 
    * -- * -- * -- * -- * -- * 
          ↑ 
         develop 

Sie würden es in diese machen wollen:

       master 
            ↓ 
* ------------ h1 ------ h2 ----- M 
\    \   \ /↖ 
    * -- * -- * -- * -- * -- * -- F develop 

F ist das Update begehen wir oben erstellt. Dies setzt voraus, dass Sie develop in master (git merge develop während auf master) zusammenführen möchten und dann vorspulen develop (git merge master während auf develop), um die Entwicklungsarbeit von diesem Punkt aus neu zu starten. Natürlich könnten Sie es auch in die andere Richtung tun, wenn Sie das bevorzugen.

Alternativ dazu können wir auch M und den Fix F in einem einzigen Schritt zusammenführen. Sie würden develop in master effektiv zusammenführen und alles so zusammenführen, dass Sie mit dem Inhalt von master enden. Dies würde wie folgt aussehen:

       master 
            ↓ 
* ------------ h1 ------ h2 ---- FM 
\    \   \ /↖ 
    * -- * -- * -- * -- * -- * ---/ develop 

Sie können es wie folgt von Hand bekommen:

# since we merge into master, we start there 
git checkout master 

# start the merge, but don’t attempt to fast-forward and do not 
# commit the merge automatically (since we want to change it) 
git merge --no-ff --no-commit develop 

# reset the index that was prepared during the merge 
git reset 

# now checkout the files from master and commit the merge 
git checkout master -- . 
git add . 
git commit 

Und tatsächlich, das ist so ein gängiges Szenario, dass git merge mit einer Merge-Strategie kommt, das tut genau dies. Anstatt also die oben genannten, können wir die ours Merge-Strategie verwenden Sie einfach und werfen alles aus der Branche verschmelzen wir in den Strom:

git checkout master 
git merge -s ours develop 
+0

Hm, ich habe das versucht, aber es scheint nicht zu "entwickeln". Es werden nur Dateien rückgängig gemacht, die sowohl in "master" als auch in "develop" geändert wurden. Aber es gibt viele Dateien, die nur in 'develop', aber nicht' master' hinzugefügt werden. Und diese werden behalten. Wenn ich also "Entwickeln" auschecke und dann, wenn ich "Entwickeln" zu "Master" fusioniere, fügt es tatsächlich alle diese Dateien zu "Master" hinzu. Fehle ich hier etwas? Muss ich alle diese Dateien manuell löschen und festschreiben? – Andrius

+0

Welche Lösung haben Sie versucht? Der allerletzte (mit der 'ours' Merge-Strategie) sollte definitiv funktionieren; Für die anderen brauchen Sie vielleicht ein 'git reset' vor dem' git checkout master - .' (das habe ich vergessen). Nach der Zusammenführung sollte 'git diff ' nichts zurückgeben und 'git diff ' sollte viele Änderungen anzeigen, die nicht mehr in der aktuellen Verzweigung sind. – poke

+0

Ich habe versucht, die erste – Andrius