【问题标题】:Retrieve a single file from a repository从存储库中检索单个文件
【发布时间】:2010-11-10 15:52:15
【问题描述】:

从远程 git 存储库获取单个文件的内容的最有效机制(就传输的数据和使用的磁盘空间而言)是什么?

到目前为止,我已经设法提出:

git clone --no-checkout --depth 1 git@github.com:foo/bar.git && cd bar && git show HEAD:path/to/file.txt

这似乎还是有点矫枉过正。

从 repo 中获取多个文件怎么样?

【问题讨论】:

  • 啊。如果有一个内置的方法来做相当于“cat-remote”和“tag-remote”,我会喜欢的。
  • 我有同样的问题我想在 2 个 repos 中拥有相同的许可证文件;在 1 个 repo 中编辑文件,然后让它自动更新另一个 repo 中的副本。

标签: git git-checkout sparse-checkout git-sparse-checkout


【解决方案1】:

如果部署了网络界面(如 gitweb、cgit、Gitorious、ginatra),您可以使用它来下载单个文件(“原始”或“普通”视图)。

如果另一方启用它,您可以使用 git archive 的 '--remote=<URL>' 选项(并可能将其限制为给定文件所在的目录) ,例如:

$ git archive --remote=git@github.com:foo/bar.git --prefix=path/to/ HEAD:path/to/ |  tar xvf -

【讨论】:

  • 注:示例未经过测试!
  • 对于您自己的存储库,如果在远程存储库上使用带有git config daemon.uploadarch true 的 git-daemon(git:// 样式 URL),则需要专门启用上传存档。默认情况下,git 守护进程使用“致命:远程错误:访问被拒绝或存储库未导出:...”来禁用远程存档
  • +1 git archive 方法是我第一次尝试 - 但后来我注意到在客户端计算机上要求 tar 对于 Windows 用户来说并不十分方便。我们最终从本地 cgit 服务器获取。它可以工作,但没有我希望的那么快(而且它仍然需要在 Windows 机器上运行 unix2dos 或类似的,因为我们将带有 Unix 行结尾的文件存储在 Git 存储库中)。
  • @FrerichRaabe 使用 -o fetched.zip。另请参阅 --format= 选项。
  • 对于它的价值,它看起来不像在 GitHub 托管的存储库上工作。见help.github.com/articles/can-i-archive-a-repositorygroups.google.com/forum/#!topic/github/z8vLHcX0HxY
【解决方案2】:

Jakubanswer 开始。 git archive 生成 tar 或 zip 存档,因此您需要通过 tar 管道输出以获取文件内容:

git archive --remote=git://git.foo.com/project.git HEAD:path/to/directory filename | tar -x

将从当前目录的远程存储库的 HEAD 中保存一份“文件名”的副本。

:path/to/directory 部分是可选的。如果排除,获取的文件将保存到<current working dir>/path/to/directory/filename

此外,如果您想在 git-daemon 托管的 Git 存储库上启用 git archive --remote,您需要启用 daemon.uploadarch 配置选项。见https://kernel.org/pub/software/scm/git/docs/git-daemon.html

【讨论】:

  • 如果它是一个文本文件并且我们想将它保存到另一个部分,那么使用它是很有用的:| tar -xO > ~/destfile.ext
  • 它是否适用于特定的提交? (即一个指定特定文件和提交)
  • 是的。将 HEAD 替换为您要使用的提交 ID。 HEAD 是一个别名,它指的是当前签出的提交(如果适用)或默认分支的尖端。几年前我写了上面的答案,今天早上得知 GitHub 不支持git archive,因此它的用处大大降低。
【解决方案3】:

这对我来说似乎是一个解决方案:http://gitready.com/intermediate/2009/02/27/get-a-file-from-a-specific-revision.html

git show HEAD~4:index.html > local_file

其中4 表示从现在开始的四个修订版,~ 是注释中提到的波浪号。

【讨论】:

  • 一定要注意它不是'HEAD'和'4'之间的'减号''-',而是'波浪号''~'。显然我没有很好地阅读 git 文档,或者我的眼镜需要更新;-)
  • 这似乎不像 OP 需要的那样从远程存储库中获取文件。
  • 或者:git show HEAD:./my_other_file > local_file 如果文件不在您的根目录中:)
  • 恳请所有反对者 - 请解释并澄清什么是不妥的 - 我们在这里学习和分享:)
  • @MichalStefanow:Mike Weller 拥有它;具体来说,这不适用于远程存储库。你至少需要一个本地克隆,即使你在上面设置了遥控器。
【解决方案4】:

我用这个

$ cat ~/.wgetrc
check_certificate = off

$ wget https://raw.github.com/jquery/jquery/master/grunt.js
HTTP request sent, awaiting response... 200 OK
Length: 11339 (11K) [text/plain]
Saving to: `grunt.js'

【讨论】:

  • 即使没有 wgetrc 调整也对我有用:wget https://raw.github.com/bk322/bk_automates/master/bkubuntu/bkubuntu.bash
  • 我的留言更有帮助:ERROR: Certificate verification error for raw.github.com: unable to get local issuer certificate. To connect to raw.github.com insecurely, use '--no-check-certificate'.
  • 这仅适用于公共存储库。对于私有存储库,您需要身份验证。
【解决方案5】:

在 git 版本 1.7.9.5 中,这似乎可以从远程导出单个文件

git archive --remote=ssh://host/pathto/repo.git HEAD README.md

这将cat文件README.md的内容。

【讨论】:

  • ... 除了它在 GitHub 上不起作用。当。 :(twitter.com/GitHubHelp/status/322818593748303873
  • 这似乎不会产生原始文件,而是产生一个只有一个文件的 tar 文件。
  • @FrerichRaabe 只需添加` | tar -x` 到命令中。 git archive --remote=ssh://host/pathto/repo.git HEAD README.md | tar -xcat README.md
  • 您可以使用tar -xO 输出到STDOUT 用于管道,例如FILE=README.md && git archive --remote=ssh://host/pathto/repo.git HEAD "$FILE" | tar -xO "$FILE"
  • 正是我正在寻找的答案,但我得到“致命:协议不支持操作”。作为 Git 的回应。啊。
【解决方案6】:

与@Steven Penny 的回答有关,我也使用 wget。此外,要决定将输出发送到哪个文件,我使用 -O 。

如果您使用的是 gitlabs,则 URL 的另一种可能性是:

wget "https://git.labs.your-server/your-repo/raw/master/<path-to-file>" -O <output-file>

除非您拥有证书或从受信任的服务器访问 gitlabs 安装,否则您需要 --no-check-certificate 正如@Kos 所说。我更喜欢这样而不是修改 .wgetrc,但这取决于您的需要。

如果它是一个大文件,你可以考虑使用 wget 的 -c 选项。如果先前的意图在中间失败,则能够继续从您离开的位置下载文件。

【讨论】:

    【解决方案7】:

    我使用 curl,它适用于公共存储库或通过 Web 界面使用 https 基本身份验证的存储库。

    curl -L --retry 20 --retry-delay 2 -O https://github.com/ACCOUNT/REPO/raw/master/PATH/TO/FILE/FILE.TXT -u USER:PASSWORD

    我已经在 github 和 bitbucket 上对其进行了测试,两者都可以使用。

    【讨论】:

      【解决方案8】:

      一般不会,但如果您使用的是 Github:

      对我来说,wget 到原始 url 原来是下载特定文件的最佳和最简单的方法。

      在浏览器中打开文件并点击“Raw”按钮。现在刷新你的浏览器,复制网址并在上面输入wgetcurl

      wget 示例:

      wget 'https://github.abc.abc.com/raw/abc/folder1/master/folder2/myfile.py?token=DDDDnkl92Kw8829jhXXoxBaVJIYW-h7zks5Vy9I-wA%3D%3D' -O myfile.py
      

      卷曲示例:

      curl 'https://example.com/raw.txt' > savedFile.txt
      

      【讨论】:

      • 这是最简单的解决方案,适用于任何可以找到的原始 txt。 curl https://example.com/raw.txt &gt; savedFile.txt
      • wget 示例不起作用,但 curl 示例可以。
      • 对我来说很好用。您是否在命令行中将您的网址放在引号中?
      • 这不会保留 git 历史记录
      • 解决方案被问到Git,答案赞同Github是git,与git无关。它基于知名 git 解决方案提供商提供的其他 API!
      【解决方案9】:

      从远程导出单个文件:

      git archive --remote=ssh://host/pathto/repo.git HEAD README.md | tar -x
      

      这会将文件README.md 下载到您的当前目录。

      如果要将文件内容导出到 STDOUT:

      git archive --remote=ssh://host/pathto/repo.git HEAD README.md | tar -xO
      

      您可以在命令末尾提供多个路径。

      【讨论】:

        【解决方案10】:

        Yisrael Dov's answer 是最简单的,但它不允许压缩。您可以使用--format=zip,但不能像使用 tar 一样使用管道命令直接解压缩,因此您需要将其保存为临时文件。这是一个脚本:

        #!/bin/bash
        
        BASENAME=$0
        
        function usage {
            echo "usage: $BASENAME <remote-repo> <file> ..."
            exit 1
        }
        
        [ 2 -gt "$#" ] && { usage; }
        
        REPO=$1
        shift
        FILES=$@
        
        TMPFILE=`mktemp`.zip
        git archive -9 --remote=$REPO HEAD $FILES -o $TMPFILE
        unzip $TMPFILE
        rm $TMPFILE
        

        这也适用于目录。

        【讨论】:

          【解决方案11】:

          这里的一些答案的细微差别回答了 OP 的问题:

          git archive --remote=git@archive-accepting-git-server.com:foo/bar.git \
            HEAD path/to/file.txt | tar -xO path/to/file.txt > file.txt
          

          【讨论】:

          • 这个不行,github不支持git归档。
          • Err.. git 不仅仅用于 GitHub
          • 您在答案中明确将 --remote 设置为 github URL ;-)
          • 感谢您的反馈。已相应修改答案。
          【解决方案12】:

          如果您想从特定哈希 + 远程存储库中获取文件,我尝试过 git-archive,但没有成功。

          您必须使用 git clone,一旦存储库被克隆,您就必须使用 git-archive 使其工作。

          我在git archive from a specific hash from remote发布了一个关于如何更简单的问题

          【讨论】:

            【解决方案13】:

            对于单个文件,只需使用 wget 命令。

            首先,请按照下图点击“raw”获取url,否则将下载嵌入在html中的代码。

            然后,浏览器会打开一个新的页面,url以https://raw.githubusercontent.com/开头...

            只需在终端输入命令:

            #wget https://raw.githubusercontent.com/...
            

            一会儿文件会放到你的文件夹里。

            【讨论】:

            • 是的,这在 Python 或其他编程语言中也很有效,具有 REST 功能。例如从不同的存储库下载模块..
            【解决方案14】:

            如果您的存储库支持令牌(例如 GitLab),则为您的用户生成一个令牌,然后导航到您将下载的文件并单击 RAW 输出以获取 URL。要下载文件,请使用:

            curl --silent --request GET --header 'PRIVATE-TOKEN: replace_with_your_token' \
            'http://git.example.com/foo/bar.sql' --output /tmp/bar.sql
            

            【讨论】:

              【解决方案15】:

              对于 bitbucket 直接从浏览器(我使用 safari...)右键单击“查看原始文件”并选择“下载链接文件”:

              【讨论】:

                【解决方案16】:

                如果您的 Git 存储库托管在 Azure-DevOps (VSTS) 上,您可以使用 Rest API 检索单个文件。

                此 API 的格式如下所示:

                 https://dev.azure.com/{organization}/_apis/git/repositories/{repositoryId}/items?path={pathToFile}&api-version=4.1?download=true
                

                例如:

                 https://dev.azure.com/{organization}/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/items?scopePath=/MyWebSite/MyWebSite/Views/Home/_Home.cshtml&download=true&api-version=4.1
                

                【讨论】:

                • 它需要api令牌,不是吗?
                • 取决于你如何运行 api
                【解决方案17】:

                我是这样解决的:

                git archive --remote=ssh://git@gitlab.com/user/mi-repo.git BranchName /path-to-file/file_name | tar -xO /path-to-file/file_name > /path-to-save-the-file/file_name
                

                如果需要,您可以将“BranchName”替换为“HEAD”

                【讨论】:

                  【解决方案18】:

                  如果您不介意克隆整个目录,这个小型 bash/zsh 函数的最终结果是将单个文件克隆到当前目录(通过将 repo 克隆到临时目录并随后将其删除)。

                  专业人士:你只得到你想要的文件

                  缺点:你仍然需要等待整个 repo 克隆

                  git-single-file () {
                          if [ $# -lt 2 ]
                          then
                                  echo "Usage: $0 <repo url> <file path>"
                                  return
                          fi
                          TEMP_DIR=$(mktemp -d)
                          git clone $1 $TEMP_DIR
                          cp $TEMP_DIR/$2 .
                          rm -rf $TEMP_DIR
                  }
                  

                  【讨论】:

                  • This answer 可能有助于进行稀疏克隆,即没有开销。
                  【解决方案19】:

                  Github 企业解决方案

                  HTTPS_DOMAIN=https://git.your-company.com
                  ORGANISATION=org
                  REPO_NAME=my-amazing-library
                  FILE_PATH=path/to/some/file
                  BRANCH=develop
                  GITHUB_PERSONAL_ACCESS_TOKEN=<your-access-token>
                  
                  URL="${HTTPS_DOMAIN}/raw/${ORGANISATION}/${REPO_NAME}/${BRANCH}/${FILE_PATH}"
                  
                  curl -H "Authorization: token ${GITHUB_PERSONAL_ACCESS_TOKEN}" ${URL} > "${FILE_PATH}"
                  

                  【讨论】:

                  • 在哪里可以找到GITHUB_PERSONAL_ACCESS_TOKEN
                  • 您可以通过转到 https:///settings/tokens 并点击“生成新令牌”按钮来创建个人访问令牌。
                  • 嗯,我们有自动生成用户名和密码的自动化系统,用于对使用相同 SSO 的多个系统进行身份验证,所以我希望有一种方法可以自动生成给定用户名的令牌和密码。
                  【解决方案20】:

                  在我看来,使用以下方法最简单:

                  wget https://github.com/name/folder/file.zip?raw=true
                  

                  【讨论】:

                    【解决方案21】:

                    如果您的目标只是下载文件,那么有一个名为 gget 的轻松应用程序:

                    gget github.com/gohugoio/hugo 'hugo_extended_*_Linux-ARM.deb'
                    

                    以上示例将从hugo 存储库下载单个文件。

                    https://github.com/dpb587/gget

                    【讨论】:

                      【解决方案22】:

                      以下 2 个命令对我有用:

                      git archive --remote={remote_repo_git_url} {branch} {file_to_download} -o {tar_out_file}

                      从 url 为remote_repo_git_url 的远程存储库的branch 下载file_to_downloadtar 存档并将其存储在tar_out_file

                      tar -x -f {tar_out_file}.tartar_out_file 中提取file_to_download

                      【讨论】:

                        【解决方案23】:

                        如果没有其他答案有效(即限制性 GitLab 访问),您可以通过以下方式进行“选择性结帐”:

                        1. git clone --no-checkout --depth=1 --no-tags URL
                        2. git restore --staged DIR-OR-FILE
                        3. git checkout DIR-OR-FILE

                        尽管此解决方案 100% 兼容 git,并且您可以签出目录,但它不像对文件执行 wget/curl 那样在磁盘和网络上都不是最优的。

                        【讨论】:

                          【解决方案24】:

                          这是特定于托管在 GitHub

                          上的 git 存储库

                          尝试使用 Github 命令行应用 gh'api' 命令,对 Github 的 'get repository contents' 端点进行经过身份验证的调用。

                          基本命令是:

                          $gh api /repos/{owner}/{repo}/contents/<path_to_the_file>
                          

                          作为额外的奖励,当您从包含您尝试从中获取文件的 repo 的克隆的目录中执行此操作时,将自动填写 {owner} 和 {repo} 部分。

                          https://docs.github.com/en/rest/reference/repos#get-repository-content

                          响应将是一个 JSON 对象。如果 确实指向一个文件,则 JSON 将包含一个“大小”、“名称”、几个用于访问该文件的 url 字段,以及一个“内容”字段,它是文件的 base64 编码版本内容。

                          要获取文件内容,您可以卷曲“download_url”的值,或者只解码“内容”字段。您可以通过管道传递 base64 命令来做到这一点,如下所示:

                          $gh api /repos/{owner}/{repo}/contents/<path-to-the-file> --jq '.content' | base64 -d
                          

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 2018-06-11
                            • 2018-12-08
                            • 2013-01-30
                            • 1970-01-01
                            • 2020-08-11
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多