Eu quero entender a diferença entre um ramo, um garfo e um clone no Git?
Da mesma forma, o que significa quando eu faço um git fetch
em oposição a umgit pull
?
Além disso, o que rebase
significa em comparação commerge
?
Como posso esmagar um indivíduo comprometido?
Como eles são usados, por que são usados e o que representam?
Como o GitHub aparece?
Respostas:
Um clone é simplesmente uma cópia de um repositório. Na superfície, seu resultado é equivalente a
svn checkout
, onde você baixa o código-fonte de outro repositório. A diferença entre VCS centralizados como o Subversion e DVCSs como o Git é que no Git, quando você clona, você está realmente copiando todo o repositório de origem, incluindo todo o histórico e ramificações. Agora você tem um novo repositório em sua máquina e quaisquer confirmações feitas nesse repositório. Ninguém verá nenhuma alteração até que você envie essas confirmações para outro repositório (ou o original) ou até que alguém receba confirmações do seu repositório, se estiver acessível ao público.Uma ramificação é algo que está dentro de um repositório. Conceitualmente, representa um segmento de desenvolvimento. Você geralmente tem uma ramificação principal, mas também pode ter uma ramificação na qual está trabalhando em algum recurso xyz e outro para corrigir o erro abc. Quando você faz check-out de uma ramificação, quaisquer confirmações feitas permanecerão nessa ramificação e não serão compartilhadas com outras ramificações até que você as mescle ou as refaça na ramificação em questão. Obviamente, o Git parece um pouco estranho quando se trata de ramificações até que você veja o modelo subjacente de como as ramificações são implementadas. Em vez de explicar por conta própria (eu já falei demais, acho), vou linkar para a explicação da "ciência da computação" de como o Git modela ramificações e confirmações, retirado do site do Git:
http://eagain.net/articles/git-for-computer-scientists/
Um garfo não é realmente um conceito do Git, é mais uma ideia política / social. Ou seja, se algumas pessoas não estiverem satisfeitas com o andamento de um projeto, poderão pegar o código-fonte e trabalhar nele separadamente dos desenvolvedores originais. Isso seria considerado um garfo. O Git facilita a bifurcação porque todos já têm sua própria cópia "principal" do código-fonte, por isso é tão simples quanto cortar os laços com os desenvolvedores do projeto original e não exige a exportação do histórico de um repositório compartilhado, como você pode fazer com o SVN .
EDIT: como eu não conhecia a definição moderna de "fork" usada por sites como o GitHub, dê uma olhada nos comentários e também na resposta de Michael Durrant abaixo da minha para obter mais informações.
fonte
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 apenasbranch_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çãobuilding_groups
, sua ramificação vai primeiro paraorigin/building_groups
e depois para o repositório remoto. Da mesma forma, se você fizer umgit fetch building_groups
, o arquivo recuperado será colocado em suaorigin/building_groups
ramificação. Você pode optar por mesclar essa ramificação em sua cópia local. Nossa prática é sempre fazer agit fetch
e uma mesclagem manual em vez de apenas umagit 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 vezfetch
editado, pode-git branch --remote
se listar as ramificações de rastreamento egit 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 é feitogit checkout master
para alternar para omaster
ramo, entãogit 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
demaster
que também é recomendado para fazer umgit 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 issogit pull
. Se for esse o caso (mestre alterado) aconselha-segit 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
egit 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):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:
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!
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
: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):
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:
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
ourebase
: 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:
Adicione sua ramificação Git ao seu
PS1
prompt (consulte https://unix.stackexchange.com/a/127800/10043 ), por exemploO ramo é
selenium_rspec_conversion
.fonte
Aqui está a imagem de Oliver Steele de como tudo se encaixa:
fonte
Fork Vs. Clone - duas palavras que significam cópia
Por favor, veja este diagrama. (Originalmente em http://www.dataschool.io/content/images/2014/Mar/github1.png ).
Garfo
Clone
fonte
anidea
diretamente ao seu repositório e economizar as tarefas de manter seu garfo atualizado. OTOH, se você não conseguir chegar a um acordo com Joe, você pode continuar desenvolvendo e usando o garfo (e ver se consegue fazê-lo mudar de idéia mais tarde).Apenas para adicionar aos outros, uma nota específica para bifurcação.
É bom perceber que tecnicamente, clonar o repositório e bifurcar o repositório são a mesma coisa. Faz:
e você pode dar um tapinha nas costas - você acabou de comprar outro repositório.
Git, como VCS, é, na verdade, tudo sobre
clonagembifurcada. Além de "apenas navegar" usando a interface do usuário remota como o cgit, há muito pouco a ver com o repositório git que não envolvebifurcaçãoclonar o repo em algum ponto.Contudo,
quando alguém diz que eu peguei o repo X , significa que eles criaram um clone do repo em outro lugar com a intenção de expô- lo a outras pessoas, por exemplo, para mostrar algumas experiências ou aplicar diferentes mecanismos de controle de acesso (por exemplo, para permitir que pessoas sem Acesso ao Github, mas com a conta interna da empresa para colaborar).
Fatos que: o repositório de criação é provavelmente criado com outro comando que
git clone
, provavelmente, está hospedado em algum lugar do servidor, em oposição ao laptop de alguém, e provavelmente possui um formato ligeiramente diferente (é um "repositório simples", ou seja, sem árvore de trabalho) são todos apenas detalhes técnicos.O fato de que provavelmente conterá diferentes conjuntos de ramificações, tags ou confirmações é provavelmente a razão pela qual eles fizeram isso em primeiro lugar.
(O que o Github faz quando você clica em "fork" é apenas clonar com adição de açúcar: clona o repositório para você, coloca-o em sua conta, grava o "bifurcado de" em algum lugar, adiciona o controle remoto chamado "upstream" e, o mais importante, reproduz a bela animação.)
Quando alguém diz que clonei o repo X , significa que eles criaram um clone do repo localmente em seu laptop ou desktop, com a intenção de estudá-lo, brincar com ele, contribuir com ele ou criar algo a partir do código-fonte.
A beleza do Git é que isso tudo se encaixa perfeitamente: todos esses repositórios compartilham a parte comum da cadeia de consolidação de
bloco, para que seja possível (com segurança, veja nota abaixo) mesclar as mudanças entre todos esses repositórios, conforme você achar melhor.Nota: "com segurança" desde que você não reescreva a parte comum da cadeia e contanto que as alterações não sejam conflitantes.
fonte