1

现有的 bitbucket 存储库 A 包含 200 多个提交。我下载了代码(没有 .git 文件)。使用第一次提交中添加的所有现有代码创建了新的 repo B。然后在 repo B 上再提交 150 次。 repo A 没有新的提交,我只在 repo B 上工作。现在要求是一个包含所有代码和历史记录(如果可能)的单一存储库,或者存储库 B 更改为历史记录中的单个条目。第三个回购 C 会很好,因为不想冒险 A 和 B。

4

3 回答 3

4

如果我理解正确,你目前有

  • A 的最新状态作为 B 中的第一次提交
  • 除此之外还有很多工作,也在B

你想得到 C

  • A的所有历史
  • 最重要的是 B 的所有历史(当然第一次提交除外)。

假设这是正确的,这是通过补丁的一种方法:

获取 A 的新克隆:

$ git clone A C

检查 B 中初始提交(使用来自 A 的内容)的哈希是什么:

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

仍然在 B 中,将所有其余的工作导出为补丁:

$ git format-patch 1234beef..HEAD

(这会在B中生成一堆.patch文件)

将所有这些更改导入新的 A 克隆:

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

你完成了。

于 2013-10-04T13:48:38.100 回答
1

另一种解决方案是使用移植物过滤器分支。请参阅示例部分,示例将提交(通常位于另一个历史记录的尖端)设置为当前初始提交的父级正是您想要做的。这是一种更可靠的方式,因为它允许一起更改所有分支并以您喜欢的方式重新排序历史图表。

首先你需要git clone B C,然后cd Cgit fetch A master。因此,您的 C 将有来自两个存储库的提交。然后添加<initial commit id from B> <last commit id from A>.git/info/grafts文件中。然后运行git filter-branch <initial commit id from B>..HEAD

于 2013-10-04T14:24:12.153 回答
0

git rebase -p --onto可能是最简单的。Rebase 的-p选项试图保留合并结构,并且它--onto允许明确指定新基数和剪切基数。

所以,

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
于 2013-10-04T22:37:29.037 回答