Ich verwende git, um ein Repository zu verwalten, an dem ich arbeite.
das master
Branch ist das “Hauptprojekt”. Ich arbeite jedoch auch an einem Parallelprodukt, das dem Hauptprodukt ähnlich, aber nicht gleich ist. Es lebt in einer Filiale namens newproject
.
Die Codebasis ist bei den beiden sehr ähnlich, aber newproject
ist abgespeckter und weist einige grundlegende Änderungen auf. Allerdings sind jede Menge Fensterdekorationsartikel wie CSS, Javascript usw. zwischen den beiden Zweigen gleich.
Auf der anderen Seite habe ich viele Dateien im gelöscht newproject
Filiale, die es noch gibt in master
.
Ich möchte diese Projekte nicht wieder zusammenführen, wie es der typische Fall bei Branches ist, in denen Sie einen Zweig erstellen, um eine Funktion hinzuzufügen oder einen Fehler zu beheben, und dann wieder zusammenführen zu master
— diese Zweige werden dauerhaft unabhängig leben.
Ich möchte jedoch immer noch Fixes von master
hinein newproject
wo es noch Überschneidungen / gemeinsam genutzte Dateien gibt.
Wenn ich es einfach tue
$ git checkout newbranch
$ git pull origin master
Ich bekomme eine Menge Konflikte, da alle gelöschten Dateien als Konflikte angezeigt werden, da sie noch in existieren master
.
Gibt es eine Möglichkeit, mit dieser Situation umzugehen?
Der Effekt, den git-Submodule erzielen, ist genau das, was Sie wollen: einen gemeinsamen Code, von dem mehrere Projekte abhängen, mit Korrekturen des gemeinsamen Codes, der von allen abhängigen Projekten geteilt wird. Submodule erreichen den Effekt, indem sie die Historie für den gemeinsam genutzten Code aussortieren, aber das ist nur Mechanik – und wenn Sie es einmal sehen, werden Sie verstehen, dass dies die natürlich richtige Lösung ist.
Der Befehl submodule selbst existiert, um einige knifflige Haushaltsdetails zu verfolgen (normalerweise können Sie rm -rf *
in einem Repository und verliert keinen festgeschriebenen Zustand, aber das ist bei verschachtelten Repositorys nicht der Fall, so dass der Befehl normalerweise das Submodul .git dirs hochzieht; solche Dinge), aber das Submodul selbst ist nichts anderes als ein verschachteltes Repository mit seiner eigenen Geschichte. Wenn Sie cd hineinlegen, wissen git-Befehle nicht einmal, dass es ein Submodul von irgendetwas ist, weil sie sich nicht darum kümmern müssen: Ein Submodul zu sein ist nur die Art und Weise, wie das Repository verwendet wird, nicht etwas, das dem Repository selbst inhärent ist.
git init projectA
cd projectA
touch A # now there's a file at the projectA root,
# but the projectA repo doesn't know about it
echo 'this content is in file "A" at the projectA root'> A
git add A # content recorded, the index points to it
git commit -m'A' # now projectA repo has a permanent record of the indexed state
git init projectInner # now there's an entire repo at the projectA root,
# but the projectA repo doesn't know about it
cd projectInner
echo "Inner content" > Inner # a file at the inner repo, no repo knows about it
git add Inner # content recorded, the inner repo's index records it
git commit -mInner # the inner repo has a permanent record
cd ..
git add projectInner # now the projectA repo knows about the inner, the content is recorded ...
git commit -mInner # and now the projectA repo has a permanent record
git add
Ein tatsächliches Repository zu erstellen bedeutet, seinen aktuellen Zustand aufzuzeichnen, genau wie beim Hinzufügen einer Datei oder eines Verzeichnisses, aber während der aufgezeichnete Zustand einer Datei ihr gesamter Inhalt ist und der aufgezeichnete Zustand eines Verzeichnisses der rekursive Zustand aller seiner (nachverfolgten oder un-ignored) Inhalt, ist der aufgezeichnete Status eines Repos einfach der SHA seines HEAD-Commits – alles andere wird bereits in diesem Repo selbst aufgezeichnet.
Die Nutzlast hier ist, dass ein Git-Submodul einfach ein verschachteltes Repository ist, und es stellt sich heraus, dass ein verschachteltes Repository sehr nützlich sein kann. Wie beim Rest von git ist das, was der submodule-Befehl tatsächlich tut, brutal einfach. Die scheinbare Komplexität besteht darin, das zu implementieren, was in all den verschiedenen Situationen, in denen es so nützlich ist, am bequemsten ist.
Nachdem Sie verzweigt haben, können Sie a git rebase master
auf Ihrem neuen Projektzweig, um seinen Trennpunkt nach oben zu verschieben HEAD
des Meisterzweiges. Dies führt dazu, dass alle Diffs erneut angewendet werden (was sehr einfach ist und möglicherweise keine größeren Konflikte hat, da die meisten Dateien nicht mehr im newproject
Filiale) von der newbranch
Trennpunkt über den Änderungen, die am Master-Zweig vorgenommen wurden. Seit der newproject
Commits beinhalten das Entfernen dieser Dateien und andere Änderungen, alles sollte glatt gehen (mit hoffentlich nicht zu vielen Konflikten). Besuche die Informationen zur Umbasierung unter dem hier verlinkten de-facto-git-Buch aufgeführt.
.
git submodule
wurde für solche Fälle entwickelt.– jthill
22. Februar ’13 bei 4:10
@jthill– kannst du es genauer erklären? Ich habe verstanden, dass Submodule dafür gedacht sind, wenn Sie ein Hauptprojekt haben, das von anderen Repositorys abhängt, sodass Sie diese Repositorys unabhängig abrufen und auf dem neuesten Stand halten können. Ich sehe nicht, wie das hier zutrifft.
– Benutzer101289
22. Februar ’13 um 6:04