Reputation: 21
I have two separate repositories - backend and frontend. I'd like to combine them, so I'm thinking about something like:
git clone [email protected]:backend.git
git clone [email protected]:frontend.git
cd frontend
mkdir frontend
git mv !(frontend) frontend
git commit -a -S -m "Moving frontend into its own subdirectory"
cd ../backend
git remote add frontend ../frontend
git fetch frontend
git checkout -b feature/merge-front-back
git merge -S --allow-unrelated-histories frontend/master
git push origin feature/merge-front-back
git remote rm frontend
...now, after verifying merge:
git checkout master
git merge feature/merge-front-back
so my 1 question is: is it good plan? do you see any flaws or better way?
And 2 question.. what about frontend branches? Most of them I don't need right now (maybe never), but would like to have option in the future to merge with them. Do I need repeat above process but for each frontend branch separately, merge frontend/branches/feature1 to backend/branches/front-back-merge-feature1, and so on?
(I asssume backend branches will don't have a problem when merging to "new" master branch containing frontend directory and history)
Upvotes: 2
Views: 915
Reputation: 45649
is it good plan? do you see any flaws or better way?
By "is it a good plan", I assume you mean "is this set of commands a good way to do what I've set out to do". In that regard, there are other ways, but I wouldn't say one is better or worse.
There is a step missing if you want the final repo to have the frontend branches; I'll address that below.
More generally - I will provide the caveat, that almost always whatever problem someone tries to solve by combining multiple projects into one repo, is replaced by bigger problems dealing with the combined structure. Whether these are logically separate projects is something you'll have to determine, but as a rule, I've seen combining repos be a move in the wrong direction more often than not.
But if you're set on your belief that they should be one repo, then those commands (at a glance) seem as good as any. I guess the obvious question is, why not try them? The only thing that can be damaged is the newly-created clones.
what about frontend branches?
When you fetch
from frontend
, your combined repo will get "remote tracking refs" for each of the frontend
branches. So for the frontend
branch master
you will get remotes/frontend/master
.
However, those will be deleted when you remove
the remote. For master
that doesn't necessarily matter (since you've merged frontend/master
into master
). For the other branches, you need to tell git to keep a ref to them - and, of course, it will be convenient if the ref it keeps is a branch. One way to do that would be
git fetch frontend refs/heads/*:refs/heads/frontend/*
Here you're creating a frontend
namespace for branches, and adding all branches from frontend
into that namespace. (As long as you don't already have either a branch named frontend
or an already-existing frontend
branch namespace in the backend repo, it's fine. If you do have one of those for some reason, you would have to use a different name for the namespace.)
These newly-created refs are under refs/heads
so they will be treated as proper branches (rather than remote tracking refs), and they won't be deleted when you remove the origin. From that point on, they are no different than your backend branches.
You might encounter problems when merging a frontend
branch to master
in the future, or you might not. git
will try to resolve the conflicts resulting from all the files moving; but remember that git doesn't really track file moves - instead it reconstructs them heuristically after the fact - so this mechanism isn't perfect.
If you're worried about such problems - or if you do some test merges and discover that there will be unacceptable levels of problem - then an option would be to rewrite the history of the frontend/*
branches to look like the files "always were" under a frontend/
folder. If I were to do that, I would do that before combining the repositories; i.e. right after cloning frontend
I would rewrite the clone's history instead of creating a new commit to move the files.
(You suggest repeating, for each branch, the type of procedure you performed on master
. I'm not confident that would work well, though you could test it. The problem is that while master
is being handled as a merge of unrelated histories, subsequent merges from other frontend
branches will not be. For those merges to work correctly, git would still have to correctly interpret the file moves - and in fact will have to interpret them correctly on both "sides" of the merge.)
If you opt to rewrite the frontend
history, the most straightforward approach is to use git filter-branch
with a --tree-filter
script that moves the files to the subdirectory. See the git filter-branch
docs for details. (https://git-scm.com/docs/git-filter-branch)
Upvotes: 4