Un-Submodul Ein Git-Submodul


378

Wie entferne ich das Submodul eines Git-Submoduls (bringe den gesamten Code zurück in den Kern)?

Wie in "sollte" ich, wie in "Best Procedure" ...


5
Hinweis: Mit git1.8.3 können Sie jetzt eine versuchen git submodule deinit, siehe meine Antwort unten
VonC

6
Ich kann falsch verstehen, aber Git Submodul Deinit scheint den Code zu entfernen.
Joe Germuska

2
Seit Git 1.8.5 (November 2013) ist ein einfaches git submodule deinit asubmodule ; git rm asubmoduleausreichend, wie in meiner Antwort unten dargestellt
VonC

Antworten:


527

Wenn Sie lediglich Ihren Submodul-Code in das Haupt-Repository einfügen möchten, müssen Sie nur das Submodul entfernen und die Dateien erneut zum Haupt-Repository hinzufügen:

git rm --cached submodule_path # delete reference to submodule HEAD (no trailing slash)
git rm .gitmodules             # if you have more than one submodules,
                               # you need to edit this file instead of deleting!
rm -rf submodule_path/.git     # make sure you have backup!!
git add submodule_path         # will add files instead of commit reference
git commit -m "remove submodule"

Wenn Sie auch den Verlauf des Submoduls beibehalten möchten, können Sie einen kleinen Trick ausführen: Das Submodul wird in das Haupt-Repository "zusammengeführt", sodass das Ergebnis das gleiche wie zuvor ist, außer dass sich die Submodul-Dateien jetzt im befinden Haupt-Repository.

Im Hauptmodul müssen Sie Folgendes tun:

# Fetch the submodule commits into the main repository
git remote add submodule_origin git://url/to/submodule/origin
git fetch submodule_origin

# Start a fake merge (won't change any files, won't commit anything)
git merge -s ours --no-commit submodule_origin/master

# Do the same as in the first solution
git rm --cached submodule_path # delete reference to submodule HEAD
git rm .gitmodules             # if you have more than one submodules,
                               # you need to edit this file instead of deleting!
rm -rf submodule_path/.git     # make sure you have backup!!
git add submodule_path         # will add files instead of commit reference

# Commit and cleanup
git commit -m "removed submodule"
git remote rm submodule_origin

Das resultierende Repository sieht etwas seltsam aus: Es wird mehr als ein erstes Commit geben. Aber es wird keine Probleme für Git verursachen.

In dieser zweiten Lösung haben Sie den großen Vorteil, dass Sie weiterhin Git-Tadel oder Git-Log für die Dateien ausführen können, die ursprünglich in Submodulen enthalten waren. Tatsächlich haben Sie hier viele Dateien in einem Repository umbenannt, und Git sollte dies automatisch erkennen. Wenn Sie immer noch Probleme mit dem Git-Protokoll haben, versuchen Sie einige Optionen (--follow, -M, -C), die eine bessere Umbenennungs- / Kopiererkennung ermöglichen.


3
Ich denke, ich muss Ihre zweite Methode (Geschichtserhaltung) für einige Git-Repos durchführen, die ich habe. Könnten Sie bitte erklären, welcher Teil der obigen Befehle dazu führt, dass die Dateien aus dem Submodul im Unterverzeichnis landen? Ist es so, dass Sie beim Zusammenführen von Git die Datei in das Verzeichnis der obersten Ebene (mit ihrem Verlauf) bringen, aber wenn Sie das Git hinzufügen, submodule_path hinzufügen, führt dies implizit eine Git-MV für jede Datei aus?
Bowie Owens

5
Grundsätzlich ja. Der Trick ist, dass git keine Umbenennungsvorgänge speichert, sondern sie anhand der übergeordneten Commits erkennt. Wenn im vorherigen Commit ein Dateiinhalt vorhanden war, der jedoch einen anderen Dateinamen hat, wird dieser als Umbenennung (oder Kopie) betrachtet. Stellt in den obigen Schritten git mergesicher, dass für jede Datei (auf einer der beiden "Seiten" der Zusammenführung) ein "vorheriges Festschreiben" erfolgt.
Gyim

6
Dank gyim habe ich ein Projekt gestartet, bei dem ich es für sinnvoll hielt, Dinge in ein paar Repositories aufzuteilen und sie wieder mit Submodulen zu verknüpfen. Aber jetzt scheint es überarbeitet und ich möchte sie wieder miteinander kombinieren, ohne meine Geschichte zu verlieren.
Bowie Owens

4
@theduke Ich hatte auch dieses Problem. Dies kann behoben werden, indem Sie vor dem Ausführen dieser Schritte alle Dateien aus Ihrem Submodul-Repository in eine Verzeichnisstruktur mit demselben Pfad wie das Repository verschieben, in das Sie zusammenführen möchten: dh. Wenn sich Ihr Submodul im Hauptrepository in foo / befindet, führen Sie es im Submodul aus mkdir foo && git mv !(foo) foo && git commit.
Chris Down

35
Musste hinzufügen --allow-unrelated-histories, um die Zusammenführung bei der gefälschten Zusammenführung zu erzwingen, wie ich es bekam fatal: refusing to merge unrelated histories, mehr hier: github.com/git/git/blob/master/Documentation/RelNotes/…
vaskort

72

Seit git 1.8.5 (Nov 2013 ) ( ohne die Geschichte des Submoduls zu behalten ):

mv yoursubmodule yoursubmodule_tmp
git submodule deinit yourSubmodule
git rm yourSubmodule
mv yoursubmodule_tmp yoursubmodule
git add yoursubmodule

Das wird:

  • das Submodul ( daher das erste ) abmelden und entladen (dh den Inhalt löschen ),deinitmv
  • räum das .gitmodulesfür dich auf ( rm),
  • und entfernen Sie den speziellen Eintrag, der dieses Submodul SHA1 darstellt, im Index des übergeordneten Repos ( rm).

Sobald das Entfernen des Submoduls abgeschlossen ist ( deinitund git rm), können Sie den Ordner wieder in seinen ursprünglichen Namen umbenennen und ihn als regulären Ordner zum Git-Repo hinzufügen.

Hinweis: Wenn das Submodul von einem alten Git (<1.8) erstellt wurde, müssen Sie möglicherweise den verschachtelten .gitOrdner im Submodul selbst entfernen , wie von Simon East kommentiert


Wenn Sie den Verlauf des Submoduls beibehalten müssen , lesen Sie die Antwort von jsears , die verwendet wird git filter-branch.


5
Dadurch wird es tatsächlich aus dem Arbeitsbaum in 1.8.4 gelöscht (mein gesamtes Submodul-Verzeichnis wurde gelöscht).
Chris Down

@ ChrisDown meinst du, der deinitallein hat den Arbeitsbaum von deinem Submodul gereinigt?
VonC

Ja, es entfernt den gesamten Inhalt im Submodulverzeichnis.
Chris Down

2
@mschuett nein, dir fehlt nichts: Ein Submodul hat überhaupt kein .git. Wenn dies bei Ihnen der Fall war, war es ein verschachteltes Repo, kein Submodul. Dies erklärt, warum diese Antwort in Ihrem Fall nicht zutreffen würde. Den Unterschied zwischen den beiden finden Sie unter stackoverflow.com/a/34410102/6309 .
VonC

1
@VonC Ich bin derzeit auf 2.9.0.windows.1, aber die Submodule wurden möglicherweise vor einigen Jahren auf einer viel früheren Version von git erstellt, ich bin mir nicht sicher. Ich denke, die Schritte scheinen zu funktionieren, solange ich diese Datei entferne, bevor ich das endgültige Hinzufügen + Festschreiben durchführe.
Simon East

67

Ich habe ein Skript erstellt, das ein Submodul in ein einfaches Verzeichnis übersetzt und dabei den gesamten Dateiversionsverlauf beibehält. Es leidet nicht unter den git log --follow <file>Problemen, unter denen die anderen Lösungen leiden. Es ist auch ein sehr einfacher einzeiliger Aufruf, der die ganze Arbeit für Sie erledigt. Glück.

Es baut auf der hervorragenden Arbeit von Lucas Jenß auf, die in seinem Blogbeitrag " Integration eines Submoduls in das übergeordnete Repository " beschrieben wurde, automatisiert jedoch den gesamten Prozess und bereinigt einige andere Eckfälle.

Der neueste Code wird mit Bugfixes auf github unter gepflegt https://github.com/jeremysears/scripts/blob/master/bin/git-submodule-rewrite , aber aus Gründen des korrekten Stackoverflow-Antwortprotokolls habe ich das hinzugefügt Lösung in ihrer Gesamtheit unten.

Verwendungszweck:

$ git-submodule-rewrite <submodule-name>

git-submodule-rewrite:

#!/usr/bin/env bash

# This script builds on the excellent work by Lucas Jenß, described in his blog
# post "Integrating a submodule into the parent repository", but automates the
# entire process and cleans up a few other corner cases.
# https://x3ro.de/2013/09/01/Integrating-a-submodule-into-the-parent-repository.html

function usage(){
  echo "Merge a submodule into a repo, retaining file history."
  echo "Usage: $0 <submodule-name>"
  echo ""
  echo "options:"
  echo "  -h, --help                Print this message"
  echo "  -v, --verbose             Display verbose output"
}

function abort {
    echo "$(tput setaf 1)$1$(tput sgr0)"
    exit 1
}

function request_confirmation {
    read -p "$(tput setaf 4)$1 (y/n) $(tput sgr0)"
    [ "$REPLY" == "y" ] || abort "Aborted!"
}

function warn() {
  cat << EOF
    This script will convert your "${sub}" git submodule into
    a simple subdirectory in the parent repository while retaining all
    contents and file history.

    The script will:
      * delete the ${sub} submodule configuration from .gitmodules and
        .git/config and commit it.
      * rewrite the entire history of the ${sub} submodule so that all
        paths are prefixed by ${path}.
        This ensures that git log will correctly follow the original file
        history.
      * merge the submodule into its parent repository and commit it.

    NOTE: This script might completely garble your repository, so PLEASE apply
    this only to a fresh clone of the repository where it does not matter if
    the repo is destroyed.  It would be wise to keep a backup clone of your
    repository, so that you can reconstitute it if need be.  You have been
    warned.  Use at your own risk.

EOF

  request_confirmation "Do you want to proceed?"
}

function git_version_lte() {
  OP_VERSION=$(printf "%03d%03d%03d%03d" $(echo "$1" | tr '.' '\n' | head -n 4))
  GIT_VERSION=$(git version)
  GIT_VERSION=$(printf "%03d%03d%03d%03d" $(echo "${GIT_VERSION#git version}" | tr '.' '\n' | head -n 4))
  echo -e "${GIT_VERSION}\n${OP_VERSION}" | sort | head -n1
  [ ${OP_VERSION} -le ${GIT_VERSION} ]
}

function main() {

  warn

  if [ "${verbose}" == "true" ]; then
    set -x
  fi

  # Remove submodule and commit
  git config -f .gitmodules --remove-section "submodule.${sub}"
  if git config -f .git/config --get "submodule.${sub}.url"; then
    git config -f .git/config --remove-section "submodule.${sub}"
  fi
  rm -rf "${path}"
  git add -A .
  git commit -m "Remove submodule ${sub}"
  rm -rf ".git/modules/${sub}"

  # Rewrite submodule history
  local tmpdir="$(mktemp -d -t submodule-rewrite-XXXXXX)"
  git clone "${url}" "${tmpdir}"
  pushd "${tmpdir}"
  local tab="$(printf '\t')"
  local filter="git ls-files -s | sed \"s/${tab}/${tab}${path}\//\" | GIT_INDEX_FILE=\${GIT_INDEX_FILE}.new git update-index --index-info && mv \${GIT_INDEX_FILE}.new \${GIT_INDEX_FILE}"
  git filter-branch --index-filter "${filter}" HEAD
  popd

  # Merge in rewritten submodule history
  git remote add "${sub}" "${tmpdir}"
  git fetch "${sub}"

  if git_version_lte 2.8.4
  then
    # Previous to git 2.9.0 the parameter would yield an error
    ALLOW_UNRELATED_HISTORIES=""
  else
    # From git 2.9.0 this parameter is required
    ALLOW_UNRELATED_HISTORIES="--allow-unrelated-histories"
  fi

  git merge -s ours --no-commit ${ALLOW_UNRELATED_HISTORIES} "${sub}/master"
  rm -rf tmpdir

  # Add submodule content
  git clone "${url}" "${path}"
  rm -rf "${path}/.git"
  git add "${path}"
  git commit -m "Merge submodule contents for ${sub}"
  git config -f .git/config --remove-section "remote.${sub}"

  set +x
  echo "$(tput setaf 2)Submodule merge complete. Push changes after review.$(tput sgr0)"
}

set -euo pipefail

declare verbose=false
while [ $# -gt 0 ]; do
    case "$1" in
        (-h|--help)
            usage
            exit 0
            ;;
        (-v|--verbose)
            verbose=true
            ;;
        (*)
            break
            ;;
    esac
    shift
done

declare sub="${1:-}"

if [ -z "${sub}" ]; then
  >&2 echo "Error: No submodule specified"
  usage
  exit 1
fi

shift

if [ -n "${1:-}" ]; then
  >&2 echo "Error: Unknown option: ${1:-}"
  usage
  exit 1
fi

if ! [ -d ".git" ]; then
  >&2 echo "Error: No git repository found.  Must be run from the root of a git repository"
  usage
  exit 1
fi

declare path="$(git config -f .gitmodules --get "submodule.${sub}.path")"
declare url="$(git config -f .gitmodules --get "submodule.${sub}.url")"

if [ -z "${path}" ]; then
  >&2 echo "Error: Submodule not found: ${sub}"
  usage
  exit 1
fi

if ! [ -d "${path}" ]; then
  >&2 echo "Error: Submodule path not found: ${path}"
  usage
  exit 1
fi

main

Funktioniert nicht unter Ubuntu 16.04. Ich habe eine Pull-Anfrage an das Github-Repo gesendet .
QZNC

1
Guter Fang, @qznc. Dies wurde unter OSX getestet. Ich werde das gerne zusammenführen, wenn es auf beiden Plattformen weitergegeben wird.
jsears

@qznc Ubuntu 16.04 Unterstützung zusammengeführt und Antwort aktualisiert.
jsears

2
Dies ist die beste Antwort, hält die ganze Geschichte. Sehr schön!
CharlesB

1
Arbeiten Sie alle fehlerfrei in Git Bash 2.20.1.1 unter Windows 10 mit der neuesten Version von github: curl https://raw.githubusercontent.com/jeremysears/scripts/master/bin/git-submodule-rewrite > git-submodule-rewrite.shund./git-submodule-rewrite.sh <submodule-name>
Alexey

32
  1. git rm --cached the_submodule_path
  2. Entfernen Sie den Submodulabschnitt aus der .gitmodulesDatei. Wenn dies das einzige Submodul ist, entfernen Sie die Datei.
  3. mache ein Commit "entferntes Submodul xyz"
  4. git add the_submodule_path
  5. ein weiteres Commit "Codebasis von xyz hinzugefügt"

Einfacheren Weg habe ich noch nicht gefunden. Sie können 3-5 über den git commit -aGeschmack in einem Schritt komprimieren .


6
Sollte es nicht .gitmodulesstatt sein .submodules?
imz - Ivan Zakharyaschev

1
Es sollte .gitmodulesnicht sein.submodules
Mkey

1
Ich musste das .gitVerzeichnis des Submoduls entfernen, bevor ich mit git adddem Submodul-Ordner arbeiten konnte
Carson Evans

16

Viele Antworten hier, aber alle scheinen zu komplex zu sein und tun wahrscheinlich nicht das, was Sie wollen. Ich bin sicher, dass die meisten Menschen ihre Geschichte behalten wollen.

In diesem Beispiel ist das Haupt-Repo git@site.com:main/main.gitund das Submodul-Repo git@site.com:main/child.git. Dies setzt voraus, dass sich das Submodul im Stammverzeichnis des übergeordneten Repos befindet. Passen Sie die Anweisungen nach Bedarf an.

Klonen Sie zunächst das übergeordnete Repo und entfernen Sie das alte Submodul.

git clone git@site.com:main/main.git
git submodule deinit child
git rm child
git add --all
git commit -m "remove child submodule"

Jetzt werden wir die untergeordneten Repos stromaufwärts zum Haupt-Repo hinzufügen.

git remote add upstream git@site.com:main/child.git
git fetch upstream
git checkout -b merge-prep upstream/master

Im nächsten Schritt wird davon ausgegangen, dass Sie die Dateien im Zweig für die Zusammenführungsvorbereitung an denselben Speicherort verschieben möchten, an dem sich das Submodul oben befand. Sie können den Speicherort jedoch leicht ändern, indem Sie den Dateipfad ändern.

mkdir child

Verschieben Sie alle Ordner und Dateien mit Ausnahme des .git-Ordners in den untergeordneten Ordner.

git add --all
git commit -m "merge prep"

Jetzt können Sie Ihre Dateien einfach wieder in den Hauptzweig einfügen.

git checkout master
git merge merge-prep # --allow-unrelated-histories merge-prep flag may be required 

Schauen Sie sich um und stellen Sie sicher, dass alles gut aussieht, bevor Sie laufen git push

Das einzige, woran Sie sich jetzt erinnern müssen, ist, dass das Git-Protokoll standardmäßig nicht verschobenen Dateien folgt. Wenn Sie jedoch ausführen git log --follow filename, können Sie den vollständigen Verlauf Ihrer Dateien anzeigen.


2
Ich bin bis ins Finale gekommen git merge merge-prepund habe den Fehler erhalten fatal: refusing to merge unrelated histories. Umgehung ist dies : git merge --allow-unrelated-histories merge-prep.
Demütiger Hacker

@humblehacker danke ich habe einen kleinen Kommentar hinzugefügt, falls andere auch darauf stoßen.
Mschuett

1
Die beste Antwort, um die Geschichte des Submoduls zu halten. Vielen Dank @mschuett
Anton Temchenko

Gibt es im Beispiel hier eine Möglichkeit, die Dateien des Upstreams in das childVerzeichnis abzurufen , damit Sie sie später nicht verschieben müssen? Ich habe die gleichen Dateinamen in einem Submodul und im Haupt-Repo ... daher erhalte ich nur einen Zusammenführungskonflikt, da versucht wird, die beiden Dateien zusammenzuführen.
Skitterm

Möglicherweise, aber ich weiß es nicht ohne weiteres. Ich persönlich würde einfach ein Commit machen, um die Dateien in dem Repo, in das Sie sich bewegen möchten, so zu verschieben, dass sie sich in dem gewünschten Verzeichnis befinden, bevor Sie sie
abrufen

12

Es ist uns passiert, dass wir 2 Repositorys für 2 Projekte erstellt haben, die so gekoppelt waren, dass es keinen Sinn machte, sie zu trennen, also haben wir sie zusammengeführt.

Ich werde zuerst zeigen, wie die Hauptzweige in jedem Zweig zusammengeführt werden, und dann erkläre ich, wie Sie dies auf alle Zweige ausweiten können, die Sie haben. Ich hoffe, es hilft Ihnen.

Wenn Sie das Submodul zum Laufen gebracht haben und es in ein vorhandenes Verzeichnis konvertieren möchten, haben Sie folgende Möglichkeiten:

git clone project_uri project_name

Hier machen wir einen sauberen Klon, um zu arbeiten. Für diesen Prozess müssen Sie die Submodule nicht initialisieren oder aktualisieren. Überspringen Sie sie einfach.

cd project_name
vim .gitmodules

Bearbeiten Sie .gitmodulesmit Ihrem bevorzugten Editor (oder Vim), um das Submodul zu entfernen, das Sie ersetzen möchten. Die Linien, die Sie entfernen müssen, sollten ungefähr so ​​aussehen:

[submodule "lib/asi-http-request"]
    path = lib/asi-http-request
    url = https://github.com/pokeb/asi-http-request.git

Nach dem Speichern der Datei,

git rm --cached directory_of_submodule
git commit -am "Removed submodule_name as submodule"
rm -rf directory_of_submodule

Hier entfernen wir die Submodul-Beziehung vollständig, damit wir das andere Repo an Ort und Stelle zum Projekt bringen können.

git remote add -f submodule_origin submodule_uri
git fetch submodel_origin/master

Hier holen wir das Submodul-Repository zum Zusammenführen.

git merge -s ours --no-commit submodule_origin/master

Hier starten wir einen Zusammenführungsvorgang der beiden Repositorys, stoppen jedoch vor dem Festschreiben.

git read-tree --prefix=directory_of_submodule/ -u submodule_origin/master

Hier senden wir den Inhalt des Masters im Submodul an das Verzeichnis, in dem er sich befand, bevor ein Verzeichnisname vorangestellt wurde

git commit -am "submodule_name is now part of main project"

Hier schließen wir den Vorgang ab, indem wir die Änderungen in der Zusammenführung festschreiben.

Nachdem Sie dies abgeschlossen haben, können Sie einen Push ausführen und erneut mit einem anderen Zweig zum Zusammenführen beginnen. Überprüfen Sie einfach den Zweig in Ihrem Repository, der die Änderungen erhält, und ändern Sie den Zweig, den Sie in die Zusammenführungs- und Lesebaumoperationen einbringen.


Dies schien den Verlauf der Submodul-Dateien nicht erhalten zu haben. Ich sehe nur ein einziges Commit im Git-Protokoll für die Dateien, die unterdirectory_of_submodule
Anentropic

@Anentropic Entschuldigung für die Verzögerung bei der Antwort. Ich habe gerade die vollständige Prozedur erneut durchgeführt (mit einer kleinen Korrektur). Das Verfahren behält den gesamten Verlauf bei, hat jedoch einen Zusammenführungspunkt. Vielleicht finden Sie ihn deshalb nicht. Wenn Sie den Submodulverlauf anzeigen möchten, führen Sie einfach ein "Git-Protokoll" durch und suchen Sie nach dem Merge-Commit (im Beispiel das mit der Meldung "Submodulname ist jetzt Teil des Hauptprojekts"). Es hat 2 übergeordnete Commits (Merge: sdasda asdasd), git protokolliert das zweite Commit und Sie haben dort Ihren gesamten Submodul- / Master-Verlauf.
dvicino

Mein Gedächtnis ist jetzt verschwommen, aber ich glaube, ich konnte den Verlauf der zusammengeführten Submodul-Dateien abrufen, indem ich git log original_path_of_file_in_submoduleden im Git-Repo registrierten Pfad für die Datei (die im Dateisystem nicht mehr vorhanden ist) durchführte, obwohl die Submodul-Datei lebt jetzt beisubmodule_path/new_path_of_file
Anentropic

Dies bewahrt die Geschichte nicht sehr gut und auch die Wege sind falsch. Ich habe das Gefühl, dass so etwas wie ein Baumfilter
Luke H

Diese Antwort ist veraltet, stackoverflow.com/a/16162228/11343 (VonC-Antwort) macht das gleiche, aber besser
CharlesB


6

Hier ist eine leicht verbesserte Version (IMHO) von @ gyims Antwort. Er nimmt eine Reihe gefährlicher Änderungen an der Hauptarbeitskopie vor, bei denen es meiner Meinung nach viel einfacher ist, separate Klone zu bearbeiten und sie am Ende zusammenzuführen.

Überprüfen Sie in einem separaten Verzeichnis (um Fehler zu bereinigen und erneut zu versuchen) sowohl das Top-Repo als auch das Subrepo.

git clone ../main_repo main.tmp
git clone ../main_repo/sub_repo sub.tmp

Bearbeiten Sie zuerst das Subrepo, um alle Dateien in das gewünschte Unterverzeichnis zu verschieben

cd sub.tmp
mkdir sub_repo_path
git mv `ls | grep -v sub_repo_path` sub_repo_path/
git commit -m "Moved entire subrepo into sub_repo_path"

Notieren Sie sich den KOPF

SUBREPO_HEAD=`git reflog | awk '{ print $1; exit; }'`

Entfernen Sie nun das Subrepo aus dem Haupt-Repo

cd ../main.tmp
rmdir sub_repo_path
vi .gitmodules  # remove config for submodule
git add -A
git commit -m "Removed submodule sub_repo_path in preparation for merge"

Und zum Schluss einfach zusammenführen

git fetch ../sub.tmp
# remove --allow-unrelated-histories if using git older than 2.9.0
git merge --allow-unrelated-histories $SUBREPO_HEAD

Und fertig! Sicher und ohne Magie.


... welche Antwort ist das? Möglicherweise möchten Sie auf den Benutzernamen verweisen, und die Top-Antwort kann sich im Laufe der Zeit ändern.
Contango

@ Contango Antwort aktualisiert. aber die Top-Antwort ist immer noch die Top-Antwort mit einem Vorsprung von 400 Punkten
;-)

Funktioniert dies, wenn das Subrepo bereits ein Verzeichnis mit Namen enthält subrepo?
Detly

Im letzten Schritt wird folgende Fehlermeldung git merge $SUBREPO_HEAD fatal: refusing to merge unrelated historiesangezeigt : Soll ich git merge $SUBREPO_HEAD --allow-unrelated-historiesin diesem Fall verwenden? Oder sollte es ohne funktionieren und ich habe einen Fehler gemacht?
Ti-m

1
@ Ti-m Ja, genau dies ist der Fall, wenn zwei Historien zusammengeführt werden, die keine Commits gemeinsam haben. Der Schutz vor nicht verwandten Geschichten scheint in git neu zu sein, seit ich dies zum ersten Mal geschrieben habe; Ich werde meine Antwort aktualisieren.
Daten

3

Für wann

git rm [-r] --cached submodule_path

kehrt zurück

fatal: pathspec 'emr/normalizers/' did not match any files

Kontext: Ich habe rm -r .git*in meinen Submodul-Ordnern festgestellt, dass sie in dem Hauptprojekt, zu dem ich sie gerade hinzugefügt hatte, de-submoduliert werden mussten. Ich habe den obigen Fehler beim De-Submodulieren einiger, aber nicht aller erhalten. Wie auch immer, ich habe sie durch Laufen repariert (natürlich nach dem rm -r .git*)

mv submodule_path submodule_path.temp
git add -A .
git commit -m "De-submodulization phase 1/2"
mv submodule_path.temp submodule_path
git add -A .
git commit -m "De-submodulization phase 2/2"

Beachten Sie, dass dadurch die Geschichte nicht erhalten bleibt.


3

Basierend auf der Antwort von VonC habe ich ein einfaches Bash-Skript erstellt, das dies tut. Das addam Ende muss Platzhalter verwenden, sonst wird das vorherige rmfür das Submodul selbst rückgängig gemacht . Es ist wichtig, den Inhalt des Submodulverzeichnisses hinzuzufügen und das Verzeichnis selbst nicht im addBefehl zu benennen .

In einer Datei namens git-integrate-submodule:

#!/usr/bin/env bash
mv "$1" "${1}_"
git submodule deinit "$1"
git rm "$1"
mv "${1}_" "$1"
git add "$1/**"

0

Ich fand es bequemer, (auch?) Lokale Commit-Daten aus dem Submodul abzurufen, da ich sie sonst verlieren würde. (Konnte sie nicht pushen, da ich keinen Zugriff auf diese Fernbedienung habe). Also habe ich submodule / .git als remote_origin2 hinzugefügt, es festgeschrieben und aus diesem Zweig zusammengeführt. Ich bin mir nicht sicher, ob ich die Submodul-Fernbedienung noch als Ursprung benötige, da ich mit Git noch nicht genug vertraut bin.


0

Folgendes fand ich am besten und am einfachsten.

Im Submodul-Repo möchten Sie von HEAD aus in das Haupt-Repo übergehen:

  • git checkout -b "mergeMe"
  • mkdir "foo/bar/myLib/" (identischer Pfad wie dort, wo Sie die Dateien im Haupt-Repo haben möchten)
  • git mv * "foo/bar/myLib/" (Bewegen Sie alle in den Pfad)
  • git commit -m "ready to merge into main"

Zurück im Haupt-Repo, nachdem das Submodul entfernt und der Pfad "foo / bar / myLib" gelöscht wurde:

  • git merge --allow-unrelated-histories SubmoduleOriginRemote/mergeMe

Boom geschafft

Geschichten erhalten

Keine Bange


Beachten Sie, dass dies fast identisch mit einigen anderen Antworten ist. Dies setzt jedoch voraus, dass Sie ein eigenes Submodul-Repo besitzen. Dies macht es auch einfach, zukünftige Upstream-Änderungen für das Submodul zu erhalten.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.