8

I had a directory that contains multiple repositories and it looks like this:

folder
|- repo1
|  |- .git
|  |- File1.txt
|- repo2
|  |- .git
|  |- File2.txt
|- repo3
|  |- .git
|  |- File3

I wanted to combine them into single git repository and I did that by following these instructions.

After these instruction I have following structure:

folder
|- .git
|- repo1
|  |- File1.txt
|- repo2
|  |- File2.txt
|- repo3
|  |- File3

And that is great. But now I have main branch (from repo1) and two orphan branches in history:

* Merge repo3
|\
| * Add third file
* Merge repo2
|\ 
| * Add second file
* Add first file

What I would like to get is something like this

* Merge repo 3
* Add third file
* Merge repo 2
* Add second file
* Add first file

or even better

* Add third file
* Add second file
* Add first file.

Is something like this possible? And how?


More details for answer provided by VonC.

I start with this:

$ git log --graph
*   commit 888bb0d7a81a40f8b42da7ad3f02103e898f5c1f
|\  Merge: cf85078 eab1269
| | Author: Bojan Delic <...>
| | Date:   Sun Oct 6 13:12:36 2013 +0200
| |
| |     Merge repo3
| |
| * commit eab1269be53929450c34c30416820c13a8058678
|   Author: Bojan Delic <...>
|   Date:   Sun Oct 6 13:07:39 2013 +0200
|
|       Add third file
|
*   commit cf85078ca96d52f2277ad7e4c6f45b04a38cf7ee
|\  Merge: 92fa311 42333f8
| | Author: Bojan Delic <...>
| | Date:   Sun Oct 6 13:12:33 2013 +0200
| |
| |     Merge repo2
| |
| * commit 42333f8589e20d29e5e444d5e16ff1a5d63b8288
|   Author: Bojan Delic <...>
|   Date:   Sun Oct 6 13:07:09 2013 +0200
|
|       Add second file
|
* commit 92fa3113507548a62407431188c308685f72865d
  Author: Bojan Delic <...>
  Date:   Sun Oct 6 13:06:39 2013 +0200

      Add first file

Then I do:

$ git branch -v
* master 888bb0d Merge repo3
$ git checkout -b branch2 eab1269be53929450c34c30416820c13a8058678
$ git checkout -b branch3 42333f8589e20d29e5e444d5e16ff1a5d63b8288
$ git checkout branch2
Switched to branch 'branch2'
$ git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded branch2 to master.
$ git checkout master
Switched to branch 'master'
$ git merge branch2
Already up-to-date.
$ git checkout branch3
Switched to branch 'branch3'
$ git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded branch3 to master.
$ git checkout master
Switched to branch 'master'
$ git merge branch3
Already up-to-date.

After that:

$ git log --graph
*   commit 888bb0d7a81a40f8b42da7ad3f02103e898f5c1f
|\  Merge: cf85078 eab1269
| | Author: Bojan Delic <...>
| | Date:   Sun Oct 6 13:12:36 2013 +0200
| |
| |     Merge repo3
| |
| * commit eab1269be53929450c34c30416820c13a8058678
|   Author: Bojan Delic <...>
|   Date:   Sun Oct 6 13:07:39 2013 +0200
|
|       Add third file
|
*   commit cf85078ca96d52f2277ad7e4c6f45b04a38cf7ee
|\  Merge: 92fa311 42333f8
| | Author: Bojan Delic <...>
| | Date:   Sun Oct 6 13:12:33 2013 +0200
| |
| |     Merge repo2
| |
| * commit 42333f8589e20d29e5e444d5e16ff1a5d63b8288
|   Author: Bojan Delic <...>
|   Date:   Sun Oct 6 13:07:09 2013 +0200
|
|       Add second file
|
* commit 92fa3113507548a62407431188c308685f72865d
  Author: Bojan Delic <...>
  Date:   Sun Oct 6 13:06:39 2013 +0200

      Add first file

$ git branch -a
  branch2
  branch3
* master
Community
  • 1
  • 1
del-boy
  • 3,556
  • 3
  • 26
  • 39

1 Answers1

13

You could rebase the two orphan branches on top of your current master (from repo1)

git checkout branch2
git rebase master
git checkout master
git merge branch2 # fast-forward master to branch2

git checkout branch3
git rebase master
git checkout master
git merge branch3 # fast-forward master to branch3

But, in your case (after edits in the question), there is... nothing to do:

Those two orphan branches were already merged into master.
That is why a rebase would only fast-forward them to master... since they are already merged into master.
You can safely ignore eab1269 and 42333f: if they aren't referenced by a tag or a branch, they will be garbage-collected.
For instance, try to clone your repo and see if those commits are still around (if yes, try a git gc --aggressive --prune=now on that clone)


Note: git 2.9 (June 2016) will allow you to merge orphan branches (commit d04aa7e only with the --allow-unrelated-histories option:

git merge --allow-unrelated-histories a b
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Maybe I didn't understand, but there is not branch2, there is only `master` and `HEAD` and they point to commit `Merge repo3`. If I add branch that points to commit `Add third file` and do the rebase and merge, as you suggested, new branch moves to `Merge repo3` commit, but orphan branch remains. – del-boy Oct 06 '13 at 12:05
  • @del-boy you said there are two orphan branches. So I refer to them as '`branch2`' and '`branch3`'. What does `git branch -v` returns? – VonC Oct 06 '13 at 12:07
  • Yes, I sad that there are two orphan branches because I found that terminology, but there is no real git branch that points anywhere except master, that points to head. `git branch -v` only returns `* master 888bb0d Merge repo3`. – del-boy Oct 06 '13 at 12:14
  • @del-boy then you can easily create those branches from the SHA1 of the two dangling branches you found. `git checkout -b branch2 SHA1` – VonC Oct 06 '13 at 12:16
  • @del-boy a branch is a branch (detached, or orphan, or in any other state): it has a HEAD. An orphan branch is just a branch with its first commit without any parent (not originating from another branch), as mentioned in http://stackoverflow.com/a/5086906/6309. If you are using the term "branch", that means you know the HEAD SHA1 of said branch. – VonC Oct 06 '13 at 12:18
  • That is what I did after your initial answer, but I end up with two more branches pointing to same commit as master and I still have orphan branches. That is why I sad that maybe I didn't understand you, because, except having `branch2` and `branch3` now, nothing else happened, structure of history remaind as it was. – del-boy Oct 06 '13 at 12:26
  • @del-boy hence my comment about the term "branch": what do you mean by "I have two orphan *branches*". Maybe we aren't talking about the same thing. How do you see that you have two orphan branches? With what git command? – VonC Oct 06 '13 at 12:29
  • @del-boy but if you did rebase and merge correctly two actual branches, then `master`, `branch2` and `branch3` are supposed to refer to the same commit. That is intentional. – VonC Oct 06 '13 at 12:30
  • I agree, but main purpose of doing this was not achieved and that is not to have orphan branches in history and to have flat history like I draw in question. – del-boy Oct 06 '13 at 12:36
  • @del-boy after the rebase (provided you actually started with two actual branches), I can guarantee the history would be flat. – VonC Oct 06 '13 at 12:41
  • I have edited question to show you what I start with, execution commands you provided and what I ended with. Maybe I did something wrong, so, please, let me know if I did. – del-boy Oct 06 '13 at 12:59
  • Thakn you, that is what I was afraid of :(. I will wait some time and, if there is no other magical answers, I will accept yours. – del-boy Oct 06 '13 at 13:30
  • @del-boy sure, but do test the clone option, to see if your `log --graph` looks nicer. – VonC Oct 06 '13 at 13:31
  • I did, but sadly - cloning and `git gc --aggressive --prune=now` does not help. – del-boy Oct 06 '13 at 13:35
  • @del-boy strange. Are those commits referenced by a tag or a branch? Following http://stackoverflow.com/a/2707110/6309, What does a `git branch --contain 42333` returns? – VonC Oct 06 '13 at 13:38
  • Well, I guess that they can not be garbabe collected because they are merged into master, and `git branch --contain 42333` does return `* master`. – del-boy Oct 06 '13 at 13:45