Ci sono insidie ​​nel mettere $ HOME in git invece che nel symlink dei dotfile?


38

Per molti anni ho avuto il mio intero $HOMEelenco verificato in sovversione. Ciò ha incluso tutti i miei dotfile e profili applicativi, molti script, strumenti e hack, la mia struttura di directory home di base preferita, non alcuni progetti strani e un magazzino di dati casuali. Questa è stata una buona cosa Fino a quando è durato.

Ma è sfuggito di mano. Il checkout di base è lo stesso su dozzine di sistemi, ma non tutte quelle cose sono appropriate per tutte le mie macchine. Non tutti giocano bene con diverse distro.

Sono in procinto di pulire la casa - separare i dati a cui appartiene, suddividere alcuni script come progetti separati, riparare alcuni collegamenti interrotti in cose che dovrebbero essere automatizzate, ecc.

Il mio intento è quello di sostituirlo subversioncon gitil checkout di livello superiore $HOME, ma mi piacerebbe ridimensionarlo solo alle cose che vorrei avere su TUTTI i miei sistemi, ovvero dotfile, alcune directory e alcuni script personalizzati di base.

Nel leggere online molte persone sembrano farlo utilizzando l'approccio symlink: clonare in una sottodirectory e creare collegamenti simbolici $HOMEnel repository. Avendo avuto il mio $HOMEcontrollo completo della versione per oltre un decennio, non mi piace l'idea di questo approccio e non riesco a capire perché le persone sembrano così avverse al metodo di checkout diretto. Ci sono delle insidie ​​che devo sapere su gitcome checkout di alto livello $HOME?

PS In parte come esercizio di buona programmazione, sto anche pianificando di rendere pubblico il mio checkout su github. È spaventoso quante informazioni sensibili sulla sicurezza che ho permesso di raccogliere in file che dovrebbero essere condivisibili senza pensarci due volte! Password WiFi, chiavi RSA non passphrased, ecc. Eeek!


5
Curioso ciò che porta alla convinzione che $ HOME dovrebbe essere condivisibile senza pensarci due volte‽ Anche le chiavi private RSA crittografate non dovrebbero essere condivise.
derobert,

3
se in effetti stai parlando di mettere il contenuto della tua home directory in git, nota solo: è difficile (ma non impossibile) scavare nella cronologia di git e rimuovere con cura gli oggetti sensibili in modo permanente (git è progettato per aiutare a prevenire la perdita di cose), e ricorda inoltre che quando gitcambi ramo o fai il checkout una revisione precedente cambierà le autorizzazioni dei tuoi file 644dopo il checkout, il che è dannoso per cose come chiavi ssh private. comunque etckeeperè una soluzione per usare git con permessi per / etc /
cwd il

@derobert: ne sono ben consapevole. Non stavo parlando di rendere pubblico $ HOME, solo dotfile e script utili. Quelli sono dove ho trovato cose che non appartengono. E sì, dovrei essere in grado di condividere la mia .zshrc, .vimrce le cose simili, senza dover disinfettare loro per primi!
Caleb,

4
Se non l'hai ancora visto, consulta la wiki e le mailing list di vcs-home , che in pratica sono le persone che discutono esattamente di questo - come mantenere il tuo $ HOME sotto controllo di revisione.
Jim Paris,

Non so quanto puoi cambiare il comportamento di git, ma almeno il modo in cui funziona fuori dal repository debian è abbastanza avido quando si tratta di cercare file tracciati / non tracciati / modificati e automaticamente si sente responsabile per ogni file. mrb lo ha già dichiarato. A volte sono infastidito da questo comportamento avido anche in progetti relativamente piccoli che non vorrei che fosse nella mia home directory. Perché vuoi usare Git? Sto anche usando un sistema di versioning per sincronizzare i miei file di configurazione tra host e sono abbastanza contento di CVS perché è così semplice! Git è molto (troppo!) Potente per questo
Bananguin,

Risposte:


17

, c'è almeno un grosso trabocchetto quando si considera gitdi gestire una home directory di cui non ci si preoccupa subversion.

Git è sia avido che ricorsivo per impostazione predefinita .

Subversion ignorerà ingenuamente tutto ciò di cui non è a conoscenza e interrompe l'elaborazione delle cartelle verso l'alto o verso il basso dal checkout quando raggiunge uno di cui non è a conoscenza (o che appartiene a un repository diverso). Git, d'altra parte, continua a ricorrere in tutte le directory secondarie rendendo i checkout nidificati molto complicati a causa di problemi di spazio dei nomi. Poiché la tua directory home è probabilmente anche il luogo in cui fai il checkout e lavori su vari altri repository git, avere la tua directory home in git renderà quasi sicuramente la tua vita un casino impossibile.

A quanto pare, questo è il motivo principale per cui le persone eseguono il checkout dei propri file dot in una cartella isolata e quindi si collegano a esso. Tiene lontano git quando fai qualsiasi altra cosa in qualsiasi directory figlio della tua $HOME. Mentre questa è puramente una questione di preferenza se si controlla la propria casa in sovversione, diventa una questione di necessità se si utilizza git.

Tuttavia , esiste una soluzione alternativa. Git consente qualcosa chiamato "radice falsa" in cui tutti i macchinari del repository sono nascosti in una cartella alternativa che può essere fisicamente separata dalla directory di lavoro di checkout. Il risultato è che il toolkit git non verrà confuso: non vedrà nemmeno VEDERE il repository, solo la copia di lavoro. Impostando un paio di variabili d'ambiente puoi indicare a git dove trovare la merce per quei momenti in cui gestisci la tua home directory. Senza le variabili d'ambiente impostate nessuno è più saggio e la tua casa sembra il classico file-y self.

Per rendere questo trucco un po 'più fluido, ci sono alcuni ottimi strumenti là fuori. La mailing list di vcs-home sembra il punto di partenza ideale e la pagina about contiene un comodo riepilogo di howtos ed esperienze delle persone. Lungo la strada ci sono alcuni piccoli strumenti eleganti come vcsh , mr . Se vuoi mantenere la tua home directory direttamente in git, vcsh è quasi uno strumento indispensabile. Se finisci per dividere la tua directory home in diversi repository dietro le quinte, combinalo vcshcon mrun modo rapido e non molto sporco per gestirlo tutto in una volta.


2
ma perché non aggiungere semplicemente '*' al tuo file .gitignore? In questo modo git ignorerà tutto tranne i file che sono già nel repository e puoi aggiungere nuovi file con git add -f <file>.
ALiX,

@ALiX: Perché gli gitstrumenti ti considererebbero comunque lavorare sul repository dir home anche se ti trovassi in una sottodirectory che era un repository git separato per qualche progetto. Questa soluzione renderebbe la tua intera directory home off limits per tutte le altre git funzionanti.
Caleb,

5
ma un '*' nel tuo .gitignore significa che tutti i file che non sono nel tuo repository home-dir vengono ignorati. e quando dai un'occhiata a un nuovo repository git in qualche sottodirectory, tutto dovrebbe ancora funzionare come previsto (credo). Per quanto ne so, gli strumenti git cercheranno la prima directory .git mentre si spostano nella gerarchia di directory. Quindi, quando si lavora nella sottodirectory, verrà utilizzato il repository git corretto. Naturalmente, se stai usando le variabili d'ambiente di git, immagino che le cose potrebbero diventare confuse. Ma per il resto, non vedo perché non funzionerebbe.
ALiX

@ALiX ha ragione. I repository git nidificati sembrano funzionare correttamente fintanto che li gitignore nel repository principale. Mi chiedo quali siano gli svantaggi di questo approccio molto semplice, a parte i possibili problemi con le variabili d'ambiente di git.
evanrmurphy,

1
Ho sperimentato questo oggi. Penso /*che *funzioni meglio rispetto al fatto che ignora ancora tutto per impostazione predefinita ma rende molto più semplice l'aggiunta di directory. Invece di git add -fusare !modelli -prefixed come !/.vimrce !/.gitignore(per il file .gitignore stesso) per includere esplicitamente le cose nel repository.
evanrmurphy,

14

Non vorrei che la mia intera directory home fosse controllata nel controllo della versione semplicemente perché significa che ogni sottodirectory in cui vado avrebbe il contesto di controllo della versione della mia home directory. Comandi del genere git checkoutavrebbero un'azione effettiva in quel caso, causando problemi se avessi accidentalmente eseguito qualcosa dalla directory sbagliata, che fosse qualcosa di per gitsé o uno script che chiama git.

Inoltre, è più probabile che si aggiunga al repository qualcosa che non si desidera, il che non sarebbe stato un problema se tutto fosse stato archiviato, ma ora diventa un problema. Cosa succede se si aggiunge un file di chiave privata (forse per abitudine) e lo si spinge su Github?

Detto questo, penso che gli svantaggi primari non siano realmente tecnici: voglio solo salvarmi da me stesso.

Per quanto riguarda il collegamento simbolico: è possibile clonare il repository in una sottodirectory e disporre di uno script che aggiorni tutti i collegamenti simbolici che devono essere aggiornati. La quantità di manutenzione richiesta per questo script potrebbe comunque superare i vantaggi di averla; il collegamento simbolico potrebbe rivelarsi meno lavoro.

Con i collegamenti simbolici, puoi anche facilmente aggiungere aggiunte specifiche per la distribuzione (o persino specifiche per l'host) che vengono verificate in git. Lo script di aggiornamento del collegamento simbolico ignorerà i file destinati a piattaforme incompatibili o host diversi e aggiornerà solo quelli appropriati.

Qualcosa di simile a:

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

Personalmente: utilizzo i collegamenti simbolici e non ricollego alle directory; solo i file all'interno. Questo mi dà una certa flessibilità per apportare modifiche al sito locale in quelle directory (es. Aggiungere / rimuovere file). Configurare il mio account su un nuovo sistema è noioso perché devo ricreare manualmente tutti i collegamenti simbolici.


Tutti i gitcomandi che eseguo sarebbero o per la home directory stessa o verrebbero seppelliti almeno in una directory NON impegnata. L'uso svndell'isolamento di questa cartella è abbastanza efficace e non mi ha causato problemi in un decennio. Il tuo primo paragrafo indica qualcos'altro. È davvero una differenza nel modo in cui gitfunziona?
Caleb,

Anche le mie configurazioni e i miei script hanno già una logica condizionale per diversi host e piattaforme integrate, quindi usare uno script per impostare collegamenti diversi in quanto i condizionali non sembra molto utile rispetto gitai rami facili da gestire. C'è ancora qualcosa che mi manca o scenderà alla preferenza?
Caleb,

3
L'isolamento di una cartella in realtà non isola git- non ne sono sicuro svn- ma, per esempio, git init foo && mkdir -p foo/bar/baz/spam && cd foo/bar/baz/spam && git status(o altri comandi git) mostrano che sei ancora nel foocontesto del controllo della versione.
sig.

Config e script: non tutti i dotfile supportano i condizionali, motivo per cui ho suggerito un approccio alternativo. Queste sono tutte ragioni per cui penso che la gente preferisca non usare il controllo di versione per $HOME- e il versioning non è davvero utile per dotfiles imo - ma alla fine è la tua home directory, quindi se preferisci usare git e questi non sono problemi per te, Fallo!
sig.

Grazie per le informazioni. In realtà il tuo commento su git che non consente l'isolamento è il bit più utile. Potresti lavorare in modo prominente nella tua risposta. Subversion si comporta in modo molto diverso su quel punto ed è significativo per questo caso d'uso.
Caleb,

6

Per dare un altro punto di vista: ho il mio $ HOME in git da qualche tempo e non ho trovato alcun inconveniente. Ovviamente non sincronizzo questo repository git su github; Uso un servizio con repository privati. Inoltre non metto alcun file multimediale o download o pacchetto sotto controllo git.

  • git status è una specie di lista di controllo "da fare, da pulire".

  • Ho un ~/tmpper cose temporanee, che è gitignored.

  • Mi piace vedere in git statustutto ciò che un software installato di recente osa aggiungere al mio $ HOME e spesso eliminare questi file o persino disinstallare i colpevoli.

  • Aggiungo manualmente i file e le directory locali veramente utili a .gitignore, che ha un vantaggio "sai cosa fai quando installi le cose".

  • Se creo una nuova macchina virtuale o installo un nuovo PC, clonerò la mia casa remota su $ HOME e avrò immediatamente tutto ciò di cui ho bisogno.

  • Cose come vundle per i plugin vim non sono più necessarie.

Non mi piace la complessità. Quando modifico qualsiasi file rc, lo faccio, commetto e spingo. Quindi, come riflesso, vado a inserire $ HOME a giorni alterni e ho sempre l'ultima configurazione. È così semplice

Macchine attualmente sotto questo regime: laptop domestici, PC di lavoro, VM di lavoro, oltre a 3 o 4 server remoti.


Hai altri checkout git nidificati all'interno della tua casa?
Caleb,

No, ho messo altre cose in una directory / work e non clonare piccoli strumenti come i pugili di Vim.
gb.

1
Ho un lavoro all'interno di ~ / Sites e faccio anche questo approccio, non ci sono problemi con i repository git nidificati
philfreo,

1
Sto usando questa configurazione da un po '. Ho un 'alias sq = git status -uno' e non mi preoccupo molto di .gitignore (ogni tanto guardo tutte le cruft e poi dico "meh"). Non ho mai avuto problemi con i repository git nidificati. Ho un server privato in cui ho fatto un git init --barepush su over ssh (anche se non inserisco le password nel repository, ho i miei file di note lì).
unhammer

5

Ho provato entrambi, e alla fine ho preferito l' approccio symlink :

  • Scopri ovunque
  • make install
  • Disconnettersi e accedere nuovamente per caricare le impostazioni X.

svantaggi:

  • Devi spostare i file nel repository prima di aggiungerli
  • Devono mantenere l' elenco dei collegamenti simbolici nel Makefile

vantaggi:

  • Non c'è bisogno di un enorme .gitignore(ho 133 dotfile nella ~mia umile scatola Ubuntu)
  • Può tenere gli script di manutenzione e altre ~cose -related (come Makefilee cleanup.sh) fuori strada
  • La versione può controllare le impostazioni personali e pubbliche separatamente

restrizioni:

  • A differenza di @mrb, creo solo collegamenti simbolici in ~. Ciò semplifica il collegamento simbolico e rende banale notare nuovi file, ad esempio ~/.vim, a spese di una .gitignoremanutenzione molto rara .

Gli ultimi due vantaggi hanno ribaltato le scale nel mio caso: non voglio ingombrare la home directory e voglio mantenere chiaramente separati i contenuti privati ​​e pubblici.

L'unica applicazione che conosco che ha (o almeno ha avuto) problemi con la gestione dei collegamenti simbolici è stata Pidgin - Continuava a sovrascrivere i miei collegamenti simbolici con file ordinari.


Grazie per il tuo contributo sui pro e contro di ogni approccio. Nel mio follow-up ho scoperto che esiste un terzo approccio che potrebbe trarre il meglio da entrambi i mondi se stai bene impostando il cablaggio extra per iniziare.
Caleb,

3

Eccone uno: se provi a fare git rebase -i --roote hai effettuato il check-in .gitconfignel primo commit nel repository, git rimuoverà temporaneamente il .gitconfigfile, il che a sua volta renderà impossibile completare l'operazione di rebase poiché richiede il tuo nome e la tua email quello, che sono memorizzati in quel file.

Puoi configurarli di nuovo e farlo di nuovo git rebase --continue, ma dopo che l'ho fatto e ho finito l'operazione di rebase, il mio repository git aveva ottenuto un commit vuoto senza un messaggio di commit prima del commit che era precedentemente il primo commit nel repository, che non conosco come sbarazzarsi di.

Non so cosa succede se lo fai git rebase -i <commit>invece, e .gitconfigviene registrato insieme a qualsiasi commit dopo <commit>.

Forse la soluzione più semplice è astenersi dall'aggiungere .gitconfigal repository e invece elencarlo .gitignore.


2

Ecco come lo faccio:

  1. installare un Linux pulito (non necessario, ma rende la vita più piacevole al passaggio 4)
  2. installa etckeeper
  3. corri git inita casa tua
  4. crea .gitignore e aggiungi tutto ciò che sembra non ti interessi o che potrebbe cambiare molto. Assicurati di aggiungere cose come *.cache, *.lockecc. Non ti consiglio di aggiungere/*perché non verrai avvisato automaticamente quando qualcosa di nuovo verrà aggiunto a casa tua. Si tratta di un approccio basato su una lista nera rispetto a un elenco di whitelist, in cui fondamentalmente voglio mantenere la mia configurazione per tutto il software ad eccezione delle cose volatili e di alcuni software che non mi interessano. Quando in seguito unisci, migra o confronti i sistemi, essere in grado di diffondere tutto è abbastanza utile. Puoi configurare i tuoi nuovi sistemi molto più velocemente che se avessi solo .bashrc e qualche altro dotfile archiviato. In questo modo manterrai la configurazione che altrimenti potresti impostare tramite la GUI e non sarai consapevole di quali file dot memorizzano le impostazioni. (Se si scopre che hai eseguito il commit di file volatili, puoi comunque dire a git di assumere invariato)
  5. correre etckeeper init -d /home/username
  6. correre git commit -d /home/username
  7. impostare gli alias nella shell per rendere più gradevole la riga di comando, ad esempio homekeeper checkout

La ragione per usare etckeeper è che memorizzerà metadati come permessi per i tuoi file (piuttosto importante per certe cose come le chiavi ssh). Ora dovresti avere un hook pre-commit che salverà automaticamente i metadati. Non sono così sicuro del post-checkout. Probabilmente dovresti usare etckeeper checkout xxx -d /home/userLo esaminerò un po 'di più ed elaborerò questa risposta.


-1

Il mio problema principale con l'utilizzo di Git nella home directory è che Git non memorizza gli attributi di file come permessi dei file e timestamp. Per me è importante sapere quando sono stati creati determinati file, che potrebbe o meno essere il tuo caso. Inoltre, perdere i permessi su file e directory come .sshè problematico. Comprendo che hai intenzione di tenerti .sshfuori da Git, ma ci saranno altri posti in cui potrebbero essere importanti le autorizzazioni (come i backup di siti Web non compressi).


Questo è fuorviante se non effettivamente sbagliato. Git per impostazione predefinita conserva molti attributi di file, comprese le autorizzazioni. Sono stato .sshin git per qualche tempo senza problemi, le autorizzazioni di sicurezza adeguate sono conservate. Quello che non fa nella configurazione di base è preservare la proprietà o i timestamp; tuttavia, se uno di questi è un problema per un caso d'uso specifico, ci sono plugin che possono rendere la gestione di queste proprietà aggiuntive parte del normale flusso di lavoro (consultare metastore o git-cache-meta).
Caleb,

Anche se non li memorizza, come è peggio che avere una home directory non in vcs? git non sovrascriverà attivamente mtimes a meno che non gli venga chiesto di modificare un file.
poolie,

-1

Una soluzione basata su git è particolarmente utile se è necessario distribuire i file su macchine diverse, e ancora di più se si hanno parti comuni a tutte le macchine e parti specifiche di alcune macchine. Puoi creare più repository e utilizzare uno strumento come multigit o vcsh per clonarli nella stessa directory (la tua home directory in questo caso).


Grazie, ma forse hai perso la domanda. Sono ben consapevole degli usi per questo (quindi perché volevo farlo in primo luogo), questa domanda era su eventuali insidie ​​che qualcuno di nuovo a fare questo con Git (come lo ero quando l'ho chiesto) potrebbe non esserne consapevole . Questo non sembra rispondere affatto a questa domanda.
Caleb,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.