Ich verwende den Git-Teilbaum mit einigen Projekten, an denen ich arbeite, um einen Basiscode zwischen ihnen zu teilen. Der Basiscode wird häufig aktualisiert, und die Upgrades können in jedem der Projekte durchgeführt werden, wobei alle letztendlich aktualisiert werden.
Ich bin auf ein Problem gestoßen, bei dem git meldet, dass mein Teilbaum auf dem neuesten Stand ist, aber das Drücken wird abgelehnt. Beispielsweise:
#! git subtree pull --prefix=public/shared project-shared master
From github.com:****
* branch master -> FETCH_HEAD
Already up-to-date.
Wenn ich drücke, sollte ich eine Nachricht erhalten, dass es nichts zu pushen gibt ... Richtig? RICHTIG? :(
#! git subtree push --prefix=public/shared project-shared master
git push using: project-shared master
To [email protected]:***
! [rejected] 72a6157733c4e0bf22f72b443e4ad3be0bc555ce -> master (non-fast-forward)
error: failed to push some refs to '[email protected]:***'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Was könnte der Grund dafür sein? Warum scheitert das Schieben?
git
git-subtree
mateusz
quelle
quelle
--rejoin
, um Teilbaum-Pushs zu beschleunigen. Wenn ich den Teilbaum-Push manuell durchlaufesubtree split --rejoin
und laufe, hat der geteilte Teilbaumzweig nur den Verlauf bis zur letzten Wiederverbindung, wenn er normalerweise den gesamten Teilbaumverlauf enthält. Für mich ist dies die unmittelbare Ursache für Fehler beim nicht schnellen Vorlauf. Ich bin mir immer noch nicht sicher, warum die Teilbaumaufteilung einen abgeschnittenen Verlauf generiert.Antworten:
Ich habe die Antwort auf diesen Blog-Kommentar https://coderwall.com/p/ssxp5q gefunden
quelle
error: unknown option 'prefix'
heroku
und welchepythonapp
Antwort ich habe . Übersetzung aus der Heroku-spezifischen Sprache:git push <your subtree's origin> `git subtree split --prefix=Path/to/subtree master`:master --force
Unter Windows funktioniert der verschachtelte Befehl nicht:
Sie können das verschachtelte Bit zuerst ausführen:
Dies gibt (nach vielen Zahlen) einen Token zurück, z
Verwenden Sie dies im enthaltenen Befehl, z. B.:
quelle
git subtree
vorher kein Befehl war. Nachdem Sie Ihre Lösung unter Verwendung war ich in der Lage , einen Ordner zu Heroku statt all meine Repo zu implementierenVerwenden Sie die
--onto
Flagge:[BEARBEITEN: Leitet leider
subtree push
nicht--onto
an den Basiswert weitersplit
, daher muss die Operation in zwei Befehlen ausgeführt werden! Wenn das erledigt ist, sehe ich, dass meine Befehle mit denen in einer der anderen Antworten identisch sind, aber die Erklärung ist anders, also lasse ich es trotzdem hier.]Oder wenn Sie keine Bash verwenden:
Ich habe Stunden damit verbracht, die Quelle des Git-Teilbaums zu durchsuchen, um dies herauszufinden, also hoffe ich, dass Sie es zu schätzen wissen;)
subtree push
beginnt mit der Ausführungsubtree split
, die Ihren Commit-Verlauf in ein Format umschreibt, das zum Pushen bereit sein sollte. Die Art und Weise, wie dies geschieht, ist, dass espublic/shared/
die Vorderseite jedes Pfads entfernt, der es hat, und alle Informationen über Dateien entfernt, die es nicht haben. Das bedeutet, dass alle Commits des Upstream-Sub-Repositorys ignoriert werden, selbst wenn Sie nicht gequetscht ziehen, da sie die Dateien nach ihren bloßen Pfaden benennen. (Commits, die keine Dateien unter berührenpublic/shared/
oder Merge-Commits, die mit einem übergeordneten Element identisch sind, werden ebenfalls reduziert. [BEARBEITEN: Außerdem habe ich seitdem eine Squash-Erkennung gefunden. Jetzt denke ich, dass dies nur dann der Fall ist, wenn Sie nicht gequetscht gezogen haben. Dann gelingt es dem in einer weiteren Antwort beschriebenen vereinfachten Zusammenführen des Zusammenführungs-Commits, den nicht gequetschten Pfad und auszuwählen Verwerfen Sie den gequetschten Pfad.]) Das Ergebnis ist, dass das Material, das versucht zu pushen, letztendlich alle Arbeiten enthält, die von jemandem an das aktuelle Host-Repository übergeben wurden, von dem Sie pushen, aber keine Mitarbeiter, die direkt an das Sub-Repository oder über einen anderen Host gebunden sind Repository.Wenn Sie jedoch verwenden
--onto
, werden alle Upstream-Commits als OK aufgezeichnet, um wörtlich verwendet zu werden. Wenn der Umschreibungsprozess sie als eines der übergeordneten Elemente einer Zusammenführung ansieht, die neu geschrieben werden soll, werden sie beibehalten, anstatt zu versuchen, sie neu zu schreiben auf die übliche Weise.quelle
git remote -v
.--onto
Option hilft git dabei, Commits zu identifizieren, die sich bereits im Sub-Repository befinden.Bei einer App vom Typ "GitHub-Seiten", bei der Sie einen Teilbaum "dist" für einen Gh-Pages-Zweig bereitstellen, sieht die Lösung möglicherweise so aus
Ich erwähne dies, da es etwas anders aussieht als die oben angegebenen Heroku-Beispiele. Sie können sehen, dass mein Ordner "dist" im Hauptzweig meines Repos vorhanden ist, und dann schiebe ich ihn als Teilbaum in den Zweig gh-pages, der sich ebenfalls im Ursprung befindet.
quelle
Ich bin auch schon einmal auf dieses Problem gestoßen, und hier ist, wie ich es gelöst habe.
Was ich herausfand, war, dass ich einen Zweig hatte, der nicht mit dem lokalen Hauptzweig verbunden war. Dieser Zweig existiert und hängt nur in der Leere. In Ihrem Fall heißt es wahrscheinlich
project-shared
. Angenommen, dies ist der Fall, und wenn Siegit branch
eine lokaleproject-shared
Verzweigung sehen, können Sie neue Commits an Ihre vorhandene Verzweigung anhängen ,project-shared
indem Sie Folgendes ausführen :git subtree split --prefix=public/shared --onto public-shared --branch public-shared
Ich habe verstanden, dass
git subtree
ich anfange, einen neuen Zweig zu erstellen--onto
, in diesem Fall den lokalenpublic-shared
Zweig. Dann bedeutet der Zweig, einen Zweig zu erstellen, der nur den altenpublic-shared
Zweig ersetzt.Dadurch bleiben alle vorherigen SHA der
public-shared
Niederlassung erhalten. Schließlich können Sie einegit push project-shared project-shared:master
Angenommen, Sie haben auch eine
project-shared
Fernbedienung. Dadurch wird das lokale Hängen im leerenproject-shared
Zweig zummaster
Zweig der Fernbedienung verschobenproject-shared
.quelle
Dies liegt an der Einschränkung des ursprünglichen Algorithmus. Bei der Verarbeitung von Merge-Commits verwendet der ursprüngliche Algorithmus ein vereinfachtes Kriterium zum Abschneiden nicht verwandter Eltern. Insbesondere wird geprüft, ob es ein übergeordnetes Element gibt, das denselben Baum hat. Wenn ein solches übergeordnetes Element gefunden wird, wird das Zusammenführungs-Commit reduziert und stattdessen das übergeordnete Commit verwendet, vorausgesetzt, andere Eltern haben Änderungen, die nicht mit dem Unterbaum zusammenhängen. In einigen Fällen würde dies dazu führen, dass Teile des Verlaufs gelöscht werden, wodurch sich tatsächlich Änderungen am Unterbaum ergeben. Insbesondere würde es Sequenzen von Commits löschen, die einen Unterbaum berühren würden, aber zu demselben Unterbaumwert führen würden.
Sehen wir uns ein Beispiel an (das Sie leicht reproduzieren können), um besser zu verstehen, wie dies funktioniert. Betrachten Sie den folgenden Verlauf (das Zeilenformat lautet: commit [tree] subject):
In diesem Beispiel teilen wir uns auf
dir
. CommitsD
undE
haben den gleichen Baumz
, weil wir Commit habenC
, das Commit rückgängig machtB
, alsoB-C
tut die Sequenz nichtsdir
, obwohl sie Änderungen daran hat.Lassen Sie uns jetzt teilen. Zuerst teilen wir uns auf Commit
C
.Als nächstes teilen wir uns auf Commit
E
.Ja, wir haben zwei Commits verloren. Dies führt zu dem Fehler, wenn versucht wird, den zweiten Split zu verschieben, da diese beiden Commits nicht vorhanden sind, die bereits im Ursprung enthalten sind.
Normalerweise können Sie diesen Fehler mithilfe von tolerieren
push --force
, da verworfene Commits im Allgemeinen keine kritischen Informationen enthalten. Langfristig muss der Fehler behoben werden, damit der Split-Verlauf tatsächlich alle Commits enthält, die sichdir
erwartungsgemäß berühren . Ich würde erwarten, dass das Update eine eingehendere Analyse der übergeordneten Commits für versteckte Abhängigkeiten enthält.Als Referenz ist hier der Teil des Originalcodes, der für das Verhalten verantwortlich ist.
quelle
Die Antwort von Eric Woodruff hat mir nicht geholfen, aber die folgende hat geholfen:
Normalerweise ziehe ich einen Teilbaum mit der Option "--squash". Es scheint, dass dies die Versöhnung erschwert hat, also musste ich einen Teilbaum ziehen, ohne diesmal zu quetschen, einige Konflikte lösen und dann pushen.
Ich muss hinzufügen, dass der gequetschte Zug keine Konflikte enthüllte, sagte mir, dass alles in Ordnung war.
quelle
Eine andere [einfachere] Lösung besteht darin, den Kopf der Fernbedienung durch ein weiteres Commit voranzutreiben, wenn Sie können. Nachdem Sie diesen erweiterten Kopf in den lokalen Teilbaum gezogen haben, können Sie ihn erneut verschieben.
quelle
Sie können Push-Local-Änderungen für das Remote-Teilbaum-Repo erzwingen
quelle
Eine schnelle PowerShell für Windows-Benutzer basierend auf der Lösung von Chris Jordan
quelle
Das habe ich also geschrieben, basierend auf dem, was @entheh gesagt hat.
quelle
Hatte auch dieses Problem. Folgendes habe ich getan, basierend auf den Top-Antworten:
Gegeben:
Geben Sie Folgendes ein:
Beachten Sie, dass das Token, das von 'git subtree push' ausgegeben wird, in 'git push' verwendet wird.
quelle