简体   繁体   English

我可以仅从另一个git存储库中提取某些文件吗?

[英]Can I pull only certain files from another git repository?

For instance, suppose I have Repository 1 and Repository 2. Repository 1 has a file /a/b/c/d . 例如,假设我有存储库1和存储库2。存储库1有一个文件/a/b/c/d Would it be possible for me to import this file into Repository 2 as /e/f/g/h ? 我可以将此文件作为/e/f/g/h导入到存储库2中吗?

The reason being that I want to pull in changes from an experimental branch from a different git repository. 原因是我想从其他git存储库的实验分支中提取更改。 I tried merging everything together, but there were a ton of conflicts (of every kind). 我尝试将所有内容合并在一起,但是有很多(各种)冲突。 Therefore, I doubt that I can merge the entire branch in, but I would like to try to bring in as much as I can. 因此,我怀疑是否可以合并整个分支,但我想尝试尽可能多地引入。

Is there any way to do what I want to do, or am I just going to have to resort to copying files directly? 有什么方法可以做我想做的事,还是我不得不直接复制文件?

You'll have to copy the file directly. 您必须直接复制文件。 Git deals with whole repositories, not single files within them. Git处理整个存储库,而不是其中的单个文件。

I suppose you could set Repository 2 up as a remote repository, fetch ( not pull) its branches, then use git checkout to grab a file out of that branch, but that solution could be messy. 我想您可以将存储库2设置为远程存储库,获取( 而不是拉出)其分支,然后使用git checkout从该分支中​​获取文件,但是该解决方案可能很麻烦。

You can get files from the remote repository using git archive . 您可以使用git archive从远程存储库获取文件。 You could then add and commit the files to your repository. 然后,您可以将文件添加并提交到存储库。 This approach will not preserve history from his branch. 这种方法不会保留其分支机构的历史记录。 See git archive docs for details. 有关详细信息,请参见git archive docs

If you want to try to preserve parts of that experimental branch, you could git fetch his repository, and then git rebase his experimental branch onto your repository, editing or skipping commits with conflicts as appropriate. 如果您想尝试保留该实验分支的某些部分,则可以git fetch其存储库,然后git rebase其实验分支重新建立到您的存储库中,并根据需要编辑或跳过具有冲突的提交。 Once you have a cleaned up branch in your repository, you can merge that in. See git rebase docs 一旦您的存储库中有一个清理分支,就可以将其合并。请参见git rebase docs

There's no simple fix, but there is a really well written guide here (Move files from one repository to another, preserving git history) by Ayushya Jaiswal and I'll quote it in this post for archival purposes. 没有简单的解决方法,但是Ayushya Jaiswal 在这里有一个写得很好的指南(将文件从一个存储库移动到另一个存储库,保留git历史记录) ,我将在这篇文章中引用它作为存档。

tl;dr : You're essentially re-basing a repo (safely) and extracting just the file(s) that you want. tl; dr :实际上,您是在(安全地)重新构建存储库并仅提取所需的文件。 Then pulling the git history from your rebased repo into whatever repo you're currently working on. 然后将git历史记录从您的基础存储库中提取到您当前正在使用的任何存储库中。

Notes before you get started : 开始之前的注意事项
You'll need https://stackoverflow.com/a/56334887/929999 for this as well, if you want a specific file. 如果您要特定的文件,则也需要https://stackoverflow.com/a/56334887/929999 I'll add a disclaimer below in the quoted guide where to add in this step. 我将在引用的指南中的以下步骤中添加免责声明。

Here's the quoted text from the article: 这是文章中引用的文字:


Getting files ready to move from Repository A. 准备好文件以从存储库A中移动。

Step 1 : Make a copy of repository A as the following steps make major changes to this copy which you should not push! 第1步 :制作存储库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)

Step 2 : Go to that directory. 第2步 :转到该目录。

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

Step 3 : To avoid accidentally making any remote changes (eg. by pushing), delete the link to the original repository. 步骤3 :为避免意外进行任何远程更改(例如,通过推送),请删除指向原始存储库的链接。

git remote rm origin

This is the step to modify , modify it by doing the git filter-branch --prune-empty ... $FILES step from here instead, that will extrapolate only your desired files. 这是修改的步骤 ,而是通过从此处执行git filter-branch --prune-empty ... $FILES步骤来进行修改 ,它将仅推断出您所需的文件。 The rest should be the same. 其余应相同。

In your case, it would be something like this: 在您的情况下,将是这样的:

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

Step 4 : Go through your history and files, removing anything that is not in FOLDER_TO_KEEP . 步骤4 :浏览您的历史记录和文件,删除 FOLDER_TO_KEEP没有的 FOLDER_TO_KEEP The result is the contents of FOLDER_TO_KEEP spewed out into the base of repository A. 结果是将 FOLDER_TO_KEEP的内容喷出到存储库A的库中。

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

Step 5 : Clean the unwanted data. 第5步 :清除不需要的数据。

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

Step 6 : Move all the files and directories to a NEW_FOLDER which you want to push to repository B. 步骤6 :将所有文件和目录移动到要推送到存储库B的NEW_FOLDER。

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

Alternatively, you can drag all the files and directory to the NEW_FOLDER using GUI. 或者,您可以使用GUI将所有文件和目录拖到NEW_FOLDER。

Step 7 : Add the changes and commit them. 步骤7 :添加更改并提交。

git add .
git commit

Merge the files into the new repository B. 将文件合并到新的存储库B中。

Step 1: Make a copy of repository B if you don't have one already. 第1步:如果还没有存储库B,请制作一个副本。

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

Step 2 : Go to that directory. 第2步 :转到该目录。

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

Step 3 : Create a remote connection to repository A as a branch in repository B. 步骤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

Step 4 : Pull files and history from this branch (containing only the directory you want to move) into repository B. 步骤4 :将文件和历史记录从此分支(仅包含要移动的目录)拉到存储库B中。

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

Step 5 : Remove the remote connection to repository A. 步骤5 :删除与存储库A的远程连接。

git remote rm repo-A

Step 6 : Finally, push the changes 步骤6 :最后,推送更改

git push

You can delete both the cloned repositories. 您可以删除两个克隆的存储库。
The files changes with history are now available online in repository B. 文件随历史记录的更改现在可在存储库B中在线获得。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM