Sou usuário do SVN e agora estou aprendendo o Git.
No SVN, geralmente faço check-out na máquina local de um repositório, que inclui todas as ramificações do meu projeto e eu costumava selecionar a pasta da minha filial na qual me interessava e trabalhava lá.
Eu vejo uma diferença usando o Git.
Atualmente, estou clonando um repositório e clonando um ramo específico usando o gitk.
A pasta do projeto contém apenas o conteúdo desse ramo e não consigo ver todos os ramos como no SVN, o que é um pouco confuso para mim.
Não consigo encontrar uma maneira fácil de ver todas as ramificações no meu repositório local usando o Git.
Eu gostaria de saber se o processo Git que descrevi é "padrão" e, de certa forma, está correto ou está faltando alguma coisa.
Também gostaria de saber como lidar com um processo em que preciso trabalhar em duas ramificações ao mesmo tempo, caso, por exemplo, precise fazer um hotfix no master, mas também mantenha o conteúdo de outra ramificação.
O que é uma convenção de nome de recomendação para tornar as pastas que incluem a ramificação clonada do repositório no Git, por exemplo
myproject-branchname
?
git clone
é mais parecidosvnadmin hotcopy
ousvnrdump
+svnadmin load
do que ésvn checkout
. Comgit
, você não solicitar pedaços do repositório; você copia o repositório inteiro e trabalha com ele localmente, enviando alterações para o repositório "fonte" quando e se lhe apetecer. Git e Subversion usam dois modelos completamente diferentes para controle de origem.git-flow
Respostas:
Bem-vindo à gangue!
Reeducação SVN
Espere um momento. Embora o CVS e o SVN e outro sistema de controle de versão tradicional (ou seja, centralizado) atendam (principalmente) ao mesmo objetivo que os sistemas de controle de versão modernos (ou seja, distribuídos), como mercurial e Git, será muito melhor aprender o Git desde o início, em vez de tentando transferir seu fluxo de trabalho SVN para o Git.
http://hginit.com ( vista sobre archive.org ) por Joel Spolsky (um dos próprios fundadores da Stack Exchange) é um tutorial para mercurial, não Git, mas é de zero-th capítulo, "Subversion Re-educação" é útil para pessoas de comutação longe de SVN para qualquer sistema de controle de versão distribuído, como ele diz o que conceitos SVN você tem que (temporariamente) un -Saiba (ou para
stash
longe , como os usuários do Git poderia dizer) para ser capaz envoltório sua cabeça em torno do distribuída conceitos de sistema de controle de versão e fluxos de trabalho idiomáticos estabelecidos para trabalhar com eles.Assim, você pode ler o capítulo zero e, em geral, apenas substituir a palavra "mercurial" por "Git" e, assim, preparar adequadamente você e sua mente para o Git.
A boa impressão
(Você pode ignorar isso por enquanto.) Enquanto mercurial e Git são muito mais semelhantes entre si do que para SVN, não são algumas diferenças conceituais entre eles, para algumas das declarações e conselhos em "Subversion Re-educação" se tornará tecnicamente errado ao substituir "mercurial" por "Git":
No SVN, tudo é um diretório (mas você não deve necessariamente tratá-lo como tal)
Mas eu tenho interrompido você. Você estava dizendo?
Se, com isso, você quer dizer que fez check-out da pasta raiz do repositório SVN (ou qualquer outra pasta correspondente a mais do que a
trunk
ou a uma única ramificação, por exemplo, no layout de repositório de SVN convencional, abranches
pasta que contém todas as ramificações que não são de tronco) Ouso dizer que você provavelmente usou SVN errado (ish), ou pelo menos abusou um pouco do fato de que tronco, ramificações e tags são todos dobrados em um único espaço de nome (embora hierárquico), juntamente com diretórios nas revisões / base de código.Embora possa ser tentador alterar várias ramificações SVN em paralelo, esse não é o AFAIK, como a SVN deve ser usada. (Embora não tenha certeza sobre quais desvantagens específicas funcionariam dessa maneira.)
No Git, apenas diretórios são diretórios
Cada clone de um repositório Git é ele próprio um repositório Git: Por padrão, ele obtém uma cópia completa do histórico do repositório de origem, incluindo todas as revisões, ramificações e tags. Mas manterá tudo do nosso jeito: o Git o armazena em um tipo de banco de dados, localizado na
.git/
subpasta oculta da pasta raiz do repositório .Mas quais são os arquivos não ocultos que você vê na pasta do repositório?
Quando você é
git clone
um repositório, o Git faz várias coisas. Aproximadamente:.git/
subpasta com o "banco de dados"master
).Essa última etapa significa que o Git consulta a revisão apontada por esse ramo e descompacta a árvore de arquivos armazenada lá (o banco de dados usa alguns meios de compactação e desduplicação) na pasta raiz do repositório. Essa pasta raiz e todas as suas subpastas (excluindo a
.git
subpasta especial ) são conhecidas como "cópia de trabalho" do seu repositório. É aí que você interage com o conteúdo da revisão / filial com check-out atualmente. Eles são apenas pastas e arquivos normais. No entanto, para interagir com o repositório em si (o "banco de dados" de revisões e referências), você usagit
comandos.Vendo ramificações Git e interagindo com ramificações Git
A versão
gitk
que obtive não pode clonar repositórios. Ele só pode exibir o histórico do repositório, criar ramificações e fazer check-out de ramificações. Além disso, não há "clonagem" de um ramo. Você pode clonar apenas repositórios.Você quis dizer que você clonar um repositório usando
git clone ...
e, em seguida, usandogitk
, confira um ramo?Sim, isso é bastante padrão:
git clone ...
git checkout ...
ou use uma ferramenta gráfica comogikt
Talvez:
git branch
git branch -r
ou todas as ramificações comgit branch -a
você pode usar
gitk
para visualizar o histórico completo (todas as tags de filiais etc. que seu representante local conhece) invocando-o comComo trabalhar com várias ramificações em paralelo
Existem diferentes cenários aqui:
Uma nova alteração (ainda a ser criada) precisa ser aplicada a várias ramificações
Use este fluxo de trabalho:
c
partir de uma revisão que já esteja na ancestralidade de todos esses ramos (por exemplo, a revisão que introduziu o bug quando a alteração for uma correção de bug) ou a partir de uma revisão que (incluindo todos os seus ancestrais) seja aceitável para ser introduzida em todos esses ramos.c
.Para cada filial
b
que precisa da mudança:Confira
b
:Mesclar
c
emb
:Remover ramo
c
:Uma mudança existente é necessária em uma ramificação diferente
(... mas sem as outras alterações feitas no local em que essa alteração reside)
Em uma ramificação
a
, você deseja alterar um ou alguns arquivos para o estado exato que eles têm em uma ramificação diferenteb
a
Obtenha o conteúdo do arquivo da filial
b
:(Além de
git checkout
não passar caminhos, isso não muda para ramificaçãob
, apenas obtém o conteúdo do arquivo solicitado a partir dali. Esses arquivos podem ou já não existira
. Se existirem , serão substituídos pelo conteúdob
.)Ao trabalhar em uma ramificação, você deseja ver como estão as coisas em outra ramificação
Confira o ramo em que você deseja trabalhar.
Então, por olhar para o outro ramo,
gitk
tentativa de alternar os botões de opção de "patch" para "árvore")git worktree
para criar um diretório de trabalho separado do mesmo repositório (ou seja, também usando o banco de dados no.git/
diretório do seu repositório local atual), onde você pode verificar essa outra ramificaçãofonte
stash
é ideal.git stash
é bom afastar o trabalho inacabado, por exemplo, para alternar entre ramificações e depois voltar.A menos que você verifique o diretório acima do tronco, no Subversion você geralmente não possui todas as ramificações disponíveis localmente. No Git, todo o conteúdo (confirmações, mensagens, ramificações etc.) é sempre clonado em todas as cópias.
Não é possível, veja acima. Você pode
git checkout branch-name
, mas você não podegit clone something branch-name
. No Subversion, ramificações são pastas. No Git, as ramificações são ponteiros para um commit.Corra
git branch
. Por padrão, ele mostra apenas ramificações locais. Usegit branch --remote
para ver ramificações remotas.fonte
--single-branch
(mesmo apenas a ponta--depth 1
). A diferença entre ramificações locais e remotas conhecidas pelo git é apenas um tipo de rótulo. As ramificações remotas são prefixadas com o nome da fonte remota (geralmenteorigin
). As ramificações locais não têm esse prefixo. Mas, no final, os dados estão disponíveis localmente (a menos que você tenha feito--single-branch
ou algo semelhante). Quando você executagit checkout $branchname
com uma ramificação para a qual não existe nenhuma ramificação local, mas remota, o git configura automaticamente uma ramificação local "rastreando" o controle remoto.Como isso está marcado com git , espero que minha falta de conhecimento sobre SVN seja negligenciável.
Você está clonando todo o repositório remoto, não apenas uma ramificação específica.
O repositório é melhor imaginado como um banco de dados, portanto, você está criando um clone do estado atual do banco de dados remoto. Mas depois disso, você está trabalhando em sua própria cópia desse banco de dados; se você confirmar, alterará seu banco de dados local.
O
fetch
comando é usado para manter o banco de dados local sincronizado com o remoto.Geralmente a partir desse banco de dados local, você faz check-out de uma filial para trabalhar. Isso nada mais é do que um marcador interno para o git, onde seu trabalho atual começou.
Digamos que você esteja trabalhando em um repositório simples, onde não há ramificações além disso
master
, você pode dar uma olhada na.git
pasta para desvendar a "mágica":Suponha que seu último commit (on
master
) foi182e8220b404437b9e43eb78149d31af79040c66
, você encontrará exatamente isso emcat .git/refs/heads/master
.git checkout -b mybranch
Depois que você ramifica uma nova ramificação , você encontrará exatamente o mesmo ponteiro no arquivocat .git/refs/heads/mybranch
.Ramos não passam de "ponteiros". O marcador "ativo" é chamado de
HEAD
.Se você quiser saber onde
HEAD
está:cat .git/HEAD
que dizref: refs/heads/mybranch
, por exemplo , que, por sua vez, aponta (cat .git/refs/heads/mybranch
) para um hash de confirmação78a8a6eb6f82eae21b156b68d553dd143c6d3e6f
As confirmações reais são armazenadas na
objects
pasta (como é um tópico próprio).Não confunda o
working directory
"git-database" como um todo. Como eu disse acima, seu diretório de trabalho é apenas um instantâneo de (talvez) um subconjunto.Digamos que você tenha ramificações diferentes, seu diretório de trabalho é dedicado a trabalhar somente nessa ramificação (embora você possa colocar o trabalho de lá em outro lugar).
Geralmente, se você deseja ver quais ramos são definidos para o projeto, você tem a possibilidade de
git branch
para filiais locaisgit branch --remote
para filiais remotasgit branch -a
para ambos(ou
git branch -v
)Como o git é um sistema de controle de versão distribuído, não é apenas possível, mas incentivado, criar diferentes ramificações localmente / remotas.
Meu fluxo de trabalho típico é:
Quando o recurso estiver concluído:
WIP
ramificação (com rebasing interativo) = fazer uma única confirmação a partir dessaWIP
ramificação na ramificação de recursos e ofereça que (se você trabalha com o github, essa oferta seria chamada de "solicitação de recebimento") para integrar na ramificação estável (mestre).Depende de como o seu projeto está estruturado:
Digamos que você tenha um mestre estável. E os recursos são desenvolvidos apenas a partir desse ramo estável - portanto, geralmente ele está atrás de um ramo de recurso. Então você teria um último commit no master que seria a raiz do ramo do recurso.
Em seguida, você faria um commit na ramificação principal e poderia decidir mesclar as duas ramificações ou fazer uma nova reformulação (que é uma espécie de mesclagem para usuários com necessidades avançadas, por assim dizer).
Ou você sempre pode fazer alterações nos galhos (por exemplo
master
) e selecioná-los em outros galhos.É com você.
Normalmente, você acaba com o nome dos repositórios.
Mas há ocasiões em que isso não é desejado:
por exemplo, você clona oh-my-zsh com
git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
Here.oh-my-zsh
é explicitamente nomeado como o destino.fonte
Git clone
na verdade, clona o repositório inteiro, mas define seu diretório de trabalho como o padrão (geralmente mestre).Você pode ver outras ramificações usando
git branch
para ver ramificações locais ougit branch -r
remotas e depoisgit checkout
mudar para uma ramificação existente ou criar uma nova com base na ramificação atual.Você deve ler a documentação do git para obter mais detalhes, e o Atlassian também possui alguns bons artigos.
fonte
Ramos no git e svn são coisas fundamentalmente diferentes.
No svn, um ramo (ou uma tag) é um diretório no repositório.
No git, um branch (ou uma tag) é um ponteiro para um commit.
Com o svn, você pode se desejar fazer o checkout da raiz do repositório. Isso significa que você tem todas as ramificações e tags verificadas de uma só vez. Afirmar que esta não é a maneira normal de usar svn.
Uma ramificação git não é um diretório; portanto, não há como "verificar a raiz do repositório". Há algum suporte para várias árvores de trabalho, então eu acho que você pode montar um script para fazer check-out de todos os ramos ao mesmo tempo, se você realmente quiser, mas seria um pouco incomum pensar nisso.
Além disso, com o SVN, há exatamente um repositório. Com o git, todo desenvolvedor tem seu próprio repositório. Isso significa que os desenvolvedores podem trabalhar offline, mas também significa que diferentes desenvolvedores podem ter uma idéia diferente do que está em cada filial.
Em virtude de serem diretórios e em virtude do modelo de história linear simples do svn, os ramos do svn têm históricos robustos. Se você quiser saber o que estava na ramificação x na data y, pode facilmente fazer essa pergunta.
Os ramos Git, por outro lado, não têm realmente histórias. Existe o "reflog", mas é mais um mecanismo de recuperação de desastres do que uma história de longo prazo. Em particular, o reflog não pode ser lido remotamente e é desativado por padrão para repositórios nus.
Compromissos, é claro, têm histórias, mas essas histórias não são suficientes para responder à pergunta do "que estava no ramo x do relatório na data z".
Você pode listar todas as ramificações locais, digitando "git branch".
Você pode listar todas as ramificações locais e remotas usando "git branch -a"
Algumas opções.
Você pode confirmar suas alterações no "outro ramo", alternar para mestre, fazer o seu trabalho lá e depois voltar.
Você também pode criar uma árvore de trabalho extra. Google "git-worktree" para obter detalhes sobre a sintaxe.
Eu não acho que exista uma convenção estabelecida. Fazer o check-out de várias árvores de trabalho ao mesmo tempo é a exceção, não a regra.
fonte