【问题标题】:Copy several folders and files from a git repository to another while preserving history将多个文件夹和文件从 git 存储库复制到另一个,同时保留历史记录
【发布时间】:2018-04-15 12:48:43
【问题描述】:

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

├── 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 中所需的分支?

【问题讨论】:

    标签: git github bitbucket-server


    【解决方案1】:

    hmm... 你的建议是让两个单独的 repos 处理一些相同的文件,但在同一个目录中。据我所知,您无法进行确切的设置。但我也认为这不是一个很好的设置——你违反了“封装”规则。

    最好有:

    回购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 repos:X、Y 和 Common。 Common 是 X 和 Y 中的子模块。这是构建项目的更好方法。

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

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

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

    嗯,这就是它的大致轮廓。如果您想进一步澄清,请询问...

    注意:如果您希望目录结构完全完整,您可以将“common”命名为“folder4”,但它仍然需要是一个子模块.. 但我认为对你的文件夹最好把所有常见的东西都移到一个地方。

    更新 1

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

    • mkdir Y - 创建新文件夹(在任何 git repo 之外)
    • cd Y - 进入该文件夹
    • git init - 把它变成一个 git 仓库
    • cp -r <path-to-X\folder1> . - 将文件夹 1 复制到 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 - 将所有文件添加到 repo 中(暂存它们)
    • git commit -m "initial version of Y" - 将文件提交到仓库
    • 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 不适用于单个文件。

    【讨论】:

    • 在 Y 提到的目录结构中,我怎样才能将文件夹 1 从 X 复制到 Y(明智的 git 命令),而且我不会在 X 中对复制的文件进行更改,但是它们仍然必须存在于相同的路径中,我可以寻找一种方法以某种方式在 Y 中完成对 X 的更改和提交/修订,但是请帮助我如何在没有子模块的情况下在 Y 中拥有这个目录结构,├─ ─ folder1 ├── folder4--a.cpp └── c.cpp 你能告诉git命令和它们的顺序,以这种方式复制文件夹并从X创建一个新的repo Y吗?
    • @J.Doe 我添加了一个更新,向您展示您可能需要执行此操作的步骤。
    • 感谢您的回答伙伴,这确实有效,但它不会保留提交历史记录,当然必须有某种方法可以做到这一点,这是一个不常见的要求,移动文件和文件夹进入另一个带有他们历史的仓库?
    • @J.Doe 我们也可以这样做 - 正如我所说的方法略有不同。我也可以添加...一秒钟
    • 这个答案有效,谢谢。我在“注意”中没有理解您的意思,我无法在 Y 中获取 c.cpp 文件,因为它是一个单独的文件?或者如果我执行 git add c.cpp 就无法获取它的历史记录?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 2017-11-30
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多