将多个文件夹和文件从 git 存储库复制到另一个存储库,同时保留历史记录

Copy several folders and files from a git repository to another while preserving history

我在 github/bitbucket 上有一个名为 X 的存储库,这是目录结构

├── folder1 ├── folder2 ├── folder3 ├── folder4 │ ├── a.cpp │ └── b.cpp ├── c.cpp └── d.cpp

我想创建一个名为 Y 的新存储库,它应该有

├── folder1 ├── folder4 │ └── a.cpp └── c.cpp

所有文件的提交历史都应该保留,X的目录结构也要完整,我该怎么做?

此外,如果上述可行,我不想将这些文件移出 X,因为 X 中的其他文件需要它们,但想在回购 Y 中处理它们,然后以某种方式将这些更改推送到 X .我不想更改 X 的目录结构或将复制的文件夹作为子模块。如何更改 Y 中复制的文件和文件夹并将这些更改推送到 X 中的所需分支?

嗯...您的建议是让两个单独的存储库处理一些相同的文件,但在同一目录中。据我所知,你不能有那个确切的设置。但我也认为这不是一个很好的设置 - 你违反了 "encapsulation" 规则。

更好的是:

回购 X:

├── folder1 ├── folder2 ├── folder3 ├── folder4 │ └── b.cpp ├── common (submodule called "common") | ├── c.cpp │ └── a.cpp └── d.cpp

回购 Y:

├── folder1 ├── common (submodule called "common") | ├── c.cpp │ └── a.cpp └── e.cpp (repo Y only files)

回购 common

├── c.cpp └── a.cpp

所以这里有三个 git 存储库:X、Y 和 Common。 Common 是 X 和 Y 中的子模块。这是构建项目的更好方式。

然后你的公共子模块保持共享历史(嗯,它自己的历史)并且你的特定 X 和特定 Y 文件有它们自己的独立历史。

要从您所在的位置到达那里,您需要创建两个新的存储库(Ycommon):

  • 将常用文件移入common。
  • 将Y文件移入Y。
  • 将公共子模块包含到X和Y中:git submodule add <url to common>
  • 提交更改并将更改推送到每个存储库。

嗯,这就是它的粗略轮廓。如果您想进一步说明,请询问...

注意:如果你想要完整的目录结构,你可以将"common"命名为"folder4",但它仍然需要是一个子模块。但我认为对您的文件夹稍作修改,将所有常用内容移到一个地方会更好。

更新 1

来自@J.Doe的请求是如何从 X 创建 Y,但如果没有子模块,您将拥有 Y 的文件副本...

  • mkdir Y - 创建新文件夹(在任何 git 存储库之外)
  • cd Y - 移至该文件夹
  • git init - 将其变成 git 存储库
  • cp -r <path-to-X\folder1> . - 将 folder1 复制到 repo
  • mkdir folder4 - 创建文件夹 4.
  • cp <path-to-X\folder4\a.cpp> folder4 - 复制 a.cpp
  • cp <path-to-X\c.cpp> . - 复制 c.cpp
  • git add -A - 将所有文件添加到存储库中(暂存它们)
  • git commit -m "initial version of Y" - 将文件提交到 repo
  • git remote add origin <url to remote Y> - 添加远程 Y 存储库(您必须先在 github 中创建它)。
  • git push origin master - 假设你在主分支上(默认)将你的初始提交推送到远程。

正如我所说,这将使用 X 的副本创建回购 Y 作为具有新历史记录的单独回购。如果你想获得 X 的历史记录,你也可以这样做,但方法略有不同。

更新 2

创建 Y 并保留 X 的历史记录:

  • cp -r X Y - 复制 X 但将其命名为 Y
  • cd Y - cd 进入 Y(注意这仍然只是 X 的副本)
  • rm -r folder2 folder3 folder4/b.cpp d.cpp - 删除 Y
  • 中不需要的文件
  • git add -A - 添加所有更改(在这种情况下 git 将检测删除文件)
  • git commit -m "Y Created from X - initial version"
  • git remote rm origin - 移除指向 github 上 X 的遥控器。
  • git remote add origin <url to Y on github> - 将遥控器添加到 github
  • 上的 Y
  • git push origin master - 将新的 repo 推送到 Y.

注意:在这里您将在回购 Y 中拥有 X 的完整历史记录。Y 现在将与 X 分开(即分歧)。

注意:您的要求的一个问题是 git 不适用于单个文件。