Same code different git files, merging with keeping history

亡梦爱人 提交于 2019-12-11 09:07:44

问题


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.


回答1:


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.




回答2:


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.




回答3:


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


来源:https://stackoverflow.com/questions/19182560/same-code-different-git-files-merging-with-keeping-history

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!