将多个文件夹和文件从 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 文件有它们自己的独立历史。
要从您所在的位置到达那里,您需要创建两个新的存储库(Y
和 common
):
- 将常用文件移入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 不适用于单个文件。
我在 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 文件有它们自己的独立历史。
要从您所在的位置到达那里,您需要创建两个新的存储库(Y
和 common
):
- 将常用文件移入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 复制到 repomkdir folder4
- 创建文件夹 4.cp <path-to-X\folder4\a.cpp> folder4
- 复制 a.cppcp <path-to-X\c.cpp> .
- 复制 c.cppgit add -A
- 将所有文件添加到存储库中(暂存它们)git commit -m "initial version of Y"
- 将文件提交到 repogit remote add origin <url to remote Y>
- 添加远程 Y 存储库(您必须先在 github 中创建它)。git push origin master
- 假设你在主分支上(默认)将你的初始提交推送到远程。
正如我所说,这将使用 X 的副本创建回购 Y 作为具有新历史记录的单独回购。如果你想获得 X 的历史记录,你也可以这样做,但方法略有不同。
更新 2
创建 Y 并保留 X 的历史记录:
cp -r X Y
- 复制 X 但将其命名为 Ycd 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 不适用于单个文件。