Neeraj
Neeraj

Reputation: 180

Same code different git files, merging with keeping history

There was an existing bitbucket repo A with over 200 commits. I downloaded the code (without .git files). Created new repo B with all the existing code added in first commit. Then 150 more commits on repo B. repo A has no new commits, I worked on repo B only. Now the requirement is a Single repo with all the code and history (if possible) or Repo B changes as a single entry in history. A third repo C will be fine coz dont want to risk A and B.

Upvotes: 1

Views: 404

Answers (3)

jthill
jthill

Reputation: 60255

git rebase -p --onto might be simplest. Rebase's -p option tries to preserve merge structure, and its --onto permits specifying both the new base and the cut base explicitly.

So,

A=/path/to/original/repo
B=/path/to/your/work

git clone $B C
cd C

root=$(git rev-list --max-parents=0 master)
echo $root                                    # this should spit a single id

git fetch $A

git rev-parse $root^{tree}                    # the two outputs here 
git rev-parse FETCH_HEAD^{tree}               # ... should be equal

git rebase -p --onto FETCH_HEAD $root master  # if both the above are true, bingo

Upvotes: 0

kan
kan

Reputation: 28951

Another solution is to use grafts and filter-branch. See Examples section, the example To set a commit (which typically is at the tip of another history) to be the parent of the current initial commit is exactly that you want to do. It is more reliable way as it allow to change all branches together and reorder history graph anyhow you like.

First you need git clone B C, then cd C and git fetch A master. So, your C will have commits from both repositories. Then add <initial commit id from B> <last commit id from A> into .git/info/grafts file. Then run git filter-branch <initial commit id from B>..HEAD.

Upvotes: 1

Ilkka
Ilkka

Reputation: 2694

If I understood you correctly, you currently have

  • The latest state of A as the first commit in B
  • Lots of work on top of that, also in B

and you want to get C with

  • All the history of A
  • All the history of B on top of that (except of course the first commit).

Assuming that's correct, this is one way of doing it, via patches:

Get a fresh clone of A:

$ git clone A C

Check what the hash of the initial commit (with the stuff from A) in B is:

$ cd B
$ git log --oneline|tail -1
1234beef Initial commit

Still in B, export all the rest of your work as patches:

$ git format-patch 1234beef..HEAD

(this will generate a bunch of .patch files in B)

The import all those changes into your fresh clone of A:

$ cd C
$ git am ../B/*.patch

And you're done.

Upvotes: 4

Related Questions