简体   繁体   中英

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 . Would it be possible for me to import this file into Repository 2 as /e/f/g/h ?

The reason being that I want to pull in changes from an experimental branch from a different git repository. 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.

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.

You can get files from the remote repository using 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.

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. Once you have a cleaned up branch in your repository, you can merge that in. See 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.

tl;dr : You're essentially re-basing a repo (safely) and extracting just the file(s) that you want. Then pulling the git history from your rebased repo into whatever repo you're currently working on.

Notes before you get started :
You'll need https://stackoverflow.com/a/56334887/929999 for this as well, if you want a specific file. 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.

Step 1 : Make a copy of repository A as the following steps make major changes to this copy which you should not push!

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.

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.

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. 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 . The result is the contents of FOLDER_TO_KEEP spewed out into the base of repository 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.

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.

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.

Step 7 : Add the changes and commit them.

git add .
git commit

Merge the files into the new repository B.

Step 1: Make a copy of repository B if you don't have one already.

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.

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.

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.

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.

git remote rm repo-A

Step 6 : Finally, push the changes

git push

You can delete both the cloned repositories.
The files changes with history are now available online in repository B.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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