Git:如何从远程原始主机更新/签出单个文件?


362

场景:

  1. 我在本地的单个文件中进行了一些更改,然后运行git addgit commit然后git push
  2. 该文件被推送到远程原始主存储库
  3. 我有另一个本地存储库,该存储库是通过Capistrano使用该远程存储库中的“ remote_cache”方法部署的
  4. 现在,我不想部署整个应用程序,而只是更新/签出该单个文件。

用git有可能吗?我找不到任何可行的方法,也无法弄清楚。有了SVN,我就做了svn up file,瞧。


19
您可能需要考虑将接受的答案更改为实际回答您的问题的答案。;)
步骤

6
经过6年多了,我相信我们可以有把握地认为这不会发生@steps ...
费利克斯·加侬-格雷尼尔

使用Git 2.23(2019年8月),它是git restore -s origin/master -- path/to/file。请参阅下面的答案
VonC

Answers:


914

可以这样做(在已部署的存储库中)

git fetch
git checkout origin/master -- path/to/file

提取操作将下载所有最近的更改,但不会将其放入您当前签出的代码(工作区)中。

检出将使用下载的更改(origin/master)中的特定文件更新工作树。

至少对于那些小的拼写错误,这对我来说是有效的,在其中创建分支等只是为了更改文件中的一个单词而感到很奇怪。


1
超级方便,效果很好。我需要获取composer.json文件并运行更新,然后才能更新生产环境中的其余站点。如果我手动放置了composer.json / lock文件,则在执行拉取操作时,说文件已经存在会产生冲突。通过这种方式,git毫无疑问地识别了文件。
大卫

6
这是我一直在寻找的答案。
javadba 2014年

20
@Mymozaaa双破折号表示后面是文件名。这是为了防止git在不幸的情况下将您的文件名解释为分支,而您却拥有两个同名文件。
乔尔·梅隆

问题是您仍在获取数据,如果它是一个大型仓库,那将是昂贵的操作。我担心唯一的选择是将gitweb安装在远程服务器上,然后访问它以检索文件等。
Christian Goetze'3

一个小问题,这样做之后,我将转到另一台计算机,然后执行上面列出的操作,但是在git status我看来它们是Changes to be committed:-意思是,我需要再次提交它们?(只是指出我想刷新单个未修改的文件,但回购本身在另一台计算机上被修改了)
Ricky Levi

42

以下代码为我工作:

     git fetch
     git checkout <branch from which file needs to be fetched> <filepath> 

19
git archive --format=zip --remote=ssh://<user>@<host>/repos/<repo name> <tag or HEAD> <filename> > <output file name>.zip

1
对于通过ssh克隆的存储库,这是一个很好的解决方案,但是似乎不支持通过https进行存储: git archive --remote=https://github.com/git/git.git master:git/contrib/completion git-completion.bash | tar -x 给我错误消息:fatal: Operation not supported by protocol.
Alderath

1
很好地与tar:s 相结合--to-stdoutgit archive --remote="gitolite3@<host>:<repo>" <tag> <file> | tar xf - --to-stdout
Puggan Se '18

18

使用Git 2.23(2019年8月)和新的(仍在试验中的)命令git restore(如“ 如何从工作目录而不是登台区域重设所有文件? ”中所示),将是:

git fetch
git restore -s origin/master -- path/to/file

这个想法是:git restore只处理文件,而不处理文件分支git checkout
请参阅“ 混淆者git checkout ”:这就是其中的git switch含义)


codersam添加了注释

就我而言,我想从上游从中派生)获取数据
因此,只需更改为:

git restore -s upstream/master -- path/to/file

2
这个命令终于存在了,这真是一种解脱... git-cluefull人们以前在做什么?我正在恢复整个过程并复制所需的单个文件,但这很痛苦。
Mike Wise

这对我有用,但就我而言,我想从上游(从中派生)获取数据。因此,更改为git restore -s upstream/master -- path/to/file
coderSam

@coderSam非常感谢您提供此反馈。我已将您的评论包含在答案中,以提高知名度。
VonC

8

您可以做的是:

  1. 更新您的本地git仓库:

    git fetch

  2. 建立一个本地分支并在其上签出:

    git branch pouet && git checkout pouet

  3. 在此分支上应用所需的提交:

    git cherry-pick abcdefabcdef

    (abcdefabcdef是您要应用的提交的sha1)


4
顺便说一句,第二步也可以在一个命令中完成git checkout -b pouet
格雷格·休吉尔

4
'pouet'是此示例的最佳分支名称。
Hussard '16

2

或在您所在的分支上使用git stash(如果有更改),检出master,获取最新更改,将该文件保存到桌面(或整个应用程序)中。签出您所在的分支。Git隐藏将应用恢复到您当时的状态,然后手动修复更改或将其拖动以替换文件。

这种方法不是很酷,但是如果你们无法解决其他任何问题,它就可以工作。


-10

我想我发现了一个容易破解的方法。

删除本地存储库中的文件(要从远程服务器中的最新提交更新的文件)

然后做一个 git pull

因为文件被删除,所以不会有冲突


这将删除在本地对该文件进行的所有最终更改,并同时提取所有其他文件,这是OP不想执行的操作。
legrojan

除了更新远程分支,删除本地不是一个好主意。
c0der512 '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.