git checkout only certain file types for entire pr

2020-06-12 03:56发布

Is there a way to perform a git checkout for only certain file types (.xlf), which recurses down through the entire repository? The results should contain the struture of the repository, meaning the folders, and the contained files of a certain extension.

Repo A

file.xlf
file.txt
level2/
    file2.xlf
    file2.txt
    level3/
        file3.xlf
        file3.txt 

After checkout repo B looks like:

Repo B

file.xlf
    /level2
    file2.xlf
        /level3
        file3.xlf

This is what I have so far:

$ git checkout FETCH_HEAD -- '*.xlf'

This gives all of the ".xlf" files at the root level, but is not recursive down to subdirectories.

Thank you for the help.

标签: git
5条回答
家丑人穷心不美
2楼-- · 2020-06-12 04:28

UPDATE: Check Dadaso's answer for a solution that will work in most of cases.

You can try something like this, using git ls-tree and grep:

git checkout origin/master -- `git ls-tree origin/master -r --name-only | grep ".xlf"`

Note this expects a remote origin in a master branch. Also you must provide the right filter/extension to grep.

Before this command, you should have done something like this:

git init
git remote add origin <project.git>
git fetch
查看更多
孤傲高冷的网名
3楼-- · 2020-06-12 04:34

You don't need find or sed, you can use wildcards as git understands them (doesn't depend on your shell):

git checkout -- "*.xml"

The quotes will prevent your shell to expand the command to only files in the current directory before its execution.

You can also disable shell glob expansion (with bash) :

set -f
git checkout -- *.xml

This, of course, will irremediably erase your changes!

查看更多
姐就是有狂的资本
4楼-- · 2020-06-12 04:34

No; git operates at a whole-repository (and whole-history) level; there's no way of getting a partial checkout of a repository. You can of course check out the repository and then delete everything that doesn't match your file, but of course you gain virtually nothing by doing so.

查看更多
5楼-- · 2020-06-12 04:36

Dadaso's answer git checkout -- "*.xml" checks out all .xml files recursively from index to working directory.

However for some reasons git checkout branch-name -- "*.xml" (checking out files from branch-name branch) doesn't work recursively and only checks "xml" files in root directory.

So IMO the best is to use git ls-tree then filter file names you are interested in and pass it to git checkout branch-name --. Here are the commands you can use:

  • Bash (and git bash on windows) version:

    git ls-tree branch-name --full-tree --name-only -r | grep "\.xml" | xargs git checkout branch-name --
    
  • cmd (windows) version (if you don't have "C:\Program Files\Git\usr\bin" in you PATH):

    git ls-tree branch-name --full-tree --name-only -r | "C:\Program Files\Git\usr\bin\grep.exe" "\.xml" | "C:\Program Files\Git\usr\bin\xargs.exe" git checkout branch-name --
    
  • for powershell it's still better to call cmd.exe because it's much faster (powershell doesn't have good support for native stdin/stdout pipelining):

    cmd.exe /C 'git ls-tree branch-name --full-tree --name-only -r | "C:\Program Files\Git\usr\bin\grep.exe" "\.xml" | "C:\Program Files\Git\usr\bin\xargs.exe" git checkout branch-name --'
    
  • However you you have small number of files you can try this in powershell (like in @aoetalks answer). But I found it extremely slow for couple of houndeds files:

    git ls-tree branch-name --full-tree --name-only -r | sls "\.xml" | %{ git checkout branch-name -- $_ }
    
查看更多
成全新的幸福
6楼-- · 2020-06-12 04:39

On PowerShell (Windows, haven't tried PowerShell Core+Linux), I was able to do it like this

git ls-tree master -r --name-only | sls ".cscfg" | foreach { git checkout origin/master -- $_ }

查看更多
登录 后发表回答