Gibt es eine Möglichkeit, Git Pull dazu zu bringen, Submodule automatisch zu aktualisieren?

203

Gibt es eine Möglichkeit, automatisch zu haben git submodule update(oder vorzugsweise git submodule update --initanzurufen, wann git pullimmer dies erledigt ist?

Suchen Sie nach einer Git-Konfigurationseinstellung oder einem Git-Alias, um dies zu unterstützen.

Philfreo
quelle
4
Siehe auch
philfreo
1
Warum ist ein Git-Alias ​​einem Shell-Alias ​​vorzuziehen?
wnoise
20
Git-Aliase sind nett, weil sie den Befehl im Namespace "git" kapseln. Sie können auch fragen, warum alle git-Befehle mit "git" beginnen, anstatt ihre eigenen Namen zu haben.
Lily Ballard
5
Für alle, die dies finden, sind die Antworten mit hohen Stimmen derzeit veraltet. Kanes Antwort ist richtig: stackoverflow.com/a/49427199/3499424
John Neuhaus

Antworten:

174

Ab Git 2.14 können Sie verwenden git pull --recurse-submodules(und es nach Belieben aliasieren).

Ab Git 2.15 können Sie submodule.recursetrue festlegen , um das gewünschte Verhalten zu aktivieren.

Sie können dies global tun, indem Sie Folgendes ausführen:

git config --global submodule.recurse true
Kane
quelle
3
Wenn Sie dies mit 2.16 bestätigen und auf true setzen, wird git pullauch ein Submodul abgerufen und ausgeführt submodule update. Dies muss jetzt wirklich die akzeptierte Antwort sein
John Neuhaus
1
Um dies global git config --global submodule.recurse true
festzulegen
14
Ich war von Submodulen frustriert, dann habe ich das gemacht. Jetzt arbeiten sie so, wie ich es erwarten würde. Gibt es einen Grund, warum ich nicht daran denke, dass dies nicht das Standardverhalten ist?
Ben
9
Sie sollten das auch ermöglichen git clone. Und schalten Sie es standardmäßig ein. Andernfalls wird es immer einen großen Widerstand gegen die Verwendung von Submodulen geben, da die Module der Leute immer nicht mehr synchron sind :-(
Ciro Santilli 30 冠状 病 六四 事件 法轮功
1
@CiroSantilli新疆改造中心法轮功六四事件Santilli git Befehle (wie commit, fetch, pullusw.) ausgelegt sind , nur auf den aktuellen Repository angewendet werden. Ein Submodul ist ein weiteres Repository und sollte nicht von Befehlen betroffen sein, die standardmäßig im übergeordneten Repository ausgeführt werden. Dies ist eine Art Design-Entscheidung des Git-Entwicklers.
Anion
113

git config --global alias.pullall '!git pull && git submodule update --init --recursive'

Wenn Sie möchten, dass Argumente an git pull übergeben werden, verwenden Sie stattdessen Folgendes:

git config --global alias.pullall '!f(){ git pull "$@" && git submodule update --init --recursive; }; f'
Lily Ballard
quelle
4
Denken Sie daran, "git config --global" zu verwenden, wenn Sie diesen Alias ​​für alle von Ihnen verwendeten Git-Repos verwenden möchten
yoyo
43

Ab Git 1.7.5 sollten Submodule standardmäßig automatisch aktualisiert werden, wie Sie es möchten.

[BEARBEITEN: pro Kommentar: Das neue Verhalten von 1.7.5 besteht darin, die neuesten Commits für Submodule automatisch abzurufen , aber nicht zu aktualisieren (im git submodule updateSinne). Die Informationen in dieser Antwort sind also als Hintergrund relevant, aber keine vollständige Antwort für sich. Sie benötigen noch einen Alias, um Submodule in einem Befehl abzurufen und zu aktualisieren.]

Das Standardverhalten "On-Demand" besteht darin, Submodule zu aktualisieren, wenn Sie ein Commit abrufen, das das Submodul-Commit aktualisiert, und dieses Commit befindet sich noch nicht in Ihrem lokalen Klon.
Sie können es auch bei jedem Abruf oder nie aktualisieren lassen (Verhalten vor 1.7.5, nehme ich an).
Die Konfigurationsoption zum Ändern dieses Verhaltens lautet fetch.recurseSubmodules.

Diese Option kann entweder auf einen booleschen Wert oder auf gesetzt werden on-demand.
Wenn Sie es auf einen Booleschen Wert setzen, ändert sich das Verhalten von fetchund pulles wird bedingungslos in Submodule zurückgeführt, wenn es auf true gesetzt ist, oder es wird überhaupt nicht wiederholt, wenn es auf false gesetzt ist.

Bei der Einstellung on-demand(der Standardwert), fetchund pull wird nur recurse in ein besiedeltes Submodul , wenn seine Superproject eine Festschreibung abruft , die Aktualisierungen der Verweis der Submodul .

Sehen:

für mehr Informationen.

git fetch --recurse-submodules[=yes|on-demand|no]
Christopher Rogers
quelle
27
Achtung: Wie die folgenden Antworten erklären, werden die Änderungen nur automatisch abgerufen. Sie müssen noch ein Submodul-Update durchführen. Die Alias-Antwort ist also richtig.
Artem
4
@Artem ist korrekt. Diese Antwort ist zwar nützlich, behandelt jedoch nicht die gesamte Frage. Diese Einstellung führt einfach a aus git fetch, nicht a git submodule update.
Andrew Ferrier
2
Diese Antwort täuscht sehr. Selbst wenn verwendet mit git pull, anstatt git fetchnur diese Option macht fetching rekursiv. Es ändert nichts daran, welches Commit in den Submodulen ausgecheckt ist. Also git submodule updateist es immer noch notwendig, wie von @Artem festgestellt.
Mark Amery
31

Ich bin überrascht, dass niemand erwähnt hat, Git Hooks zu verwenden, um dies zu tun!

Fügen Sie einfach Dateien mit dem Namen post-checkoutund post-mergezu Ihrem .git/hooksVerzeichnis der relevanten Repositorys hinzu und fügen Sie Folgendes in jedes ein:

#!/bin/sh
git submodule update --init --recursive

Da Sie speziell nach einem Alias ​​gefragt haben und davon ausgehen, dass Sie diesen für viele Repositorys haben möchten, können Sie einen Alias ​​erstellen, der diese .git/hooksfür Sie zu einem Repository hinzufügt .

Taleinat
quelle
2
Gibt es eine Möglichkeit, dies zu einer globalen Umgebung zu machen? Oder eine, die Sie automatisch beim Auschecken des Repositorys erhalten?
Raoul Steffen
3
Die neueste Version von git, 2.9, hat eine Einstellung hinzugefügt, die core.hooksPathfür ein Hooks-Verzeichnis benannt ist. git-configWeitere Informationen finden Sie in den Dokumenten .
Taleinat
1
Was beim Auschecken automatisch eingegangen ist, habe ich gesucht, aber nichts dergleichen gefunden. Eine Quelle erwähnte, dass dies aus Sicherheitsgründen absichtlich nicht unterstützt wird, da es ziemlich einfach verwendet werden könnte, um beliebigen Code auf Client-Computern auszuführen.
Taleinat
1
Ich sehe, wie das ein Sicherheitsproblem sein kann. Schließlich möchte ich damit Code ausführen, den ich auf den Computern meiner Mitarbeiter programmiere, ohne sie anweisen zu müssen.
Raoul Steffen
1
Diese Lösung war mein erster Gedanke, aber dann wurde mir klar, dass sie nicht Leute abdecken würde, die git pull --rebaseFolgendes verwenden :(
Vaz
8

Ein Alias, wie von Kevin Ballard vorgeschlagen, ist eine vollkommen gute Lösung. Um eine weitere Option zu bieten, können Sie auch einen Post-Merge-Hook verwenden, der einfach ausgeführt wird git submodule update [--init].

Cascabel
quelle
7

Sie können einen Alias ​​für den Befehl git erstellen, der die Aktualisierung des Submoduls automatisch übernimmt. Fügen Sie Ihrer .bashrc Folgendes hinzu

# make git submodules usable
#   This overwrites the 'git' command with modifications where necessary, and
#   calls the original otherwise
git() {
    if [[ $@ == clone* ]]; then
        gitargs=$(echo "$@" | cut -c6-)
        command git clone --recursive $gitargs
    elif [[ $@ == pull* ]]; then
        command git "$@" && git submodule update --init --recursive
    elif [[ $@ == checkout* ]]; then
        command git "$@" && git submodule update --init --recursive
    else
        command git "$@"
    fi
}
Branden Ghena
quelle
1
Anstelle eines Alias ​​für git können Sie git über den Alias-Befehl oder durch Erstellen von Befehlen in Ihrem Pfad Aliase hinzufügen, die mit git- (git-bettermodule) beginnen
idbrii
7

Wie andere bereits erwähnt haben, können Sie dies ganz einfach einstellen mit:

git config --global submodule.recurse true

Wenn Sie jedoch wie ich sind und ein komplexeres .gitconfigSetup haben (meine Hauptdatei ~/.gitconfigwird includezum Laden in andere .gitconfigDateien verwendet) und Sie sich nie daran erinnern können, wie zwischen dem Befehlszeilen- gitKonfigurationsformat und dem .gitconfigFormat konvertiert wird, können Sie es wie folgt hinzufügen zu einer Ihrer .gitconfigDateien:

[submodule]
  recurse = true
JacobEvelyn
quelle
0

Nur so konnte ich die Submodule und verschachtelten Submodule aktualisieren:

git submodule update --remote --merge --recursive; git submodule foreach --recursive "(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);" git add .; git commit -m 'SubmodulesSynced'; git push; git pull;

Ich hatte aufgrund der Klammern Probleme, den Alias ​​über das Terminal zu erstellen, daher musste ich diesen manuell zu .gitconfig für global hinzufügen:

[alias] supdate = "!git submodule update --remote --merge --recursive; git submodule foreach --recursive '(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);' git add .; git commit -m 'SubmodulesSynced'; git push; git pull;"

Irgendwelche Vorschläge, wie die Befehle oder der Alias ​​automatisch ausgeführt werden?

Sauli Kiviranta
quelle