4

有没有办法从 git 存储库只下载给定的子目录?假设我只想从https://github.com/djdeath/toys.gitnyancat获取目录。

我可以克隆整个存储库并忽略我不想要的文件,或者转到https://github.com/djdeath/toys/tree/master/nyancat并一一下载相关文件。我认为必须有一个更简单的方法。

注意我不是在问是否可以克隆目录,这是之前问过的,显然是不可能的。我只是对快速获取文件感兴趣,不需要重新提交,或者再次对它们使用 git。

4

3 回答 3

2

git-archive命令几乎可以执行您想要的操作,但它需要在已经克隆的 repo 上运行,因此如果您具有对主机的 SSH 访问权限,您可以执行以下操作:

cd /path/to/destination
ssh user@host "cd /path/to/repo && git archive HEAD dir/you/want" | tar xf -

或者,对网络传输进行压缩:

cd /path/to/destination
ssh user@host "cd /path/to/repo && git archive HEAD dir/you/want | gzip" | tar xzf -
于 2012-11-05T19:48:36.743 回答
1

一个完整的参数化 bash 函数(不依赖)

#!/bin/bash

gitsub() {

  usage() {
        cat <<- EOF
        ------------------------------------------------------------------------
        GNU gitsub 0.0.1, a non-interactive github filtered subrepo retriever.
        Usage: gitsub [-h] [[-d[dir] -s[strip] -e[ext]] -o owner -r repo -b sub]
        ------------------------------------------------------------------------
        Mandatory arguments to long options are mandatory for short options too.
        ------------------------------------------------------------------------
        MANDATORY:
          -o, --owner           repo's owner
          -r, --repo            repo's name
          -b, --subrepo         directory(s) to be cloned
        OPTIONS:
          -s, --strip           number of dirs (/) to be skipped, default 0
          -d, --dir             output directory default current directory
          -e, --extension       filter by ext, if missing clone all (including subdirs)
        COMMANDS:
          -h, --help            display this help and exit
        ------------------------------------------------------------------------
        Mail bug reports and suggestions to makramjandar@gmail.com
        ------------------------------------------------------------------------
        EOF
  }

  error() { echo -e "\033[1;31mError: $1\033[0m" ;}

  # check supplied args
  is_arg() { 
    [[ -n "$2" && ${2:0:1} != "-" ]] \
    || { error "Argument for $1 is missing..." >&2 \
    && usage \
    && exit 1 ;}
  }

  POSITIONAL=()
  while (( "$#" )); do
    case "$1" in
      # commands
      -h|--help)      usage && exit 0                                    ;;
      # mandatory flags with arguments
      -o|--owner)     is_arg $1 $2 && OWNER=$2                 ; shift 2 ;;
      -r|--repo)      is_arg $1 $2 && REPO=$2                  ; shift 2 ;;
      -b|--subrepo)   is_arg $1 $2 && SUBREPO=$2               ; shift 2 ;;
      # optional flags with arguments
      -d|--dir)       is_arg $1 $2 && DIR=$2 && mkdir -p $DIR  ; shift 2 ;;
      -s|--strip)     is_arg $1 $2 && STRIP=$2                 ; shift 2 ;;
      -e|--extension) is_arg $1 $2 && EXTENSION=$2             ; shift 2 ;;
      # unsupported flags 
      -*|--*=) error "Unsupported flag $1" >&2 && usage        ; exit 1  ;;
      # preserve positional arguments
      *) POSITIONAL+=("$1")                                    ; shift   ;;
    esac
  done
  # set positional arguments in their proper place
  set -- "${POSITIONAL[@]}"

  # check mandatory arguments
  [[ -z "$OWNER" || -z "$REPO" || -z "$SUBREPO" ]] \
  && { error "Missing mandatory arguments..." >&2 \
  && usage \
  && exit 1 ;}

  # get github filtered (optional) subrepository
  {
    curl -L "https://api.github.com/repos/$OWNER/$REPO/tarball" \
    | 
      tar \
      --verbose \
      --extract \
      --gzip \
      --directory=${DIR:-$PWD} \
      --strip=${STRIP:-0} \
      --wildcards */${SUBREPO}/*.${EXTENSION}*
  } 2>/dev/null \
    && echo "Done" \
    || \
  { 
    error "Invalid args..." \
    && usage \
    && exit 1
  }
}

gitsub "$@"

对于给定的仓库:https ://github.com/jenskutilek/free-fonts

下载子文件夹 Fira 的全部内容,包括目录和文件

$ bash gitsub.sh -o "jenskutilek" -r "free-fonts" -b "Fira" -d "FiraUnfiltered" -s 2

$ tree -d FiraUnfiltered/
FiraUnfiltered/
├── Fira Mono
│   ├── OTF
│   ├── TTF
│   ├── VFB
│   └── WOFF
└── Fira Sans
    ├── OTF
    ├── TTF
    ├── VFB
    └── WOFF

下载相同的子文件夹但使用字体 TTF 过滤

$ bash gitsub.sh -o "jenskutilek" -r "free-fonts" -b "Fira" -d "FiraFiltered" -s 2 -e "ttf"

$ tree -d FiraFiltered/
FiraFiltered/
├── Fira Mono
│   └── TTF
└── Fira Sans
    └── TTF

通过将 -s|--strip 设置为 4,仅将过滤后的文件下载到 outdir

bash gitsub.sh -o "jenskutilek" -r "free-fonts" -b "Fira" -d "ttfFilesOnly" -s 4 -e "ttf"

$ tree ttfFilesOnly/
ttfFilesOnly/
├── FiraMono-Bold.ttf
├── FiraMono-Regular.ttf
├── FiraSans-Bold.ttf
├── FiraSans-BoldItalic.ttf
├── FiraSans-Light.ttf
├── FiraSans-LightItalic.ttf
├── FiraSans-Medium.ttf
├── FiraSans-MediumItalic.ttf
├── FiraSans-Regular.ttf
└── FiraSans-RegularItalic.ttf
于 2021-12-19T15:09:59.770 回答
0

嘿,我刚刚写了一个脚本

用法

      python get_git_sub_dir.py path/to/sub/dir <RECURSIVE>
于 2014-01-23T18:47:57.797 回答