O básico de Git
Tags: git, programming
Published: 2023-11-21 12:36:42

## O que é Git?
Git é um versionador de código, gratuito e de código aberto. Um versionador de código serve para que possamos criar um histórico de tudo o que fazemos no código, isso é ótimo porque podemos trabalhar em equipe e todas as alterações ficam registradas de forma padronizada, facilitando o entendimento do que a outra pessoa fez no código e tendo a possibilidade de "voltar no tempo", para uma determinada versão do código.

## Configuração básica
Depois de instalar o Git é importante fazer algumas configurações básicas. Primeiro vamos definir o email e username, isso serve para identificar quem fez alguma alteração no código.
```
$ git config --global user.email "<seu-email>"
$ git config --global user.name "<seu-nome>"
```

Agora vamos definir um editor que será utilizado para resolver conflitos.
```
$ git config --global core.editor "<seu-editor>"
```

Para finalizar vamos definir o nome padrão da branch quando inicializamos o Git.
```
$ git config --global init.defaultBranch "main"
```

Agora podemos visualizar as configurações que fizemos com `$ git config --list`.
```
$ git config -list

user.email="<seu-email>"
user.name="<seu-nome>"
init.defaultBranch="main"
core.editor="<seu-editor>"
```

## Inicializando um novo repositório local
Antes de inicializar um novo repositório Git vamos criar um diretório para podermos trabalhar. 
```
$ mkdir my-project
$ cd my-project
```

Agora com o diretório criado podemos inicializar um novo repositório Git.
```
$ git init
```

Note que foi criado um diretório `.git` que contém todos os arquivos de repositório necessários, portando não mexa nestes arquivos, eles são necessários para o funcionamento do Git.

## Trabalhando com arquivos
Depois de inicializar um novo repositório Git no diretório que criamos, vamos começar criando um novo arquivo com o nome de `a.txt` com um conteúdo qualquer dentro.
```
$ touch a.txt
$ echo "Conteúdo do arquivo a.txt" >> a.txt
```

O Git possuí um comando muito importante para que possamos visualizar o status do nosso repositório que é o `$ git status`. Executando ele agora podemos ver algumas informações.
```
$ git status

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	a.txt
```

Aqui o Git está informando que exite um ou mais arquivos que não estão sendo rastreados, ou seja, caso fizermos alterações nesse arquivo não vamos conseguir ter um histórico do que foi alterado ou adicionado.

Para criar um commit você precisa separar os arquivos que irão para o commit e para isso usamos o comando `$ git add <nome-do-arquivo>...`, no nosso caso vamos adicionar o arquivo `a.txt` e rodar `$ git status` para ver o que mudou.

Mas antes vamos entender o que é um commit. Commits são a parte essencial do Git, basicamente um commit é o estado do seu repositório em um determinado momento, normalmente commits são feitos a cada nova pequena funcionalidade. Neles contém informações sobre a data, quem fez a alteração e a mensagem informando sobre o que foi alterado ou adicionado.

```
$ git add a.txt
$ git status

On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
	new file:   a.txt
```

Nesse caso o Git está informando os arquivos que irão para o próximo commit e o status do arquivo, se ele é novo, foi deletado ou alterado.

Agora vamos fazer o commit com `$ git commit -m "<mensagem-do-commit>"`. 
```
$ git commit -m "adicionado arquivo a.txt"
$ git status

On branch main
nothing to commit, working tree clean
```

Para visualizar o histórico de commits feitos, podemos usar o comando `$ git log`.
```
$ git log

commit de75b4a5e0affac9c36e70ffdfbcc43f4edd1fb4 (HEAD -> main)
Author: <seu-nome> <seu-email>
Date:   Sun Oct 29 19:18:37 2023 -0300

    adicionado arquivo a.txt
```

Aqui está apresentado todas as informações sobre os commits feitos, data, nome e email de quem fez, a mensagem indicando a mudança e o identificador do commit que fica logo na primeira linha após a palavra "commit". Para sair dessa tela pressione a tecla "q".

Agora vamos fazer uma alteração no arquivo `a.txt` adicionado mais conteúdo e vamos marcar essa alteração para o próximo commit.
```
$ echo "Novo conteúdo do arquivo a.txt" >> a.txt
$ git add a.txt
```

Agora vamos supor que eu adicionei um arquivo errado ou que eu não queira que esse arquivo vá para o próximo commit. Como reverter isso? Simples, é só executar o comando `$ git restore --staged <nome-do-arquivo>`.
```
$ git restore --staged a.txt
$ git status

On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   a.txt

no changes added to commit (use "git add" and/or "git commit -a")
```

Caso você queira descartar as alterações que você fez no arquivo você pode executar o comando `$ git restore <nome-do-arquivo>`, perceba que aqui não temos a parte `--staged`.
```
$ git restore a.txt
$ git status

On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean
```

## Branch
Com o que foi visto até agora podemos trabalhar tranquilamente com Git, mas ainda falta um último tópico a ser visto que é sobre branch.

Branch é basicamente uma ramificação no repositório onde podemos ter, por exemplo, uma branch que trabalhamos na funcionalidade "abc" e outra branch para trabalhar na funcionalidade "def" e quando a funcionalidade estiver pronta podemos fazer um merge para a branch principal, que em todo repositório Git se chama `main`. O ponto aqui é que quando criamos branchs não vamos comprometer a branch principal do repositório caso a funcionalidade não fique boa ou as coisas não deem certo.

Voltando ao repositório que estamos trabalhando, vamos começar com o comando `$ git branch` que mostra todas as branchs criadas nesse repositório.
```
* main
(END)
```

Podemos ver que temos uma branch criada, que se chama `main` essa branch é criada pelo próprio Git na inicialização do repositório e é onde todo o código principal do projeto está, o que estiver na produção é o que está na branch `main`.

Agora vamos supor que queremos fazer um teste de uma nova funcionalidade mas não queremos comprometer nada do fizemos até agora, para isso vamos criar uma nova branch com o comando `$ git branch <nome-da-branch>`.
```
$ git branch funcionalidade-abc
$ git branch

  funcionalidade-abc
* main
(END)
```

Note que criamos uma nova branch e depois listamos as branchs existentes no repositório e agora temos duas. Para mudar de branch usamos o comando `$ git checkout <nome-da-branch>`

```
$ git checkout funcionalidade-abc
Switched to branch 'funcionalidade-abc'

$ git branch

* funcionalidade-abc
  main
(END)
```

Com o comando `$ git branch` podemos notar que o `*` que estava no `main` mudou para `funcionalidade-abc` indicando em qual branch estamos trabalhando.

A partir de agora podemos trabalhar normalmente como antes, vamos adicionar mais algum conteúdo no arquivo `a.txt`, vamos marcar essa alteração para o próximo commit e depois vamos fazer o commit.

```
$ echo "Novo conteúdo do arquivo a.txt" >> a.txt
$ git add a.txt
$ git commit -m "adicionado novo conteúdo no arquivo a.txt"
$ git log

commit d26ed7a5fde35bb229cf0f3ade3171ac886f44ca (HEAD -> funcionalidade-abc)
Author: <seu-nome> <seu-email>
Date:   Fri Nov 17 09:43:40 2023 -0300

    adicionado novo conteúdo no arquivo a.txt
    
commit de75b4a5e0affac9c36e70ffdfbcc43f4edd1fb4 (main)
Author: <seu-nome> <seu-email>
Date:   Sun Oct 29 19:18:37 2023 -0300

    adicionado arquivo a.txt
(END)
```

Depois de rodar `$ git log` para ver o histórico de commits, podemos ver que temos agora dois commits, o primeiro (de baixo para cima) é o que fizemos no início desse artigo e o último commit é o que acabamos de fazer. Note que o primeiro foi feito na branch `main` e o último foi feito na branch `funcionalidade-abc`.

Voltando para a branch principal `main` podemos notar que as modificações que fizemos na outra branch não estão lá.

```
$ git checkout main
Switched to branch 'main'
$ git log

commit de75b4a5e0affac9c36e70ffdfbcc43f4edd1fb4 (main)
Author: <seu-nome> <seu-email>
Date:   Sun Oct 29 19:18:37 2023 -0300

    adicionado arquivo a.txt
(END)
```

Aqui está o poder de usar branchs, as modificações ficam separadas, não comprometendo a branch principal. Agora vamos supor que a funcionalidade que fizemos está de acordo, ocorreu tudo bem e é uma boa funcionalidade para adicionar no projeto, como juntar as modificação feitas, na branch principal? Para isso vamos usar o comando `$ git merge <nome-da-branch`.

```
$ git merge funcionalidade-abc

Updating de75b4a..d26ed7a
Fast-forward
 a.txt | 1 +
 1 file changed, 1 insertion(+)

$ git log

commit d26ed7a5fde35bb229cf0f3ade3171ac886f44ca (HEAD -> main, funcionalidade-abc)
Author: <seu-nome> <seu-email>
Date:   Fri Nov 17 09:43:40 2023 -0300

    adicionado novo conteúdo no arquivo a.txt

commit de75b4a5e0affac9c36e70ffdfbcc43f4edd1fb4
Author: <seu-nome> <seu-email>
Date:   Sun Oct 29 19:18:37 2023 -0300

    adicionado arquivo a.txt
(END)
```

Agora podemos ver que os dois commit estão apontando para a branch `main`. A branch que criamos ainda está criada e você pode manter uma branch para apenas desenvolvimento, a medida que novas funcionalidade são desenvolvidas na branch de desenvolvimento, você faz o merge para a branch principal.

Caso você tenha criado uma branch para apenas fazer algum teste e não deu certo e você queira deletar esta branch, você pode usar o comando `$ git branch -D <nome-da-branch>`. Caso você já vez o merge e queira deletar esta branch pois não vai mais usá-la, você pode usar o mesmo comando só que com o "d" minúsculo `$ git branch -d <nome-da-branch>`.

``` 
$ git branch -d funcionalidade-abc
Deleted branch funcionalidade-abc (was d26ed7a).

* main
(END)
```

## Resumo do que foi visto
* `$ git init` - Inicializar um novo repositório.
* `$ git status` - Visualizar o status do repositório.
* `$ git add <nome-do-arquivo>` - Adiciona um ou mais arquivos para iram para o próximo commit.
* `$ git restore --staged <nome-do-arquivo>` - Remove o arquivo para ir para o próximo commit.
* `$ git restore <nome-do-arquivo>` - Descarta as alterações feitas no arquivos.
* `$ git commit -m "<mensagem-do-commit>"` - Cria um commit.
* `$ git branch` - Lista as branchs criadas.
* `$ git branch <nome-da-branch>` - Cria uma nova branch.
* `$ git checkout <nome-da-branch>` - Muda de branch.
* `$ git branch -d <nome-da-branch>` - Deleta uma branch que já fez o marge.
* `$ git branch -D <nome-da-branch>` - Deleta uma branch que não fez o marge.
* `$ git merge <nome-da-branch>` - Faz o merge da branch atual com a indicada.