Controle de Versão: Conceitos e Tipos PDF

Summary

Este documento fornece uma introdução ao controle de versão, destacando seus conceitos e funcionalidades. Aborda diferentes tipos de controle de versões, incluindo o sistema Git, com exemplos práticos. O documento explica a importância do controle de versão em contextos como desenvolvimento de software, design e edição de vídeo.

Full Transcript

# Controle de Versão: Conceitos e Tipos ## Introdução ao Controle de Versão O controle de versão é um software capaz de gerenciar versões de qualquer tipo de arquivo, incluindo: - Arquivos de texto (txt, docx) - Arquivos XML - Planilhas (xls) - Arquivos web (html, css) - PDFs - Arquivos de vídeo -...

# Controle de Versão: Conceitos e Tipos ## Introdução ao Controle de Versão O controle de versão é um software capaz de gerenciar versões de qualquer tipo de arquivo, incluindo: - Arquivos de texto (txt, docx) - Arquivos XML - Planilhas (xls) - Arquivos web (html, css) - PDFs - Arquivos de vídeo - Arquivos de imagem Embora seja comumente associado ao desenvolvimento de software, o controle de versão não se limita a essa aplicação. Por exemplo, designers e editores de vídeo podem utilizá-lo para rastrear alterações em seus projetos, como adição de transições, músicas e efeitos. ## Principais Funcionalidades ### 1. Histórico de Alterações - Permite visualizar mudanças feitas em diferentes períodos - Possibilita retornar a versões anteriores quando necessário - Mantém uma linha do tempo completa das modificações ### 2. Segurança - Permite fazer alterações com segurança - Em caso de erro, é possível reverter para versões anteriores - Mantém histórico completo das mudanças ### 3. Trabalho Paralelo - Permite trabalho simultâneo de múltiplas pessoas - Suporta diferentes equipes trabalhando no mesmo projeto - Possibilita criar diferentes versões do mesmo arquivo ### 4. Branches (Ramos) - Permite criar diferentes versões a partir de um único ponto - Possibilita juntar alterações de diferentes versões - Permite descartar versões que não deram certo sem afetar outras ### 5. Rastreabilidade - Registra quem fez as alterações - Registra horário das modificações - Identifica quais arquivos foram alterados - Auxilia na identificação de origem de erros ## Tipos de Controle de Versão ### 1. Centralizado - Todo o histórico e controle ficam em um servidor central - Clientes buscam versões específicas no servidor - Exemplos: Subversion (SVN), Visual Studio TFS, PerForce - Vantagens: - Facilidade de localização das informações - Processo centralizado - Desvantagens: - Dependência do servidor - Risco de perda total em caso de falha do servidor ### 2. Distribuído - Tanto servidor quanto clientes possuem o histórico completo - Permite ações locais sem dependência do servidor - Exemplos: Git, Mercurial - Vantagens: - Maior eficiência em operações locais - Redundância de dados - Independência do servidor central ## Características Específicas do Git - Ações locais rápidas e eficientes - Suporte ao desenvolvimento não linear - Integridade do histórico - Eficiência independente do tamanho do projeto - Mantém histórico mesmo após remoção de arquivos - Adequado para projetos pequenos e grandes - Complexidade linear independente do tamanho do projeto ## Importância do Controle de Versão O controle de versão resolve problemas comuns como: - Proliferação de múltiplas cópias de arquivos - Dificuldade em identificar versões finais - Confusão no gerenciamento de modificações - Perda de histórico de alterações É utilizado por grandes empresas, demonstrando sua eficácia e confiabilidade no gerenciamento de versões de arquivos e projetos. # Git - Guia de Configuração e Uso ## Configuração Inicial Para começar a utilizar o Git, é necessário realizar algumas configurações iniciais. O Git pode ser usado em qualquer sistema operacional (Windows, Mac ou Linux), pois seus comandos são independentes de plataforma. Para configurar o Git pela primeira vez, é preciso identificar o usuário através do nome e email usando os seguintes comandos: ```bash git config --global user.name "Seu Nome" git config --global user.email "[email protected]" ``` Estas configurações são salvas globalmente e não precisam ser repetidas a cada uso do Git. Para verificar se as configurações foram aplicadas corretamente, use: ```bash git config --global user.name git config --global user.email ``` Para ver todas as configurações do Git, utilize: ```bash git config --list ``` ## Interface e Ambiente No Windows, é possível usar o Git Bash ou o CMD (prompt de comando). O Git Bash oferece uma interface mais amigável e colorida, com melhor visualização das alterações. Para abrir o Git Bash, basta clicar com o botão direito em qualquer pasta e selecionar "Git Bash Here". ## Criando um Repositório Para criar um repositório Git, navegue até a pasta desejada e execute: ```bash git init ``` Este comando inicializa um repositório Git vazio na pasta selecionada. A pasta pode estar vazia ou já conter arquivos - não há diferença para o Git. Após a inicialização, uma pasta oculta `.git` é criada, contendo as configurações do repositório. Por padrão, o branch principal é chamado de "master", mas pode ser alterado usando: ```bash git config --global init.defaultBranch nome-do-branch ``` ## Gerenciando Arquivos Para verificar o status do repositório e seus arquivos: ```bash git status ``` Quando um arquivo é criado, ele aparece como "untracked" (não rastreado). Para começar a rastrear um arquivo: ```bash git add nome-do-arquivo ``` Para adicionar todos os arquivos de uma vez, use uma das opções: ```bash git add. git add -A git add --all ``` ## Commits Após adicionar os arquivos, é possível criar um commit para salvar as alterações no histórico do Git: ```bash git commit -m "Mensagem descritiva do commit" ``` A mensagem do commit deve ser descritiva mas concisa, explicando as principais alterações realizadas. É importante criar mensagens significativas, pois elas ajudam a entender o histórico de alterações do projeto. Cada commit representa uma versão do projeto e contém informações como: - Quem fez as alterações - O que foi alterado - Quais arquivos foram modificados - Data e hora das alterações O Git mantém todo o histórico de commits, permitindo rastrear todas as mudanças realizadas no projeto ao longo do tempo. É importante notar que nunca se deve remover a pasta `.git` manualmente, pois isso apaga todo o histórico do repositório. A pasta `.git` deve ser tratada como intocável, sendo manipulada apenas através dos comandos do Git. # Estados e Ciclo de Vida de Arquivos no Git ## Estados Fundamentais O Git possui quatro estados bem definidos para os arquivos em um repositório. Quando um arquivo é inicialmente criado em um repositório, ele assume o estado de "Untracked" (não rastreado). Neste estado, o Git reconhece a existência do arquivo, mas não realiza nenhuma ação sobre ele. Quando decidimos que um arquivo é importante e deve ser monitorado, realizamos uma adição através do comando `git add`. Neste momento, o arquivo passa para o estado "Staged" (preparado). Este estado pode ser comparado a um artista que está nos bastidores, se preparando para entrar no palco - ainda não está em cena, mas está se preparando, aquecendo e repassando suas falas. Após realizar um commit, o arquivo passa para o estado "Unmodified" (não modificado). Este é considerado um estado neutro, onde o arquivo está presente, o Git tem conhecimento dele, mas não há nenhuma modificação pendente. O arquivo está simplesmente "quieto". Quando realizamos alterações em um arquivo que já está sendo rastreado pelo Git (tracked), ele passa para o estado "Modified" (modificado). Neste estado, o Git reconhece que houve mudanças no conteúdo do arquivo em relação à sua última versão commitada. ## Transições entre Estados É possível realizar várias transições entre estes estados: 1. De "Untracked" para "Staged" através do `git add` 2. De "Staged" para "Unmodified" através do `git commit` 3. De "Unmodified" para "Modified" quando o arquivo é alterado 4. De "Modified" para "Staged" através do `git add` 5. De "Modified" para "Unmodified" ao descartar as alterações 6. De "Unmodified" para "Untracked" ao remover o arquivo do repositório ## Situações Práticas ### Arquivo em Múltiplos Estados Um arquivo pode estar em dois estados simultaneamente. Por exemplo, quando um arquivo é adicionado à área de preparação (staged) através do `git add`, o Git captura uma imagem do arquivo naquele momento específico. Se posteriormente o arquivo for modificado, ele aparecerá tanto na área de preparação (com sua versão anterior) quanto como arquivo modificado (com suas alterações mais recentes). ### Remoção de Arquivos da Área de Preparação Se um arquivo for adicionado por engano à área de preparação, existem comandos para reverter esta ação: - Para remover um arquivo específico: `git rm --cached ` - Para remover todos os arquivos: `git rm --cached -r.` ### Arquivos Sensíveis É importante ter cuidado ao adicionar arquivos com informações sensíveis (como senhas) ao repositório. Se um arquivo contendo informações confidenciais for adicionado por engano, ele deve ser removido imediatamente da área de preparação usando os comandos mencionados acima. ## Estados Superiores Existem dois estados superiores que englobam os quatro estados básicos: 1. **Tracked**: Engloba os estados Unmodified, Modified e Staged. Neste estado, o Git monitora todas as alterações que ocorrem no arquivo. 2. **Untracked**: Representa apenas o estado inicial, onde o arquivo existe mas o Git não o monitora ativamente. Essa estrutura de estados permite ao Git manter um controle preciso sobre as mudanças em cada arquivo do repositório, facilitando o versionamento e o gerenciamento do código. # Navegação entre Versões ## Histórico de Commits e Comando `git log` O Git permite rastrear alterações no projeto através do histórico de commits. O comando `git log` exibe uma lista detalhada dos commits, ordenados do mais recente para o mais antigo. Cada commit possui: - **Hash único**: Gerado pelo algoritmo SHA-1 (ex: `a1b2c3d4`), que identifica exclusivamente o commit. - **Autor**: Nome e e-mail configurados no Git (via `git config --global user.name` e `git config --global user.email`). - **Data e horário**: Incluindo fuso horário. - **Mensagem**: Descrição das alterações, cuja clareza é crucial para entender o contexto das mudanças. **Comandos úteis**: - `git log --oneline`: Exibe commits resumidos em uma linha (hash + mensagem). - `git log -n 3`: Limita a exibição aos últimos 3 commits. - `git log --patch`: Mostra diferenças detalhadas (linhas adicionadas/removidas) entre versões. - `git log --stat`: Exibe estatísticas das alterações (arquivos modificados e quantidade de linhas). --- ## Visualização de Alterações com `git diff` Para inspecionar mudanças antes de commitar: 1. **Alterações não stageadas**: ```bash git diff ``` Compara arquivos modificados com a última versão commitada. 2. **Alterações stageadas**: ```bash git diff --staged ``` Mostra diferenças entre a área de preparação (staging) e o último commit. **Exemplo**: Se um arquivo `relatorio.txt` teve a linha "Versão 4" alterada para "Versão 5", o `git diff` destacará essa modificação. --- ## Navegação Temporal com `git checkout` Para acessar versões anteriores do projeto: ```bash git checkout ``` **Exemplo**: ```bash git checkout 8876a1b ``` Isso permite visualizar arquivos como estavam no momento do commit especificado. Para retornar à versão mais recente: ```bash git checkout master ``` **Atenção**: Ao acessar um commit antigo, o Git entra em modo *detached HEAD*, onde novas alterações não são vinculadas a um branch. Ideal apenas para consulta. --- ## Modificação de Commits Existentes (`git commit --amend`) Para corrigir erros no último commit (mensagem ou arquivos esquecidos): 1. **Alterar mensagem**: ```bash git commit --amend -m "Nova mensagem" ``` 2. **Adicionar arquivos esquecidos**: ```bash git add arquivo-esquecido.txt git commit --amend --no-edit ``` **Importante**: Evite modificar commits já compartilhados em repositórios remotos, pois isso pode causar inconsistências. --- ## Configuração do Editor Padrão Para substituir o editor Vim por um de sua preferência (ex: Visual Studio Code): ```bash git config --global core.editor "code --wait" ``` **Passo a passo**: 1. Instale o editor desejado. 2. Execute o comando acima substituindo `code` pelo comando do seu editor (ex: `atom`, `subl`). 3. Ao usar `git commit --amend`, o editor configurado abrirá para editar a mensagem. --- ## Fluxo de Trabalho com `git add` e `git commit` 1. **Modificar arquivos**: Edite ou crie novos arquivos. 2. **Verificar status**: ```bash git status ``` 3. **Adicionar alterações à staging area**: ```bash git add. # Adiciona todos os arquivos git add arquivo.txt # Adiciona um arquivo específico ``` 4. **Commitar**: ```bash git commit -m "Descrição das alterações" ``` --- ## Boas Práticas - **Mensagens claras**: Descreva o *porquê* da alteração, não apenas o *o que*. Ex: `Corrige cálculo de impostos` em vez de `Alteração no arquivo X`. - **Commits atômicos**: Cada commit deve representar uma única mudança lógica. - **Evitar commits grandes**: Divida alterações complexas em commits menores para facilitar revisões. Esta documentação sintetiza os principais conceitos e comandos abordados, garantindo um uso eficiente do Git em projetos de software. # Controle de Versão com Git ## Gerenciamento de Arquivos com.gitignore Arquivos gerados automaticamente, como pastas de configuração local (*.gradle* em projetos Android) ou arquivos temporários, não devem ser versionados. Para ignorá-los, utiliza-se o arquivo **.gitignore**. Este arquivo permite definir padrões de nomes ou extensões que o Git deve desconsiderar. Por exemplo, para ignorar todos os arquivos *.bmp*, adicione a linha `*.bmp` no.gitignore. Ao adicionar um arquivo ao.gitignore após ele já ter sido versionado, o Git continuará a rastrear suas alterações. Para parar de rastrear um arquivo já commitado, use o comando `git update-index --skip-worktree [nome-do-arquivo]`. Isso faz com que o Git ignore futuras modificações no arquivo, mas mantém seu histórico. Para reverter essa ação, utilize `git update-index --no-skip-worktree [nome-do-arquivo]`. Exemplo de.gitignore para projetos Android: ```.gradle/ build/ *.log ``` --- ## Comandos para Desfazer Alterações ### Reverter Arquivos Rastreados - **`git checkout [nome-do-arquivo]`**: Reverte um arquivo modificado para a versão do último commit. Perde todas as alterações não commitadas. Exemplo: `git checkout meu_arquivo.txt` remove as mudanças feitas desde o último commit. - **`git restore --staged [nome-do-arquivo]`**: Remove um arquivo da área de staging (preparação), mantendo as alterações no diretório de trabalho. Útil se o arquivo foi adicionado por engano com `git add`. Exemplo: `git restore --staged config.txt`. ### Remover Arquivos Não Rastreados - **`git clean -f`**: Remove arquivos não rastreados do diretório de trabalho. Use com cautela, pois a ação é irreversível. Exemplo: `git clean -f` exclui todos os arquivos não versionados. ### Desfazer Tudo - **`git reset --hard`**: Reverte todas as alterações (rastreadas e não rastreadas) para o último commit. Combinado com `git clean -f`, restaura o repositório ao estado original: ``` git reset --hard git clean -f ``` --- ## Trabalhando com Repositórios Remotos ### Clonagem de Repositórios O comando **`git clone`** cria uma cópia local de um repositório remoto, incluindo todo o histórico de commits. Exemplo para clonar um repositório do GitHub: ``` git clone https://github.com/usuario/repositorio.git ``` Após a clonagem, o repositório remoto é referenciado como **`origin`**. Para sincronizar alterações locais com o remoto, comandos como `git push` e `git pull` são utilizados (não detalhados nas transcrições, mas mencionados como próximos passos). ### Exemplo de Clonagem Local Para duplicar um repositório local em outra pasta: ``` git clone /caminho/do/repositorio/ pasta-destino ``` Isso replica todos os arquivos, histórico e branches, permitindo trabalho distribuído. --- ## Considerações sobre Estados do Git - **Arquivos não rastreados**: São ignorados até serem adicionados com `git add`. - **Arquivos em staging**: Preparados para commit, mas podem ser removidos com `git rm --cached [arquivo]`. - **Arquivos modificados**: Alterações podem ser revertidas com `git checkout` ou `git restore`. O Git gerencia estados de forma granular, permitindo controle preciso sobre quais alterações são mantidas, descartadas ou sincronizadas. A combinação de comandos como `reset`, `checkout` e `clean` oferece flexibilidade para corrigir erros ou reiniciar o trabalho sem perder o histórico. --- ## Notas sobre Repositórios Distribuídos Cada clone de um repositório contém uma cópia completa do histórico, permitindo trabalho offline e redundância. Alterações em um clone não afetam outros repositórios até que sejam explicitamente sincronizadas (via `push` ou `pull`). Isso facilita colaboração em equipe e protege contra perda de dados. # Utilização do Git e GitHub para Controle de Versão e Colaboração Este documento detalha os procedimentos e conceitos relacionados ao uso do Git e GitHub para gerenciamento de repositórios, sincronização de alterações e colaboração em projetos. Abaixo estão as informações organizadas de acordo com os tópicos abordados. --- ## Sincronização de Alterações entre Repositório Local e Remoto Quando há mudanças no servidor remoto (GitHub) que não estão presentes no repositório local, o comando `git pull` é utilizado para trazer essas atualizações. Este comando combina `git fetch` (busca as alterações) e `git merge` (integra as alterações ao código local). Por exemplo, após editar um arquivo HTML diretamente no GitHub (como alterar o título "Lorem Ipsum" para "Aprendendo sobre Git"), é necessário executar `git pull` para sincronizar a versão local com a remota. Isso evita a necessidade de clonar o repositório novamente. ### Passos para Edição Direta no GitHub: 1. Acesse o arquivo no repositório remoto e clique no ícone de edição (lápis). 2. Modifique o conteúdo (ex.: substituir "Lorem Ipsum" por "Aprendendo sobre Git"). 3. Adicione uma mensagem de commit (ex.: "Atualização do título"). 4. Selecione a branch principal (ex.: `main`) e confirme o commit. 5. No repositório local, execute `git pull` para receber as alterações. --- ## Criação de Repositórios no GitHub Para criar um novo repositório: 1. Acesse o GitHub e clique em **Novo repositório**. 2. Defina um **nome único** (ex.: `quit-happy`). 3. Adicione uma descrição opcional (ex.: "Projeto de estudo"). 4. Escolha entre **Público** (visível a todos) ou **Privado** (acesso restrito). 5. Opções adicionais: - **README.md**: Arquivo de documentação inicial (usado para descrever o projeto). - **.gitignore**: Lista de arquivos/pastas a serem ignorados pelo Git (exemplo: arquivos temporários). - **Licença**: Define os termos de uso do projeto (ex.: MIT, GPL). 6. Clique em **Criar repositório**. ### Importância do README.md: O arquivo `README.md` é essencial para documentar o projeto, incluindo instruções de uso, dependências e exemplos. Ele utiliza sintaxe Markdown para formatação (títulos, listas, links). Um README bem elaborado facilita a compreensão do projeto por outros colaboradores. --- ## Introdução ao GitHub: Funcionalidades e Contexto Histórico O GitHub é uma plataforma de hospedagem de repositórios Git, com funcionalidades como controle de versão, branches, pull requests e colaboração em equipe. Diferencia-se de serviços como Google Drive por suportar histórico detalhado de alterações e workflows complexos. ### Estatísticas e Relevância: - Mais de **83 milhões de desenvolvedores** ativos. - **200 milhões de repositórios** hospedados. - Adquirido pela Microsoft em 2018 por US$ 7,5 bilhões. ### Planos de Uso: - **Gratuito**: Repositórios públicos e privados ilimitados. - **Team**: Para colaboração em equipe (pago). - **Enterprise**: Soluções corporativas (pago). --- ## Vinculação de Repositórios Locais e Remotos Para associar um repositório local a um remoto: 1. **Clonar um repositório existente**: ```bash git clone ``` Exemplo: `git clone https://github.com/usuario/repositorio.git`. 2. **Adicionar um remote manualmente**: ```bash git remote add origin ``` O nome `origin` é convencional, mas pode ser alterado (ex.: `git remote add teste `). 3. **Verificar remotes configurados**: ```bash git remote -v ``` ### Alteração de URL Remota: Se o repositório mudar de nome ou URL, atualize a configuração local com: ```bash git remote set-url origin ``` --- ## Envio de Alterações para o Repositório Remoto (Git Push) Após realizar commits locais, envie as alterações para o GitHub com: ```bash git push origin main ``` - `origin`: Nome do remote. - `main`: Branch de destino. ### Verificações: - Use `git status` para confirmar se há commits não enviados. - Após o push, atualize a página do repositório no GitHub para verificar as alterações. ### Autenticação: Na primeira execução do `git push`, o GitHub solicitará credenciais (usuário e senha). O Git Credential Manager armazena essas informações para futuras operações. --- ## Trabalhando com Branches e Merge O GitHub utiliza `main` como branch padrão (anteriormente `master`). Para sincronizar branches: - `git pull`: Atualiza a branch local com alterações remotas. - `git push`: Envia commits locais para a branch remota. Em caso de conflitos (ex.: alterações simultâneas no mesmo arquivo), o Git solicitará a resolução manual antes de concluir o merge. --- ## Boas Práticas e Considerações Finais 1. **Commits Descritivos**: Mensagens claras ajudam a rastrear alterações (ex.: "Correção de bug no login"). 2. **Branching Estratégico**: Use branches separados para funcionalidades específicas. 3. **Atualizações Frequentes**: Execute `git pull` regularmente para evitar conflitos. 4. **Documentação**: Mantenha o `README.md` atualizado e utilize `.gitignore` para evitar arquivos desnecessários. Para projetos públicos, lembre-se de que qualquer pessoa pode visualizar o código, mas apenas colaboradores autorizados podem alterá-lo. Repositórios privados são ideais para projetos em estágio inicial ou com informações sensíveis. # Funcionalidades e Configurações Essenciais no GitHub ## Gerenciamento de Projetos com Issues, Milestones e Labels **Issues (Problemas ou Solicitações)** são utilizadas para relatar problemas, sugerir melhorias ou discutir ideias em um projeto. Para criar uma Issue, é necessário descrever o título, detalhar os passos para reproduzir o problema (se aplicável) e adicionar formatações como negrito, itálico ou listas para melhor organização. Issues podem ser categorizadas com **Labels** (etiquetas), como *bug*, *documentação*, *melhoria*, ou *good first issue* (indicando tarefas adequadas para novos contribuidores). Projetos maduros, como o exemplo citado com mais de 1.100 Issues, costumam ter Labels específicos para componentes (ex: *Router*, *Forms*) ou prioridades (ex: *P1*, *P2*). **Milestones (Marcos)** agrupam Issues relacionadas a objetivos específicos, como lançamentos de versões ou conclusão de módulos. Ao criar um Milestone, é possível definir uma data limite e associar Issues existentes. Por exemplo, um Milestone "Site mais colorido" pode incluir uma Issue proposta pela comunidade. Projetos grandes utilizam Milestones para organizar tarefas em categorias como *backlog* ou *triagem*. **Labels** são gerenciados pelos donos do repositório e servem para filtrar e priorizar Issues. Projetos como o *Handler* possuem centenas de Labels para refletir processos complexos. É possível personalizar Labels conforme as necessidades do projeto, como adicionar tags para identificar componentes ou status de revisão. --- ## Interação com a Comunidade e Fork de Repositórios A funcionalidade **Watch** permite receber notificações sobre atividades em repositórios específicos, como novos commits ou discussões. **Stars** são usados para favoritar repositórios, facilitando o acesso posterior através da seção *Your Stars*. O **Fork** cria uma cópia independente de um repositório na conta do usuário, permitindo modificações sem afetar o projeto original. Por exemplo, ao fazer Fork do repositório *Kit Apple*, é possível editar arquivos livremente. Para sincronizar com alterações do repositório original, utiliza-se o comando *Sync fork*, que atualiza a branch local com os commits mais recentes. Projetos open source incentivam Forks para que contribuidores proponham mudanças via Pull Requests. --- ## Contribuição com Pull Requests (PRs) Um **Pull Request** é uma solicitação para integrar alterações de um Fork ao repositório original. O processo inclui: 1. Editar arquivos no Fork (ex: modificar um título no README). 2. Criar um PR descrevendo as mudanças e referenciando a branch de destino (ex: *main* do projeto original). 3. Revisão por mantenedores, que podem comentar, solicitar ajustes ou aprovar o PR. Em projetos como o *Engler*, com mais de 25.000 commits, PRs são essenciais para manter a qualidade. É comum configurar regras como *Requerer aprovações* (ex: 3 revisores) antes do merge. PRs fechados sem aprovação permanecem no histórico, facilitando a auditoria. --- ## Documentação com Arquivos README.md O arquivo **README.md** é exibido na página inicial do repositório e fornece informações essenciais sobre o projeto. Utiliza sintaxe Markdown para formatação: - Títulos com `#`, `##`. - Listas com `-` ou `*`. - Links com `[texto](URL)`. - Blocos de código com ``` ```. Projetos complexos podem ter múltiplos README.md em subpastas. Por exemplo, uma pasta *docs* pode incluir um README detalhando a estrutura de diretórios. Ferramentas como o *Dillinger* ajudam a visualizar a renderização do Markdown em tempo real. --- ## Autenticação Segura com SSH A autenticação via **SSH** substitui usuário/senha por chaves criptográficas, aumentando a segurança. Para configurar: 1. Gerar chaves no terminal: ```bash ssh-keygen -t ed25519 ``` (Pressionar Enter para usar caminhos padrão e sem senha). 2. Copiar a chave pública (`cat ~/.ssh/id_ed25519.pub`) e adicioná-la em *Settings > SSH and GPG keys* no GitHub. 3. Clonar repositórios usando a URL SSH (ex: `git clone [email protected]:user/repo.git`). Se o Git não reconhecer a chave automaticamente, adicione-a manualmente com: ```bash eval "$(ssh-agent -s)" ssh-add ~/.ssh/caminho_da_chave ``` Chaves SSH são vinculadas à conta, não a repositórios específicos, simplificando o gerenciamento em múltiplos projetos. # Branches ## Conceitos Fundamentais de Branches Uma **branch** é uma ramificação independente em um projeto Git, permitindo a criação de versões paralelas a partir de um ponto comum. Cada branch opera de forma isolada, o que possibilita que equipes ou indivíduos trabalhem simultaneamente em diferentes funcionalidades sem interferir no trabalho alheio. A branch principal (geralmente chamada de `main` ou `master`) serve como base para outras branches. - **Independência**: Alterações em uma branch não afetam outras branches. Por exemplo, se uma branch `tarefa-14` é criada a partir da `main`, modificações nela não impactam a `main` até que um **merge** (mesclagem) seja realizado. - **Experimentos e Testes**: Branches podem ser usadas para testes ou experimentos. Se uma alteração não é bem-sucedida, a branch pode ser descartada sem afetar o projeto principal. - **Paralelismo**: Permite que múltiplas tarefas sejam desenvolvidas ao mesmo tempo, inclusive em arquivos compartilhados, desde que as branches permaneçam independentes. --- ## Comandos para Criação e Gerenciamento de Branches ### Criando e Listando Branches - **Listar branches existentes**: ```bash git branch ``` A branch atual é destacada na lista. - **Criar uma nova branch**: ```bash git branch ``` Exemplo: `git branch developer` cria a branch `developer`. - **Criar e alternar para uma branch**: ```bash git checkout -b ``` Ou, com o comando mais recente `git switch`: ```bash git switch -c ``` Exemplo: `git checkout -b teste-1` cria e muda para a branch `teste-1`. ### Alternando entre Branches - **Mudar para uma branch existente**: ```bash git checkout ``` Ou: ```bash git switch ``` Exemplo: `git switch main` retorna para a branch principal. - **Voltar à branch anterior**: ```bash git switch - ``` Este comando alterna para a última branch utilizada. --- ## Navegação entre Branches e Alterações não Commitadas Ao alternar entre branches com alterações não salvas (não commitadas), o Git pode levar essas modificações consigo, o que pode causar conflitos indesejados. ### Gerenciando Alterações não Commitadas - **Forçar a troca de branch (descartar alterações não commitadas)**: ```bash git checkout -f ``` Exemplo: `git checkout -f developer` ignora alterações não salvas e muda para `developer`. - **Cuidados**: - Alterações não rastreadas (arquivos novos não adicionados com `git add`) não são afetadas pelo `checkout -f`. - Alterações rastreadas (modificações em arquivos existentes) são revertidas ao usar `checkout -f`. --- ## Trabalhando com Commits Antigos e HEAD Detached O **HEAD detached** ocorre quando você faz checkout de um commit específico, em vez de uma branch. Nesse estado, novas alterações não estão vinculadas a nenhuma branch, o que pode gerar a mensagem *"teste de rede"* (tradução de *"detached HEAD"*). ### Comandos para HEAD Detached - **Checkout de um commit específico**: ```bash git checkout ``` Exemplo: `git checkout a1b2c3d` permite visualizar o projeto no estado desse commit. - **Criar uma branch a partir de um commit**: ```bash git switch -c ``` Isso vincula o HEAD a uma nova branch, evitando o estado detached. - **Voltar para uma branch existente**: ```bash git switch main ``` ### Observações: - Alterações feitas em HEAD detached podem ser perdidas se não forem associadas a uma branch. - A mensagem *"teste de rede"* pode ser desativada com: ```bash git config advice.detachedHead false ``` --- ## Sincronização de Branches com Repositório Remoto Para enviar uma branch local para um repositório remoto (como GitHub), é necessário vincular a branch local a uma branch remota. ### Enviando uma Branch para o Remoto - **Primeiro envio (criação da branch remota)**: ```bash git push --set-upstream origin ``` Exemplo: `git push --set-upstream origin developer` cria a branch `developer` no remoto e vincula à local. - **Envios subsequentes**: ```bash git push ``` Após o vínculo, o comando padrão `git push` sincroniza as alterações. ### Verificando Branches Remotas - Após o envio, a branch remota aparecerá no repositório (ex: GitHub). - A branch `main` é vinculada automaticamente ao clonar um repositório, dispensando `--set-upstream` no primeiro envio. --- ## Considerações Finais - **Nomeação de Branches**: Evite espaços e caracteres especiais. Use padrões como `kebab-case` (ex: `tarefa-14`). - **Merge**: A mesclagem de branches é essencial para integrar alterações à branch principal, mas será abordada em detalhes em procedimentos futuros. - **Organização**: Ramificações excessivas podem complicar a gestão do projeto. Mantenha uma estrutura clara e documentada. Este conteúdo abrange desde conceitos básicos até operações avançadas, garantindo controle eficiente de versões e colaboração em projetos Git. --- # Gerenciamento de Branches ## Deleção de Branches Locais e Remotas Para remover uma branch local, utilize o comando `git branch -d `. Caso a branch contenha alterações não integradas em outras branches, o Git emitirá um aviso. Para forçar a exclusão, utilize `git branch -D `. É importante ressaltar que a deleção de uma branch remove todo o histórico associado a ela, incluindo commits não integrados em outras branches. Exemplo: ```bash git branch -d teste git branch -D teste_force ``` Para excluir uma branch remota, execute `git push origin --delete `. Isso remove a branch do repositório remoto, mas não afeta branches locais em outras máquinas. Por exemplo: ```bash git push origin --delete task5 ``` Após a exclusão remota, é necessário comunicar a equipe, pois outros desenvolvedores podem ainda ter a branch localmente. Se alguém fizer push da branch local após a exclusão remota, ela será recriada no servidor. --- ## Renomeação de Branches Para renomear uma branch local, utilize `git branch -m `. Se estiver na branch que deseja renomear, basta executar: ```bash git branch -m novo_nome ``` Caso queira renomear uma branch sem estar nela, especifique o nome atual e o novo: ```bash git branch -m nome_antigo novo_nome ``` Branches remotas não podem ser renomeadas diretamente. O processo envolve: 1. Deletar a branch remota: ```bash git push origin --delete nome_antigo ``` 2. Renomear a branch local. 3. Enviar a branch renomeada para o remoto: ```bash git push origin novo_nome ``` Este processo requer atenção, pois outras pessoas podem ainda referenciar a branch antiga. --- ## Integração de Branches (Merge) Para integrar alterações de uma branch em outra, utilize `git merge`. Primeiro, certifique-se de estar na branch que receberá as mudanças: ```bash git checkout main git merge develop ``` Isso trará todos os commits da branch `develop` para `main`. Se não houver conflitos, o merge será concluído automaticamente. Para verificar branches não mergeadas na branch atual, execute: ```bash git branch --no-merged ``` --- ## Resolução de Conflitos durante o Merge Conflitos ocorrem quando alterações conflitantes são feitas nas mesmas linhas de arquivos em branches diferentes. Ao detectar um conflito, o Git marcará as seções problemáticas no arquivo: ``` > develop ``` Para resolver: 1. Edite o arquivo manualmente, escolhendo qual alteração manter ou combinando ambas. 2. Adicione o arquivo resolvido ao staging area: ```bash git add arquivo.txt ``` 3. Finalize o merge com: ```bash git commit -m "Resolvendo conflitos" ``` Ferramentas como o Visual Studio Code auxiliam visualmente, destacando conflitos e permitindo aceitar mudanças de uma branch específica. Para abortar um merge em andamento, utilize: ```bash git merge --abort ``` Ou reverta para o estado anterior com: ```bash git reset --hard ``` --- ## Visualização de Logs Específicos de Branches Para visualizar os commits de uma branch sem alternar para ela, execute `git log `. Por exemplo: ```bash git log develop ``` Isso lista todos os commits da branch `develop`, facilitando a análise do histórico sem necessidade de checkout. --- ## Considerações Importantes - **Comunicação em equipe**: Alterações em branches remotas (exclusão ou renomeação) devem ser comunicadas para evitar inconsistências. - **Validação pré-deleção**: Antes de deletar uma branch, certifique-se de que todos os commits relevantes foram integrados. - **Conflitos frequentes**: Em projetos colaborativos, conflitos são comuns. Utilize ferramentas de merge para agilizar a resolução. - **Histórico distribuído**: Cada clone do repositório possui uma cópia independente das branches. Ações remotas não afetam automaticamente branches locais em outras máquinas. # Comandos Avançados do Git para Gerenciamento de Histórico e Colaboração ## Revertendo e Desfazendo Commits Para desfazer commits de forma permanente, utiliza-se o comando `git reset` com diferentes opções. A opção `--hard` remove completamente os commits subsequentes, revertendo o repositório para um estado anterior sem preservar alterações locais. Exemplo: ```bash git reset --hard HEAD~1 ``` Isso move os ponteiros `HEAD` e a branch atual para o commit anterior, descartando quaisquer mudanças não commitadas. Já a opção `--mixed` (padrão) desfaz o commit, mas mantém as alterações na área de trabalho, permitindo modificações antes de um novo commit. A opção `--soft` mantém as alterações na área de preparação (staging), útil para ajustes finos antes de recomitar. ## Revertendo Commits com Preservação de Histórico O comando `git revert` é utilizado para desfazer as mudanças de um commit específico, criando um novo commit que inverte as alterações. Isso mantém o histórico intacto, ideal para colaboração ou quando o commit já foi compartilhado. Exemplo: ```bash git revert HEAD ``` Isso abrirá um editor para a mensagem do novo commit de reversão. Para evitar a abertura do editor, adicione a flag `--no-edit`: ```bash git revert HEAD --no-edit ``` Caso precise reverter múltiplos commits, especifique o intervalo: ```bash git revert HEAD~3..HEAD ``` ## Sobrescrevendo o Histórico Remoto com Cautela O comando `git push --force` sobrescreve o histórico remoto com o local, ignorando divergências. Isso é perigoso em equipes, pois pode causar conflitos e perda de commits de outros colaboradores. Exemplo de uso: ```bash git push origin main --force ``` Uma alternativa mais segura é `--force-with-lease`, que verifica se o estado do repositório remoto coincide com o local antes de sobrescrever: ```bash git push origin main --force-with-lease ``` Isso evita a perda acidental de commits adicionados por outros após o último pull. ## Sincronização e Resolução de Conflitos Ao encontrar erros como *"updates foram rejeitados"* durante um `git push`, a solução recomendada é realizar um `git pull` para trazer as mudanças remotas, resolver conflitos localmente e então enviar as alterações: ```bash git pull origin main # Resolva conflitos manualmente git push origin main ``` Evite usar `--force` nesse cenário, pois ele ignora alterações remotas. Em vez disso, priorize a integração das mudanças através de merges ou rebases. ## Cenários de Uso de `git reset` e `git revert` - **`git reset`**: Ideal para correções locais, como remover commits não compartilhados ou ajustes em branches privadas. Por exemplo, para descartar os últimos dois commits: ```bash git reset --hard HEAD~2 ``` - **`git revert`**: Recomendado para corrigir commits já enviados ao repositório remoto. Por exemplo, reverter um commit que expôs dados sensíveis: ```bash git revert abc123 ``` ## Impactos do `git push --force` em Equipes Ao usar `--force`, o histórico remoto é alterado, o que pode causar inconsistências em clones existentes. Colaboradores com clones antigos podem enfrentar erros ao tentar sincronizar. Para mitigar isso: 1. **Comunique a equipe** sobre a alteração forçada. 2. **Oriente todos a atualizarem** seus repositórios locais: ```bash git fetch origin git reset --hard origin/main ``` ## Considerações sobre `git push --force-with-lease` Esta opção é útil quando se deseja forçar um push apenas se nenhuma alteração remota foi feita desde o último fetch. Exemplo: ```bash git push origin main --force-with-lease ``` Se o repositório remoto tiver novos commits não presentes localmente, o comando falhará, prevenindo a sobrescrita acidental. ## Fluxo de Trabalho Seguro para Colaboração 1. **Sempre sincronize** antes de enviar mudanças: ```bash git pull origin main ``` 2. **Resolva conflitos** localmente. 3. **Teste as alterações** antes de enviar. 4. **Evite `--force`** a menos que seja estritamente necessário (ex.: remover dados sensíveis do histórico). ## Exemplo de Cenário de Merge Conflict Se dois desenvolvedores modificam o mesmo arquivo em commits separados: - O primeiro envia suas mudanças com `git push`. - O segundo tenta enviar e recebe um erro. - O segundo executa `git pull`, resolve os conflitos manualmente, commitando as correções: ```bash git pull origin main # Edita arquivos conflitantes git add. git commit -m "Resolve merge conflict" git push origin main ``` Este fluxo garante que todas as alterações sejam integradas sem perda de dados. # Gerenciamento de Histórico e Branches no Git ## Merge vs. Rebase: Mantendo o Histórico Linear Ao integrar mudanças entre branches, o Git oferece duas abordagens principais: **merge** e **rebase**. O **merge** cria um commit adicional (merge commit) para unir as alterações, resultando em um histórico não linear. Já o **rebase** reaplica os commits de uma branch em cima de outra, evitando commits de merge e mantendo o histórico linear. ### Cenário de Merge 1. **Criação de Branches**: - Suponha uma branch `main` com três commits. - Uma nova branch `developer` é criada a partir de `main`, e alterações são feitas nela. - Enquanto isso, a `main` também recebe novos commits. 2. **Integração com Merge**: - Ao executar `git merge developer` na `main`, um **merge commit** é gerado para mesclar as alterações divergentes. - Isso cria um histórico com bifurcações, dificultando a leitura em projetos com muitos merges. ### Cenário de Rebase 1. **Reaplicando Commits**: - Na branch `developer`, execute `git rebase main`. - Isso move a base da `developer` para o último commit da `main`, reaplicando os commits da `developer` em sequência. - O histórico resultante é linear, sem merge commits. 2. **Atualização da Branch Principal**: - Após o rebase, integre as mudanças com `git merge developer` na `main`. - Como as branches estão alinhadas, não há necessidade de merge commit. **Atenção**: Evite rebase em branches públicas, pois ele altera o histórico, causando conflitos para outros colaboradores. --- ## Resolução de Conflitos Durante Rebase Ao executar `git rebase`, conflitos podem surgir se commits alteram as mesmas linhas em branches diferentes. ### Passos para Resolver Conflitos: 1. **Inicie o Rebase**: ```bash git rebase main ``` 2. **Identifique o Conflito**: - O Git indicará em qual commit o conflito ocorreu (ex.: "Etapa 2 de 3"). - Arquivos conflitantes terão marcadores como ``. 3. **Edite os Arquivos**: - Use ferramentas como VS Code para escolher entre alterações locais (`HEAD`) ou remotas. - Exemplo de resolução manual: ```html > developer ``` Resultado após edição: ```html Main Developer ``` 4. **Continue o Rebase**: - Adicione as mudanças resolvidas: ```bash git add. ``` - Prossiga com: ```bash git rebase --continue ``` - Se necessário, cancule com `git rebase --abort`. --- ## Git Pull com Rebase: Evitando Merge Commits Ao atualizar uma branch local com alterações remotas, `git pull` padrão faz merge. Use `git pull --rebase` para manter o histórico linear. ### Configuração Global: ```bash git config --global pull.rebase true ``` ### Exemplo Prático: 1. Duas pessoas trabalham na mesma branch `main`: - Pessoa 1 faz commit e envia para o remoto. - Pessoa 2 faz commits locais sem atualizar. 2. Ao tentar enviar alterações, Pessoa 2 recebe um erro. 3. Execute: ```bash git pull --rebase ``` - Isso reaplica os commits locais em cima da versão atualizada do remoto. - Nenhum merge commit é criado. --- ## Lidando com Histórico Alterado Remotamente Se o histórico remoto foi forçado (`git push --force`), sincronize a branch local sem merges: ### Passos para Atualização: 1. **Remova a Branch Local**: ```bash git branch -D developer ``` 2. **Busque a Versão Remota**: ```bash git fetch origin developer ``` 3. **Recrie a Branch Local**: ```bash git checkout developer ``` - A branch local agora reflete exatamente o remoto. --- ## Rebase Interativo: Combinando Commits (Squash) Para consolidar múltiplos commits em um único (útil para tarefas fragmentadas): ### Executando Squash: 1. Inicie o rebase interativo: ```bash git rebase -i HEAD~3 # Revisa os últimos 3 commits ``` 2. No editor, altere `pick` para `squash` (ou `s`) nos commits que deseja fundir: ``` pick a1b2c3d Commit 1 squash d4e5f6g Commit 2 squash h7i8j9k Commit 3 ``` 3. Salve e feche. Edite a mensagem do novo commit consolidado. ### Resultado: - Três commits são substituídos por um, com todas as alterações agrupadas. - O histórico fica mais limpo e focado em tarefas específicas. **Nota**: Alterar histórico público com squash pode causar conflitos. Use apenas em branches locais ou coordenadamente em equipe. --- Estes procedimentos permitem maior controle sobre o histórico do Git, adaptando- o às necessidades de clareza, colaboração e manutenção do projeto. # Comandos e Configurações Essenciais do Git ## Cherry Pick para Transferência Seletiva de Commits O **Cherry Pick** é utilizado para trazer commits específicos de uma branch para outra, sem a necessidade de realizar um merge completo. Isso é útil quando uma branch contém múltiplas alterações, mas apenas um subset delas é relevante para o contexto atual. Por exemplo, ao trabalhar em uma branch `feature-task` com quatro commits, pode-se selecionar apenas o commit relacionado a "alterações de menu" e aplicá-lo na branch principal (`main`) usando: ```bash git cherry-pick [hash-do-commit] ``` Isso evita a incorporação de alterações indesejadas. O processo inclui: 1. Navegar para a branch de destino (`git checkout main`). 2. Identificar o hash do commit desejado na branch de origem. 3. Executar `git cherry-pick` com o hash. 4. Verificar se as alterações foram aplicadas corretamente com `git log`. Caso a branch de origem tenha muitos commits, o Cherry Pick permite isolar funcionalidades críticas sem aguardar a finalização de todas as tarefas. É especialmente útil em cenários de desenvolvimento paralelo, onde diferentes equipes trabalham em features distintas. --- ## Identificação de Bugs com Git Bisect e Busca Binária O **Git Bisect** automatiza a identificação do commit que introduziu um bug usando o algoritmo de **busca binária**. Suponha que um problema surgiu entre o commit 1 (funcional) e o commit 15 (defeituoso). O processo é: 1. Iniciar a busca: ```bash git bisect start ``` 2. Definir os commits "bom" e "ruim": ```bash git bisect good [hash-do-commit-1] git bisect bad [hash-do-commit-15] ``` 3. O Git alternará automaticamente entre commits intermediários. Em cada etapa, o usuário verifica se o bug está presente e responde com `git bisect good` ou `git bisect bad`. 4. Ao final, o Git apontará o commit exato que causou o problema. A busca binária reduz drasticamente o número de verificações necessárias. Por exemplo, em 1 milhão de commits, são necessárias no máximo 20 iterações. O algoritmo divide o intervalo de commits ao meio repetidamente, descartando metade dos commits a cada passo com base no feedback do usuário. --- ## Configuração de Aliases para Comandos Frequentes Aliases simplificam comandos repetitivos do Git. Para criar um alias global: ```bash git config --global alias.[atalho] "[comando]" ``` Exemplos: - Abreviar `git status` para `git s`: ```bash git config --global alias.s status ``` - Abreviar `git log --oneline` para `git l`: ```bash git config --global alias.l "log --oneline" ``` - Criar um alias para comandos complexos, como `git line` para `git log -- oneline`: ```bash git config --global alias.line "log --oneline" ``` Para remover um alias: ```bash git config --global --unset alias.[atalho] ``` Por exemplo, remover `git s`: ```bash git config --global --unset alias.s ``` Aliases devem ser únicos e não conter espaços. Eles agilizam o fluxo de trabalho, especialmente em comandos usados frequentemente, como verificação de status e histórico. --- ## Atualização Segura com Git Fetch O **Git Fetch** atualiza o repositório local com as alterações remotas sem modificar os arquivos locais. Diferente do `git pull`, que faz fetch seguido de merge, o fetch permite revisar as mudanças antes de integrá-las. Passos típicos: 1. Buscar atualizações: ```bash git fetch ``` 2. Listar branches remotas atualizadas: ```bash git branch -a ``` 3. Inspecionar alterações em uma branch remota: ```bash git checkout origin/main ``` 4. Mesclar manualmente após validação: ```bash git merge origin/main ``` Isso é útil para evitar conflitos inesperados. Por exemplo, se a branch `main` remota recebeu um commit `update.html`, o fetch traz esse commit para o repositório local, mas o merge só ocorre após confirmação explícita. O comando também atualiza referências de tags e outras branches remotas, mantendo o histórico local sincronizado sem alterar o workspace atual.

Use Quizgecko on...
Browser
Browser