git pull mantendo alterações locais

132

Como posso atualizar (puxar) um projeto git com segurança, mantendo arquivos específicos intocados, mesmo se houver alterações no upstream?

myrepo / config / config.php

Existe uma maneira, mesmo que esse arquivo esteja sendo alterado no controle remoto, quando eu git pull, todo o resto é atualizado, mas esse arquivo é inalterado (nem mesclado)?

PS. Preciso fazer o que estou pedindo, porque só estou escrevendo scripts de implantação baseados em git. Não consigo alterar os arquivos de configuração para modelos.

portanto, preciso escrever scripts de atualização que não percam o que foi alterado localmente. Eu esperava algo tão simples como:

git assume-remote-unchanged file1
git assume-remote-unchanged file2

então git pull

Johnny Everson
fonte
As alterações estão config.phpconfirmadas?
Mark Longair
Não está comprometido. Eu preferiria não ter que
Johnny Everson
@JhonnyEverson: É a mesma classe geral do problema (Você tem um arquivo de configuração e você não quer se comprometer configurações específicas, mas as necessidades da estrutura arquivo de configuração para ser rastreado.)
Daenyth

Respostas:

248

Existe uma solução simples baseada no Git stash. Esconda tudo o que você mudou, puxe todas as coisas novas, aplique sua quantidade.

git stash
git pull
git stash pop

No stash pop, pode haver conflitos. No caso que você descreve, de fato haveria um conflito config.php. Mas, resolver o conflito é fácil porque você sabe que o que você coloca no estoque é o que deseja. Então faça o seguinte:

git checkout --theirs -- config.php
GoZoner
fonte
5
o comando git checkout --theirs é muito confuso. Ele fez o que eu queria uma vez e algo muito ruim em outra hora. Tem alguma boa documentação?
Milimétrico
3
Sim, às vezes 'deles' e 'nossos' podem ser confusos. Em um git merge'nosso' é o que está atualmente no diretório de trabalho. Mas para um git rebase(ou git rebase -onto) o significado pode ser trocado.
GoZoner 19/09/2013
1
git stash , git pull , git stash apply Você pode soltar o esconderijo com: git stash dropUma vez que você mesclar as alterações com sucesso
BeingSuman
11
O problema do git é que você precisa entender o que ele fará. A outra coisa com o git é que, mesmo para pessoas inteligentes, muitas vezes é muito difícil entender o que o git fará.
Brad Thomas
1
Você deve verificar se há algo a esconder. Caso contrário, você exibirá as alterações ocultas de uma anterior git stash.
Jörn Reimerdes
15

Se você tiver um arquivo em seu repositório que deve ser personalizado pela maioria dos extratores, renomeie o arquivo para algo como config.php.templatee adicione config.phpao seu .gitignore.

KurzedMetal
fonte
5
verifique esta resposta também, você pode usar .gitattributespara manter sempre suas alterações durante a mesclagem.
KurzedMetal 2/12/12
É mais como o que eu precisava. O modelo é a solução elegante, mas receio não poder usar isso, pois estou apenas escrevendo scripts de implantação.
Johnny Everson
6

Atualização: isso literalmente responde à pergunta, mas acho que a resposta do KurzedMetal é realmente o que você deseja.

Assumindo que:

  1. Você está no ramo master
  2. O ramo upstream está masteremorigin
  3. Você não possui alterações não confirmadas

.... você poderia fazer:

# Do a pull as usual, but don't commit the result:
git pull --no-commit

# Overwrite config/config.php with the version that was there before the merge
# and also stage that version:
git checkout HEAD config/config.php

# Create the commit:
git commit -F .git/MERGE_MSG

Você pode criar um alias para isso se precisar fazer isso com frequência. Observe que, se você tiver alterações não confirmadas config/config.php, isso as descartará.

Mark Longair
fonte
4

Também podemos tentar o git pull com rebase

git pull --rebase origin dev
Bhavesh Maniya
fonte
1

Para responder à pergunta: se você deseja excluir determinados arquivos de um checkout, pode usar a finalização esparsa

1) Em .git/info/sparse-checkout, defina o que você deseja manter. Aqui, queremos tudo (*), mas (observe o ponto de exclamação) config.php:

 /*
 !/config.php

2) Diga ao git que você deseja levar em consideração a compra esparsa

 git config core.sparseCheckout true

3) Se você já possui esse arquivo localmente, faça o que o git faz em um checkout esparso (diga que ele deve excluir esse arquivo, definindo o sinalizador "skip-worktree")

git update-index --skip-worktree config.php

4) Desfrute de um repositório onde seu arquivo config.php é seu - quaisquer que sejam as alterações no repositório.


Observe que os valores de configuração não devem estar no controle de origem:

  • É uma possível violação de segurança
  • Causa problemas como este para implantação

Isso significa que você DEVE excluí-los (colocá-los em .gitignore antes da primeira confirmação) e criar o arquivo apropriado em cada instância em que faz check-out do seu aplicativo (copiando e adaptando um arquivo "modelo")

Observe que, depois que um arquivo é assumido pelo git, o .gitignore não terá nenhum efeito.

Dado que, uma vez que o arquivo está sob controle de origem, você só tem duas opções (): - rebase todo o seu histórico para remover o arquivo (com git filter-branch) - crie uma confirmação que remova o arquivo. É como travar uma batalha perdida, mas, às vezes, você precisa conviver com isso.

Pierre-Olivier Vares
fonte
0

Encaixe suas alterações locais não confirmadas e evite conflitos de mesclagem ao puxar.

git stash save
git pull
git stash pop

refer - https://happygitwithr.com/pull-tricky.html

Ujjwal Roy
fonte