【问题标题】:Is there a way to download only a subdirectory from git?有没有办法从 git 只下载一个子目录?
【发布时间】:2012-10-25 16:46:28
【问题描述】:

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

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

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

【问题讨论】:

  • 缺乏这种能力是git最糟糕的地方。

标签: git download


【解决方案1】:

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 -

【讨论】:

    【解决方案2】:

    嘿,我只是wrote a script

    用法

          python get_git_sub_dir.py path/to/sub/dir <RECURSIVE>
    

    【讨论】:

      【解决方案3】:

      一个完整的参数化 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
      

      【讨论】:

      • 你应该稍微解释一下你的脚本。
      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      • 我的函数提供了嵌入式帮助...我应该打印它还是必须为帮助本身重写第二个帮助!有点一致性,请先生
      • @Ale 我的意思是编辑答案,而不是添加评论添加答案的详细信息。
      猜你喜欢
      • 2017-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-31
      • 2010-10-17
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      相关资源
      最近更新 更多