Existem armadilhas para colocar $ HOME no git em vez de vincular arquivos de ponto?

38

Por muitos anos, meu $HOMEdiretório inteiro foi verificado no subversion. Isso incluiu todos os meus arquivos de pontos e perfis de aplicativos, muitos scripts, ferramentas e hacks, minha estrutura básica preferida de diretório inicial, não alguns projetos excêntricos e um armazém com dados aleatórios. Isto foi uma coisa boa. Enquanto durou.

Mas ficou fora de controle. A verificação básica é a mesma em dezenas de sistemas, mas nem tudo isso é apropriado para todas as minhas máquinas. Nem todos tocam bem com diferentes distribuições.

Estou no processo de limpeza da casa - separando os dados onde eles pertencem, dividindo alguns scripts como projetos separados, corrigindo alguns links quebrados em coisas que devem ser automatizadas etc.

Minha intenção é substituir subversioncom gitpara o check-out de nível superior de $HOME, mas eu gostaria de pare este para baixo a apenas as coisas que eu gostaria de ter em todos os meus sistemas, significando dotfiles, alguns diretórios e alguns scripts personalizados básicas.

Ao ler on-line, muitas pessoas parecem estar fazendo isso usando a abordagem de link simbólico: clone em um subdiretório e crie links simbólicos $HOMEno repositório. Tendo meu $HOMEcontrole de versão completo por mais de uma década, não gosto da ideia dessa abordagem e não consigo entender por que as pessoas parecem tão avessas ao método de checkout direto. Existem armadilhas que preciso saber sobre gitcomo um checkout de nível superior $HOME?

PS Em parte, como um exercício de boa codificação, também estou planejando tornar meu checkout raiz público no github. É assustador a quantidade de informações confidenciais de segurança que eu permiti coletar em arquivos que antes eram compartilháveis ​​sem pensar duas vezes! Senha WiFi, chaves RSA sem senha, etc. Eeek!

Caleb
fonte
5
Curioso, o que leva à crença de que $ HOME deve ser compartilhável sem um segundo pensamento‽ Nem mesmo as chaves privadas RSA criptografadas devem ser compartilhadas.
derobert
3
se você está realmente falando sobre colocar o conteúdo do seu diretório home no git, observe: é difícil (mas não impossível) vasculhar o histórico do git e remover cuidadosamente itens sensíveis permanentemente (o git é projetado para ajudar a evitar a perda de coisas) e lembre-se também de que, quando você alterna ramificações ou check-out, uma revisão anterior gitaltera as permissões de seus arquivos para 644depois do check-out, o que é ruim para coisas como chaves ssh privadas. no entanto etckeeperé uma solução para a utilização de git com permissões para / etc /
CWD
@derobert: Estou bem ciente disso. Eu não estava falando sobre tornar público o $ HOME, apenas arquivos de ponto e scripts de conveniência. É aí que tenho encontrado coisas que não pertencem. E sim, eu deveria ser capaz de partilhar a minha .zshrc, .vimrce coisas semelhantes sem ter para higienizar-los em primeiro lugar!
Caleb
4
Se você ainda não viu, consulte o wiki do vcs-home e as listas de discussão, que são basicamente pessoas discutindo exatamente isso - como manter seu $ HOME sob controle de revisão.
22612 Jim Jim
Eu não sei o quanto você pode mudar o comportamento do git, mas pelo menos o modo como ele funciona fora do repositório debian, é bastante ganancioso quando se trata de procurar por arquivos rastreados / não rastreados / modificados e automaticamente se sente responsável por cada arquivo. MRB já afirmou isso. Às vezes, fico aborrecido com esse comportamento ganancioso, mesmo em projetos relativamente pequenos que não gostaria disso no meu diretório pessoal. Por que você quer usar o git? Também estou usando um sistema de controle de versão para sincronizar meus arquivos de configuração entre hosts e estou muito feliz com o CVS porque é muito simples! Git é muito (muito!) Poderoso para isso
Bananguin

Respostas:

17

Sim , há pelo menos uma grande armadilha ao considerar gitgerenciar um diretório inicial que não é uma preocupação subversion.

Git é ganancioso e recursivo por padrão .

O Subversion ignorará ingenuamente qualquer coisa que não conheça e interrompe o processamento de pastas para cima ou para baixo do seu checkout quando atingir uma que não conhece (ou que pertence a um repositório diferente). O Git, por outro lado, continua recorrendo a todos os diretórios filhos, tornando as caixas aninhadas muito complicadas devido a problemas no namespace. Como seu diretório pessoal provavelmente também é o local onde você faz checkout e trabalha em vários outros repositórios git, ter seu diretório pessoal no git quase certamente tornará sua vida uma bagunça impossível.

Como se vê, esse é o principal motivo pelo qual as pessoas fazem check-out de seus arquivos de ponto em uma pasta isolada e, em seguida, fazem o link simbólico para ele. Ele mantém o git fora do caminho ao fazer qualquer outra coisa em qualquer diretório filho do seu $HOME. Embora isso seja puramente uma questão de preferência se você verificar sua casa no subversion, isso se tornará uma necessidade se você usar o git.

No entanto , existe uma solução alternativa. O Git permite algo chamado "raiz falsa", onde todo o mecanismo do repositório fica oculto em uma pasta alternativa que pode ser fisicamente separada do diretório de trabalho do checkout. O resultado é que o kit de ferramentas git não ficará confuso: nem verá o seu repositório, apenas a cópia de trabalho. Ao definir algumas variáveis ​​de ambiente, você pode informar ao git onde encontrar as mercadorias para aqueles momentos em que estiver gerenciando seu diretório inicial. Sem as variáveis ​​de ambiente definidas, ninguém é mais sábio e sua casa parece clássica.

Para fazer esse truque fluir um pouco mais, existem algumas ótimas ferramentas disponíveis. A lista de discussão vcs-home parece o local ideal para começar, e a página about contém um resumo conveniente de howtos e experiências das pessoas. Ao longo do caminho, existem algumas pequenas ferramentas bacanas como vcsh , sr . Se você deseja manter seu diretório pessoal diretamente no git, vcsh é quase uma ferramenta obrigatória. Se você acabar dividindo seu diretório pessoal em vários repostórios nos bastidores, combine vcshcom mruma maneira rápida e não muito suja de gerenciar tudo de uma só vez.

Caleb
fonte
2
mas porque não basta adicionar '*' ao seu arquivo .gitignore? Dessa forma, o git ignorará tudo, exceto os arquivos que já estão no repositório, e você poderá adicionar novos arquivos git add -f <file>.
ALiX 31/08/12
@ALiX: Como as gitferramentas ainda consideram que você está trabalhando no seu repositório de diretório doméstico, mesmo se você estiver em algum subdiretório que seja um repositório git separado para algum projeto. Essa solução tornaria seu diretório pessoal inteiro fora dos limites para todos os outros trabalhos do git.
Caleb
5
mas um '*' no seu .gitignore significa que todos os arquivos que não estão no seu repositório home-dir são ignorados. e quando você verifica um novo repositório git em algum subdiretório, tudo ainda deve funcionar como esperado (eu acho). Até onde eu sei, as ferramentas git procurarão o primeiro diretório .git enquanto avançam na hierarquia de diretórios. Portanto, ao trabalhar no subdiretório, o repositório git correto será usado. Obviamente, se você estiver usando variáveis ​​de ambiente do git, acho que as coisas podem ficar confusas. Mas, caso contrário, não vejo por que isso não funcionaria.
Alix
@ALiX está certo. Os repositórios git aninhados parecem funcionar bem, desde que você os gitignore no repositório pai. Gostaria de saber quais são as desvantagens dessa abordagem muito simples, além de possíveis problemas com as variáveis ​​de ambiente do git.
evanrmurphy
1
Estive experimentando isso hoje. Eu acho que /*funciona melhor do que *porque ainda ignora tudo por padrão, mas torna muito mais fácil adicionar diretórios. Em vez de git add -fusar !padrões pré-prefixados como !/.vimrce !/.gitignore(para o próprio arquivo .gitignore) para incluir explicitamente as coisas no repositório.
evanrmurphy
14

Eu não gostaria que meu diretório pessoal inteiro fosse verificado no controle de versão simplesmente porque significa que todos os subdiretórios nos quais eu entraria teriam o contexto de controle de versão do meu diretório home. Comandos como git checkoutteriam uma ação real nesse caso, causando problemas se eu acidentalmente executar algo do diretório errado, seja algo em gitsi ou um script que chame git.

Também aumenta a probabilidade de adicionar algo ao repositório que você não deseja, o que não teria sido um problema quando você tinha tudo verificado, mas agora se torna um problema. E se você acidentalmente adicionar um arquivo de chave privada (talvez por hábito) e empurrá-lo para o github?

Dito isto, acho que as principais desvantagens não são realmente técnicas - apenas querer me salvar de mim mesma.

Quanto à ligação simbólica: você pode clonar seu repositório em um subdiretório e ter um script que atualize todos os links simbólicos que precisam ser atualizados. A quantidade de manutenção necessária para esse script pode superar os benefícios de tê-lo; o link simbólico pode se tornar menos trabalhoso.

Com links simbólicos, você também pode facilmente adicionar adições específicas de distribuição (ou mesmo de host) que são verificadas no git. Seu script symlink-update ignorará os arquivos destinados a plataformas incompatíveis ou hosts diferentes e atualizará apenas os apropriados.

Algo como:

HOMEREPO=$HOME/homerepo
HOST=$(hostname)
UNAME=$(uname)

for dotfile in $HOMEREPO/shared/* $HOMEREPO/host-$HOST/* $HOMEREPO/uname-$UNAME/*
do
    target=$HOME/$(basename $dotfile)
    [ ! -r $target ] && ln -s $dotfile $target
done

Pessoalmente: uso links simbólicos e não vinculo diretórios; somente os arquivos dentro. Isso me dá alguma flexibilidade para fazer alterações no site local nesses diretórios (por exemplo, adicionar / remover arquivos). Configurar minha conta em um novo sistema é entediante, pois preciso recriar todos os links simbólicos manualmente.

mrb
fonte
Qualquer gitcomando que eu execute seria para o próprio diretório inicial ou seria enterrado pelo menos um em um diretório não confirmado. Usar svnesse isolamento de uma pasta é bastante eficaz e não me causa nenhum problema há uma década. Seu primeiro parágrafo indica outra coisa. Isso é realmente uma diferença na maneira como gitfunciona?
Caleb
Além disso, minhas configurações e scripts já possuem lógica condicional para diferentes hosts e plataformas integradas, portanto, usar um script para configurar links diferentes como condicionais não parece ser um grande ganho em relação gitàs ramificações fáceis de gerenciar. Ainda falta alguma coisa ou isso vai se tornar preferência?
Caleb
3
O isolamento de uma pasta realmente não se isola git- não tenho certeza svn- mas, por exemplo, git init foo && mkdir -p foo/bar/baz/spam && cd foo/bar/baz/spam && git status(ou outros comandos git) mostram que você ainda está no foocontexto de controle de versão.
Mrb 28/08
Configurações e scripts: nem todos os dotfiles suportam condicionais, e foi por isso que sugeri a abordagem alternativa. Essas são todas as razões pelas quais acho que as pessoas preferem não usar o controle de versão $HOME- e o controle de versão não é realmente valioso para o dotfiles imo - mas, no final das contas, é o seu diretório pessoal; portanto, se você preferir usar o git e esses não são problemas para você, vá em frente!
Mrb 28/08
Obrigado pela informação. Na verdade, seu comentário sobre o git, que não permite isolamento, é o bit mais útil. Você pode trabalhar com destaque na sua resposta. O Subversion se comporta de maneira muito diferente nesse ponto e é significativo para este caso de uso.
Caleb
6

Para dar outro ponto de vista: eu tenho meu $ HOME no git desde algum momento e não encontrei nenhuma desvantagem. Obviamente, eu não sincronizo esse repositório do git com o github; Eu uso um serviço que possui contratos particulares. Também não coloco arquivos de mídia, downloads ou pacotes sob o controle git.

  • git status é uma espécie de lista de verificação "fazer, limpar".

  • Eu tenho um ~/tmppara coisas temporárias, que é gitignored.

  • Eu gosto de ver git statustudo o que um software instalado recentemente ousa adicionar ao meu $ HOME e, com frequência, exclui esses arquivos ou até mesmo desinstala os culpados.

  • Eu adiciono manualmente os arquivos e diretórios locais realmente úteis .gitignore, que têm o benefício 'saber o que você faz ao instalar as coisas'.

  • Se eu construo uma nova VM ou instalo um novo PC, clono minha casa remota para $ HOME e tenho imediatamente tudo o que preciso em mãos.

  • Coisas como o vundle for plugins vim não são mais necessárias.

Eu não gosto de complexidade. Quando eu ajusto qualquer arquivo rc, apenas o faço, cometo e empurro. Então, como reflexo, eu consigo extrair $ HOME todos os dias, e sempre tenho a última configuração. É simples assim.

Máquinas atualmente sob este regime: laptop doméstico, PC comercial, VM comercial, além de 3 ou 4 servidores remotos.

gb.
fonte
Você tem algum outro check-out aninhado dentro de sua casa?
Calebe
Não, coloquei outras coisas no diretório / work e não clono pequenas ferramentas como o vim pugins.
gb.
1
Tenho trabalho dentro de um ~ / Sites e fazer essa abordagem, bem como, não há nenhum problema com repos git aninhados
philfreo
1
Estou usando essa configuração há um tempo. Eu tenho um 'alias sq = git status -uno' e não me preocupo muito com .gitignore (de vez em quando, dou uma olhada em todo o problema e depois digo "meh"). Nunca tive problemas com repositórios aninhados de git. Eu tenho um servidor privado onde fiz um git init --bareenvio para o ssh (embora eu não coloque senhas no repositório, eu tenho meus arquivos de anotações lá).
Unhammer 1/1
5

Eu tentei os dois e preferi a abordagem de link simbólico no final:

  • Confira em qualquer lugar
  • make install
  • Efetue logout e logon novamente para carregar as configurações do X

Desvantagens:

  • É necessário mover os arquivos para o repositório antes de adicioná-los
  • É necessário manter a lista de links simbólicos no Makefile

Vantagens:

  • Não há necessidade de um maciço .gitignore(tenho 133 dotfiles na ~minha humilde caixa do Ubuntu)
  • Pode manter os scripts de manutenção e outras ~coisas relacionadas (como Makefilee cleanup.sh) fora do caminho
  • A versão pode controlar configurações pessoais e públicas separadamente

Restrições:

  • Ao contrário do @mrb, apenas crio links simbólicos no ~. Isso mantém a ligação simbólica simples e torna trivial a observação de novos arquivos, por exemplo ~/.vim, ao custo de uma .gitignoremanutenção muito rara .

Essas duas últimas vantagens mudaram a balança no meu caso - não quero desorganizar o diretório inicial e quero manter o conteúdo público e privado claramente separado.

O único aplicativo que eu conheço que tem (ou pelo menos teve) problemas ao lidar com links simbólicos foi o Pidgin - ele continuou substituindo meus links simbólicos por arquivos comuns.

l0b0
fonte
Obrigado por sua contribuição sobre os prós e contras de cada abordagem. No meu acompanhamento, descobri que há uma terceira abordagem que pode tirar o melhor dos dois mundos se você estiver bem, configurando a fiação extra para começar.
Caleb
3

Aqui está um: Se você tentar fazer git rebase -i --rooto check-in .gitconfigno primeiro commit no repositório, o git removerá temporariamente o .gitconfigarquivo, o que, por sua vez, o tornará incapaz de concluir a operação de rebase, uma vez que exige seu nome e seu e-mail. que são armazenados nesse arquivo.

Você pode configurá-los novamente e fazer git rebase --continue, mas depois que eu fiz isso e concluí a operação de rebase, meu repositório git ganhou uma confirmação vazia sem uma mensagem de confirmação antes da confirmação que era anteriormente a primeira confirmação no repositório, que eu não sei como se livrar.

Eu não sei o que acontece se você fizer isso git rebase -i <commit>, e .gitconfigé verificado junto com qualquer confirmação depois <commit>.

Talvez a solução mais fácil seja evitar adicionar .gitconfigao repositório e listá-lo .gitignore.

Olá adeus
fonte
2

É assim que eu faço:

  1. instale um linux limpo (não é necessário, mas torna a vida mais agradável na etapa 4)
  2. instale o etckeeper
  3. correr git initem sua casa
  4. crie .gitignore e adicione tudo que parece que não lhe interessa ou que pode mudar muito. Certifique-se de adicionar coisas como *.cache, *.locketc. Eu não recomendo adicionando/*porque você não será notificado automaticamente quando algo novo for adicionado à sua casa. É uma abordagem de lista negra versus lista de permissões, onde basicamente quero manter minha configuração para todos os softwares, exceto para itens voláteis e alguns softwares com os quais não me importo. Quando você mesclar, migrar ou comparar sistemas posteriormente, poder diferenciar tudo é bastante útil. Você pode configurar seus novos sistemas muito mais rapidamente do que se tivesse apenas o .bashrc e alguns outros arquivos de ponto armazenados. Dessa forma, você manterá a configuração que, de outra forma, poderá definir através da GUI e não saberá quais arquivos de ponto armazenam as configurações. (Se alguma vez você confirmou arquivos voláteis, ainda pode dizer ao git para assumir a forma inalterada)
  5. corre etckeeper init -d /home/username
  6. corre git commit -d /home/username
  7. configure aliases em seu shell para tornar a linha de comando mais agradável, como homekeeper checkout

O motivo para usar o etckeeper é que ele armazenará metadados como permissões para seus arquivos (bastante importante para certas coisas, como chaves ssh). Agora você deve ter um gancho de pré-confirmação que salvará os metadados automaticamente. Não tenho tanta certeza sobre o pós-pagamento. Você provavelmente deveria usar. etckeeper checkout xxx -d /home/userVou investigar um pouco mais e elaborar esta resposta.


fonte
-1

Meu principal problema com o uso do Git no diretório inicial é que o Git não armazena atributos de arquivo, como permissões e carimbos de data e hora. Para mim, é importante saber quando determinados arquivos foram criados, que podem ou não ser o seu caso. Além disso, perder permissões para arquivos e diretórios como .sshé problemático. Entendo que você planeja ficar .sshfora do Git, mas haverá outros locais onde as permissões podem ser importantes (como backups de sites não compactados).

dotancohen
fonte
Isso é enganoso, se não factualmente errado. Por padrão, o Git preserva muitos atributos de arquivo, incluindo permissões. Estou mantendo o .sshgit há algum tempo sem problemas, as permissões seguras apropriadas são preservadas. O que ele não faz na configuração básica é preservar a propriedade ou os carimbos de data e hora; no entanto, se um deles for um problema para um caso de uso específico, existem plug-ins que podem tornar o manuseio dessas propriedades adicionais parte do fluxo de trabalho regular (consulte metastore ou git-cache-meta).
Caleb
Mesmo que não os armazene, como isso é pior do que apenas ter um diretório inicial que não esteja no vcs? O git não substituirá ativamente os mtimes, a menos que você peça para alterar um arquivo.
poolieby
-1

Uma solução baseada em git é especialmente útil se você precisar implantar seus arquivos em máquinas diferentes, e mais ainda se você tiver peças comuns a todas as máquinas e partes específicas de algumas máquinas. Você pode criar vários repositórios e usar uma ferramenta como multigit ou vcsh para cloná-los no mesmo diretório (seu diretório pessoal nesse caso).

capricho
fonte
Obrigado, mas talvez você tenha perdido a pergunta. Estou bem ciente dos usos para isso (por isso, por que eu queria fazer isso em primeiro lugar), essa pergunta era sobre quaisquer armadilhas que alguém novo em fazer isso com o git (como eu era quando perguntei) pode não estar ciente de . Isso não parece responder a essa pergunta.
Caleb