Ignorieren Sie neue Commits für das Git-Submodul

82

Hintergrund

Verwenden von Git 1.8.1.1 unter Linux. Das Repository sieht wie folgt aus:

master
  book

Das Submodul wurde wie folgt erstellt:

$ cd /path/to/master
$ git submodule add https://[email protected]/user/repo.git book

Das bookSubmodul ist sauber:

$ cd /path/to/master/book/
$ git status
# On branch master
nothing to commit, working directory clean

Problem

Der Master hingegen zeigt, dass es "neue Commits" für das Buch-Submodul gibt:

$ cd /path/to/master/
$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   book (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")

Git sollte das Submodulverzeichnis vollständig ignorieren, damit der Master auch sauber ist:

$ cd /path/to/master/
$ git status
# On branch master
nothing to commit, working directory clean

Fehlgeschlagener Versuch Nr. 1 - schmutzig

In der Datei master/.gitmodulesbefindet sich gemäß dieser Antwort Folgendes :

[submodule "book"]
        path = book
        url = https://[email protected]/user/repo.git
        ignore = dirty

Fehlgeschlagener Versuch Nr. 2 - nicht verfolgt

Gemäß master/.gitmodulesdieser Antwort wurde Folgendes geändert :

[submodule "book"]
        path = book
        url = https://[email protected]/user/repo.git
        ignore = untracked

Fehlgeschlagener Versuch Nr. 3 - showUntrackedFiles

master/.git/configNach dieser Antwort wie folgt bearbeitet :

[status]
   showUntrackedFiles = no

Fehlgeschlagener Versuch Nr. 4 - ignorieren

Das Buchverzeichnis wurde zur Master-Ignorierdatei hinzugefügt:

$ cd /path/to/master/
$ echo book > .gitignore

Fehlgeschlagener Versuch Nr. 5 - Klon

Das Buchverzeichnis wurde dem Master wie folgt hinzugefügt:

$ cd /path/to/master/
$ rm -rf book
$ git clone https://[email protected]/user/repo.git book

Frage

Wie kann sich das bookSubmodul in einem eigenen Repository-Verzeichnis unter dem masterRepository befinden, ohne dass Git das bookSubmodul ignoriert ? Das heißt, Folgendes sollte nicht angezeigt werden:

#
#       modified:   book (new commits)
#

Wie kann diese Nachricht bei der Ausführung git statusim Master-Repository unterdrückt werden ?

Ein Artikel über Fallstricke bei Git-Submodulen legt nahe, dass dies eine unangemessene Verwendung von Submodulen ist.

Dave Jarvis
quelle
3
Normalerweise verwenden Sie Submodule, wenn Sie das Repository mit einer bestimmten Version eines anderen Repositorys verknüpfen und dies nachverfolgen möchten. Aber das scheint nicht das zu sein, was Sie wollen. Sie möchten nur ein Repository in einem anderen verwenden, ohne es zu verfolgen. Fügen Sie es dann nicht als Submodul hinzu.
Felix Kling
@FelixKling, wenn Sie solche Repos auf diese Weise hinzufügen und an GitHub senden, würde es dann nur einen Link dafür erstellen, ohne den Inhalt dieser Ordner zu kopieren?
Roman Bekkiev
@ Roland: Submodule sind nur Dateien mit einem Verweis auf die Version eines anderen Repositorys. Sobald sie in einer lokalen Kopie des Repositorys initialisiert wurden, werden sie durch den tatsächlichen Inhalt des Repositorys ersetzt.
Felix Kling
2
Ich denke, Sie suchen nach "ignorieren = alle"
greuze
1
Mit Git 2.13 (Q2 2017) können Sie berücksichtigen git config submodule.<name>.active false. Siehe meine Antwort unten
VonC

Antworten:

59

Versuchen Sie Folgendes, um ein weiteres Repository aufzunehmen, das nicht in seinem Super-Repo erfasst werden muss:

$ cd /path/to/master/
$ rm -rf book
$ git clone https://[email protected]/user/repo.git book
$ git add book
$ echo "book" >> .gitignore

Dann begehen.

Wie im Artikel über Fallstricke bei verknüpften Git-Submodulen angegeben :

... die einzige Verknüpfung zwischen dem übergeordneten Element und dem Submodul ist [der] aufgezeichnete Wert des ausgecheckten SHA des Submoduls, der in den Commits des übergeordneten Moduls gespeichert ist.

Das bedeutet, dass ein Submodul nicht durch seinen ausgecheckten Zweig oder Tag gespeichert wird, sondern immer durch ein bestimmtes Commit. Dieses Commit (SHA) wird wie eine normale Textdatei im Super-Repo (das das Submodul enthält) gespeichert (es ist natürlich als solche Referenz gekennzeichnet).

Wenn Sie ein anderes Commit im Submodul auschecken oder ein neues Commit darin ausführen, stellt das Super-Repo fest, dass sich das ausgecheckte SHA geändert hat. Dann bekommen Sie die modified (new commits)Leitung von git status.

Um dies zu beseitigen, können Sie entweder:

  • git submodule update, Der das Submodul die derzeit in der Super-Repo gespeichert commit (Details siehe wird zurückgesetzt , die git submoduleMan - Page oder
  • git add book && git commit um den neuen SHA im Super-Repo zu speichern.

Wie in den Kommentaren erwähnt, sollten Sie das bookSubmodul aufgeben : Klonen Sie es in das Super-Repo, wenn die Verfolgung seines Zustands als Teil des Super-Repos nicht erforderlich ist.

Nevik Rehnel
quelle
3
Wow, jetzt verstehe ich, warum das Supermodul die Version des Submoduls kennen muss. Natürlich macht es Sinn, dies zu tun git add book && git commit. Mir war nicht klar, dass Git tatsächlich sicherstellen kann, dass die beiden Repos synchron sind.
Sergey Orshanskiy
101

Lauf einfach:

$ git submodule update

Dadurch wird das Submodul auf das alte Commit zurückgesetzt (angegeben in Parent-Repo), ohne das Parent-Repo mit der neuesten Version des Submoduls zu aktualisieren.

Shiv Kumar
quelle
6
Nein, ist es nicht, es wird den Status nicht ändern.
Ed Bishop
Warum genau sollte OP nicht das Neueste aus dem bookRepository haben wollen? Ich denke nicht, dass Ihre Antwort in diesem Zusammenhang Sinn macht.
Alexis Wilke
@AlexisWilke und wenn sich die Buchschnittstelle dramatisch ändert und OP keine Zeit hat, Änderungen am Master-Repo vorzunehmen?
Logman
Dies ist die Antwort, nach der ich gesucht habe!
LLSv2.0
21

Es gibt zwei Arten von Änderungsbenachrichtigungen, die Sie unterdrücken können (ab Git 1.7.2).

Der erste ist nicht verfolgter Inhalt, der auftritt, wenn Sie Änderungen an Ihrem Submodul vornehmen, diese jedoch noch nicht festgeschrieben haben. Das übergeordnete Repository bemerkt diese und der Git-Status meldet sie entsprechend:

modified: book (untracked content)

Sie können diese unterdrücken mit:

[submodule "book"]
    path = modules/media
    url = https://[email protected]/user/repo.git
    ignore = dirty

Sobald Sie diese Änderungen festschreiben, nimmt das übergeordnete Repository diese erneut zur Kenntnis und meldet sie entsprechend:

modified:   book (new commits)

Wenn Sie diese ebenfalls unterdrücken möchten, müssen Sie alle Änderungen ignorieren

[submodule "book"]
    path = book
    url = https://[email protected]/user/repo.git
    ignore = all
greuze
quelle
Stellen Sie sich vor, ich habe ignore = allallen Submodulen eine Option hinzugefügt . Schließlich haben einige Module neue Commits, die gepusht wurden. Wenn jemand dann Super-Repo klont, befindet es sich dann im alten Zustand der Submodule oder werden die neuesten überprüft?
FelikZ
Mit dem Befehl erhalten git clone --recursive git@...Sie den alten Zustand der Submodule. Um sie zu aktualisieren, benötigen Sie etwas wie git submodule foreach "git pull"nach dem Klonen
greuze
1
Leider ignore = allignoriert die Option die neuen Commits des Submoduls nicht. Ich verwende Git Version 1.7.1. Irgendeine Idee?
Romulus
10

Git 2.13 (Q2 2017) wird eine weitere Möglichkeit hinzufügen, ein Submodul einzuschließen, das nicht von seinem übergeordneten Repo verfolgt werden muss.

Im Fall des OP:

git config submodule.<name>.active false

Siehe Commit 1b614c0 , Commit 1f8d711 , Commit bb62e0a , Commit 3e7eaed , Commit a086f92 (17. März 2017) und Commit ee92ab9 , Commit 25b31f1 , Commit e7849a9 , Commit 6dc9f01 , Commit 5c2bd8b (16. März 2017) von Brandon Williams ( mbrandonw) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit a93dcb0 , 30. März 2017)

submodule: URL und Submodul-Interesse entkoppeln

Derzeit wird die submodule.<name>.urlKonfigurationsoption verwendet, um festzustellen, ob ein bestimmtes Submodul für den Benutzer von Interesse ist. Dies ist in einer Welt, in der verschiedene Submodule in verschiedenen Arbeitsbäumen ausgecheckt werden sollen, oder ein allgemeinerer Mechanismus zur Auswahl der interessierenden Submodule umständlich.

In einer Zukunft mit Arbeitsbaumunterstützung für Submodule wird es mehrere Arbeitsbäume geben, für die möglicherweise nur eine Teilmenge der ausgecheckten Submodule erforderlich ist.
Die URL (unter der das Submodul-Repository abgerufen werden kann) sollte sich nicht zwischen verschiedenen Arbeitsbäumen unterscheiden.

Es kann für Benutzer auch praktisch sein, Gruppen von Submodulen, an denen sie interessiert sind, einfacher anzugeben, als " git submodule init <path>" für jedes Submodul auszuführen, das in ihrem Arbeitsbaum ausgecheckt werden soll.

Zu diesem Zweck werden zwei Konfigurationsoptionen eingeführt, submodule.activeund submodule.<name>.active.

  • Die submodule.activeKonfiguration enthält eine Pfadspezifikation, die angibt, welche Submodule im Arbeitsbaum vorhanden sein sollen.
    • Die submodule.<name>.activeKonfiguration ist ein boolesches Flag, das angibt, ob dieses bestimmte Submodul im Arbeitsbaum vorhanden sein soll.

Es ist wichtig zu beachten, dass dies submodule.activeanders funktioniert als die anderen Konfigurationsoptionen, da eine Pfadspezifikation erforderlich ist.
Auf diese Weise können Benutzer mindestens zwei neue Workflows übernehmen:

  1. Submodule können mit einem führenden Verzeichnis gruppiert werden, so dass eine Pfadspezifikation, z. B. ' lib/', alle bibliotheksbezogenen Module abdeckt, damit diejenigen, die an bibliotheksbezogenen Modulen interessiert sind, " submodule.active = lib/" nur einmal festlegen können, um zu sagen, dass alle Module in ' lib/' sind interessant.
  2. Sobald die Pfadspezifikationsattributfunktion erfunden wurde, können Benutzer Submodule mit Attributen kennzeichnen, um sie zu gruppieren, sodass eine breite Pfadspezifikation mit Attributanforderungen, z. B. ' :(attr:lib)', verwendet werden kann, um zu sagen, dass alle Module mit dem libAttribut ' ' interessant sind.
    Da die .gitattributesDatei genau wie die .gitmodulesDatei vom Superprojekt verfolgt wird, kann das Projekt beim Verschieben eines Submoduls im Superprojektbaum anpassen, in welchem ​​Pfad das Attribut abgerufen wird .gitattributes, genauso wie es anpassen kann, in welchem ​​Pfad sich das Submodul befindet .gitmodules.
VonC
quelle
Wie finde ich das genaue <name>für ein Untermodul in einem bestehenden Projekt?
ideasman42
@ ideasman42 Das Lesen der Konfiguration in den .gitmodules sollte helfen: stackoverflow.com/a/12641787/6309
VonC
Ah, es ist nur der Wert von .git/config->[submodule "<name>"]
ideasman42
1
Arbeite nicht für mich. Folgendes mache ich: 1) Git-Klon mit --recursive; 2) setze git config als Antwort; 3) git checkout, git pull to checkout letztes Submodul; Erhalten Sie immer noch "(neue Commits)".
Wu Baiquan
2
@VonC Bevor ich Ihnen eine Nachricht übermittelte, habe ich beide (mit vorhandenem Repo sowie neu initialisiertem Repo) ausprobiert. In beiden Fällen hat es nicht funktioniert.
Porcupine
3

Die Antwort von Nevik Rehnel ist sicherlich die richtige für das, was Sie fragen: Ich wollte kein Submodul haben, wie zum Teufel komme ich aus dieser Situation heraus?! .

Nur wenn für Ihr masterProjekt das bookSubmodul erforderlich ist , ist es eine nette Geste, es als solches beizubehalten, da andere Benutzer, die Ihr Projekt auschecken, auf diese Weise keinen speziellen gitBefehl ausführen können (naja ... es gibt einige spezielle Befehle, die verwendet werden müssen) Submodule, aber insgesamt ist es immer noch einfacher zu verwalten, denke ich.)

In Ihrem Fall nehmen Sie Änderungen im bookRepository vor und übernehmen diese Änderungen irgendwann. Dies bedeutet, dass Sie in diesem Submodul neue Commits haben , die eine neue SHA1-Referenz haben.

Im Master-Verzeichnis müssen Sie diese Änderungen im Master-Repository festschreiben.

cd /path/to/master
git commit . -m "Update 'book' in master"

Dadurch wird die SHA1-Referenz masterauf die neueste im bookRepository verfügbare Version aktualisiert . Infolgedessen können andere mit diesem Commit alle master& bookRepositorys an der Spitze auschecken.

Tatsächlich erhalten Sie also ein weiteres Commit, wenn Sie Änderungen an einem Submodul vornehmen. Es ist halbtransparent, wenn Sie auch Änderungen an einigen Dateien im masterRepository vornehmen, da Sie beide gleichzeitig festschreiben würden.

Alexis Wilke
quelle
-5

Lauf

git submodule update 

auf der Wurzelebene.

think2010
quelle
Nur für alle, die sich fragen. In meinem Fall (und bei OPs?) Ändert dies nichts an den git statusAussagen. Es glaubt immer noch, dass Veränderungen stattgefunden haben.
Squarism
Es ist sehr schlecht, die Antworten anderer zu klonen
Maxim