marina-medeiros
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Sumário [TOC] # Versionadores ### O que são e por que surgiram? - São sistemas que registram alterações em um arquivo ou conjunto de arquivos ao longo do tempo para que você possa lembrar versões específicas mais tarde. - Surgiram devido a necessidade do aumento da eficiência, do aumento do número de colaboradores e do gerenciamento de projetos de software moderno. ![Captura de tela 2024-06-04 094408](https://hackmd.io/_uploads/ryblu7zSR.png) ### Tipos de Versionadores Sistemas de controle de versão podem ser: **locais**, **centralizados** ou **distribuídos**. - Sistemas **locais** de controle de versão tem um banco de dados simples que mantêm todas as alterações nos arquivos sob controle de versão. ![Captura de tela 2024-06-04 101220](https://hackmd.io/_uploads/SJv-sbGHA.png) - Sistemas **centralizados** de controle de versão têm um **único servidor** que contém todos os arquivos de controle de versão, e um número de clientes que usam arquivos a partir desse lugar central. Por muitos anos, este foi o padrão para controle de versão. Um **defeito grave** desses versionadores é que se o servidor der problema por uma hora, durante essa hora ninguém pode colaborar ou salvar as alterações de versão para o que quer que eles estejam trabalhando. - Os primerios Modelos surgiram descentralizados - Necessidade de estar conectado ao servidor central - Para equiper pequenas - Mais simples de Utilizar - Wikipédia se utiliza desse modelo ![Captura de tela 2024-06-11 092630](https://hackmd.io/_uploads/By_qMTBHR.png) ![Captura de tela 2024-06-04 101557](https://hackmd.io/_uploads/HJUGsZzB0.png) - Já em sistemas **distribuídos** de controle de versão, os clientes não somente usam o estado mais recente dos arquivos, mas também duplicam localmente o repositório completo. Cada clone é um backup completo de todos os dados. ![descentralizado](https://hackmd.io/_uploads/SJpghZzrA.png) Nesse curso estudaremos um dos sistemas de versionamento mais usados do mundo: o Git. - Escalabilidade - Não depende de um servidor central - Maior eficiência - Maior segurança a ataques ![Captura de tela 2024-06-11 092957](https://hackmd.io/_uploads/S12LXpBHA.png) ![upscayledImage](https://hackmd.io/_uploads/ry_kclLHA.png) # História do Git: ### Como surgiu? Como vimos durante o curso, Linux kernel é um projeto de software livre de grande prote. Durante os anos iniciais de criação e manutenção desse sistema, mudanças do software eram feitas a partir do envio de arquivos entre os desenvolvedores e, um tempo depois, passaram a serem feitas usando o versionador BitKeeper. Na época em que o BitKeeper passou a ser pago, a comunidade Linux (em especial, Linus Torvalds) passou a desenvolver sua própria ferramenta baseada em lições que haviam aprendido durante os anos usando o BitKeeper. Esses eram alguns dos objetivos do sistema: - Velocidade - Design simples - Forte suporte para o desenvolvimento não linear (milhares de branches paralelas) - Altamente distribuído - Ter a capacidade de lidar com grandes projetos como o Linux kernel de forma eficiente ### De onde vem o nome "Git"? Git é uma gíria britânica para "pessoa desagradável". Linus Torvalds disse sarcasticamente em uma entrevista: "eu sou um egoísta e nomeio todos os meus projetos em minha homenagem. Primeiro 'Linux' e agora 'git'". Se você estiver de bom humor, pode significar 'Global Information Tracker'. Vejam o manual do git usando o terminal ('man git'). ### Git como um versionador ![descentralizado](https://hackmd.io/_uploads/SJpghZzrA.png) 1. Open Source 2. Trabalho em equipe 3. Desenvolvimento de softwares de todos os tipos 4. O mais utilizado atualmente - Como o Git funciona? Sabemos que o Git é um versionador, ou seja, é uma ferramenta que tem a finalidade de gerenciar diferentes versões no desenvolvimento de um arquivo ou conjunto de arquivos. - Com o Git, sempre que você salta o estado do projeto, é "tirada uma foto" de como os arquivos estavam naquele momento e salva uma referência a esse snapshot. Por eficiência, se um arquivo não foi modificado, ele não o salva o arquivo novamente, mas apenas um "link" para a versão anterior que já está salva. ![image](https://hackmd.io/_uploads/SkYli-6zR.png) - Quase todas as operações são locais -Com o Git, todo o histórico do projeto é armazenado localmente, fazendo com que as operações sejam quase intantâneas. Comparar versões antigas do seu projeto pode ser feito localmente sem a necessidade de interagir com o servidor remoto. - O Git, no geral, apenas **adiciona** informações -É difícil fazer com que o sistema apague dados ou faça algo irreversível, principalmente se você der pushes regulares do seu trabalho(enviar as suas alterações para o servidor remoto constantemente). # Github & Shell ### Introdução a plataformas de hospedagem remota - Git Lab, Codeberg e BitBucket - ![Design sem nome](https://hackmd.io/_uploads/rJ9yYGwH0.png) - O que eles têm em comum? - Todos são plataformas onde é possível hospedar repositórios. ### Github - Hospedagem de Repositórios - Se utiliza do git para fazer o controle de versão dos respositórios hospedados - Comunidade ativa - Vários outros serviços - Um dos maiores repositórios de projetos open source do mundo Github é a maior plataforma de hospedagem para repositórios Git, além de ser o ponto central de colaboração para milhões de desenvolvedores. Grande parte dos repositórios Git estão hospedados no Github e muitos projetos de código aberto o usam para hospedagem, monitoramento de problemas e tarefas, revisão de código etc. > O git e o github são a mesma coisa? >> Não, Github e similares como GitLab e Bitbucket, são provedores que utilizam o git, fornecendo uma interface visual, além de armazenamento na nuvem para os projetos. ### Chave SSH - **Para que serve a chave SSH?** As chaves SSH (Secure Shell) são utilizadas para autenticar conexões seguras entre computadores, permitindo uma comunicação criptografada. Elas substituem a necessidade de senhas tradicionais, proporcionando uma maneira mais segura e conveniente de acessar sistemas remotos e serviços, como repositórios Git. Ao configurar uma chave SSH, você cria um par de chaves: uma chave privada, que deve ser mantida em segredo no seu computador, e uma chave pública, que é adicionada ao servidor ou serviço remoto. Quando uma conexão é iniciada, o servidor usa a chave pública para verificar a identidade do usuário, sem que a chave privada precise ser transmitida pela rede, garantindo assim a segurança. No contexto do Git, a autenticação via chave SSH é especialmente útil ao interagir com repositórios remotos hospedados em plataformas como GitHub, GitLab e Bitbucket. Essas plataformas suportam autenticação por chave SSH, permitindo que os desenvolvedores enviem (push) e busquem (pull) alterações de forma segura, sem precisar digitar senhas repetidamente. # Um pouco mais sobre Git ### Como ele lida com informações O Git é um sistema de controle de versão distribuído que gerencia informações armazenando cada versão do projeto como um snapshot completo, em vez de apenas as diferenças entre versões. Ele utiliza uma estrutura de objetos que inclui blobs (conteúdo de arquivos), trees (diretórios), commits (mudanças com metadados) e tags (marcadores de versão). Cada objeto é identificado por um hash SHA-1, garantindo a integridade dos dados. Git permite a criação de branches para desenvolvimento paralelo e merges para combinar mudanças. As modificações são preparadas na staging area antes de serem commitadas. Com funcionalidades robustas de colaboração e resolução de conflitos, Git suporta operações offline e sincronização com repositórios remotos através de comandos como push e pull, facilitando o trabalho simultâneo de múltiplos desenvolvedores. ### Workflow básico 1) Você **modifica arquivos** na sua árvore de trabalho 2) Você **seleciona apenas as mudanças que você quer** que façam parte do seu próximo commit, e apenas essas mudanças serão adicionadas à staging area 3) Você **faz um commit**: os arquivos como eles estão na staging area são armazenados em forma de snapshot permanentemente no seu diretório Git. ![image](https://hackmd.io/_uploads/HJKOTMTGC.png) Assim, podemos perceber que um arquivo pode estar em um dos 3 estados: * modified * staged * commited ### Lidando com repositórios No final desta sessão, você será capaz de **configurar** e **inicializar** um repositório, iniciar e interromper o **rastreamento de arquivos**, usar a **área de stage** e realizar **commits** das alterações. Também mostraremos como configurar o Git para ignorar certos arquivos e padrões de arquivo,como desfazer erros de maneira rápida e fácil, como navegar no histórico do seu projeto e visualizar alterações entre commits e como fazer push e pull em repositórios remotos. - **Obtendo um repositório Git** Você pode obter um repositório de duas formas principais: 1) Pegando um diretório local que não está sob controle de versão e transaformando-o em um repositório 2) Fazendo um clone de um repositório Git existente em outro lugar Por enquanto, vamos lidar apenas com repositórios locais. **Inicializando um repositório em um diretório existente:** ``` cd new_repository git init ``` Agora, temos um subdiretório chamado .git que contém todos os arquivos necessários de seu repositório – um esqueleto de repositório Git. Nada em seu projeto é monitorado ainda. ![Captura de tela 2024-06-11 094114](https://hackmd.io/_uploads/BJL-L6rHA.png) > Quando fazemos o comando git init no local/diretório onde queremos criar um repositório, uma pasta oculta é criada chamada".git", que vai ter as configurações necessárias para o monitoramento do git naquele diretório. ![Captura de tela 2024-06-11 094203](https://hackmd.io/_uploads/SyhQUaSB0.png) - **Gravando alterações em seu repositório** Cada arquivo em seu repsitório pode estar em um dos seguintes estados: rastreado e não-rastreado. Arquivos rastreados são arquivos que foram incluídos no último snapshot; eles podem ser não modificados, modificados ou preparados (adicionados ao stage). Em resumo, arquivos rastreados são os arquivos que o Git conhece. Quando você clona um repositório pela primeira vez, todos os seus arquivos serão rastreados e não modificados já, que o Git acabou de obtê-los e você ainda não editou nada. Assim que você edita alguns arquivos, Git os considera modificados, porque você os editou desde o seu último commit. Você prepara os arquivos editados e então faz commit das suas alterações, e o ciclo se repete. ![image](https://hackmd.io/_uploads/SJWWiARzC.png) <!-- Aqui será feito o primeiro repositório remoto seguindo os passos do github --> # Lidando com o git ### Verificando os status de seus arquivos A principal ferramenta que você vai usar para determinar quais arquivos estão em qual estado é o comando git status. ```sh $ git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean ``` Digamos que você adiciona um novo arquivo no seu projeto, um simples arquivo README. Se o arquivo não existia antes, e você executar git status, você verá seu arquivo não rastreado da seguinte forma: ```sh $ echo 'My Project' > README $ git status On branch master Your branch is up-to-date with 'origin/master'. Untracked files: (use "git add <file>..." to include in what will be committed) README nothing added to commit but untracked files present (use "git add" to track) ``` Nós queremos incluir esse arquivo README, então vamos rastreá-lo. ### Rastreando arquivos novos Para começar a rastrear um novo arquivo, você deve usar o comando git add $ git add README Executando o comando status novamente, você pode ver que seu README agora está sendo rastreado e preparado (staged) para o commit: $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README É possível saber que o arquivo está preparado porque ele aparece sob o título “Changes to be committed”. Se você fizer um commit neste momento, a versão do arquivo que existia no instante em que você executou git add, é a que será armazenada no histórico de snapshots. ### Preparando Arquivos Modificados (Adicionando arquivos modificados à staging area) Vamos modificar um arquivo que já está sendo rastreado. Se modificarmos o CONTRIBUTING.md que já era rastreado, e executarmos o `git status`, teremos isso: $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: CONTRIBUTING.md Isso significa que o arquivo rastreado foi modificado no diretório mas ainda não foi mandado para o stage (preparado). Para isso, vamos usar o `git add`. Pode ser útil pensar nesse comando mais como “adicione este conteúdo ao próximo commit”. $ git add CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README modified: CONTRIBUTING.md :::info Ao mesmo tempo que a saída do git status é bem completa, ela também é bastante verbosa. O Git também tem uma flag para status compacto. $ git status -s M README MM Rakefile A lib/git.rb M lib/simplegit.rb ?? LICENSE.txt ::: ### Fazendo commit das suas alterações Agora que a área de stage está preparada, podemos fazer commit nas alterações. O jeito mais simples de fazer commit é digitar o seguinte comando: $ git commit e adicionar uma mensagem no editor de texto. Alternativamente, podemos fazer: $ git commit -m "mensagem" Lembre-se de que o commit grava o snapshot que você deixou na área de stage. Qualquer alteração que você não tiver mandado para o stage permanecerá como estava, em seu lugar; você pode executar outro commit para adicioná-la ao seu histórico. Toda vez que você executa um commit, você está gravando um snapshot do seu projeto que você pode usar posteriormente para fazer comparações, ou mesmo restaurá-lo. ### Como ver todos os commit feitos? - O comando git log É um comando feito para exibir os históricos de commits do projeto. Aparece nome, hora, data e a mensagem relacionada a cada commit. ![Captura de tela 2024-06-08 164219](https://hackmd.io/_uploads/ByYVV4MHC.png) > Dica: para sair da tela é só digitar "q" - **Uma flag eficiente** ``` $git log --oneline ``` ![Captura de tela 2024-06-08 164718](https://hackmd.io/_uploads/BJJOrVGSR.png) Essa flag apresenta os commits feitos de uma forma bem mais simples: apresenta o código referente ao commit e a respectiva mensagem. ### Subindo auterações para o repositório remoto `git push` Se você tem um commit pronto e quer adiciona-lo ao repositório remoto, podemos fazer: $ git push Fazendo o git push os seus commits irão subir para o seu repositório remoto. <!--Primeiro exercício usando git commit--> ### Visualizando commits anteriores - Git checkout <endereço do commit> Ao utilizar `git checkout` você consegue visualizar como estavam os seus arquivos para um commit específico. ![Captura de tela 2024-06-11 101121](https://hackmd.io/_uploads/BJ7zaaHSR.png) - Note que agora quando fazemos o comando git log --oneline ele mosta apenas os commits anteriores ao escolhido para visualizar. - Não perdemos as outras alterações, apenas voltamos no tempo para ver como estava o nosso projeto naquele commit em específico. ![Captura de tela 2024-06-11 101214](https://hackmd.io/_uploads/HyjraprHR.png) - Para voltar ao commit de onde paramos, precisamos fazer o commando `git checkout <nomedabranch>`, como feito na imagem abaixo. ![Captura de tela 2024-06-11 101719](https://hackmd.io/_uploads/HyJFCprBA.png) ### Revertendo commits - Ao utilizar o `git revert` podemos reverter um commit que foi realizado, para o seu estado original. Basicamente será feito um novo commit para a reversão - **git revert HEAD** Este comando vai reverter o commit mais recente ![Captura de tela 2024-06-11 132920](https://hackmd.io/_uploads/SkIkhxUS0.png) >Acima temos todos os commits feitos em um arquivo txt chamado facebook ![Captura de tela 2024-06-11 132856](https://hackmd.io/_uploads/H1yx2g8SC.png) > Note acima como está o estado atual do documento > Vamos utilizar o comando "git revert HEAD" > Após isso, aparece a seguinte página. ![Captura de tela 2024-06-11 132950](https://hackmd.io/_uploads/Hy3e2x8SR.png) > para sair dela digite ":q" ![Captura de tela 2024-06-11 133010](https://hackmd.io/_uploads/S1IWnl8S0.png) > Note acima que o último commit que foi a criação do "feedline" foi revertido e só temos o chat. ![Captura de tela 2024-06-11 140247](https://hackmd.io/_uploads/HyMcX-IBR.png) > Note que o comando reverte o commit criando outro commit com essa reversão - **git revert <endereço do commit>** Reverte o commit indicado, ou seja, a auteração que foi feita neste commit será retirada. > Observe o seginte exemplo: Vamos criar um repositório chamado facebook e crie três arquivos chamdo estrutura.txt, chat.txt e timeline.txt, fazendo um commit a cada arquivo criado. ![Captura de tela 2024-06-11 143623](https://hackmd.io/_uploads/H12IiZLBC.png) >Faça no terminal o seguinte comando "git revert 7d2b5e1" > Note que vai aparecer a seguinte tela ![Captura de tela 2024-06-11 143832](https://hackmd.io/_uploads/H1_osWLH0.png) > Escreva ":q" para finalizar a reversão ![Captura de tela 2024-06-11 143920](https://hackmd.io/_uploads/By7y2-Lr0.png) > volte na sua página e note que o arquivo com nome "chat.txt" foi retirado, pois ele tinha sido criado naquele commit. <div style="border: 2px solid red"> Nessa parte poderiamos mostrar resolução de conflitos , um exemplo bem simples com um arquivo com 4 linhas, cada linha um commit. Poderiamos tentar reverter o segundo commit, vai dar um conflito e resolvemos. - **git revert - -abort** Aborta uma reversão que etá em andamento - **git revert - -continue** Continua uma reversão que está em andamento </div> ### Desfazendo coisas - **Ajustando commits** Aqui devemos tomar cuidado, porque nem sempre você pode voltar uma alteração desfeita. Essa é uma das poucas áreas do Git onde pode perder algum trabalho feito se você cometer algum engano. Se você fez um commit cedo demais e esqueceu de adicionar alguns arquivos ou quer corrigir a mensagem, você pode refazer o commit usando a opção --amend: $ git commit --amend Esse comando pega a área stage e a usa para realizar o commit. Se você não fez nenhuma alteração desde o último commit (por exemplo, se você executar o comando imediatamente depois do commit anterior), então sua imagem dos arquivos irá ser exatamente a mesma, e tudo o que você alterará será a mensagem do commit. O mesmo editor de mensagens de commit é acionado, porém o commit anterior já possui uma mensagem. Você pode editar a mensagem como sempre, porém esta sobrescreve a mensagem do commit anterior. Também podemos fazer dessa forma: $ git commit -m 'initial commit' $ git add forgotten_file $ git commit --amend No final das contas, o segundo commit substituiu o resultante do primeiro. - **Retirando um arquivo do Stage** Se você alterou dois arquivos, e deseja realizar o commit deles separadamente, porém você acidentalmente digitou `git add *` adicionando ambos ao stage. Como você pode retirar um deles do stage? O comando git status lhe lembrará de como fazer isso: $ git add * $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) renamed: README.md -> README modified: CONTRIBUTING.md Logo abaixo do texto “Changes to be committed”, diz `git reset HEAD <file>...` para retirar o arquivo do stage. Então, vamos usar esta sugestão para retirar o arquivo CONTRIBUTING.md do stage: $ git reset HEAD CONTRIBUTING.md Unstaged changes after reset: M CONTRIBUTING.md $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) renamed: README.md -> README Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: CONTRIBUTING.md O arquivo CONTRIBUTING.md volta ao estado modificado porem está novamente fora do stage. - **Desfazendo mofificações me um arquivo** E se você se der conta de que na verdade não quer manter as modificações do arquivo CONTRIBUTING.md? Como você pode reverter as modificações, voltando a ser como era quando foi realizado o último commit (ou clone inicial, ou seja como for que você chegou ao seu working directory)? Felizmente, git status diz a você como fazer isso também. Neste último exemplo, a área fora do stage parece com isso: Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: CONTRIBUTING.md Isso lhe diz de forma explícita como descartar as modificações que você fez. Vamos fazer o que o comando nos sugeriu: $ git checkout -- CONTRIBUTING.md $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) renamed: README.md -> README Você pode notar que as modificações foram revertidas. ### Trabalhando de forma remota - **O que são repositórios remotos?** Para colaborar com qualquer projeto Git, você precisará saber como gerenciar seus repositórios remotos. Repositórios remotos são versões de seu repositório hospedado na Internet ou em uma rede qualquer. Colaborar com outras pessoas envolve o gerenciamento destes repositórios remotos, fazer pushing(atualizar) e pulling(obter) de dados para e deles quando você precisar compartilhar seu trabalho. - **Adicionando repositórios remotos** Caso você já tenha um repositório local, é possível torná-lo um repositório remoto executando o comando `git remote add <shortname> <url>` $ git remote add meu-repositorio https://github.com/marina/meu-repositorio Agora, o seu repositório local estará ligado a esse repositório remoto Tá, mas e agora? Como eu coloco o que eu já tenho no meu repositório local no GitHub? - **Dando push para um repositório remoto** Se você tem um commit pronto e quer adiciona-lo ao repositório remoto, podemos fazer: $ git push origin master Por enquanto ainda não sabemos o que "master" significa, mas descobriremos na próxima seção. - **Clonando um repositório existente:** Para isso, vamos usar o comando `git clone`. Com esse comando, o Git recebe uma cópia completa de praticamente todos os dados que o servidor possui. Cada versão de cada arquivo do histórico do projeto é obtida quando você executa o git clone. - **Dando pull em um repositório remoto** O comando `git pull` é usado para buscar e baixar conteúdo de repositórios remotos e fazer a atualização imediata ao repositório local para que os conteúdos sejam iguais. ## Git branching Branches são ramificações para criar ramos de desenvolvimento, tipo versões. Nessas ramificações podemos criar diferentes recursos que depois serão mesclados. ![334154431-2eb608f8-a923-4ca5-8f1f-d1f63471febe](https://hackmd.io/_uploads/HJ82XGzBC.png) Conforme ilustrado na imagem fornecida, os pontos azuis representam uma branch criada especificamente para desenvolver a funcionalidade de chat de um app como o facebook. Esta branch está separada do projeto principal, permitindo que os desenvolvedores trabalhem no novo recurso sem interferir na base de código principal. Isso nos permite evitar de causar problemas no ramo principal, em quanto estamos desenvolvendo novas funcionalidades. ### As vantagens do uso de branchs: 1. **Isolamento**: Encapsular o desenvolvimento de novos recursos em uma branch separada evita alterações acidentais no projeto principal, garantindo estabilidade e integridade. 2. **Desenvolvimento Paralelo**: Múltiplos desenvolvedores podem trabalhar em diferentes recursos simultaneamente sem conflitos ou interrupções, aumentando a produtividade e a eficiência. 3. **Teste e Refinamento**: Novos recursos podem ser testados e refinados minuciosamente dentro da branch antes de serem mesclados na base de código principal, garantindo uma experiência do usuário de alta qualidade. ### Branches em uma casca de pitomba 1) Vamos fazer o commit de um diretório com 3 arquivos - Agora, o seu repositório tem 5 objetos: - 3 blobs (arquivos) - um commit com o ponteiro para a raíz da árvore - os metadados do commit ![image](https://hackmd.io/_uploads/S1hzEwpMC.png) Se você fizer alguma alteração no diretório e commitar novamente, esse último commit armazenará um ponteiro para o commit que veio antes dele. ![image](https://hackmd.io/_uploads/HJBKVDafR.png) Uma branch no Git é simplesmente um ponteiro móvel para um desses commits. O nome da branch padrão no Git é master. Conforme você começa a fazer commits, você recebe uma branch master que aponta para o último commit que você fez. Cada vez que você faz um novo commit, ele avança automaticamente. ::: info A branch **'master'** no Git não é uma branch especial. Todo repositório tem uma porque o comando git init a cria por padrão e a maioria das pessoas não muda isso. ::: 2) Criando uma nova branch Criar uma nova branch cria um novo ponteiro para você mover. ``` $ git branch testing ``` ![image](https://hackmd.io/_uploads/S1qgUwTzC.png) Como o git sabe onde eu estou agora? Ele tem um ponteiro especial chamado HEAD. ![image](https://hackmd.io/_uploads/rJ1SLDpMR.png) Observe que o comando *git branch* apenas criou uma nova branch. Para mudar de branch, devemos executar o comando ``` $ git checkout testing ``` ![image](https://hackmd.io/_uploads/ryMwi_pGA.png) Tá. Mas o que isso muda? Veja o que acontece quando fazemos outro commit: ![image](https://hackmd.io/_uploads/SJ4mnuTGC.png) Observe que a branch testing avançou, mas a master continua apontado para o commit que estava quando você executou o checkout para alternar entre as branches. Podemos voltar para a master: ``` $ git checkout master ``` ![image](https://hackmd.io/_uploads/S1HNAupGC.png) E se você fizer um commit na master? O que acontece? ![image](https://hackmd.io/_uploads/BJ7rRd6zC.png) Agora, o histórico do seu projeto divergiu. Ambas as mudanças feitas são isoladas em branches separadas: você pode alterar entre essas ramificações e mesclá-las quando quiser. Tudo o que fizemos até agora foi bem simples. Usamos apenas os comandos: - Branch - Checkout - Commit ## Mesclagem (merging) - Ramificação e mesclagem simples Primeiramente, digamos que você esteja trabalhando em seu projeto e já tenha alguns commits na branch master. Você decidiu que você vai trabalhar no chamado #53 em qualquer que seja o sistema de gerenciamento de chamados que a sua empresa usa. Para criar uma nova branch e mudar para ele ao mesmo tempo, você pode executar o comando git checkout com o parâmetro -b: $ git checkout -b iss53 Switched to a new branch "iss53" Esta é a abreviação de: $ git branch iss53 $ git checkout iss53 ![image](https://hackmd.io/_uploads/rJh5srfm0.png) Ao fazer isso, você move o branch iss53 para a frente, pois este é o branch que está selecionado, ou checked out(isto é, seu HEAD está apontando para ele): $ vim index.html $ git commit -a -m 'Create new footer [issue 53]' ![image](https://hackmd.io/_uploads/SJIniSfQ0.png) Porém, um problema importante surgiu e precisamos corrigí-lo imediatamente. Então, vamos voltar para a branch master e criar uma outra branch a partir de lá. Entretanto, antes de fazer isso, note que se seu diretório de trabalho o stage possui alterações ainda não commitadas que conflitam com a branch que você quer usar, o Git não deixará que você troque de branch. O melhor é que seu estado de trabalho atual esteja limpo antes de trocar de branches, então, se você não tiver dado commit em suas alterações, certifique-se de fazer isso. Agora sim poderemos mudar para a master: $ git checkout master Switched to branch 'master' Neste ponto, o diretório de trabalho de seu projeto está exatamente da forma como estava antes de você começar a trabalhar no chamado #53, e você pode se concentrar na correção. Seu próximo passo é fazer a correção necessária; Vamos criar uma branch chamado hotfix no qual trabalharemos até a correção estar pronta: $ git checkout -b hotfix Switched to a new branch 'hotfix' $ git commit -a -m 'Fix broken email address' [hotfix 1fb7853] Fix broken email address 1 file changed, 2 insertions(+) ![image](https://hackmd.io/_uploads/HJYF6SfXA.png) Você pode executar seus testes, se assegurar que a correção está do jeito que você quer, e finalmente mesclar a branch hotfix de volta para a branch master para poder enviar para produção. Para isso, você usa o comando git merge: $ git checkout master $ git merge hotfix Updating f42c576..3a0874c Fast-forward index.html | 2 ++ 1 file changed, 2 insertions(+) Você vai notar a expressão “fast-forward” nesse merge. Isso ocorre porque a branch `hotfix`que você mesclou aponta para o commit `c4`, que está diretamente à frente do commit `c2`, no qual você está agora, então o Git simplesmente move o ponteiro da branch master para a frente. Um merge fast-forward ocorre quando você tenta mesclar um commit A com outro commit B que pode ser alcançado por meio do histórico linear do commit A. ![image](https://hackmd.io/_uploads/SyS428z7R.png) Assim que a sua correção importantíssima é entregue, você já pode voltar para o trabalho que estava fazendo antes da interrupção. Porém, você irá antes excluir o branch hotfix, pois ele já não é mais necessário — o branch master aponta para o mesmo lugar. Você pode remover o branch usando a opção -d com o comando git branch: $ git branch -d hotfix Deleted branch hotfix (3a0874c). Agora você pode retornar à branch com seu trabalho em progresso na issue #53 e continuar trabalhando. $ git checkout iss53 Switched to branch "iss53" $ vim index.html $ git commit -a -m 'Finish the new footer [issue 53]' [iss53 ad82d7a] Finish the new footer [issue 53] 1 file changed, 1 insertion(+) É importante frisar que o trabalho que você fez na sua branch hotfix não está contido nos arquivos do seu branch iss53. Caso você precise dessas alterações, você pode fazer o merge da branch master na branch iss53 executando git merge master, ou você pode esperar para integrar essas alterações até que você decida mesclar a branch iss53 de volta para master mais tarde. - Outra forma de mesclagem Digamos que você decidiu que o seu trabalho no chamado #53 está completo e pronto para ser mesclado de volta para a branch master. Para fazer isso, você precisa fazer o merge da branch iss53, da mesma forma com que você mesclou a branch hotfix anteriormente. Tudo o que você precisa fazer é mudar para a branch que receberá as alterações e executar o comando git merge: $ git checkout master Switched to branch 'master' $ git merge iss53 Merge made by the 'recursive' strategy. index.html | 1 + 1 file changed, 1 insertion(+) Isso é um pouco diferente do merge anterior que você fez com a branch hotfix. Neste caso, já que histórico de desenvolvimento divergiu de um ponto mais antigo. O Git precisa trabalhar um pouco mais, pois o commit na sua branch atual não é um ancestral direto do branch cujas alterações você quer integrar. Neste caso, o Git faz uma simples mesclagem de três vias (three-way merge), usando os dois snapshots referenciados pela ponta de cada branch e o ancestral em comum dos dois. ![image](https://hackmd.io/_uploads/Sy2I0LGXR.png) Ao invés de apenas mover o ponteiro da branch para a frente, o Git cria um novo snapshot que resulta desse merge em três vias e automaticamente cria um novo commit que aponta para este snapshot. Esse tipo de commit é chamado de commit de merge, e é especial porque tem mais de um pai. ![image](https://hackmd.io/_uploads/SJwPR8fQA.png) Agora que seu trabalho foi integrado, você não precisa mais da branch iss53. Você pode encerrar o chamado no seu sistema e excluir a branch: $ git branch -d iss53 Observe que quem trabalhou mais foi o Git, não você, porque os comandos utilizados foram os mesmos. - Conflitos básicos de mesclagem De vez em quando, esse processo não acontece de maneira tão tranquila. Se você mudou a mesma parte do mesmo arquivo de maneiras diferentes nas duas branches que você está tentando mesclar, o Git não vai conseguir integrá-las de maneira limpa. Se a sua correção para o problema #53 modificou a mesma parte de um arquivo que também foi modificado em hotfix, você vai ter um conflito de merge que se parece com isso: $ git merge iss53 Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result. O Git não criou automaticamente um novo commit de merge. Ele pausou o processo enquanto você soluciona o conflito. Para ver quais arquivos não foram mesclados a qualquer momento durante um conflito de merge, você pode executar git status: $ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") Unmerged paths: (use "git add <file>..." to mark resolution) both modified: index.html no changes added to commit (use "git add" and/or "git commit -a") Qualquer arquivo que tenha conflitos que não foram solucionados é listado como unmerged("não mesclado"). O Git adiciona símbolos padrão de resolução de conflitos nos arquivos que têm conflitos, para que você possa abrí-los manualmente e solucionar os conflitos. O seu arquivo contém uma seção que se parece com isso: <<<<<<< HEAD:index.html <div id="footer">contact : email.support@github.com</div> ======= <div> please contact us at support@github.com </div> >>>>>>> iss53:index.html Isso significa que a versão em HEAD (a sua branch master, porque era o que estava selecionado quando você executou o comando merge) é a parte superior daquele bloco (tudo após =======), enquanto que a versão na branch iss53 contém a versão na parte de baixo. Para solucionar o conflito, você precisa escolher um dos lados ou mesclar os conteúdos diretamente. Por exemplo, você pode resolver o conflito substituindo o bloco completo por isso: <div id="footer"> please contact us at email.support@github.com </div> Essa solução tem um pouco de cada versão, e as linhas com os símbolos <<<<<<<, =======, e >>>>>>> foram completamente removidas. Após solucionar cada uma dessas seções em cada arquivo com conflito, execute `git add` em cada arquivo para marcá-lo como solucionado. Adicionar o arquivo ao stage o marca como resolvido para o Git. Após você sair da ferramenta, o Git pergunta se a operação foi bem sucedida. Se você responder que sim, o Git adiciona o arquivo ao stage para marcá-lo como resolvido. Você pode executar git status novamente para verificar que todos os conflitos foram resolvidos: $ git status On branch master All conflicts fixed but you are still merging. (use "git commit" to conclude merge) Changes to be committed: modified: index.html Se você estiver satisfeito e verificar que tudo o que havia conflitos foi testado, você pode digitar git commit para finalizar o commit. A mensagem de confirmação por padrão é semelhante a esta: Merge branch 'iss53' Conflicts: index.html # # It looks like you may be committing a merge. # If this is not correct, please remove the file # .git/MERGE_HEAD # and try again. # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # All conflicts fixed but you are still merging. # # Changes to be committed: # modified: index.html # Se você acha que seria útil para outras pessoas olhar para este merge no futuro, você pode modificar esta mensagem de confirmação com detalhes sobre como você resolveu o conflito e explicar por que você fez as mudanças que você fez se elas não forem óbvias. ## Rebasing - O básico do rebase Se você voltar a um exemplo anterior de Mesclagem Básica, você pode ver que o seu trabalho divergiu e fez commits em duas branches diferentes. ![image](https://hackmd.io/_uploads/SJeWNvMmC.png) A maneira mais fácil de integrar as branches, como já vimos, é o comando merge. Ele realiza uma fusão de três vias entre os dois últimos snapshots de branch (C3 e C4) e o ancestral comum mais recente dos dois (C2), criando um novo snapshot (e commit). ![image](https://hackmd.io/_uploads/rk3-VPfXA.png) No entanto, há outra maneira: você pode pegar o patch da mudança que foi introduzida no C4 e reaplicá-lo em cima do C3. No Git, isso é chamado de rebasing. Com o comando rebase, você pode pegar todas as alterações que foram confirmadas em um branch e reproduzi-las em outro. Neste exemplo, você executaria o seguinte: $ git checkout experiment $ git rebase master First, rewinding head to replay your work on top of it... Applying: added staged command Ele funciona indo para o ancestral comum dos dois branches (aquele em que você está e aquele em que você está fazendo o rebase), obtendo o diff introduzido por cada commit do branch em que você está, salvando esses diffs em arquivos temporários, redefinindo o branch atual para o mesmo commit do branch no qual você está fazendo o rebase e, finalmente, aplicando cada mudança por vez. ::: danger Será que precisamos explicar isso? Porque sinceramente nem eu entendi direito ::: ![image](https://hackmd.io/_uploads/r1lS4wfmA.png) Agora você pode voltar ao branch master e fazer uma fusão rápida. $ git checkout master $ git merge experiment Agora, o snapshot apontado por C4' é exatamente o mesmo que foi apontado por C5 no exemplo de merge. Não há diferença no produto final da integração, mas o rebase contribui para um histórico mais limpo. Se você examinar o log de um branch que foi feito rebase, parece que todo o trabalho aconteceu em série, mesmo quando originalmente aconteceu em paralelo. - Rebases mais interessantes :::danger Acho que isso talvez seja avançado demais para o escopo e tempo do nosso curso ::: - Rebase vs. Merge Existem dois pontos de vista sobre o histórico de commits em um repositório Git. O primeiro considera o histórico de commits como um registro histórico que não deve ser alterado, pois representa o que realmente aconteceu. Mudar o histórico seria como mentir sobre os eventos reais. O segundo ponto de vista vê o histórico de commits como a narrativa de como o projeto foi desenvolvido, e, assim como um rascunho de um livro não é publicado, o histórico deve ser editado para clareza e melhor compreensão futura, utilizando ferramentas como rebase e filter-branch. A escolha entre merge e rebase não é simples, pois depende das necessidades específicas de cada equipe e projeto. A prática recomendada é fazer rebase em mudanças locais não compartilhadas para manter o histórico limpo, mas nunca faça rebase em algo que você empurrou em algum lugar. ## Pull Request e a função de Review - O que é o Pull Request? É quando solicitámos que a tarefa que fizemos, quando finalizada, seja incrementada no projeto principal. - Por exemplo, observe a imagem: ![Captura de tela 2024-06-11 163110](https://hackmd.io/_uploads/HkifL7IrA.png) > Temos a desenvolvedora Ana que vai trabalhar para um app > - Este app tem um código principal que está em verde. > - Foi criada uma branch para que ana trabalhe e implemente o recurso chat do app > - Assim que ela termina todo o chat, ela vai fazer uma solicitação para que o que ela implementou seja margeado, porém sabemos que isso não pode ser feito sem uma revisão, pois podem haver erros. > - o Pull request é essa solicitação, que será analisada pelo code Review, que é outro desenvolvedor que tem a atribuição de revisar os códigos. ## Fork - Garfar projetos > Ainda não elaboramos essa parte. Estamos decidindo se vamos ensinar essas funcionalidades do github. # Exercícios ## Exercícios de fixação ($) ### Exercício 1 ($) 1. Navegue até a pasta projeto01 que você criou e conectou remotamente. 2. Crie um arquivo aventuras.txt, dentro da pasta onde está o seu reepositório local(projeto01),por enquanto não escreva nada dentro. 3. Faça git status e note que existem mudaças para serem registradas. 4. Adicione essa mudaça, que é a criação do arquivo historia, na standing área utilizando o comando aprendido. 5. Agora é hora de fazer o commit, digite a seguinte mensagem neste commit "Criei o arquivo historia" 6. Agora escreva o primeiro capítulo, depois adicione ao staging area e faça um commit com a mensagem "adicionei o capítulo 01". 7. Agora você pode fazer outro capítulo salvar e depois fazer o mesmo processo do passo 6. > Missão: faça 3 capítulos e a cada capítulo faça um commit. 8. Agora é hora de enviar os arquivos e os commits para o repositório remoto. Utilize o comando aprendido. ## Exercícios obrigatórios (#) ### Exercício 1 (#) 1. Crie uma pasta nova em seu computador com o seguinte nome "projeto02" 2. Acesse-a pelo seu terminal utilizando os comando aprendidos no dia anterior. 3. Execute o comando para inicializar o git dentro da pasta/diretório. > Dica: este comando cria uma pasta oculta chamada ".git" no diretório 4. Crie um arquivo chamado `biografia<numero de matrícula>.txt` e escreva algumas linhas. > Dica: Meu número de matrícula é 20005425 , logo meu arquivo terá o seguinte nome: "biografia20005425.txt" > Escrevam algo engraçado, pois a melhor biografia será lida no último dia do nosso minicurso e o vencedor ganhará uma surpresa. 5. Adicione o arquivo `biografia<numero de matrícula>.txt` ao repositório Git utilizando o comando que coloca as alterações na staging área > Dica: antes de fazer o comando, execute git status e analise o que precisa ser trackeado e o que foi modificado. 6. Faça um commit com uma mensagem descritiva dizendo que que você criou o arquivo com a sua biografia. 7. Vá até o arquivo novamente e acrescente seu nome e salve. 8. Adicione a alteração ao repositório Git utilizando o comando que coloca as alterações na staging área. 9. Faça um commit com a seguinte mensagem "coloquei meu nome no arquivo". 8. Digite o comando que visualiza todos os commits feitos e veja o seu histórico de commits. 9. Crie um repositório vazio no github com o nome projeto01 10. Faça o comando para conectar o seu repositório local com o seu repositório remoto criado 11. Depois ulilize o comando que sobe os arquivos do projeto local para o seu repositório remoto. > Para saber se tudo deu certo, basta olhar os seus commits no repositório do github e analisar se a sua biografia está escrita com o seu nome abaixo. ### Exercício 2 (#) 1. Escolha a sua dupla para esta grande aventura. 2. Acesse o GitHub e apenas o componente 'A' deve criar um novo repositório no github com o nome projeto03 e criar um arquivo chamado historia_<numero de matricula de A>_<numero de matricula de A>.txt. 3. Agora ambos têm que clonar o projeto em seus computadores. > O aluno B deve pesquisar na barra de pesquisa pelo usuário do aluno A e acessar o repositório criado, para poder clonar. 4. Uma vez que ambos clonaram o repositório é hora de criar a história em conjunto. 5. Um dos alunos deve escrever o primeiro capítulo. Vamos chamar o aluno A. > Dica: Escrever capítulo > salvar > add > commit > push 6. Agora o aluno B deve atualizar o repositório, puxando as alterações que foram subidas pelo outro aluno para o repositório remoto utilizando o comando aprendido em aula. > Assim, antes de o aluno B escrever o capítulo 2, ele vai ter o capitulo 1 no documento já no seu repositório local. 7. Hora do aluno B escrever o próximo capítulo. 8. Agora o aluno A fará o mesmo que o B fez no passo 5 . > - Puxar as alterações que foram subidas pelo outro aluno para o repositório remoto > - Depois o aluno A terá que escrever o próximo capítulo. 9. Missão: escrever até o capítulo 5. ### Exercicio 3 1. Clone o repositório do projeto <na conta do petcc-exercícios>. 2. Crie uma branch para suas alterações. 3. Vá na pasta onde está o repositório clonado e crie um arquivo chamado "seunome.txt". 4. Adicione o arquivo "<numero da matricula>.txt" ao repositório Git, se o seu número de matrícula é 202343, o arquivo será 202343.txt. 5. Faça um commit com uma mensagem descritiva. > Seja criativo! Incremente o arquivo com um texto falando sobre o que achou do curso. 6. Envie suas alterações para o repositório remoto. 7. Crie uma Pull Request pelo github: > 1. Acesse o repositório no GitHub. > 2. Navegue até a seção "Pull Requests". > 3. Clique no botão "New Pull Request". > 4. Selecione sua branch como a branch de origem e a branch principal do projeto como a branch de destino. > 5. Adicione um título e uma descrição detalhados para sua Pull Request. > 6. Revise as alterações e clique em "Create Pull Request". > 8. Aguarde a revisão da equipe: > > Um membro da equipe revisará suas alterações e poderá solicitar revisões ou aprovar sua Pull Request. > > Responda a quaisquer comentários ou solicitações de revisão e faça as alterações necessárias. 8. Integre suas alterações: > Quando sua Pull Request for aprovada, ela poderá ser integrada à branch principal do projeto. > O repositório será atualizado com suas alterações e todos os colaboradores poderão acessá-las. 9. Se a sua Pull Request foi aprovada, então parabéns!!! Você conseguiu finalizar o exercício.

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully