Git
Esta resposta inclui o GitHub, como muitas pessoas perguntaram sobre isso também.
Repositórios locais
O Git (localmente) possui um diretório ( .git
) no qual você submete seus arquivos e este é o seu 'repositório local'. Isso é diferente de sistemas como o SVN, em que você adiciona e confirma o repositório remoto imediatamente.
O Git armazena cada versão de um arquivo que muda, salvando o arquivo inteiro. Também é diferente do SVN nesse aspecto, pois você pode acessar qualquer versão individual sem "recriá-la" por meio de alterações delta.
O Git não 'bloqueia' os arquivos e evita a funcionalidade 'bloqueio exclusivo' para uma edição (sistemas mais antigos como pvcs vêm à mente), para que todos os arquivos sempre possam ser editados, mesmo quando estiverem off-line. Na verdade, ele faz um trabalho incrível de mesclar alterações de arquivos (dentro do mesmo arquivo!) Durante puxões ou buscas / empurram para um repositório remoto como o GitHub. O único momento em que você precisa fazer alterações manuais (na verdade, editar um arquivo) é se duas alterações envolverem a mesma linha (s) de código.
Ramos
As ramificações permitem preservar o código principal (a ramificação 'principal'), fazer uma cópia (uma nova ramificação) e depois trabalhar dentro dessa nova ramificação. Se o trabalho demorar algum tempo ou o mestre receber muitas atualizações desde que a ramificação foi feita, a mesclagem ou reestruturação (geralmente preferida para melhorar o histórico e facilitar a resolução de conflitos) contra a ramificação mestre deve ser feita. Quando você terminar, mesclar as alterações feitas na ramificação de volta ao repositório principal. Muitas organizações usam ramificações para cada trabalho, seja um item de recurso, bug ou tarefa. Outras organizações usam apenas ramificações para grandes mudanças, como atualizações de versão.
Bifurcação: com uma ramificação, você controla e gerencia a ramificação, enquanto que com uma bifurcação alguém controla a aceitação do código de volta.
De um modo geral, existem duas abordagens principais para fazer ramificações. O primeiro é manter a maioria das alterações na ramificação principal, usando apenas ramificações para coisas maiores e de execução mais longa, como alterações de versão, nas quais você deseja ter duas ramificações disponíveis para diferentes necessidades. A segunda é a maneira pela qual você basicamente faz uma ramificação para cada solicitação de recurso, correção de bug ou tarefa e depois decide manualmente quando realmente mesclar essas ramificações na ramificação principal principal. Embora isso pareça entediante, essa é uma abordagem comum e atualmente a que uso e recomendo, porque mantém a ramificação principal mais limpa e é a master que promovemos para a produção; portanto, queremos apenas código completo e testado por meio de rebasing e fusão de sucursais.
A maneira padrão de trazer uma ramificação para o domínio é fazer a merge
. As ramificações também podem ser "reformuladas" para 'limpar' a história. Não afeta o estado atual e é feito para fornecer um histórico "mais limpo".
Basicamente, a idéia é que você ramificou a partir de um certo ponto (geralmente do mestre). Desde que você se ramificou, o próprio 'mestre' avançou desde esse ponto de ramificação. Será 'mais limpo' (mais fácil de resolver problemas e o histórico mais fácil de entender) se todas as alterações feitas em uma ramificação forem executadas no estado atual do mestre com todas as alterações mais recentes. Então, o processo é: salve as alterações; obtenha o 'novo' mestre e, em seguida, aplique novamente (esta é a parte da reorganização) as alterações novamente. Esteja ciente de que a recuperação, assim como a mesclagem, pode resultar em conflitos que você precisa resolver manualmente (por exemplo, editar e corrigir).
Uma diretriz a ser observada:
somente faça uma nova reformulação se a ramificação for local e você ainda não a empurrou para remoto!
Isso ocorre principalmente porque o rebasing pode alterar a história que outras pessoas veem e que podem incluir seus próprios commits.
Rastreando ramos
Estes são os ramos que são nomeados origin/branch_name
(ao contrário de apenas branch_name
). Quando você está pressionando e puxando o código de / para repositórios remotos, esse é realmente o mecanismo pelo qual isso acontece. Por exemplo, quando você git push
chama uma ramificação building_groups
, sua ramificação vai primeiro para origin/building_groups
e depois para o repositório remoto. Da mesma forma, se você fizer um git fetch building_groups
, o arquivo recuperado será colocado em sua origin/building_groups
ramificação. Você pode optar por mesclar essa ramificação em sua cópia local. Nossa prática é sempre fazer a git fetch
e uma mesclagem manual em vez de apenas uma git pull
(que faz as duas opções acima em uma etapa).
Buscando novas ramificações.
Obtendo novas ramificações: No ponto inicial de um clone, você terá todas as ramificações. No entanto, se outros desenvolvedores adicionam ramificações e as enviam para o controle remoto, é preciso que haja uma maneira de 'conhecer' essas ramificações e seus nomes para poder localizá-las localmente. Isso é feito por meio de um git fetch
que colocará todas as ramificações novas e alteradas no repositório local usando as ramificações de rastreamento (por exemplo, origin/
). Uma vez fetch
editado, pode- git branch --remote
se listar as ramificações de rastreamento e git checkout [branch]
realmente mudar para uma delas.
Mesclando
A mesclagem é o processo de combinar alterações de código de ramificações diferentes ou de versões diferentes da mesma ramificação (por exemplo, quando uma ramificação local e remota estão fora de sincronia). Se alguém tiver desenvolvido trabalho em uma ramificação e o trabalho estiver completo, pronto e testado, poderá ser mesclado na master
ramificação. Isso é feito git checkout master
para alternar para o master
ramo, então git merge your_branch
. A mesclagem reunirá todos os arquivos diferentes e até alterações diferentes nos mesmos arquivos . Isso significa que ele realmente mudará o código dentro dos arquivos para mesclar todas as alterações.
Ao fazer a checkout
de master
que também é recomendado para fazer um git pull origin master
para obter a versão mais recente do mestre remoto mesclados ao seu mestre local. Se o mestre remoto mudou, ou seja, moved forward
você verá informações que refletem isso durante isso git pull
. Se for esse o caso (mestre alterado) aconselha-se git checkout your_branch
e, em seguida, rebase
para dominar a fim de que as alterações realmente obter 'repetido' em cima do mestre 'novo'. Em seguida, você continuaria atualizando o mestre, como mostra o próximo parágrafo.
Se não houver conflitos, o mestre terá as novas alterações incluídas. Se houver conflitos, isso significa que os mesmos arquivos têm alterações em torno de linhas de código semelhantes que não podem ser mescladas automaticamente. Nesse caso, git merge new_branch
será relatado que há conflitos a serem resolvidos. Você os 'resolve' editando os arquivos (que terão as duas alterações), selecionando as alterações desejadas, excluindo literalmente as linhas das alterações que você não deseja e salvando o arquivo. As alterações são marcadas com separadores como ========
e <<<<<<<<
.
Depois de resolver qualquer conflito, você novamente git add
e git commit
essas alterações para continuar a mesclagem (você receberá feedback do git durante esse processo para guiá-lo).
Quando o processo não funcionar bem, você descobrirá que git merge --abort
é muito útil redefinir as coisas.
Renascimento interativo e esmagamento / reordenação / remoção de confirmações
Se você fez um trabalho em várias etapas pequenas, por exemplo, você confirma o código como 'trabalho em andamento' todos os dias, pode querer 'esmagar' esses muitos pequenos commits em alguns commits maiores. Isso pode ser particularmente útil quando você deseja fazer revisões de código com colegas. Você não deseja reproduzir todas as etapas que você executou (por meio de confirmações), apenas quer dizer que aqui está o efeito final (diff) de todas as minhas alterações para este trabalho em uma confirmação.
O principal fator a ser avaliado ao considerar se é necessário fazer isso é se as confirmações múltiplas são contra o mesmo arquivo ou arquivos mais de uma vez (melhor squash confirma nesse caso). Isso é feito com a ferramenta de rebaseamento interativo. Essa ferramenta permite esmagar confirmações, excluir confirmações, reformular mensagens etc. Por exemplo, git rebase -i HEAD~10
( observação: isso é a ~
, não a-
) traz o seguinte:
Tenha cuidado e use esta ferramenta 'cuidadosamente'. Faça um squash / exclua / reordene de cada vez, saia e salve essa confirmação e, em seguida, insira novamente a ferramenta. Se as confirmações não forem contíguas, você poderá reordená-las (e depois esmagá-las conforme necessário). Você também pode excluir confirmações aqui também, mas realmente precisa ter certeza do que está fazendo quando faz isso!
Forquilhas
Existem duas abordagens principais para colaboração nos repositórios Git. O primeiro, detalhado acima, é diretamente via ramificações que as pessoas puxam e empurram de / para. Esses colaboradores têm suas chaves SSH registradas no repositório remoto. Isso permitirá que eles enviem diretamente para esse repositório. A desvantagem é que você deve manter a lista de usuários. A outra abordagem - bifurcação - permite que qualquer pessoa 'bifurque' o repositório, basicamente fazendo uma cópia local em sua própria conta de repositório Git. Eles podem fazer alterações e, quando terminar, enviar uma 'solicitação de recebimento' (na verdade, é mais um 'envio' deles e uma solicitação de recebimento para o mantenedor do repositório) para obter o código aceito.
Este segundo método, usando garfos, não requer que alguém mantenha uma lista de usuários para o repositório.
GitHub
O GitHub (um repositório remoto) é uma fonte remota na qual você normalmente envia e puxa essas alterações confirmadas se tiver (ou for adicionado a) um repositório desse tipo, portanto local e remoto são realmente bastante distintos. Outra maneira de pensar em um repositório remoto é que é uma .git
estrutura de diretório que vive em um servidor remoto.
Quando você 'bifurca' - na GUI do navegador GitHub, pode clicar neste botão - cria uma cópia ('clone') do código na sua conta do GitHub. Pode ser um pouco sutil a primeira vez que você faz isso, portanto, verifique em qual repositório uma base de código está listada - o proprietário original ou o 'bifurcado' e você, por exemplo:
Depois de obter a cópia local, você pode fazer as alterações que desejar (puxando e empurrando-as para uma máquina local). Quando terminar, você envia uma 'solicitação de recebimento' para o proprietário / administrador do repositório original (soa chique, mas na verdade você apenas clica nisto :) e eles o 'puxam'.
Mais comum para uma equipe que trabalha com código em conjunto é 'clonar' o repositório (clique no ícone 'copiar' na tela principal do repositório). Em seguida, digite git clone
e cole localmente . Isso o configurará localmente e você também pode pressionar e puxar para o local (compartilhado) do GitHub.
Clones
Conforme indicado na seção GitHub, um clone é uma cópia de um repositório. Quando você tem um repositório remoto, emite o git clone
comando em relação à URL e termina com uma cópia local ou clone do repositório. Este clone tem tudo , os arquivos, o ramo principal, os outros ramos, todos os commits existentes, todo o shebang. É nesse clone que você faz suas inclusões e confirmações e, em seguida, o próprio repositório remoto é o que você envia essas confirmações. É esse conceito local / remoto que faz do Git (e sistemas similares a ele, como Mercurial) um DVCS ( Sistema de controle de versão distribuído ), em oposição aos CVSs (sistemas de versão de código) mais tradicionais, como SVN, PVCS, CVS, etc. você confirma diretamente no repositório remoto.
Visualização
A visualização dos conceitos principais pode ser vista em
http://marklodato.github.com/visual-git-guide/index-en.html e
http://ndpsoftware.com/git-cheatsheet.html#loc=index
Se você quiser uma exibição visual de como as alterações estão funcionando, não poderá vencer a ferramenta visual gitg
( gitx
para macOS) com uma GUI que chamo de 'mapa do metrô' (especialmente London Underground), ótimo para mostrar quem fez o que, como as coisas mudam, divergem e se fundem, etc.
Você também pode usá-lo para adicionar, confirmar e gerenciar suas alterações!
Embora o gitg / gitx seja bastante mínimo, o número de ferramentas da GUI continua a se expandir. Muitos usuários de Mac usam o fork do gitx da brotherbard e, para Linux, uma ótima opção é o smart-git, com uma interface intuitiva e poderosa:
Observe que, mesmo com uma ferramenta GUI, você provavelmente executará muitos comandos na linha de comando.
Para isso, tenho os seguintes aliases no meu ~/.bash_aliases
arquivo (que é chamado do meu ~/.bashrc
arquivo para cada sessão do terminal):
# git
alias g='git status'
alias gcob='git checkout -b '
alias gcom='git checkout master'
alias gd='git diff'
alias gf='git fetch'
alias gfrm='git fetch; git reset --hard origin/master'
alias gg='git grep '
alias gits='alias | grep "^alias g.*git.*$"'
alias gl='git log'
alias gl1='git log --oneline'
alias glf='git log --name-status'
alias glp='git log -p'
alias gpull='git pull '
alias gpush='git push '
E eu tenho os seguintes "aliases de git" no meu ~/.gitconfig
arquivo - por que os têm?
Para que a conclusão da ramificação (com a tecla TAB) funcione!
Então, são eles:
[alias]
co = checkout
cob = checkout -b
Exemplo de uso: a git co [branch]
conclusão da guia <para ramificações funcionará.
Ferramenta de Aprendizagem GUI
Você pode achar https://learngitbranching.js.org/ útil para aprender alguns dos conceitos básicos. Captura de tela:
Vídeo: https://youtu.be/23JqqcLPss0
Finalmente, 7 salva-vidas importantes!
Você faz alterações, as adiciona e as confirma (mas não as pressiona) e então oh! você percebe que está no mestre!
git reset [filename(s)]
git checkout -b [name_for_a_new_branch]
git add [file(s)]
git commit -m "A useful message"
Voila! You've moved that 'master' commit to its own branch !
Você bagunça alguns arquivos enquanto trabalha em uma ramificação local e simplesmente deseja voltar ao que teve na última vez que fez git pull
:
git reset --hard origin/master # You will need to be comfortable doing this!
Você começa a fazer alterações localmente, edita meia dúzia de arquivos e, oh, merda, ainda está no ramo mestre (ou em outro):
git checkout -b new_branch_name # just create a new branch
git add . # add the changes files
git commit -m"your message" # and commit them
Você bagunça um arquivo específico em sua ramificação atual e deseja basicamente 'redefinir' esse arquivo (perde as alterações) para como foi a última vez que você o extraiu do repositório remoto:
git checkout your/directories/filename
Na verdade, isso redefine o arquivo (como muitos comandos do Git, ele não é bem conhecido pelo que está fazendo aqui).
Você faz algumas alterações localmente, quer ter certeza de não perdê-las enquanto faz um git reset
ou rebase
: Costumo fazer uma cópia manual de todo o projeto ( cp -r ../my_project ~/
) quando não tenho certeza se posso atrapalhar o Git ou perder informações importantes. alterar.
Você está reestruturando, mas as coisas ficam confusas:
git rebase --abort # To abandon interactive rebase and merge issues
Adicione sua ramificação Git ao seu PS1
prompt (consulte https://unix.stackexchange.com/a/127800/10043 ), por exemplo
O ramo é selenium_rspec_conversion
.