Preserva o git – arquivos inalterados entre os checkouts das filiais

Eu tenho usado o git --assume-unchanged yacs/settings/development.py para ignorar o arquivo de configuração do database local no meu branch de desenvolvimento. Mas quando eu quero mudar ramos (para implantações), recebo um erro que ainda tenho alterações pendentes:

 % git checkout production error: Your local changes to the following files would be overwritten by checkout: yacs/settings/development.py Please, commit your changes or stash them before you can switch branches. Aborting 

Que é chato. A única maneira de saber como contornar isso seria armazená-lo:

 % git stash % git checkout production % git merge dev % ./deploy.sh % git checkout dev % git stash pop # On branch dev # Changes not staged for commit: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: yacs/settings/development.py # 

Mas agora está de volta no índice novamente (ugh)! Existe uma alternativa melhor para esse stream de trabalho?

[Eu particularmente não me importo se as alterações locais permanecerem localmente (também é ok se for o ramo de produção), eu não quero que ele seja enviado para um repository remoto.]

Você pode tentar ( git update-index man page ):

 git update-index --skip-worktree -- path 

O bit Skip-worktree pode ser definido em uma sentença (longa): Ao ler uma input, se ela estiver marcada como skip-worktree, o Git finge que sua versão do diretório de trabalho está atualizada e, ao invés disso, lê a versão do índice.

No entanto, como mencionado em ” git assume inalterado vs skip worktree “:

Ambas as opções têm problemas. --assume-unchanged redefine-se sempre que o índice é descartado (por exemplo, git reset ), de modo que provavelmente você irá tropeçar mais cedo ou mais tarde. O mesmo vale para --skip-worktree .

O que comecei a fazer é criar um branch off master chamado private que tenha minhas alterações locais; pense nisso como um ramo proxy entre o meu ramo de trabalho e mestre. Eu posso rebase meu ramo de trabalho atual contra privado quando eu preciso de minhas alterações somente locais e eu tenho um par de aliases no meu .gitconfig que automatizam mantendo privado em dia com o mestre. Quando eu preciso mesclar para master, meus aliases certificam-se de rebase – em vez de master private meu ramo de trabalho primeiro.

Eu publiquei uma input de blog sobre isso em mais detalhes aqui http://blog.ericwoodruff.me/2013/02/git-private-branch-pattern.html

A solução que funcionou para mim foi usar o –skip-worktree. No entanto, como alguns acima, lutei com a possibilidade de alternar entre uma ramificação do ticket e a ramificação principal sem reclamar do git mesmo depois de definir o sinalizador –skip-worktree no arquivo cujas alterações eu desejava permanecer local.

Parece que você vai se deparar com esse problema se fizer alterações no arquivo local somente antes de executar o –skip-worktree, que é o que aconteceu comigo.

Uma solução sugerida, acima, é include o arquivo em your_repo/.git/info/exclude . Mas eu não queria adicionar o arquivo à lista de exclusão, então fiz o seguinte a partir do diretório da minha tree de trabalho:

  1. cp ~/
    • Copiar arquivo que tenha suas alterações somente locais para algum lugar seguro no sistema de arquivos
  2. git checkout
    • na tree de trabalho, arquivo de checkout para que ele corresponda ao arquivo de ramificação principal
  3. git update-index --skip-worktree --
  4. cp ~/ .
    • copie o arquivo em questão do local seguro de volta à tree de trabalho
  5. git diff
    • nenhuma mudança deve ser mostrada; se você empurrar para o principal, nenhuma alteração em será incluída no push

Esse problema acontece quando o arquivo ignorado não é o mesmo que o do branch que você está tentando fazer ou o que você está tentando extrair.