Git: Como atualizar / retirar um único arquivo do mestre de origem remota?


362

O cenário:

  1. I fazer algumas mudanças em um único arquivo localmente e executar git add, git commitegit push
  2. O arquivo é enviado ao repositório principal de origem remota
  3. Eu tenho outro repositório local que é implantado via Capistrano com o método "remote_cache" desse repositório remoto
  4. Agora, não quero implantar o aplicativo inteiro, apenas atualizar / fazer check-out desse arquivo único.

Isso é de alguma forma possível com o git? Não consegui encontrar nada que funcionasse nem consegui descobrir. Com SVN acabei de fazer svn up filee pronto.


19
Você pode considerar alterar a resposta aceita para a que realmente responde à sua pergunta. ;)
— passos

6
Depois de mais de 6 anos, eu acredito que nós podemos seguramente assumir que isso não vai acontecer @steps ...
— Félix Gagnon-Grenier

Com o Git 2.23 (agosto de 2019), é git restore -s origin/master -- path/to/file. Veja minha resposta abaixo .
— VonC 19/09/19

Respostas:


914

É possível fazer (no repositório implantado)

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

A busca fará o download de todas as alterações recentes, mas não o colocará em seu código de saída atual (área de trabalho).

O checkout atualizará a árvore de trabalho com o arquivo específico das alterações baixadas ( origin/master).

Pelo menos isso funciona para mim, para aquelas pequenas correções de erros de digitação, nas quais é estranho criar um ramo etc. apenas para alterar uma palavra em um arquivo.


11
Super útil, isso funcionou muito bem. Eu precisava obter um arquivo composer.json e executar uma atualização antes de atualizar o restante do site em produção. Se eu tivesse manualmente colocado os arquivos composer.json / lock, quando fiz um pull, haveria conflito dizendo que os arquivos já existiam. Fazendo dessa maneira, o git reconheceu os arquivos sem uma reclamação.
— David

6
Esta é a resposta que eu estava procurando.
— Javadba

20
@Mymozaaa O traço duplo designa que o que se segue é um nome de arquivo. É para evitar que o git interprete seu nome de arquivo como uma ramificação no caso infeliz de você ter dois com o mesmo nome.
— Joel Mellon

O problema é que você ainda está buscando e, se for um repositório grande, essa será a operação cara. Receio que a única alternativa seria instalar o gitweb no controle remoto e acessá-lo para recuperar o arquivo ou algo assim.
— Christian Goetze

pergunta pequena, depois de fazer isso, vou para uma máquina diferente, depois faço suas ações listadas acima, mas depois as git statusvejo como Changes to be committed:- ou seja, preciso comprometê-las novamente? (Basta notar que eu queria para atualizar um único arquivo intocado mas o repo em si é tocado em uma máquina diferente)
— Ricky Levi

42

O código a seguir funcionou para mim:

     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

11
Esta é uma boa solução para repositórios clonados por ssh, mas parece que isso não é suportado por https: git archive --remote=https://github.com/git/git.git master:git/contrib/completion git-completion.bash | tar -x Dá-me uma mensagem de erro:fatal: Operation not supported by protocol.
— Alderath 6/18

11
foi legal combinado com tar: s --to-stdout,git archive --remote="gitolite3@<host>:<repo>" <tag> <file> | tar xf - --to-stdout
— Puggan Se 28/04

19

Com o Git 2.23 (agosto de 2019) e o novo comando (ainda experimental) git restore, visto em " Como redefinir todos os arquivos do diretório de trabalho, mas não da área de preparação? ", Isso seria:

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

A idéia é: git restorelida apenas com arquivos, não com arquivos e ramificações git checkout.
Veja " Confundido porgit checkout ": é aí que git switchentra)


codersam acrescenta nos comentários :

no meu caso, eu queria obter os dados do meu upstream (do qual eu bifurquei).
Então, mudei para:

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

2
Que alívio que esse comando finalmente existe ... O que as pessoas idiotas estavam fazendo antes? Eu estava restaurando a coisa toda e copiando os arquivos individuais que precisava, mas foi doloroso.
— Mike Wise

Isso funcionou para mim, mas no meu caso eu queria obter os dados do meu upstream (do qual eu bifurquei). Então apenas mudou paragit restore -s upstream/master -- path/to/file
— coderSam

@coderSam Do que você por esse feedback. Incluímos seu comentário na resposta para obter mais visibilidade.
— VonC

8

O que você pode fazer é:

  1. Atualize seu repositório git local:

    git fetch

  2. Crie uma filial local e faça checkout nela:

    git branch pouet && git checkout pouet

  3. Aplique a confirmação que você deseja neste ramo:

    git cherry-pick abcdefabcdef

    (abcdefabcdef é o sha1 do commit que você deseja aplicar)


4
Como um aparte, seu segundo passo também pode ser feito em um comando como git checkout -b pouet.
— Greg Hewgill

4
'pouet' é o melhor nome do ramo para este exemplo.
— Hussard

2

Ou git stash (se houver alterações) no ramo em que está, checkout master, obtenha as alterações mais recentes, pegue esse arquivo na área de trabalho (ou no aplicativo inteiro). Faça o checkout da filial em que você estava. O Git stash aplica-se novamente ao estado em que você estava e, em seguida, corrija as alterações manualmente ou arraste-o substituindo o arquivo.

Dessa forma, não é tããããããão legal, mas funcionará se vocês não puderem descobrir mais nada.


-10

Eu acho que encontrei um truque fácil.

Exclua o arquivo que você possui no repositório local (o arquivo que você deseja atualizar a partir da confirmação mais recente no servidor remoto)

E então faça um git pull

Como o arquivo foi excluído, não haverá conflito


Isso remove todas as eventuais alterações feitas nesse arquivo localmente e também extrai todos os outros arquivos, que é especificamente o que o OP não deseja fazer.
— Legrjan 17/11

Em vez de atualizar a filial remota, remover a ideia local é uma péssima idéia.
— C0der512
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.