I want to bring to repositories together, but the second repository should go into a branch
A - B - C - D - E - F - G - H Repo1
A1 - B1 - C1 Repo2
Crete new repo reponew
git init reponew
Add a remote for and fetch the old repo Repo1
git remote add -f Repo1 ..\..\output\Repo1
Merge the files from Repo1/master into new/master
git merge Repo1/master --allow-unrelated-histories
The new repository reponew looks like:
A - B - C - D - E - F - G - H master
Now I've created a new branch on specific commit and checkout
git branch branchX 200303b0b215cc0fb2d92f50ffc9d7df8bbaab74
git checkout branchX
Add a remote for and fetch the old repo Repo1
git remote add -f Repo2 ..\..\output\Repo2
Merge the files from Repo1/master into new/master
git merge -Xtheirs Repo2/master --allow-unrelated-histories
And now the new repository repnew looks like this:
A1 - B1 - C1 branchX
\
A - B - C - - - - - - - - - - - - - -
\
D - E - - - - - F - G - H master
It looks like that this is caused by the merge request which has a merge date of now
But I owuld like that it look like this:
A - B - C - D - E - - - - - F - G - H master
\
- - - A1 - B1 - C1 branchX
The main way to "move" commits AFTER an existing history is to use
rebase
. Merge can only add a new commit with both histories as parents.But
rebase
will not really move the commist but replay them after the specifiedonto
. So, if there is still a reference (branch or tag) on the old commits, they will stay available in the whole commit history.In your case you want to rebase the history of
Repo2/master
onto the commitC
.So the solution is:
You should get the result you want.
Suggested by @torek, there is also
filter-branch
.filter-branch
allows you to rewrite a commit history by applying a filter on each rewritten commit. It's mainly used to remove wrongly committed sensitive data (such as password), to remove large files from history, or to change the root folder of a repository. The advantage offilter-branch
is that it will also move the tags.It will also filter commits with empty message.
With
filter-branch
, there is a--parent-filter
that allow you to change the parent(s) of a commit while filtering.It will filter all the references listed, so to move tags, we have to list all tags in current
branchX
:git tag --merged branchX
, then filter them as-is with--tag-name-filter cat
.So the command will be:
Then you will have the rewritten history, but still the old one available with references prefixed by
refs/original/
.If it's OK, you can remove the original references (
rm -rf .git/refs/original/
), otherwise you can restore them (cp -r .git/refs/original/refs .git && rm -rf .git/refs/original/
).