Como escolher as mudanças para apenas um arquivo, não todo o commit


Respostas:


137

Você tem opções diferentes com base no que deseja alcançar:

Se quiser que o conteúdo do arquivo seja o mesmo do branch de destino, você pode usar git checkout <branch> -- <filename>. No entanto, isso não “selecionará” as mudanças que aconteceram em um único commit, mas apenas tomará o estado resultante do referido arquivo. Então se você adicionou uma linha em um commit, mas os commits anteriores mudaram mais, e você só quer adicionar aquela linha sem aquelas outras mudanças, então um checkout não é o que você quer.

Caso contrário, se você deseja aplicar o patch introduzido em um commit a apenas um único arquivo, você tem várias opções. Você pode executar git cherry-pick -n, ou seja, sem submetê-lo, editar o commit (por exemplo, redefinir todos os arquivos usando git reset -- .e apenas adicionar o arquivo que você realmente deseja alterar usando git add <filename>). Ou você pode criar o diff para o arquivo e aplicar o diff então:

git diff <branch>^..<branch> -- <filename> | git apply

22

Crie um patch filee aplique-o.

git diff branchname -- filename > patchfile
git apply patchfile

EDITAR:

Já que você precisa fazer as alterações de um commit, crie o patch assim:

git show sha1 -- filename > patchfile

1
git diff sha1(ou git diff branch- é o mesmo se a ramificação apontar para o mesmo hash) produzirá apenas uma diferença do diretório de trabalho atual em relação a esse hash, mas não o que muda um commit introduzido por si mesmo.
cutucar

Corrigir. Editou a resposta. Obrigado.
Sailesh

1
-1 git checkoutcom um nome de arquivo é o martelo certo para este prego. Ambas as opções são desnecessariamente complexas.
Rein Henrichs

7
Para este caso específico, sim. Mas, em geral, se você quiser escolher as alterações de um commit feito em um arquivo específico, então checkoutnão funcionará, já que pode envolver outras alterações anteriores indesejadas e pode não conter alterações feitas no branch atual.
Sailesh de

11

Outra coisa útil a fazer é obter o patch localmente e usar:

git checkout {<name_of_branch>, commit's SHA} <path to the file> 

Isso não é uma escolha seletiva.


2
Atenção: como @poke diz em sua resposta, isso não copia as alterações; ele copia todo o estado do arquivo. Portanto, se você quiser adicionar as alterações de um commit ao arquivo, fazendo check-out desta forma, você acabará sobrescrevendo quaisquer alterações mais recentes, o que não é bom.
Alexander Bird

7

Git tem tudo pronto :)

Apenas use git checkout <sha> <path-to-file>


4
Isso não é uma escolha acertada - isso verifica o arquivo por completo. O objetivo é fazer uma alteração específica de um commit. Freqüentemente, são a mesma coisa, mas às vezes não são.
AndrewF de

6
git checkout the_branch_with_the_change the/path/to/the/file/you/want.extension

isto funciona se você quiser que um único arquivo de outro ramo seja copiado para o ramo de trabalho atual


1
Tenha cuidado, as alterações feitas no arquivo que não estão na versão do outro branch serão perdidas.
Patrick Schlüter

Concordo com isso. isso é útil se você precisa apenas de uma cópia do arquivo e deseja alterá-lo no branch atual
Ismail Iqbal

1
Pode-se usar globs (caminho / *) e especificar mais de um caminho / arquivo
Todd

1

Isso é o que você está procurando:

git checkout target-branch sha1 path/to/file

sha1 é opcional


11
não, "escolher alterações no commit" não é "selecionar arquivo inteiro"
Abyx

1

O que costumo fazer é usar git ls-tree

apenas faça:

git ls-tree -r <commit-id> |grep 'your filename'
# there will be output that shows a SHA1 of your file
git show ${SHA1 of your file} > 'your filename'

Isso imprimirá todos os nomes de arquivo que correspondam ao seu grep e fornecerá as chaves SHA1 dos arquivos no commit.

O Git show também pode ser usado em arquivos fora do seu branch. usar >de seu shell para canalizar a saída para um arquivo fornece o resultado que você está procurando.


0

Você pode tentar fazer isso:

git show COMMIT_ID -- path/to/specific-file | git apply

Por exemplo:

git show 3feaf20 -- app/views/home/index.html | git apply

-9
git reset HEAD~1

move os arquivos para o estágio de pré-confirmação

git stash

remove da memória

Agora seu branch está bem limpo (revertido para o commit anterior)

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.