我可以从另一个git仓库中提取特定的文件吗?

ffx8fchx  于 2023-06-04  发布在  Git
关注(0)|答案(4)|浏览(251)

例如,假设我有Repository 1和Repository 2。存储库% 1有一个文件/a/b/c/d。我是否可以将此文件作为/e/f/g/h导入到Repository 2中?
原因是我想从一个不同的git仓库的实验分支中拉入更改。我试着把所有的东西合并在一起,但是有很多冲突(各种各样的)。因此,我怀疑我是否可以将整个分支合并进来,但我想尽可能多地合并进来。
有没有什么方法可以做我想做的事情,或者我只是要诉诸于直接复制文件?

hs1rzwqc

hs1rzwqc1#

您可以使用git archive从远程存储库获取文件。然后,您可以将文件添加并提交到存储库中。这种方法不会从他的分支保存历史。详情请参见git archive docs
如果你想保留部分实验分支,你可以git fetch他的仓库,然后git rebase他的实验分支到你的仓库,编辑或跳过有冲突的提交。一旦你的仓库中有了一个清理过的分支,你就可以将它合并进来。参见git rebase docs

7y4bm7vi

7y4bm7vi2#

没有简单的修复方法,但有一个写得很好的指南here (Move files from one repository to another, preserving git history),作者是 Ayushya Jaiswal,我将在这篇文章中引用它以供存档。

tl;dr:您实际上是(安全地)重新构建了一个存储库,并提取了您想要的文件。然后将git历史从你的rebased repo中拉到你当前正在处理的任何repo中。
使用前注意事项

如果你想要一个特定的文件,你还需要https://stackoverflow.com/a/56334887/929999。我将在下面引用的指南中添加一个免责声明,说明在此步骤中要添加的位置。
以下是文章中引用的文字:

从Repository A获取准备移动的文件。

第一步:创建仓库A的副本,因为下面的步骤会对该副本进行重大更改,您不应该推送!

mkdir cloneA
cd cloneA
git clone --branch <branch> --origin origin --progress \
  -v <git repository A url>
# eg. git clone --branch master --origin origin --progress \
#   -v https://github.com/username/myproject.git
# (assuming myprojects is the repository you want to copy from)

第二步:进入该目录。

cd <git repository A directory>
#  eg. cd myproject
# Folder Path is ~/cloneA/myproject

步骤3:为了避免意外地进行任何远程更改(例如通过推送),删除到原始存储库的链接。

git remote rm origin

这是修改的步骤,通过从here执行git filter-branch --prune-empty ... $FILES步骤来修改它,这将仅推断出您想要的文件。其余的应该是一样的。

在你的情况下,它会是这样的:

FILES='/a/b/c/d'
git filter-branch --prune-empty --index-filter "
                        git read-tree --empty
                        git reset \$GIT_COMMIT -- $FILES
                " \
        -- --all -- $FILES

第四步:查看您的历史记录和文件,删除所有不在FOLDER_TO_KEEP中的内容。结果是FOLDER_TO_KEEP的内容被释放到存储库A的底部。

git filter-branch --subdirectory-filter <directory> -- --all
# eg. git filter-branch --subdirectory-filter subfolder1/subfolder2/FOLDER_TO_KEEP -- --all

第五步:清理无用数据。

git reset --hard
git gc --aggressive 
git prune
git clean -fd

第六步:将所有文件和目录移动到一个NEW_FOLDER中,并推送到仓库B。

mkdir <base directory>
#eg mkdir NEW_FOLDER
mv * <base directory>
#eg mv * NEW_FOLDER

或者,您可以使用GUI将所有文件和目录拖到NEW_FOLDER。

第七步:添加修改并提交。

git add .
git commit

将文件合并到新仓库B。

**步骤1:**如果您还没有仓库B,请复制一份。

mkdir cloneB
cd cloneB
git clone <git repository B url>
# eg. git clone 
https://github.com/username/newproject.git

第二步:进入该目录。

cd <git repository B directory>
#  eg. cd newproject
# Folder Path is ~/cloneB/newproject

步骤3:创建仓库A的远程连接,作为仓库B的分支。

git remote add repo-A <git repository A directory>
# (repo-A can be anything - it's just a random name)

# eg. git remote add repo-A ~/cloneA/myproject

第四步:从该分支(仅包含您要移动的目录)拉取文件和历史到仓库B。

git pull repo-A master --allow-unrelated-histories
# This merges master from repository A into repository B

第五步:移除仓库A的远程连接。

git remote rm repo-A

第六步:最后推送修改

git push

您可以删除这两个克隆的资料库。
现在可以在存储库B中在线获得文件更改历史。

wgxvkvu9

wgxvkvu93#

你必须直接拷贝文件。Git处理的是整个仓库,而不是其中的单个文件。
我想您可以将Repository 2设置为远程存储库,获取(* 不是 * 拉取)它的分支,然后使用git checkout从该分支获取文件,但该解决方案可能会很混乱。

f4t66c6m

f4t66c6m4#

Extracting a file or a folder from a git repository with full git history中描述了一个非常简单的过程:
1.创建补丁文件

cd ~/repository/path
git log --pretty=email --patch-with-stat --reverse --full-index --binary -- path/to/file_or_folder > /tmp/patch

1.如果需要,可以选择替换路径
1.将提交应用到新存储库

cd ~/another_repository/path
git am < /tmp/patch

相关问题