Quando un controllo di versione è troppo grande? [chiuso]

62

Ho sentito dire in diversi punti "Non commettere grandi commit", ma non ho mai realmente capito che cosa è un "grande" commit. È grande se lavori su un mucchio di file anche se ci sono in relazione? In quante parti di un progetto dovresti lavorare contemporaneamente?

Per me, ho difficoltà a cercare di fare "piccoli commit" poiché dimentico o creo qualcosa che crea qualcos'altro che crea qualcos'altro. Finisci con cose del genere:

Made custom outgoing queue

Bot
-New field msgQueue which is nothing more than a SingleThreadExecutor
-sendMsg blocks until message is sent, and adds wait between when messages get
sent
-adminExist calls updated (see controller)
-Removed calles to sendMessage

Controller
-New field msgWait denotes time to wait between messages
-Starting of service plugins moved to reloadPlugins
-adminExists moved from Server because of Global admins. Checks at the channel,
server, and global level

Admin
-New methods getServer and getChannel that get the appropiate object Admin
belongs to

BotEvent
-toString() also show's extra and extra1

Channel
-channel field renamed to name
-Fixed typo in channel(int)

Server
-Moved adminExists to Controller

PluginExecutor
-Minor testing added, will be removed later

JS Plugins
-Updated to framework changes
-Replaced InstanceTracker.getController() with Controller.instance
-VLC talk now in own file

Various NB project updates and changes

---

Affected files
Modify  /trunk/Quackbot-Core/dist/Quackbot-Core.jar
Modify  /trunk/Quackbot-Core/dist/README.TXT
Modify  /trunk/Quackbot-Core/nbproject/private/private.properties
Modify  /trunk/Quackbot-Core/nbproject/private/private.xml
Modify  /trunk/Quackbot-Core/src/Quackbot/Bot.java
Modify  /trunk/Quackbot-Core/src/Quackbot/Controller.java
Modify  /trunk/Quackbot-Core/src/Quackbot/PluginExecutor.java
Modify  /trunk/Quackbot-Core/src/Quackbot/info/Admin.java
Modify  /trunk/Quackbot-Core/src/Quackbot/info/BotEvent.java
Modify  /trunk/Quackbot-Core/src/Quackbot/info/Channel.java
Modify  /trunk/Quackbot-Core/src/Quackbot/info/Server.java
Modify  /trunk/Quackbot-GUI/dist/Quackbot-GUI.jar
Modify  /trunk/Quackbot-GUI/dist/README.TXT
Modify  /trunk/Quackbot-GUI/dist/lib/Quackbot-Core.jar
Modify  /trunk/Quackbot-GUI/nbproject/private/private.properties
Modify  /trunk/Quackbot-GUI/nbproject/private/private.xml
Modify  /trunk/Quackbot-GUI/src/Quackbot/GUI.java
Modify  /trunk/Quackbot-GUI/src/Quackbot/log/ControlAppender.java
Delete  /trunk/Quackbot-GUI/src/Quackbot/log/WriteOutput.java
Modify  /trunk/Quackbot-Impl/dist/Quackbot-Impl.jar
Modify  /trunk/Quackbot-Impl/dist/README.TXT
Modify  /trunk/Quackbot-Impl/dist/lib/Quackbot-Core.jar
Modify  /trunk/Quackbot-Impl/dist/lib/Quackbot-GUI.jar
Modify  /trunk/Quackbot-Impl/dist/lib/Quackbot-Plugins.jar
Modify  /trunk/Quackbot-Impl/lib/javarebel.stats
Add /trunk/Quackbot-Impl/lib/jrebel.info
Modify  /trunk/Quackbot-Impl/nbproject/private/private.properties
Modify  /trunk/Quackbot-Impl/nbproject/private/private.xml
Modify  /trunk/Quackbot-Impl/nbproject/project.properties
Modify  /trunk/Quackbot-Impl/plugins/CMDs/Admin/reload.js
Add /trunk/Quackbot-Impl/plugins/CMDs/Operator/hostBan
Modify  /trunk/Quackbot-Impl/plugins/CMDs/Operator/mute.js
Modify  /trunk/Quackbot-Impl/plugins/CMDs/lyokofreak/curPlaying.js
Modify  /trunk/Quackbot-Impl/plugins/CMDs/lyokofreak/lfautomode.js
Modify  /trunk/Quackbot-Impl/plugins/listeners/onJoin.js
Modify  /trunk/Quackbot-Impl/plugins/listeners/onQuit.js
Modify  /trunk/Quackbot-Impl/plugins/testCase.js
Add /trunk/Quackbot-Impl/plugins/utils/whatsPlaying.js
Modify  /trunk/Quackbot-Impl/src/Quackbot/impl/SandBox.java
Add /trunk/Quackbot-Impl/vlc_http
Add /trunk/Quackbot-Impl/vlc_http/current.html
Modify  /trunk/Quackbot-Plugins/dist/Quackbot-Plugins.jar
Modify  /trunk/Quackbot-Plugins/dist/README.TXT
Modify  /trunk/Quackbot-Plugins/dist/lib/Quackbot-Core.jar
Modify  /trunk/Quackbot-Plugins/nbproject/private/private.properties
Modify  /trunk/Quackbot-Plugins/nbproject/private/private.xml
Modify  /trunk/Quackbot-Plugins/src/Quackbot/plugins/JSPlugin.java
Add /trunk/Quackbot-Plugins/vlc_http
Add /trunk/global-lib/jrebel.jar

Sì ....

Quindi per domande:

  • Quali sono alcuni fattori per quando un commit diventa troppo grande ( cose non ovvie )?
  • Come puoi evitare tali commit? Si prega di fornire specifiche
  • Che dire di quando sei alle prime fasi dello sviluppo quando le cose si muovono velocemente? I commit enormi sono ancora a posto?
posta TheLQ 12.10.2010 - 03:47
fonte

19 risposte

66

To me, I have trouble trying to make "small commits" since I forget or create something that creates something else that creates something else.

Questo è un problema. Sembra che tu abbia bisogno di imparare per suddividere il tuo lavoro in blocchi più piccoli e più gestibili.

Il problema con i commit di grandi dimensioni sono:

  • In un progetto a più persone, una maggiore possibilità che i tuoi commit causino conflitti da risolvere per altri sviluppatori.
  • È più difficile descrivere con precisione ciò che è stato fatto nei messaggi di registro.
  • È più difficile rintracciare l'ordine in cui sono state apportate modifiche e quindi comprendere la causa dei problemi.
  • Aumenta la probabilità di perdere un sacco di lavoro non impegnativo.

A volte grandi commit sono inevitabili; per esempio. se devi cambiare una API importante. Ma di solito non è così. E se ti trovi in questa situazione, è probabilmente una buona idea creare una filiale e fare il tuo lavoro lì dentro ... con un sacco di piccoli commit ... e reintegrarti quando hai finito.

(Un altro caso è quando si esegue un'importazione iniziale, ma NON è problematico dal punto di vista dei problemi sopra elencati.)

    
risposta data 10.10.2010 - 16:30
fonte
38

Il principio di responsabilità singola.

Ogni commit del controllo sorgente dovrebbe servire solo a uno scopo. Se devi inserire la parola "e" o "anche" nel tuo riepilogo, devi dividerlo.

È molto comune finire con un sacco di modifiche indipendenti o semi-correlate nella tua copia di lavoro. Questo è chiamato il "problema della copia di lavoro intricata" ed è davvero molto difficile da evitare anche per gli sviluppatori disciplinati. Tuttavia, Git e Mercurial offrono entrambi gli strumenti per risolverlo - git add -p o selezione del blocco e code Mercurial in TortoiseHg rispettivamente.

    
risposta data 20.01.2011 - 00:23
fonte
25

Immagina che il cliente abbia chiesto che venga apportata una particolare modifica, ad esempio per aggiungere una regola secondo cui qualcosa o un'altra non può essere eseguita entro due giorni dalla data "qualunque". Quindi, dopo aver apportato il cambiamento, cambiano idea. Dovrai eseguire il rollback del commit. Se è tutto sommato da alcune cose riguardo al cambiare l'ordinamento dei rapporti non correlati, la tua vita è infelice.

Un oggetto di lavoro, un changeset. Una richiesta dal client, un changeset. Una cosa su cui potresti cambiare idea, un changeset. A volte ciò significa che è una singola riga di codice. A volte sono dieci diversi file incluso lo schema del database. Va bene.

    
risposta data 10.10.2010 - 21:11
fonte
10

I grandi commit sono quando hai tonnellate di cambiamenti che non vanno tutti nello stesso bucket. Se cambio la logica del controller, quindi il modello di connessione del database, quindi alcuni misc. script, non dovrei associarlo tutto sotto un unico commit.

La prevenzione sta effettuando i commit in base a ciò che stai completando. Nell'esempio precedente, eseguirò il commit dopo la logica del controller, dopo il funzionamento del database e dopo gli script. Non rimandare il commit semplicemente perché tu sai cosa è cambiato. Altre persone guarderanno al tuo messaggio di registro di commit "Cambia materiale" e si chiederanno cosa stavi fumando.

Le importazioni iniziali sono probabilmente il più grande impegno che dovresti mai avere. Configurare un sistema da zero? Certo avere qualche grosso impegno. Dopo averlo livellato, è il momento di organizzare le cose.

    
risposta data 10.10.2010 - 07:05
fonte
7

Se sai che lavorerai su una grossa porzione di codice in anticipo, ti suggerirei di creare un ramo per la tua funzione specifica mentre estrai periodicamente il codice dalla linea principale per assicurarti che il tuo codice rimanga sincronizzato. Quando hai finito di lavorare sul ramo, unisci tutte le tue modifiche alla linea principale. In questo modo gli altri membri del team non saranno sorpresi e / o annoiati quando vedranno un enorme impegno. Inoltre, c'è meno possibilità di rompere le cose. Continua a praticare per suddividere le cose in piccoli commit. Con il tempo diventerà una seconda natura.

    
risposta data 10.10.2010 - 08:08
fonte
7

Questo esempio mostra un commit troppo grande.

Come regola generale, descrivi il cambiamento in una frase o in una riga di testo. (In base a questa regola, il commit dovrebbe essere suddiviso in 10-15 quelli più piccoli.) Se non puoi commentare adeguatamente un commit in una riga, allora è già troppo grande.

Per esercitarti in piccoli commit, prendi appunti nel tuo blocco note (o nel Blocco note) di ciò che hai già modificato o aggiunto. Impegnati prima che diventi una lunga lista o prima di apportare un cambiamento di codice non correlato a ciò che hai già nel blocco note.

    
risposta data 11.10.2010 - 04:41
fonte
6

Nel mio campo (modellazione fisica), scopro un bug nell'output di oggi che non era nel repository di 6 mesi fa. Quando ciò accade, eseguirò una ricerca binaria sulle revisioni:

  1. Esegui modello da 3 mesi fa
  2. Se il bug è ancora in uscita, esegui il modello da 4.5 mesi fa
  3. ... ripetere finché non trovo il commit che produce un output scadente

Quando il bug è stato introdotto in un commit mostruoso, devo sedermi con un pettine a denti fini per trovare la fonte del problema. Se il commit ha toccato un piccolo numero di file, è meno doloroso rintracciare la / e riga / i di codice che ha introdotto il problema.

Suggerirei di suddividere il problema in una serie di attività più piccole (idealmente mettere ogni attività in un bug tracker). Effettua un commit mentre completi ciascuna attività (e chiudi bug / funzionalità nel tuo tracker dei bug).

    
risposta data 15.10.2010 - 23:16
fonte
5

Non è la dimensione del commit che conta davvero, è lo scope del cambiamento che dovrebbe determinare come sono organizzati i tuoi impegni.

Potresti, ad esempio, cambiare ogni istanza di __macro1 in __macro2 in una base di codice estesa, che modifica 200 file. 200 impegni non sarebbero stati equilibrati in quel caso.

Ciò a cui vuoi arrivare è riuscire a estrarre il repository in ogni singola revisione e far funzionare la build. Sei passato da libfoo a libbar ? Spero che la modifica includa anche l'aggiornamento degli script di build e dei Makefile (o qualsiasi altra cosa sia applicabile).

A volte, potresti dover effettuare una serie di modifiche sperimentali che portano a termine una cosa, nel qual caso devi determinare quale ambito è più importante per te se devi ripristinare in un secondo momento. Si dipende dall'altra? Impegnali tutti in una volta in un'unica revisione. Altrimenti, in questo caso, suggerirei un commit per cambiamento. Dovresti fare qualcosa del genere in un altro ramo, o in un altro repo comunque.

Mentre sì, si ha il potere di ripristinare un singolo file in una revisione precedente (supportando così un file con un impegno più ampio), così facendo si mettono davvero a dura prova strumenti come la bisezione più avanti lungo la strada e si inquina la cronologia .

Se ti fermi e pensi "Ok, i test passano, penso che funzioni ... ma se va a male, posso tornare indietro facilmente?" .. finirai per prendere impegni sensati.

    
risposta data 15.10.2010 - 11:57
fonte
4

La cosa da capire qui è che "Grande" in questo contesto riguarda il numero di cambiamenti distinti non la dimensione fisica del commit (anche se generalmente i due andranno di pari passo).

Non è tanto una questione di "non commettere grandi commit" quanto fare fare piccoli commit - l'essere ideale per commettere piccoli cambiamenti autonomi.

È chiaro dal changelog che hai una serie di cose che potrebbero essere state commesse separatamente (e in sicurezza) e quindi è abbastanza evidente che è troppo grande.

Il motivo per cui questo può essere un problema è che il tuo ultimo commit è il tuo punto di riferimento per le modifiche che stai facendo attualmente e se, ad esempio, ottieni il primo bit a destra e poi ottieni il prossimo bit sbagliato hai non è un modo semplice per riportare il lavoro al punto in cui hai iniziato a commettere errori (BTDTGTTS).

Ovviamente a volte i cambiamenti sono solo grandi - refactoring su larga scala - e come suggerito da altri questo è il punto in cui devi ramificarti, anche se i tuoi singoli commit potrebbero in teoria violare le cose che sono separate dal tronco di sviluppo principale in modo che non sia è un problema e puoi continuare a impegnarti presto e spesso.

Un'ultima cosa: se qualcosa viene fuori nel bel mezzo del tuo lavoro che richiede più attenzione immediata, devi cambiarlo separatamente (idealmente in un insieme completamente distinto di cartelle) e commetterlo separatamente.

La vera sfida in tutto questo non è la meccanica è la sua mentalità - che un commit non è solo una copia di backup che fai ogni tanto ma che ogni commit è un pezzetto di pollice lungo la strada e che non c'è niente sbagliato con un sacco di piccoli commit e che munging cose diverse insieme in un commit mob è un brutto frammento di funzionalità mungeramente vagamente correlato insieme in un pezzo di codice.

    
risposta data 10.10.2010 - 12:42
fonte
4

Per lo meno, allenati a impegnarti ogni volta che pensi a te stesso "Mi piacciono i miei progressi fino ad ora, e non voglio perderlo se i cambiamenti che sto per fare sono un disastro." Quindi hai la possibilità di sfruttare il VCS per spazzare via qualsiasi vicolo cieco che hai provato o un codice di debug speciale che hai aggiunto per rintracciare un problema. (ad es. con git reset --hard o rm -rf *; svn update )

    
risposta data 11.10.2010 - 05:29
fonte
2

Non esiste una regola dura e veloce, nessuna riga di divisione oltre la quale il commit è troppo grande.

è tuttavia una linea guida che i commit più piccoli sono migliori, entro limiti ragionevoli (ad esempio, il commit di ogni riga è eccessivo).

Tengo a mente questo tipo di linee guida:

  • Un singolo commit dovrebbe includere le modifiche per una sola correzione di bug
  • Un singolo commit non dovrebbe includere più di mezza giornata di lavoro
  • Un singolo commit non dovrebbe rompere la build

Ovviamente - questi sono quelli che tengo a mente - YMMV. Diversi sviluppatori preferiscono diversi livelli di granularità.

    
risposta data 10.10.2010 - 20:31
fonte
1

Più piccolo è il commit, più facile sarà trovare esattamente da dove viene una potenziale regressione.

Idealmente un commit dovrebbe essere atomic , nel senso del più piccolo cambiamento coerente alla base del codice (correlato a bug, funzionalità, ecc.)

Per quanto riguarda i suggerimenti specifici per mantenere ridotte le dimensioni del commit, dipende molto dal tuo VCS e dalla sua configurazione: devi essere in grado di eseguire il commit localmente o lavorare nel tuo ramo sul server.

La chiave è impegnarsi nel tuo ramo "privato" ogni volta che esegui una modifica atomica, e quindi puoi unire regolarmente il tuo ramo, ad esempio ogni settimana.

Usando un dvcs, il tuo flusso di lavoro potrebbe essere simile a questo:

code code code
git commit       // create commit locally with meaningful message
code code code
git commit       // create commit locally with meaningful message
code code code
git commit       // create commit locally with meaningful message
...
git push         // push your previous commits to the team server

Utilizzo di vcs centralizzati:

svn copy trunk my_feature_branch  // create your private branch
svn co my_private_branch          //
code code code
svn commit                        // commit on your private branch with meaningful comment
code code code
svn commit                        // commit on your private branch with meaningful comment
code code code
svn commit                        // commit on your private branch with meaningful comment
...
svn merge my_feature_branch trunk  // all your previous commit are merged to main/master branch
    
risposta data 20.01.2011 - 10:56
fonte
0

Probabilmente hai sentito dire che la perfezione è quando non puoi prendere niente di più. Questo dovrebbe anche descrivere lo standard per le dimensioni del commit.

Dipende dal tuo progetto dove è quella dimensione "perfetta". Se si effettua la spedizione a clienti esterni, una buona dimensione potrebbe essere il più piccolo incremento che si sarebbe reso comodo se non si fosse terminato il prossimo in tempo. Se crei applicazioni interne e utilizzate di frequente, la dimensione migliore potrebbe essere l'incremento minimo che non infrange nulla (e ti avvicina a dove vuoi essere).

I moderni sistemi di controllo delle versioni ti aiutano a creare buoni commit con branching facile, rebasing interattivo, area di staging, ecc.

    
risposta data 10.10.2010 - 11:20
fonte
0

I messaggi di commit dovrebbero essere solo una riga (e per git max 60 caratteri). La quantità di codice impegnata deve essere abbastanza piccola da mantenere il messaggio descrittivo entro tale limite.

Tendo a impegnarmi ogni volta (ancora di più ora che siamo passati a git) Ho fatto un chunk, in quanto permette di catturare il "perché" le cose sono state fatte in questo modo.

    
risposta data 10.10.2010 - 20:43
fonte
0

A volte hai lavorato tutto il giorno su diverse chagnes logicamente distinte e ti sei dimenticato di inserire il tuo codice in mezzo. L'utilizzo di git citool può essere molto utile per suddividere il tuo lavoro in bei pezzi di dimensioni mordenti alla fine della giornata, anche se non sei stato così attento durante il giorno mentre stavi lavorando.

git citool può consentire di selezionare quali hunk specifici di un file (o quali linee specifiche) commettere in un particolare commit, in modo da poter suddividere le modifiche (non sovrapposte) apportate allo stesso file in più commit.

(Sembra che tu usi Subversion. Non conosco uno strumento che faccia questo per Subversion, ma puoi guardare usando git-svn , l'adattatore Subversion per git, che cambierà la tua vita.)

    
risposta data 11.10.2010 - 05:23
fonte
0

Più grande è il commit, più è probabile che interromperà la build e verrà pagato dal resto della tua squadra. Provo a commutare le modifiche due volte al giorno. Poco prima di pranzo e prima di andare a casa. Quindi, alle 12 e alle 16:30, cerco di mettere tutto a posto e pronto per il commit. Trovo che questa pratica funzioni per me.

    
risposta data 11.10.2010 - 07:21
fonte
0

Per rispondere alle tue domande:

1) Per me il commit standard è considerato grande se fa più di una cosa. Per cosa intendo correggere un bug o aggiungere una funzionalità.

2) Prevenire tali commit rendendo un'abitudine e una regola da commettere ogni volta che finisci qualcosa.

3) Nelle fasi semi-iniziali dello sviluppo, permetto al commit di includere la prima creazione dei file che verranno utilizzati in seguito.

Vorrei sottolineare che, terminato, intendo che tutti i bug che puoi identificare sono stati corretti e non interromperesti la build impegnandoti.

Sì, questo genera un gran numero di commit, ma ti consente di eseguire il rollback esattamente ciò che ha rotto le cose invece di dover eseguire il rollback di una serie di modifiche che sono state commesse nello stesso momento in cui solo una delle modifiche sta causando un problema .

Vorrei anche sottolineare che le regole cambiano un po 'per i sistemi di controllo delle versioni distribuiti (DVCS) come Mercurial e Git. Nel caso in cui tu stia utilizzando uno di questi, ti impegni ogni volta che hai apportato una modifica, ma non l'hai ancora testato e poi fai clic sul repository centrale quando funziona. Questo è preferibile in quanto ti consente di revisionare più modifiche al tuo codice senza preoccuparti di rompere la build.

    
risposta data 20.01.2011 - 17:51
fonte
0

Nel mio caso sto provando a trasferire file di un server sul sistema di repository (SVN). Questo è il commit iniziale e non voglio scaricarlo perché è un progetto molto grande (alcuni GB) e voglio eseguire il commit iniziale dal server dei client.

Il problema è che il client si trova su un server condiviso, il client svn viene ucciso (o qualsiasi altro software) se viene eseguito più di un minuto.

Un'alternativa sarebbe scaricare il progetto sul mio computer e fare il commit iniziale da lì, ma sono interessato a sapere se c'è un'opzione in SVN per rompere il commit grande in più, qualcosa di simile ai metodi delle transazioni.

Lo sviluppatore prima di me non ha mai utilizzato un sistema di controllo della versione.

    
risposta data 24.03.2013 - 15:12
fonte
-1

La società per cui lavoro for force una revisione del codice peer per ogni commit. Pertanto, qualsiasi commit che renda difficile per un peer capire cosa sta succedendo e rivedere in un ragionevole lasso di tempo, è troppo grande.

    
risposta data 20.01.2011 - 05:56
fonte

Leggi altre domande sui tag