Quando um commit de controle de versão é muito grande? [fechadas]

62

Eu já ouvi em vários lugares "Não faça grandes commits", mas eu nunca entendi o que é um commit "grande". É grande se você trabalha em um monte de arquivos, mesmo se houver relacionado? Quantas partes de um projeto você deveria estar trabalhando ao mesmo tempo?

Para mim, tenho dificuldade em tentar fazer "pequenos commits", pois esqueço ou crio algo que cria alguma outra coisa que cria alguma outra coisa. Você acaba com coisas assim:

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

Sim ....

Então, para perguntas:

  • Quais são alguns fatores para quando um commit se torna muito grande ( coisas não óbvias )?
  • Como você pode evitar esses commits? Por favor, dê detalhes
  • E quando você está em estágios iniciais de desenvolvimento quando as coisas estão se movendo rapidamente? Os commits enormes ainda estão bem?
por TheLQ 12.10.2010 / 03:47
fonte

19 respostas

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.

Isso é um problema. Parece que você precisa aprender para dividir seu trabalho em partes menores e mais gerenciáveis.

O problema com grandes commits é:

  • Em um projeto de várias pessoas, há uma chance maior de que seus commits causem conflitos para outros desenvolvedores resolverem.
  • É mais difícil descrever com precisão o que foi feito nas mensagens de log.
  • É mais difícil controlar a ordem em que as alterações foram feitas e, portanto, entender a causa dos problemas.
  • Aumenta a probabilidade de perder muito trabalho não confirmado.

Às vezes grandes commits são inevitáveis; por exemplo. se você tiver que mudar uma API principal. Mas normalmente não é o caso. E se você se encontrar nessa situação, provavelmente é uma boa ideia criar um branch e fazer o seu trabalho lá ... com muitos commits pequenos ... e reintegrar quando terminar.

(Outro caso é quando você faz uma importação inicial, mas isso NÃO é problemático do ponto de vista dos problemas listados acima.)

    
por 10.10.2010 / 16:30
fonte
38

O princípio da responsabilidade única.

Todo commit de controle de origem deve servir apenas a um propósito. Se você tiver que colocar a palavra "e" ou "também" no seu resumo, você precisará separá-lo.

É muito comum acabar com muitas alterações separadas, não relacionadas ou semi-relacionadas, na sua cópia de trabalho. Isso é chamado de "problema complicado da cópia de trabalho" e, na verdade, é muito difícil evitar até mesmo para desenvolvedores disciplinados. No entanto, o Git e o Mercurial fornecem ferramentas para resolvê-lo - git add -p ou chunk selection e Mercurial Queues in TortoiseHg respectivamente.

    
por 20.01.2011 / 00:23
fonte
25

Imagine que o cliente pediu para fazer uma alteração específica - por exemplo, para adicionar uma regra de que algo ou outra não pode ser feito dentro de dois dias da data "o que for". Então, depois que você fez a mudança, eles mudam de idéia. Você vai querer reverter seu commit. Se tudo estiver relacionado a mudanças na ordem de classificação de relatórios não relacionados, sua vida é uma miséria.

Um item de trabalho, um conjunto de alterações. Uma solicitação do cliente, um conjunto de alterações. Uma coisa sobre a qual você pode mudar sua opinião é um conjunto de alterações. Às vezes isso significa que é uma única linha de código. Às vezes, são dez arquivos diferentes, incluindo o esquema do banco de dados. Isso é bom.

    
por 10.10.2010 / 21:11
fonte
10

Grandes commits são quando você tem toneladas de alterações que não são todas do mesmo tipo. Se eu mudar a lógica do controlador, então o modelo de conexão do banco de dados, em seguida, alguns misc. scripts, eu não deveria estar agrupando tudo em um commit.

A prevenção está fazendo commits de acordo com o que você está concluindo. No exemplo acima, eu iria confirmar após a lógica do controlador, após o trabalho do banco de dados e após os scripts. Não desista de se comprometer simplesmente porque você sabe o que mudou. Outras pessoas olharão para a sua mensagem de registro de commit "Changed stuff" e ficarão imaginando o que você estava fumando.

As importações iniciais são provavelmente os maiores commits que você deve ter. Configurando um sistema do zero? Claro que tem alguns grandes commits. Depois de nivelar, é hora de manter as coisas organizadas.

    
por 10.10.2010 / 07:05
fonte
7

Se você sabe que estará trabalhando em um grande bloco de código de antemão, sugiro criar uma ramificação para seu recurso específico enquanto extrai periodicamente o código da linha principal para garantir que seu código permaneça sincronizado. Quando você terminar de trabalhar no ramo mesclar todas as suas alterações de volta para a linha principal. Desta forma, os outros membros da equipe não ficarão surpresos e / ou aborrecidos quando virem um commit enorme. Além disso, há muito menos chance de quebrar as coisas. Continue praticando para dividir as coisas em pequenos commits. Com o tempo, ela se tornará uma segunda natureza.

    
por 10.10.2010 / 08:08
fonte
7

Este exemplo mostra um commit muito grande.

Como regra geral, descreva a alteração em uma frase ou em uma linha de texto. (Com base nessa regra, o commit deve ser dividido em 10 a 15 pontos menores.) Se você não puder comentar adequadamente um commit em uma linha, então ele já é muito grande.

Para praticar commits menores, anote no seu bloco de notas (ou no Bloco de Notas) o que você já alterou ou adicionou. Confirme antes de se tornar uma lista longa ou antes de fazer uma alteração de código não relacionada ao que você já tem no bloco de notas.

    
por 11.10.2010 / 04:41
fonte
6

No meu campo (modelagem física), descubro um erro na saída hoje que não estava no repositório há 6 meses. Quando isso acontecer, farei uma pesquisa binária em revisões:

  1. Executar modelo a partir de 3 meses atrás
  2. Se o bug ainda estiver na saída, execute o modelo a partir de 4,5 meses atrás
  3. ... repete até encontrar o commit que resulta em output ruim

Quando o bug foi introduzido em um commit monstruoso, eu tenho que sentar com um pente fino para encontrar a origem do problema. Se o commit tocou em um pequeno número de arquivos, é menos doloroso rastrear a (s) linha (s) de código que apresentou o problema.

Eu recomendaria quebrar seu problema em uma série de tarefas menores (o ideal é colocar cada tarefa em um rastreador de bugs). Faça um commit ao concluir cada tarefa (e feche esse bug / recurso no seu bug tracker).

    
por 15.10.2010 / 23:16
fonte
5

Não é o tamanho do commit que realmente importa, é o escopo da mudança que deve determinar como seus compromissos são organizados.

Você pode, por exemplo, alterar cada instância de __macro1 para __macro2 em uma base de código grande, que altera 200 arquivos. 200 compromissos não seriam saudáveis nesse caso.

O que você quer terminar é poder puxar o repositório em qualquer revisão única e ter a construção funcionando. Você alterou de libfoo para libbar ? Espero que a mudança inclua também a atualização de seus scripts de construção e Makefiles (ou o que for aplicável).

Às vezes, pode ser necessário fazer uma série de alterações experimentais que realizem uma coisa. Nesse caso, você precisa determinar qual é o escopo mais importante para você se precisar reverter mais tarde. Um depende do outro? Comprometa-os todos de uma só vez em uma única revisão. Caso contrário, nesse caso, sugiro um commit por alteração. Você deveria estar fazendo algo assim em outro ramo, ou em outro repo de qualquer maneira.

Embora sim, você tem o poder de reverter um único arquivo para uma revisão anterior (fazendo com que um arquivo saia de um compromisso maior), fazendo isso realmente estraga ferramentas como a bisseção mais adiante e polui o histórico .

Se você parar e pensar "Ok, os testes são aprovados, acho que isso funciona ... mas se ficar ruim, posso facilmente voltar atrás?" .. você acabará assumindo compromissos sensatos.

    
por 15.10.2010 / 11:57
fonte
4

A coisa a entender aqui é que "Large" neste contexto é sobre o número de mudanças distintas não o tamanho físico do commit (embora geralmente os dois andem de mãos dadas).

Não é uma questão de "não fazer grandes commits", pois do faz pequenos commits - o ideal é cometer pequenas mudanças independentes.

Está claro no changelog que você tem uma série de coisas que poderiam ter sido cometidas separadamente (e com segurança) e, portanto, é bastante evidente que é muito grande.

A razão pela qual isso pode ser um problema é que o seu último commit é o seu ponto de referência para as alterações que você está fazendo atualmente e se, por exemplo, você acertar o primeiro bit e depois errar o próximo. nenhuma maneira fácil de rolar seu trabalho de volta ao ponto em que você começou a cometer erros (BTDTGTTS).

É claro que às vezes as mudanças são grandes - refatoração em larga escala - e como é sugerido por outros é onde você precisa se ramificar, embora seus commits individuais possam quebrar coisas que são separadas do trunk principal de desenvolvimento é um problema e você começa a se comprometer cedo e com frequência.

Mais uma coisa - se algo surgir no meio do seu trabalho que requeira atenção mais imediata, você precisará alterá-lo separadamente (idealmente em um conjunto completamente diferente de pastas) e enviá-lo separadamente.

O verdadeiro desafio em tudo isso não é a mecânica, é a mentalidade - que um commit não é apenas uma cópia de backup que você faz de vez em quando, mas que cada commit é um pedregulho ao longo do caminho e que não há nada errado com muitos pequenos commits e que colocar coisas diferentes juntos em um mob commit é tão ruim quanto um pouco vagamente relacionado a funcionalidade em um pedaço de código.

    
por 10.10.2010 / 12:42
fonte
4

No mínimo, treine-se para se comprometer sempre que pensar consigo mesmo. "Eu gosto do meu progresso até agora, e não quero perdê-lo se as mudanças que estou prestes a fazer forem um desastre." Então você tem a opção de tirar proveito do VCS para eliminar quaisquer becos sem saída que você tenha tentado ou código de depuração especial que você adicionou para rastrear um problema. (por exemplo, com git reset --hard ou rm -rf *; svn update )

    
por 11.10.2010 / 05:29
fonte
2

Não existe uma regra rígida e rápida, nenhuma linha divisória além da qual seu commit seja grande demais.

Existe uma diretriz de que os commits menores são melhores, dentro do razoável (isto é, comprometer cada linha é excessivamente provável).

Eu mantenho estes tipos de diretrizes em mente:

  • Um único commit deve incluir alterações para apenas uma correção de bug
  • Um único commit não deve incluir mais de meio dia de trabalho
  • Um único commit não deve quebrar a compilação

Claro - isso é o que eu tenho em mente - YMMV. Desenvolvedores diferentes favorecem diferentes níveis de granularidade.

    
por 10.10.2010 / 20:31
fonte
1

Quanto menor for o commit, mais fácil será encontrar exatamente de onde vem uma possível regressão.

Idealmente, um commit deve ser atômico , no sentido da menor mudança coerente na base de código (relacionada a um bug, recurso, etc.).

Quanto a dicas específicas para manter o tamanho do commit pequeno, ele depende muito do seu VCS e de como ele é configurado: você deve ser capaz de se comprometer localmente ou trabalhar em sua própria filial no servidor.

A chave é se comprometer com sua ramificação "privada" toda vez que você fizer uma alteração atômica e, em seguida, você poderá mesclar regularmente sua ramificação, por exemplo, toda semana.

Usando um dvcs, seu fluxo de trabalho pode ser assim:

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

Usando um vcs centralizado:

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
    
por 20.01.2011 / 10:56
fonte
0

Você provavelmente já ouviu o ditado de que a perfeição é quando você não pode tirar mais nada. Isso também deve descrever seu padrão para o tamanho do commit.

Depende do seu projeto onde o tamanho "perfeito" é. Se você estiver enviando para clientes externos, um bom tamanho pode ser o menor incremento que seria mais confortável se você não terminasse o próximo no prazo. Se você estiver criando aplicativos internos e freqüentemente implantados, o melhor tamanho pode ser o menor incremento que não quebra nada (e aproxima você de onde você quer estar).

Os sistemas de controle de versão modernos ajudam você a criar bons commits com ramificação fácil, rebasing interativo, área de preparação, etc.

    
por 10.10.2010 / 11:20
fonte
0

As mensagens de confirmação devem ser apenas uma linha (e para git max 60 caracteres). A quantidade de código que está sendo confirmada deve ser pequena o suficiente para manter a mensagem descritiva dentro desse limite.

Eu costumo me comprometer toda vez (ainda mais agora que eu mudei para o git) Eu tenho um pedaço pronto, já que ele permite capturar o "porquê" as coisas foram feitas dessa maneira.

    
por 10.10.2010 / 20:43
fonte
0

Às vezes você tem trabalhado o dia todo em vários chagnes diferentes e logicamente distintos, e você esqueceu de cometer seu código entre eles. O uso de git citool pode ser muito útil para dividir seu trabalho em partes agradáveis no final do dia, mesmo que você não tenha sido muito cuidadoso durante o dia enquanto trabalhava.

git citool pode permitir que você selecione quais partes específicas de um arquivo (ou quais linhas específicas) devem ser confirmadas em um commit específico, para que você possa dividir (sem sobreposição) as alterações feitas no mesmo arquivo em vários commits. / p>

(Parece que você usa o Subversion. Eu não conheço uma ferramenta que faça isso para o Subversion, mas você poderia procurar usar git-svn , o adaptador do Subversion para git, que irá mudar sua vida.)

    
por 11.10.2010 / 05:23
fonte
0

Quanto maior o commit, maior a probabilidade de você quebrar a build e ser pago pelo restante de sua equipe. Eu tento fazer alterações duas vezes por dia. Pouco antes do almoço e antes de ir para casa. Então, às 12h e às 16h30, tento colocar tudo em funcionamento e pronto para me comprometer. Eu acho que essa prática funciona para mim.

    
por 11.10.2010 / 07:21
fonte
0

Para responder às suas perguntas:

1) Para mim, o commit padrão é considerado grande se estiver fazendo mais de uma coisa. Por coisa eu quero dizer consertar um bug ou adicionar um recurso.

2) Evite tais commits tornando o hábito e a regra de commit sempre que você terminar algo.

3) Nos estágios semi-iniciais do desenvolvimento, permito que os commits incluam a primeira criação dos arquivos que serão usados posteriormente.

Gostaria de observar que, por fim, quero dizer que todos os erros que você pode identificar foram corrigidos e você não quebrará a compilação comprometendo-se.

Sim, isso gera um grande número de confirmações, mas permite reverter exatamente o que quebrou as coisas, em vez de ter que reverter uma grande série de alterações que foram confirmadas ao mesmo tempo em que apenas uma das alterações está causando um problema .

Eu também gostaria de salientar que as regras mudam um pouco para os sistemas de controle de versão distribuída (DVCS), como o Mercurial e o Git. No caso de você estar usando um desses, você comete sempre que fez uma mudança, mas ainda não testou e, em seguida, envia para o repositório central quando está funcionando. Isso é preferível, pois permite revisar mais alterações em seu código sem se preocupar em quebrar a compilação.

    
por 20.01.2011 / 17:51
fonte
0

No meu caso, estou tentando confirmar arquivos de um servidor para o sistema de repositório (SVN). Este é o commit inicial e não quer baixá-lo, pois é um projeto realmente grande (alguns GB) e eu quero fazer o commit inicial do servidor do cliente.

O problema é que o cliente está em um servidor compartilhado, o cliente svn é eliminado (ou qualquer outro software) se for executado mais de um minuto.

Uma alternativa seria baixar o projeto no meu computador e fazer o commit inicial a partir dele, mas estou interessado em saber se existe uma opção no SVN para dividir o commit grande em algo mais parecido com os métodos de transações.

O desenvolvedor antes de mim nunca usou um sistema de controle de versão.

    
por 24.03.2013 / 15:12
fonte
-1

A empresa em que trabalho reforça uma revisão de código peer para cada commit. Portanto, qualquer commit que torne difícil para um colega descobrir o que está acontecendo e revisar em um período de tempo razoável, é muito grande.

    
por 20.01.2011 / 05:56
fonte