Il codice temporaneo deve essere messo sotto controllo della versione e come?


29

Ecco alcuni esempi di codice temporaneo / locale. È necessario per lavorare con la base di codice, ma sarebbe dannoso farne parte:

  1. File di progetto. Potrebbe essere necessario modificare i percorsi per riflettere il layout sul PC corrente.
  2. Makefiles. Ad esempio, potrebbe essere necessario disattivare l'ottimizzazione durante il debug, ma non per il server CI.
  3. Trucchi brutti e sporchi. Ad esempio return 7nel mezzo di una funzione, al fine di testare qualcosa, a seconda della funzione, e sospettato di infrangere al valore di 7. O 7 è il codice del pulsante non ancora implementato, che sto implementando e che dovrò testare la vita del mio ramo.

Ho provato a mantenere quelli in un git commit che rifaccio sempre in cima prima di spingere verso il repository e quindi spingere HEAD~. Questo è abbastanza scomodo e non funziona con svn. Lo stashing mi spaventa ancora di più - "mi sono ricordato di fare pop dopo aver spinto ??".

Mantenere il codice fuori controllo della versione introduce rumori spiacevoli ogni volta che viene assemblato un commit, inoltre potrebbe essere accidentalmente introdotto in un commit venerdì sera.

Quale sarebbe una soluzione sana per tale codice da buttare via?


Questo codice temporaneo dovrà essere aggiornato dal progetto originale durante il suo periodo di utilizzo temporaneo?
JeffO,

@JeffO, non sono sicuro che ti capisca. Gli snippet sporchi sono piccoli e raramente si scontrano con il codice in fase di sviluppo. Tuttavia, @ Blrfl, è molto pericoloso per loro essere coinvolti nel mainstream. Immaginate una return 7nel trunkVenerdì sera, dopo un'unione schifoso nella calura estiva.
Vorac,

@Vorac: ecco a cosa servono le revisioni e i test del codice! Posso mostrarti molto peggio di così - codice che non funziona anche se a prima vista sembrava buono. Return 7.. se solo fossero tutti così evidenti!
gbjbaanb,

@Vorac: era più un commento filosofico che altro.
Blrfl,

2
C'è un modo per dire in quale ambiente ti trovi? Ad esempio, puoi impostarlo per eseguire il codice se rileva che sei nell'ambiente dev, ma non in val / prod. In questo modo non è necessario aggiungere / rimuovere costantemente il codice segnaposto durante il commit.
Saggio,

Risposte:


46

Tutto il codice è temporaneo. Quando apporterò delle modifiche, introdurrò di tanto in tanto dei segnaposto: quell'icona che ho disegnato aspettando quella vera dal designer, la funzione che conosco chiamerà la biblioteca che il mio collega sta scrivendo e non ha ancora terminato (o avviato), la registrazione aggiuntiva che verrà rimossa o altrimenti subordinata, i bug che risolverò una volta che sono stati notati dal team di test, ecc.

Quindi controlla tutto. Usa un ramo di funzionalità per tutto il tuo sviluppo, quindi puoi unire la versione finale al trunk e nessuno dovrà sapere quali hack, bodges e correzioni hai fatto durante il tuo ciclo di sviluppo, dovranno solo vedi la versione finale. Ma se ti sei impegnato regolarmente nella tua filiale, sarai in grado di vedere le cose che valevano la pena tenere se una giornata andasse in modo spettacolare sbagliato o continuassi a scrivere codice dopo l'ora di pranzo nel pub.

Il controllo della versione non è un repository di artefatti o un sistema di archiviazione dei documenti. Si tratta di tenere la storia dei cambiamenti. Attacca tutto quello che ti piace perché un giorno potresti voler vedere di cosa si trattava, e questi sono i giorni in cui ti rendi conto di cosa tratta veramente il tuo SCM.

PS. I file veramente temporanei (ad es. .Obj o manufatti di compilazione) non hanno posto nel tuo SCM. Queste sono cose che non hanno alcun valore per nessuno. Puoi dire cosa sono: se li elimini non ti dispiace o noti che non ci sono più.


5
Concordato. La ramificazione è la strada da percorrere. Crea un ramo, fai quello che vuoi lì e unisci il codice finito quando è completo. La testa dovrebbe essere trattata come una versione di rilascio che il client può scaricare e utilizzare in qualsiasi momento.
Cameron McKay,

Ottima risposta, da quello che ho visto, GIT ha introdotto il versioning locale in parte per aiutare le persone che vogliono avere un registro del loro lavoro locale. Il codice temporaneo dovrebbe rimanere nelle macchine degli sviluppatori fino a quando non sarà pronto per impegnarle nel repository
Informato

2
Ho intenzione di stampare un grande poster che dice "TUTTO IL CODICE È TEMPORANEO" e incollarlo sul muro. Probabilmente nel Comic Sans.
Bob Tway,

2
@MattThrower tra virgolette, proveniente dalle labbra di Clippy?
gbjbaanb,

1
Tuttavia, il codice non in esecuzione o il codice che non viene compilato non deve essere sottoposto al controllo della versione.
Tulains Córdova,

17

File di progetto. Potrebbe essere necessario modificare i percorsi per riflettere il layout sul PC corrente.

Per i file di progetto, la strategia migliore è quando è possibile generare il file di progetto tramite uno script. Aggiungi il file di progetto effettivo al tuo ignore e semplicemente rigenerare il file di progetto, se necessario. Ad esempio, nei progetti Java, uso Gradle che può generare un progetto eclissi.

Makefiles. Ad esempio, potrebbe essere necessario disattivare l'ottimizzazione durante il debug, ma non per il server CI.

Dovresti essere in grado di passare dalla modalità di ottimizzazione a quella di debug senza modificare il tuo Makefile. Utilizzare invece un flag della riga di comando, una variabile di ambiente o un file separato non presente nel repository per controllarlo.

Trucchi brutti e sporchi. Ad esempio, restituire 7 nel mezzo di una funzione, al fine di testare qualcosa, a seconda della funzione, e si sospetta che si rompa al valore di 7. Oppure 7 è il codice del pulsante non ancora implementato, che sto implementando e che devo implementare test per tutta la vita del mio ramo.

Non riesci a scrivere un test che induca il caso sospetto di fallimento?

Nella maggior parte dei casi, dovresti essere in grado di regolare il flusso di lavoro in modo da non apportare queste modifiche ai file nel tuo repository. Quei file che vengono cambiati localmente dovrebbero essere aggiunti al meccanismo ignore del tuo progetto e non essere nel repository. In alcuni casi, eseguirai comunque modifiche temporanee che non desideri inserire nel repository. Per quelli, aggiungi una sequenza speciale come: XXX, e aggiungi un hook pre-commit che rifiuta i commit che ancora lo contengono.


A volte ho bisogno di fare piccoli hack su un file, mentre allo stesso tempo scrivo il codice di produzione nello stesso file. svnnon supporta il commit parziale dei file, quindi è una seccatura in quelle situazioni. La maggior parte dei miei colleghi ha appena commesso gli hack al ramo e li ha eliminati alla fusione trunk. Tuttavia, mi distraggo (e commetto errori durante le fusioni, e le fusioni in svn sono sacre e immutabili) molto più facili e quindi questa domanda.
Vorac,

@Vorac, esaminerei gli hook di sovversione che ti permetteranno di eseguire script durante il commit. Dovrebbe essere possibile scrivere uno script che rifiuta un'unione se contiene XXX o qualcosa del genere.
Winston Ewert,

1
@Vorac: se si utilizza TortoiseSVN, è possibile utilizzare Restore After Commit su un file per eseguire il commit parzialmente, utilizzare uno strumento diff o l'editor per rimuovere temporaneamente i blocchi che non si desidera eseguire il commit, quindi eseguire il commit. Tortoise ripristinerà il file completo subito dopo e puoi impegnare i blocchi rimanenti se pronto. Ciò potrebbe essere fatto eseguendo un backup rapido del file e ripristinandolo dopo il primo commit.
leokhorn,

5

Il controllo della versione deve contenere il codice e la configurazione necessari per compilare l'applicazione.

Ciò significa che:

  • Le cose temporanee che sono state introdotte per un breve periodo di tempo (il tempo necessario per individuare la posizione di un bug o per sperimentare una funzionalità di una lingua, ad esempio) non dovrebbero essere in un controllo di versione: tenerlo fino a quando non è necessario quindi rimuoverlo semplicemente quando si esegue il commit .

  • I file locali che sono propri di un determinato computer possono essere conservati in un ramo.

    Eviterei di tenerli solo a livello locale, poiché è troppo doloroso ripetere tutto questo quando il tuo laptop viene rubato o un virus ti costringe a reinstallare il sistema operativo (e, a proposito, scopri che l'ultimo backup è stato eseguito due anni fa) .

    D'altra parte, fai attenzione con la struttura dei file: la configurazione locale è OK, fino a quando non diventa travolgente, e ti costringe a fare una singola modifica in ogni file di ciascuno dei 42 sviluppatori che partecipano al progetto.

    Controlla l'opportunità di rimuovere le particolarità tra le macchine. Può significare:

    • Dare accesso a un server SQL dev per sostituire le istanze locali sui computer degli sviluppatori,

    • Utilizzando servizi di distribuzione di pacchetti come Pypi o npm per i pacchetti pubblici e le loro controparti private per i pacchetti interni,

    • Chiedi ai membri del team di installare le stesse versioni di software,

    • Rendi gli aggiornamenti del software il più trasparenti possibile,

    • O rendere possibile distribuire il sistema operativo e il software necessario su una macchina in un solo clic (più il tempo per ogni sviluppatore di installare il suo Vim preferito rispetto a Emacs, Chrome vs Firefox, ecc.)

Così:

File di progetto. Potrebbe essere necessario modificare i percorsi per riflettere il layout sul PC corrente.

Perché non usare lo stesso layout su tutti i PC? I percorsi all'interno del progetto dovrebbero essere relativi al file di progetto, il che significa che non importa dove si trova il progetto. Le versioni di software e librerie sono meglio essere le stesse per evitare bug criptici che compaiono solo su alcune macchine e che sono impossibili da riprodurre per altri membri del team.

Esempio:

In un progetto creato con Visual Studio, è possibile trovare:

  • I file stessi. I percorsi sono relativi, non importa se sulla mia macchina, il progetto si trova H:\Development\Hello World Project\mentre altri membri del team hanno verificato il progetto C:\Work\HelloWorld\.

  • Le dipendenze, ovvero librerie di terze parti e interne. Entrambi i tipi dovrebbero essere gestiti da NuGet che rende obsolete tutte le discussioni relative ai conflitti. Se non hai la stessa versione della mia libreria, chiedi a NuGet di aggiornare le dipendenze. Semplice come quello (quando funziona bene, che non è sempre il caso).

    Si noti che è fondamentale mantenere anche le librerie interne in un NuGet privato. Avere un mucchio di librerie archiviate in una cartella condivisa o inviate via e-mail a un team porta all'anarchia e ai server CI depressivi.

  • Le impostazioni. È fondamentale che il team condivida le stesse impostazioni. Se metà del team decide di considerare gli avvisi come errori e metà del team mantiene gli avvisi così come sono, i membri della prima parte del team impiegheranno il loro tempo a rimuovere gli avvisi generati dagli sviluppatori dalla seconda parte del team.

  • Le impostazioni relative alle utility. Questi sono difficili, perché alcuni membri del team potrebbero aver installato alcuni programmi di utilità, mentre altri no.

    Si consiglia vivamente di installare lo stesso set di strumenti. Se alcuni programmatori vogliono usare StyleCop, ma altri no, il team non farà il lavoro. Se alcuni usano contratti di codice ma altri no, avranno gli stessi problemi.

Makefiles. Ad esempio, potrebbe essere necessario disattivare l'ottimizzazione durante il debug, ma non per il server CI.

Mantieni più makefile nel controllo versione. Non è insolito creare una versione di debug anche sul server CI e inviarla a un client che presenta un bug difficile.

Trucchi brutti e sporchi. Ad esempio, restituire 7 nel mezzo di una funzione, al fine di testare qualcosa, a seconda della funzione, e si sospetta che si interrompa al valore di 7.

Vorrei evitare tale codice in primo luogo. Per testare qualcosa, usa i test unitari. Se ci vogliono davvero alcuni secondi per scambiare un po 'di codice con lo scopo di eseguire il debug , allora fallo, ma rimuoverai comunque questo codice in pochi minuti, quindi non è necessario impegnarlo.

Mentre lo descrivi, dovresti scrivere un test. Ad esempio, se vuoi essere sicuro che:

class TemperatureConverter
{
    public int CelsiusToFahrenheit(int temperature)
    {
        ...
    }
}

genera un'eccezione quando temperatureè inferiore a AbsoluteZerocostante, non si dovrebbe giocare con il codice stesso. Invece, crea un test unitario che:

  • autocompensare il tuo codice,
  • aumentare l'affidabilità del tuo codice,
  • assicurarsi che i manutentori possano fare affidamento sul test di regressione durante la modifica del metodo sopra riportato,
  • servire ad altri sviluppatori del tuo team che potrebbero aver bisogno di fare lo stesso test.

2
Sfortunatamente non ho esperienza con i test di scrittura. La piattaforma attuale prevede una CPU ARM, che configura alcuni componenti hardware in risposta ai comandi USB. Non ci sono feedback dall'hardware alla CPU.
Vorac,

2
Se il codice temporaneo può avere effetti persistenti, anche se il codice potrebbe non essere mai necessario una volta che tali effetti sono stati raggiunti, penso che mantenere il codice da qualche parte sarebbe saggio nel caso in cui ci siano dubbi sul fatto che gli effetti siano stati raggiunti correttamente. Ad esempio, se un po 'il formato del database per un prodotto viene modificato mentre è in fase di sviluppo, si potrebbe scrivere una rapida utility una tantum per cambiare il formato. L'utilità potrebbe non essere mai necessaria dopo la conversione del solo database esistente nel vecchio formato, ma potrebbe essere necessario esaminare come è stata eseguita la conversione.
supercat

Per i file di progetto di Visual Studio, ho avuto buone esperienze nel generarli con CMake, il che consente una certa flessibilità su come si trovano esattamente il codice sorgente e il codice compilato nel file system. Quindi controllo la versione dei file di input di CMake anziché dei file di progetto VS. Ma questo è ancora conforme al tuo detto, "Il controllo della versione dovrebbe contenere il codice e la configurazione necessari per compilare l'applicazione". Sono completamente d'accordo!
David K,

Con VS, a volte devi fare attenzione per assicurarti di non avere percorsi assoluti che si intrufolano. Ho riscontrato più di alcuni problemi con riferimenti bloccati durante l'aggiornamento a Win64 e il passaggio daC:\Program Files\...C:\Program Files (x86)\...
Dan Neely,

@DanNeely: ecco perché le librerie di terze parti dovrebbero essere gestite da NuGet.
Arseni Mourzenko,

2

Usiamo i @@commenti nel codice per indicare qualcosa che non è del tutto pronto, a scopo di test, ecc.

In questo modo possiamo impegnarci, i colleghi non devono aspettare troppo a lungo per la sincronizzazione e possono vedere dove ci sono ancora lavori in corso (ad esempio capire perché una parte non funziona ancora completamente).

Facciamo una ricerca globale per @@prevenire eventuali "residui" prima di entrare nelle fasi finali del beta test ecc.

Usando quella disciplina, non vedo alcun motivo per non limitarsi a commettere. In questo modo, non abbiamo rami separati e solo un 'protocollo' aggiuntivo da seguire.


Come ulteriore vantaggio, queste cose da fare (di solito piccole cose) sono sempre nel codice. Lo sviluppatore che ci sta lavorando può superarli rapidamente e non è necessario mantenere elenchi separati.
Sai come va lo sviluppo: stai lavorando in un posto ma stai costantemente usando la tua mente come una pila (" Dovrei cambiarlo laggiù quando avrò finito qui "). Basta annotare una breve @@osservazione per evitare l'overflow dello stack.

Uso anche @@nameper indicare i problemi che devo discutere con "nome".


1

2 soluzioni HAMSTER:

  • Puoi usare un hook pre-commit per controllare il tuo codice per qualche parola chiave insolita come HAMSTER. Non lasciare che le persone commettano codice che è stato HAMSTER e utilizzalo ogni volta che esegui hack sporchi.

  • Un'altra opzione, ad esempio in C, è usare #ifdef HAMSTER, quindi il codice verrà eseguito sul tuo computer solo dove hai un flag di compilatore HAMSTER.


0

Mettiamo tutto sotto il controllo del codice sorgente necessario per costruire e testare i binari attuali e capire perché le cose sono state progettate / implementate / testate così come sono.

Ciò vale anche per i picchi http://www.extremeprogramming.org/rules/spike.html , come quelli che hai descritto; li ospitiamo in un sottoalbero diverso.


0

Ecco alcune soluzioni che utilizzo occasionalmente in varie circostanze e che potresti considerare utili quando applicate ai tuoi flussi di lavoro:

  1. Rami leggeri che possono essere schiacciati.

    Git è eccezionale in questo. Hack su un ramo, fai un sacco di commit, quindi rifa la cronologia o schiaccia la tua cronologia per eliminare il rumore.

  2. Utilizzare una coda di patch in cima a SCM.

    Mi trovo spesso ad usare StGit per far galleggiare le patch all'inizio del mio ramo attuale. Quando ho finito con il ramo, posso rimuoverli dallo stack prima di unirli, schiacciarli o ridisegnarli, oppure posso unirli nella base di codice principale se voglio tenerli in giro.

  3. Usa RCS come un SCM "fuori banda" per piccoli esperimenti.

    A volte vuoi solo controllare un file in corso in modo usa e getta, senza dover ripulire la cronologia in seguito. In genere uso RCS per questo all'interno di Git o SVN. Dico a Git di ignorare gli artefatti di RCS, di controllare il mio lavoro in corso in RCS e quando mi piacciono i risultati lancio semplicemente i *,vfile o l'intera directory di RCS. Non eseguire git clean -fdxo simili fino a quando non hai affidato il tuo lavoro al tuo "vero" SCM, o te ne pentirai.

  4. Stash nominati.

    Un altro Git-ism, ma utile: git stash save --include-untracked <some-cool-title>può essere utile in un pizzico. È possibile salvare, visualizzare e applicare i lavori in corso in questo modo e visualizzare i vari punti di controllo tramite git stash listo git reflog --all. Altri SCM possono avere caratteristiche simili, ma il tuo chilometraggio può variare molto con questo.


0

Parte di quel codice temporaneo è in realtà solo una manifestazione di metodologia impropria di costruzione / test / sviluppo e, si spera, la loro esistenza motiverà il miglioramento futuro.

Almeno su git, dovresti essere libero di giocare con qualsiasi numero di rami di funzionalità finché non sono pronti per essere uniti in master / trunk.

Il controllo della versione dovrebbe aiutarti , e molto spesso apprezzo le intuizioni dal modo in cui gli errori (o forse solo decisioni meno intuitive) sono stati fatti in passato e prendono decisioni più informate per il presente.


0

Credo che alcuni sistemi emetteranno avvisi nel vedere TODO in un commento, quindi

// TODO: remove this hack.

potrebbe essere tutto ciò che è necessario se riesci a trovare un'opzione rilevante in qualche parte del tuo ambiente di sviluppo, o semplicemente inserisci una sorta di comando grep nel tuo file di build. Potrebbe anche essere possibile organizzare // HACKo raccogliere qualsiasi stringa arbitraria.

È più semplice che organizzare il tuo codice in un modo particolare e sperare che le persone si ricordino di non usarlo. Inoltre, è più sicuro seguire i consigli di @gbjbaanb (se puoi assicurarti che tutti vedano gli avvisi!).

Attacca tutto quello che ti piace perché un giorno potresti voler vedere di cosa si trattava, e questi sono i giorni in cui ti rendi conto di cosa tratta veramente il tuo SCM.


0

Non è mai dannoso mettere il codice nel controllo del codice sorgente.

Ogni singolo degli elementi che menzioni dovrebbe essere nel controllo del codice sorgente.

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.