git subtree
Who does not know this common situation: We have a new Idea to extend our existing Project old
. So we create a subdirectory newIdea
in the corresponding repository. It turns out that the idea was so good that it would also be useful outside of the project old
. It would be sensible to create a new repository new
which should only contain the subdirectory newIdea
. In fact, this problem seems to be so common that there is a special git subcommand since 2012 for this purpose (and more complicated cases): git subtree
New repository from subdirectory
old/
├─ newIdea/
│ ├─ lib.rs
├─ main.rs
So inside the directory old
we execute the following command:
git subtree split --prefix=newIdea/ --branch=onlyNewIdeaBranch
This creates a new Branch onlyNewIdeaBranch
which only contains the contents of newIdea
, i.e., a new root directory. So this branch has a newly written history consisting only of commits with influence on files below of newIdea/
.
Now we can create the new repository new
and pull the newly created branch.Branch pullen.
cd .. ; mkdir new ; cd new
git init
git pull ../alt onlyNewIdeaBranch
Maybe we want to delete the newIdea
subdirectory from the old
repository. Probably we have to change infrastructure code in the new
repository.
old/
├─ main.rs
new/
├─ lib.rs
Move a subdirectory into an existing repository
Possibly we notice that the code would fit better into an existing repository instead of a new one? Perhaps because we are in the process of moving our code into a monorepo? No problem at all!
old/
├─ newIdea/
│ ├─ lib.rs
├─ main.rs
monorepo/
├─ project1/
├─ project2/
We already created the onlyNewIdeaBranch
, which we want to move into the subdirectory goodIdea
of the monorepo
. Again, we can solve it with git subtree
:
cd monorepo
git branch withGoodIdeadBranch
git checkout withGoodIdeadBranch
git subtree add --prefix=goodIdea/ ../old onlyNewIdeaBranch
As soon as we ensured that our new Branch withGoodIdeadBranch
looks good and we modified the infrastructure code, we can merge it into main.
old/
├─ neueIdee/
│ ├─ lib.rs
├─ main.rs
monorepo/
├─ project1/
├─ project2/
├─ goodIdea/
│ ├─ lib.rs