Ok, we have a repository with 3 submodules. Now we want to merge this submodules back into main repository, keeping all history (well, using submodules turned out to be more headache than being usefull). How do we proceed?
Let's say you have the following filesystem (and let's assume you only have one submodule, to simply the answer)
myRepoRoot
├── myMainFiles/
└── submodule/
You just need to do:
# Preparing the filesystems
cd submodule
# "submodule" is basically the path where you need your submodule code to be in the new repository,
# e.g. app/code/x/y (<-- in this case you need to create multiple folders ofc, not just one like seen here)
mkdir submodule
git mv file1 file2 dir1 dir2 submodule
git commit -am "Moved file"
# Actually merging
cd myRepoRoot
git remote add sub url_to_submodule
git fetch sub
git merge sub/master
To explain it with words: you have several trees with no commit in common, and you just need to merge those trees. That's what the second part is doing.
The first part is just needed to ensure the filesystem of the submodule will be what you could expect.
I've added an example based on the answer of @gturri, i hope it helps someone:
Example
Let's say this is your submodule:
app/
├─ code/
│ ├─ Foo/
│ │ ├─ Bar/
│ │ │ ├─ .git/
│ │ │ ├─ .gitignore
│ │ │ ├─ registration.php
│ │ │ ├─ etc/
│ │ │ │ └─ modules.xml
│ │ │ ├─ view/
│ │ │ │ ├─ frontend/
│ │ │ │ │ ├─ templates/
│ │ │ │ │ │ ├─ foo.phtml
Your submodule is stored in app/code/Foo/Bar and you need it to be in the exact location in the new repo, then do it like this:
# CD into the submodule
cd app/code/Foo/Bar
# Create the same directory tree as the current submodule path, in your submodule
mkdir -p app/code/Foo/Bar
Pro Tip: Use
git submodule foreach 'mkdir -p "$sm_path"'
to automatically create the directory structure in all submodules.See Documentation
New Directory added:
app/
├─ code/
│ ├─ Foo/
│ │ ├─ Bar/
│ │ │ ├─ .git/
│ │ │ ├─ .gitignore
│ │ │ ├─ registration.php
│ │ │ ├─ etc/
│ │ │ │ └─ modules.xml
│ │ │ ├─ view/
│ │ │ │ ├─ frontend/
│ │ │ │ │ ├─ templates/
│ │ │ │ │ │ ├─ foo.phtml
│ │ │ ├─ app/
│ │ │ │ ├─ code/
│ │ │ │ │ ├─ Foo/
│ │ │ │ │ │ ├─ Bar/
Move files to new folder via GIT:
git checkout <target_branch>
git pull
git mv .gitignore registration.php etc/ view/ app/code/Foo/Bar
git commit -am "Moved files"
git push
Now it looks like this:
app/
├─ code/
│ ├─ Foo/
│ │ ├─ Bar/
│ │ │ ├─ .git/
│ │ │ ├─ app/
│ │ │ │ ├─ code/
│ │ │ │ │ ├─ Foo/
│ │ │ │ │ │ ├─ Bar/
│ │ │ │ │ │ │ ├─ .gitignore
│ │ │ │ │ │ │ ├─ registration.php
│ │ │ │ │ │ │ ├─ etc/
│ │ │ │ │ │ │ │ └─ modules.xml
│ │ │ │ │ │ │ ├─ view/
│ │ │ │ │ │ │ │ ├─ frontend/
│ │ │ │ │ │ │ │ │ ├─ templates/
│ │ │ │ │ │ │ │ │ │ ├─ foo.phtml
Delete submodule folder:
rm -rf <my_repo_root>/app/code/Foo/Bar
Merge your submodule to your repo:
cd myRepoRoot
git remote add sub <url_to_submodule>
git fetch sub
git merge sub/master --allow-unrelated-histories
Remove submodule from repo (helps from https://mcmap.net/q/12767/-how-do-i-remove-a-submodule)
rm -rf .git/modules/app/code/Foo/Bar
git config --remove-section submodule.app/code/Foo/Bar
Your submodule should now be located in your repository at app/code/Foo/Bar
--allow-unrelated-histories
as you can see in https://mcmap.net/q/12641/-git-refusing-to-merge-unrelated-histories-on-rebase –
Wachter git rm <path-to-submodule>
- before it allowed the merge. (stackoverflow.com/a/1260982). I also had to use a local copy of the submodule as the remote, git remote add sub ../localcopyofsubmodule
, as otherwise git-lfs absolutely refused to work. –
Dubonnet © 2022 - 2024 — McMap. All rights reserved.