Nossa equipe de documentação de cerca de dez pessoas mudou-se recentemente do SVN para o Git. No SVN, todo mundo trabalhava no mestre - um modelo que eu sempre odiei, mas não consegui fazer essa mudança. Como parte da mudança para o Git, concordamos em consertar isso, mas ainda não podemos fazer isso (aguardando alterações na compilação que permitirão compilações a partir de ramificações arbitrárias). Enquanto isso, todo mundo está trabalhando no mestre. Sim, eu sei que isso é terrível, acredite em mim.
Estamos vendo muito mais problemas agora do que quando estávamos usando o SVN, alguns dos quais são causados pelo modelo de dois estágios do Git (local e remoto). Às vezes, as pessoas cometem, mas não conseguem, ou puxam e entram em conflito com as mudanças locais pendentes. Ontem alguém subornou mudanças recentes - de alguma forma - com uma mescla que deu errado, o que eu acho que foi a mescla que o Git faz quando você puxa e tem mudanças pendentes. (Ele não foi capaz de me dizer exatamente o que fez e, por estar usando uma GUI, não posso apenas inspecionar seu histórico de shell.)
Como o usuário Git mais proficiente (leia: eu já o usei antes, embora não seja para algo super complicado), sou a pessoa que define a política, ensina as ferramentas e limpa as bagunças. Que mudanças posso fazer na maneira como estamos usando as ferramentas para tornar um mestre compartilhado e ativo menos propenso a erros até que possamos mudar para o desenvolvimento em ramificações?
A equipe está usando o Tortoise Git no Windows. Estamos usando o Tortoise Git porque usamos o Tortoise SVN antes. ( Eu pessoalmente uso a linha de comando no Cygwin para algumas operações, mas a equipe deixou claro que eles precisam de uma interface gráfica do usuário e nós vamos usar essa.) As respostas devem funcionar com essa ferramenta, e não propor substituições.
O Tortoise Git tem o "Commit & Push" disponível como uma única operação e eu disse a eles para sempre fazer isso. No entanto, não é atômico - pode acontecer que o commit (que afinal é local) funcione bem, mas o push não funcione (por exemplo, devido a um conflito ou um problema de rede). Quando isso acontece, eles recebem um erro ambíguo; Eu disse a eles para verificar o log de confirmação do BitBucket se tiverem alguma dúvida sobre uma confirmação recente e, se não o virem, forçar. (E para resolver o conflito, se esse é o problema, ou peça ajuda se eles não souberem o que fazer.)
A equipe já tem o bom hábito de "puxar cedo e com frequência". No entanto, parece que a atração pode causar conflitos, o que eu acho novo? Se não for novo, muito mais frequente do que no SVN. Ouvi dizer que posso mudar a forma como o Git puxa (rebase em vez de mesclar), mas não tenho um bom entendimento das vantagens e desvantagens lá (ou como fazê-lo em nosso ambiente).
O servidor é o BitBucket (não o Github). Eu tenho controle administrativo total sobre nosso repositório, mas nenhum no servidor de maneira mais geral. Nada disso é mutável.
Os arquivos de origem são XML. Também existem arquivos gráficos, que todo mundo sabe que você não pode mesclar, mas também quase nunca temos colisões por lá. Os conflitos de mesclagem vêm dos arquivos XML, não dos gráficos.
Que alterações posso fazer no uso do Git para tornar o mestre de compartilhamento mais tranquilo para a equipe até que possamos passar a usar ramificações de recursos com solicitações de recebimento revisadas e validadas por teste?
Respostas:
Até agora, o SourceTree foi o melhor IDE para aprender os conceitos, porque mostra todas as caixas de diálogo e opções relevantes que você tem em cada estágio, as opções padrão geralmente são boas, não mexa com rebase, etc. Basta seguir o fluxo normal:
Se todos seguirem esta receita, eles devem ficar bem.
Sempre que alguém fizer uma alteração maior ou central, informe os outros usuários a se comprometerem localmente e retirarem do mestre, para que não tenham muitos conflitos mais tarde e a primeira pessoa ainda esteja por perto para resolver os conflitos junto com eles.
Invista muito tempo para que todos compreendam o fluxo; caso contrário, eles poderão se movimentar um pouco e, em seguida, se sentirem confortáveis com ele enquanto estão danificando o ramo principal, por exemplo "use meu arquivo em vez de remoto" para resolver um conflito. todas as alterações feitas por outras pessoas.
O Git é um sistema difícil de aprender, especialmente se você cresceu com o Svn, seja paciente e dê a eles tempo para aprendê-lo adequadamente. Com os novos usuários, às vezes você pode passar o dia limpando alguma bagunça, o que é normal. ;)
fonte
Há três coisas principais a serem lembradas quando você trabalha no mesmo ramo que outra pessoa:
--force
menos que você realmente saiba o que está fazendo.commit
oustash
o seu trabalho em andamento antes de cadapull
.pull
antes de umpush
.Além disso, destacarei que, com o controle de versão distribuído, não importa se o seu repositório "oficial" usa ramificações ou não. Isso não tem qualquer influência sobre o que os usuários individuais fazem em seus repositórios locais. Eu costumava usar o git para obter filiais locais quando minha empresa usava um VCS central completamente diferente. Se eles criarem ramificações locais para seus recursos e cometerem erros de fusão com os locais
master
, é muito mais fácil corrigi- los sem entrar no reflog ou em alguma outra mágica.fonte
pull
antespush
é um grande conselho, mas eu ir um passo além e sugerir que você considere se você podepull --rebase
quando você faz.--force
menos que você realmente saiba o que está fazendo." Eu iria além. Não permita que o histórico de reescritas no repositório "principal" seja de todos, exceto dos indivíduos mais confiáveis. Se você pode fazer isso pelo menos em parte depende da sua hospedagem, mas o BitBucket tem a opção.É possível levar um dia para que todos aprendam git?
Espera-se que os usuários de computadores aprendam realmente uma nova ferramenta e, embora seja possível cometer muitos erros em qualquer VCS, eles devem usar a ferramenta conforme foi projetada para ser usada.
A melhor maneira de introduzir isso é fazer com que cada um trabalhe em sua própria ramificação quando eles fizerem uma alteração (o mais curta possível) e a reorganização e, em seguida, retornem ao mestre quando terminar. Isso não está muito longe da maneira atual de trabalhar e introduz um fluxo de trabalho simples com o qual eles podem se acostumar até se sentirem confiantes o suficiente para realizar operações mais complicadas.
Eu não uso o Windows, mas se o Tortoise está basicamente escondendo o git deles e fingindo que é SVN, talvez o Tortoise seja a ferramenta errada.
fonte
Às vezes, o que você está fazendo precisa mudar.
O maior problema é que todos estão trabalhando no mestre. Isso não é típico para o desenvolvimento de código e também pode ser o modelo errado no seu caso. Se você pode mudar isso, solicitando / exigindo que as alterações sejam feitas em ramificações separadas, você estará em melhor forma. Com ramificações, você pode obter o seguinte:
master
é permitido.Se você não puder usar a ramificação, considere escrever um
merge-and-push
script que possa automatizar alguns dos pontos problemáticos. Talvez verifique se o usuário não está atrasado no mestre, faça uma busca e puxe e tente a mesclagem ( possivelmente com--no-commit --no-ff
) e assim por diante.fonte
master
.Enfatize que você pode refazer mesclagens
Pode ser óbvio para você, mas os ex-usuários do SVN podem não estar cientes de que podem tentar resolver uma mesclagem várias vezes. Isso pode reduzir o número de sinalizadores de ajuda que você recebe.
Em SVN quando se trabalha fora
trunk
você tem alterações não confirmadas sentados. Então você faria umsvn update
. Nesse ponto, suas mudanças se misturarão com as de outras pessoas para sempre. Não havia como desfazê-lo (afaik), então você não tinha escolha a não ser verificar manualmente tudo e torcer para que o repo estivesse em bom estado. Quando realmente você se sentiria muito mais confortável apenas refazendo a fusão.As pessoas teriam a mesma mentalidade mesmo quando mudássemos para o git. Levando a muitos erros não intencionais.
Felizmente, com o git, existe um caminho de volta, especificamente porque você pode fazer confirmações locais. (Descrevo mais adiante como isso é expresso na linha de comando)
Embora como isso seja feito, varie com base nas ferramentas. Acho que refazer um pull não é algo exposto em muitas GUIs como um único botão, mas provavelmente é possível. Eu gosto de você usar cygwin. Meus colegas de trabalho usam o sourcetree. Como você usa o BitBucket, faria sentido usá-lo como sua GUI, pois ele é gerenciado pela mesma empresa: Atlassian. Suspeito que exista alguma integração mais estreita.
Em relação à tração
Eu acho que você está certo que a fusão
pull
é o que está atrapalhando as pessoas. Apull
é realmente ogit fetch
que recupera as alterações do servidor, seguido porgit merge origin/<branchname>
* que mescla as alterações remotas na sua filial local. ( https://git-scm.com/docs/git-pull )O resultado é que todos os comandos de mesclagem padrão funcionam com pull. Se essa mesclagem tiver conflitos, você poderá cancelar
git merge --abort
. O que deve levar você de volta antes da mesclagem. Então você pode tentar novamente comgit pull
ougit merge origin/<branchname>
.Se você puder aprender de alguma forma como fazer isso acima usando a ferramenta GUI de escolha dos colegas de trabalho, acho que resolverá a maioria dos seus problemas. Desculpe, não posso ser mais específico.
* Entendo que a origem nem sempre é o caso aqui.
Use
git reflog
para diagnosticar problemasEu, como você, tenho que diagnosticar problemas criados principalmente pelo uso indevido de ferramentas da GUI. Acho que
git reflog
às vezes pode ser útil, pois é uma trilha de ações razoavelmente consistente no repositório. Embora seja difícil de ler às vezes.Uma alternativa
Como sua situação é temporária , você pode simplesmente voltar ao SVN até ter o processo em andamento. Eu hesitaria em fazer isso, já que muitos lugares continuavam dizendo 'Tentamos o git uma vez, mas simplesmente não funcionou ...' e nunca o recuperamos.
Alguns outros problemas transitórios comuns
git log --decorate
a maneira mais fácil de visualizar as diferenças. Mas se as coisas ficarem peludas no mestre (por exemplo), você podegit reset --hard origin/master
fonte
git log --oneline --decorate --graph
ideal. Tanto que defini um apelido de shell para essa combinação precisa.Um mecanismo possível, adotado por muitas equipes de código aberto, é usar o modelo de bifurcação - https://www.atlassian.com/git/tutorials/comparing-workflows ( lembre- se de enunciar claramente ao discutir um fluxo de trabalho de bifurcação git ) .
Neste, cada desenvolvedor ou sub-equipe tem sua própria bifurcação do repositório que eles conferem no BitBucket fornece um mecanismo para isso , definindo uma origem "upstream" além do controle remoto padrão - eles terão que se lembrar de "buscar upstream" "e" mesclam controle remoto / upstream / mestre "regularmente.
Possivelmente resolverá os problemas do seu mecanismo de construção, pois as ferramentas de construção seriam apontadas para o mestre em um projeto diferente, ou seja, a bifurcação.
Em seguida, você pode remover da maioria das pessoas a capacidade de avançar diretamente para o projeto principal e transformar uma equipe menor de pessoas em revisar e aprovar funções. Consulte https://www.atlassian.com/git/tutorials/making-a-pull-request
O lugar para ler sobre como garantir que praticamente todas as verificações desejáveis sejam feitas antes dos pushs está na seção de livros do git sobre ganchos - https://git-scm.com/book/gr/v2/Customizing-Git-Git-Hooks - você pode usar ganchos de pré-confirmação e pré-envio para executar tarefas como executar alguns testes na confirmação proposta para garantir que o trabalho seja válido etc. - o único problema com os ganchos do lado do cliente é que os desenvolvedores podem desativá-los ou não ativar eles.
A busca / mesclagem a montante e os ganchos estão disponíveis no TortoiseGit.
fonte
Isso vai parecer contra-intuitivo, mas ouça-me:
Incentive-os a começar a experimentar o git
Uma das coisas interessantes sobre o git é que é surpreendentemente fácil tornar qualquer operação local completamente segura. Quando comecei a usar o git, uma das coisas que me vi fazendo foi fechar o diretório inteiro como backup, caso eu estragasse alguma coisa. Mais tarde, descobri que esse é um enorme problema e quase nunca é realmente necessário para proteger seu trabalho, mas tem a virtude de ser muito seguro e muito simples, mesmo que você não saiba o que diabos está fazendo e como o comando que você deseja tentar será exibido. A única coisa que você deve evitar ao fazer isso é
push
. Se você não pressionar nada, esta é uma maneira 100% segura de experimentar o que quiser.O medo de tentar coisas é um dos maiores obstáculos ao aprendizado do git. Dá-lhe de modo muito controle sobre tudo o que é meio assustador. A realidade é que você pode manter algumas operações muito seguras durante a maior parte do seu uso diário, mas descobrir quais comandos são necessários, é preciso explorar.
Ao dar a eles uma sensação de segurança , eles estarão muito mais dispostos a tentar descobrir como fazer as coisas por conta própria. E eles terão muito mais poder para encontrar um fluxo de trabalho pessoal na máquina local que funcione para eles. E se nem todos fazem a mesma coisa localmente , tudo bem, desde que sigam os padrões com o que eles impõem . Se for necessário fechar o repositório inteiro antes de executar uma operação para fazê-los se sentir assim, tudo bem; eles podem aprender maneiras melhores de fazer as coisas à medida que avançam e tentam coisas. Qualquer coisa para você começar a tentar coisas e ver o que faz.
Isso não significa que o treinamento é inútil. Pelo contrário, o treinamento pode ajudá-lo a apresentar recursos, padrões e normas. Mas não é um substituto para sentar e realmente fazer coisas no seu trabalho diário. Nem o git nem o SVN são coisas sobre as quais você pode simplesmente ir a uma aula e saber tudo. Você precisa usá- los para resolver seus problemas para se familiarizar com eles e quais recursos são adequados para quais problemas.
Pare de desencorajá-los de aprender os meandros do git
Eu mencionei não pressionar nada, o que realmente vai contra uma das coisas que você está ensinando a eles: sempre "Commit & Push". Eu acredito que você deve parar de dizer para eles fazerem isso e dizer para começarem a fazer o contrário. O Git tem basicamente 5 "lugares" onde suas alterações podem ser:
Em vez de incentivá-los a puxar e empurrar tudo em uma única etapa, incentive-os a aproveitar esses 5 lugares diferentes. Incentive-os a:
Fazer uma decisão como lidar com as mudanças buscadas. As opções são:
Esconda suas alterações, mescle e desinstale e resolva quaisquer conflitos.
Há outras coisas, mas não vou entrar aqui. Observe que um pull é literalmente apenas uma busca e uma mesclagem. Não é como eles; que é deles. (As
--rebase
alterações passadas são extraídas de buscar + mesclar para buscar + rebase.)Isso os incentivará a verificar seu trabalho antes que ele seja disponibilizado publicamente a todos, o que significa que eles perceberão seus erros mais cedo. Eles verão o commit e pensam: "Espere, não era isso que eu queria" e, ao contrário do SVN, eles podem voltar e tentar novamente antes de pressionar.
Depois que eles se acostumam à idéia de entender onde estão as alterações, eles podem começar a decidir quando ignorar as etapas e combinar determinadas operações (quando extrair porque você já sabe que deseja buscar + mesclar ou quando clicar na opção Confirmar e enviar) .
Este é realmente um dos enormes benefícios do git sobre o SVN, e o git é projetado com esse padrão de uso em mente. O SVN, por outro lado, assume um repositório central, portanto, não é surpreendente que as ferramentas para o git não sejam tão otimizadas para o mesmo fluxo de trabalho. No SVN, se seu commit estiver errado, seu único recurso real é um novo commit para desfazer o erro.
Fazer isso levará naturalmente à próxima estratégia:
Incentive-os a usar filiais locais
As ramificações locais realmente facilitam muitos pontos problemáticos do trabalho em arquivos compartilhados. Eu posso fazer todas as alterações que desejar no meu próprio ramo, e isso nunca afetará ninguém, pois não estou pressionando. Então, quando chegar a hora, eu posso usar todas as mesmas estratégias de mesclagem e rebase, apenas mais fáceis:
Usar ramificações locais também é um bom começo para descobrir uma estratégia sistemática de ramificação. Isso ajuda seus usuários a entender melhor suas próprias necessidades de ramificação, para que você possa escolher uma estratégia com base nas necessidades e no nível de entendimento / habilidade atual da equipe e não apenas cair no Gitflow porque todos já ouviram falar.
Sumário
Em resumo, o git não é SVN e não pode ser tratado como ele. Você precisa:
Isso tudo irá ajudá-lo a adotar gradualmente um melhor uso do git, até chegar ao ponto em que você pode começar a implementar um conjunto de padrões.
Características específicas
No prazo imediato, as seguintes idéias podem ajudar.
Rebase
Você mencionou rebase e que realmente não entende isso na sua pergunta. Então, aqui está o meu conselho: experimente o que acabei de descrever. Faça algumas alterações localmente enquanto outra pessoa faz algumas alterações. Confirme suas alterações localmente . Compacte o diretório do repositório como backup. Busque as alterações da outra pessoa. Agora tente executar um comando rebase e veja o que acontece com seus commits! Você pode ler inúmeras postagens no blog ou receber treinamento sobre rebase e como deve ou não usá-lo, mas nada disso é um substituto para vê-lo vivo em ação. Então tente .
merge.ff=only
Essa será uma questão de gosto pessoal, mas vou recomendá-la pelo menos temporariamente, pois você mencionou que já tem problemas com o tratamento de conflitos. Eu recomendo configurar
merge.ff
paraonly
:"ff" significa "avanço rápido". Uma mesclagem de avanço rápido é quando o git não precisa combinar alterações de confirmações diferentes. Apenas move o ponteiro da ramificação para um novo commit ao longo de uma linha reta no gráfico.
O que isso faz na prática é impedir que o git tente automaticamente criar confirmações de mesclagem. Portanto, se eu confirmar algo localmente e puxar as alterações de outra pessoa, em vez de tentar criar um commit de mesclagem (e potencialmente forçar o usuário a lidar com conflitos), a mesclagem falhará. De fato, o git terá realizado apenas a
fetch
. Quando você não possui confirmações locais, a mesclagem continua normalmente.Isso oferece aos usuários a chance de revisar os diferentes commits antes de tentar mesclá-los e os força a tomar uma decisão sobre como lidar melhor com a combinação deles. Eu posso me refazer, continuar com a mesclagem (usando
git merge --no-ff
para ignorar a configuração) ou até mesmo adiar a fusão de minhas alterações por enquanto e lidar com isso mais tarde. Acho que esse pequeno aumento de velocidade ajudará sua equipe a evitar tomar decisões erradas sobre fusões. Você pode deixar sua equipe desativá-lo assim que melhorar a manipulação de fusões.fonte
Passei exatamente pela mesma experiência SVN -> git na minha empresa e, pela minha experiência, o único remédio é o tempo. Deixe as pessoas se acostumarem com as ferramentas, cometerem erros, mostrarem como corrigi-las. Sua velocidade sofrerá por um tempo, as pessoas perderão o trabalho e todos ficarão um pouco cansados, mas essa é a natureza de mudar algo tão fundamental quanto o seu VCS.
Dito isto, concordo com todos que consideram que o TortoiseGit é um obstáculo, e não uma ajuda, tão cedo no período de transição. O TortoiseGit ... não é uma ótima GUI na melhor das hipóteses, e obscurecendo como o git realmente funciona em nome da simplicidade, também está impedindo que seus colegas de trabalho obtenham uma compreensão dos principais conceitos do git, como o commit em duas fases.
Tomamos a decisão (bastante drástica) de forçar os desenvolvedores a usar a linha de comando (git bash ou posh-git ) por uma semana, e isso funcionou maravilhosamente para entender como o git realmente funciona e como ele difere do SVN. Pode parecer drástico, mas eu sugiro que você tente simplesmente porque cria esse entendimento do modelo git - e, depois que eles são reduzidos, seus colegas de trabalho podem começar a usar as fachadas da GUI sobre o git que quiserem.
Nota final: alguns de seus colegas de trabalho entenderão como o git funciona quase que imediatamente e outros que nunca o farão. No último grupo, você apenas precisa ensinar os encantamentos místicos a fazer o código passar da máquina local para o servidor, para que todos possam vê-lo.
fonte
Bem, recentemente eu adaptei o seguinte fluxo de trabalho para nunca aumentar a ramificação principal:
1) Todo mundo usa sua própria ramificação, que é inicialmente uma cópia da ramificação principal.
Vamos nomear o ramo mestre "mestre" e meu próprio ramo "my_master".
Acabei de fazer meu ramo com o mestre, então é exatamente o mesmo. Começo a trabalhar em um novo recurso em minha própria filial e, quando terminar, faço o seguinte.
Atualmente no meu ramo, acabei de codificar
Volte para o ramo principal
Puxe se não estiver atualizado
Volte para o meu próprio ramo
Mesclar o mestre mais recente ao meu próprio ramo
Corrigir conflitos e mesclagens
Teste tudo de novo
Quando tudo estiver mesclado e corrigido em meu próprio ramo, empurre-o
Volte para o ramo principal
Mesclar com meu ramo
Impossível ter conflitos, pois eles são resolvidos em sua própria ramificação com mesclagem anterior
Push master
Se todos seguirem isso, o ramo mestre estará limpo.
fonte
Portanto, temos uma equipe que mudou do TFS para o git e manteve as velhas formas de pensar. As regras gerais de operação são mais ou menos as mesmas.
Sim, isso significa que todo mundo trabalha no mestre. Isso não é tão ruim assim; e uma equipe acostumada a TFS ou SVN achará isso mais natural.
Procedimentos gerais para tornar isso o mais simples possível:
git stash && git pull --rebase && git stash pop
todas as manhãspara empurrar, faça o seguinte loop:
git add git commit git pull --rebase fix any merges compile git push loop until you don't get the can't fast forward error message.
fonte
git
: você geralmente aprende a se bifurcar e mesclar desde o primeiro dia. Isso é parte integrante do usogit
. Evite isso e você está abusando da ferramenta da mesma maneira que está abusando de um carro ao percorrer não mais de 15 km / h.Se todo mundo está trabalhando no mestre, não há nada que você possa fazer. As coisas inevitavelmente ficarão confusas.
Você deve usar o mestre para produtos concluídos que são enviados a um cliente. Você deve usar o desenvolvimento para o desenvolvimento contínuo, e você deve não permitir que ninguém para empurrar para o desenvolvimento. O padrão é que todos ramifiquem do dev, façam suas alterações, os transfiram do local para sua ramificação no servidor e emitam uma solicitação por push. Então alguém analisa a mudança e a funde no desenvolvimento.
Para evitar conflitos, todos mesclam o desenvolvimento em seu próprio ramo antes de enviar por push e resolvem conflitos nesse estágio (portanto, isso afeta apenas um desenvolvedor localmente). Se a mesclagem no desenvolvimento causar conflitos, ele não será mesclado - o desenvolvedor mescla o desenvolvimento em sua ramificação novamente e envia para o servidor novamente e é revisado novamente.
Você pode usar o sourcetree, por exemplo, para fazer isso funcionar sem nenhuma dor.
fonte