- onde eu apresento de forma escrita os comandos demonstrados no curso de git para fins de estudo pós-curso.
- Um commit é uma série de modificações introduzidas a um repositório.
- Um repositório git nada mais é do que um grafo direcionado acíclico em que os vértices são os commits.
- Um commit pode ter infinitos pais.
- Geralmente um commit tem um commit pai. O commit sempre aponta para o seu pai, se tiver pai.
- Um commit pai nunca aponta para um commit filho. (por isso que é um grafo direcionado).
- Um commit nunca é destruído.
- referências tornam commits alcançaveis.
- um commit é alcançável quando uma referência aponta para ele ou para um filho dele.
- se um commit não é alcançável, ele não aparecerá no histórico. Não irá para o remote no momento do
git push
. - referências são apenas ponteiros para um commit. A única coisa que uma referência faz é apontar para um commit.
- uma referência é apenas um nome ligando um commit
SHA
. - São referências no git: o
HEAD
, qualquerbranch
, e qualquertag
.
- Uma
tag
é uma referência. Logo, é apenas um ponteiro para um commit. - Uma tag, uma vez criada, nunca poderá ser alterada.
- Em outras palavras, aponta sempre para o mesmo commit e nunca muda, desde sua criação.
- Um
branch
nada mais é do que uma referência. Logo é apenas um ponteiro para um commit. Por isso que se diz que no git os branches são 'leves'. - Um
branch
pode apontar para diferentes commits, de acordo com o vontade do usuário. - O git commit faz com que o commit atual, apontado pelo branch atual, ganhe um filho, e faz o branch atual apontar para esse filho.
- quando você inicia um repo git, o git cria um branch com o nome padrão de
master
. - O
master
é só isso, um nome padrão para o primeiro branch criado. Poderia ser outro nome. Você pode mudar o nome para o nome que você quiser.
- Assim como
branches
etags
, oHEAD
é apenas uma referência para um commit. Mas não qualquer commit.- Veja que em qualquer momento da linha do tempo, no seu repo git, você tem um commit
checkoutizado
. - esse commit
checkoutizado
é apontado sempre pela referênciaHEAD
.
- Veja que em qualquer momento da linha do tempo, no seu repo git, você tem um commit
- Além disso, o HEAD é uma referência que pode apontar para outra referência: um
branch
. - Então o
HEAD
pode apontar para um commit diretamente, ou no caso normal, aponta para umbranch
- Quando o
HEAD
aponta para um branch, por exemplo,master
, ele acompanha omaster
.- para ficar claro: suponha que o
master
estava apontando paraA
e agora aponta paraB
. - então o HEAD também estava apontando para
A
e agora está apontando paraB
, viamaster
.
- para ficar claro: suponha que o
-
No seu repo git, o arquivo pode estar em 3 locais diferentes:
-
O arquivo pode estar na
WORKING COPY
: que é o seu sistema de arquivos. -
Você pode ver como o arquivo nesse local por meio de, por ex:
$ cat arquivo.txt
- Pode estar no
INDEX
(tbm chamado destaging area
,stage
, oucache
): que é o seucommit proposto
. - é efetivamente um commit, mas o git não aplicou um
SHA
a ele ainda. então não tem referência, nem pai, nem identificador. - Você pode ver como o arquivo se encontra nessa área especial por meio do comando:
# onde :arquivo.txt é o full path para o arquivo no seu repo.
# poderia ser config/arquivo.txt ou outra coisa
$ git show :arquivo.txt
- No
HEAD
: que é como o arquivo está no commitcheckoutizado
nesse momento no seu repo. - Então quando se diz: quero ver como o arquivo está no
HEAD
, é a mesma coisa que dizer: quero ver como o arquivo está no commit checkoutizado no momento no meu repo - Você enxerga o arquivo tal como ele está no
HEAD
por meio do comando:
# mesma sintaxe do INDEX, acima
# perceba que no lugar do HEAD você poderia colocar qualquer referência: um branch, uma tag, um commit SHA, etc...
$ git show HEAD:arquivo.txt
- é remotes, no plural mesmo, porque você pode adicionar infinitos remotes no seu git repo local
- Quando você git clona um repo, o git, por padrão, adiciona um remote chamado
origin
que aponta para o repo git clonado. - o
origin
abriga upstream branches, ou seja, os branches que estão na máquina remota que abriga o repo git que éa verdade
. (tem upstream tags também) - você tem na verdade uma cópia desses branches remotos no seu origin local. Cabe a você ir
syncando
ou atualizando essa cópia. - fora essas características, para efeitos práticos, o
origin
abriga apenas referências para commits:origin/HEAD
,origin/master
,origin/feature-1
,origin/v2.1
, etc...
- você pode pensar que o index é o seu commit proposto.
- você tem que adicionar os arquivos modificados localmente ao INDEX. antes de commitar.
- o
git commit
simplesmente pega as modificações adicionadas ao INDEX monta um commit e adiciona esse commit no histórico. - você adiciona um arquivo ao INDEX com o comando:
$ git add arquivo.txt
$ ga arquivo.txt
# ou para adicionar toda e qualquer mudança local no index:
$ git add --all :/
$ gal
- suponha que você escreveu fez uma alteração a um arquivo
git add arquivo.txt
e assim adicionou essa modificaçãoINDEX
- se você quer desfazer essa operação, basta escrever:
git reset arquivo.txt
- dessa forma as modificações no arquivo.txt continuarão a ficar como modificações apenas na working copy.
- suponha que você tenha um
arquivo.txt
no HEAD. - suponha ainda que você abriu esse arquivo e adicionou umas 7 linhas. Mas quer reverter isso. Quer deixar o arquivo como ele estava.
- um
git status
vai revelar que o arquivoarquivo.txt
contém modificações locais. Para reverter essas modificações nesse arquivo, basta escrever:
$ git checkout `arquivo.txt`
# forma padrão
$ git commit -m 'sua mensagem de commit'
# atalho: abre o vim para que vc digite uma msg de commit
# e ainda apresenta o diff entre o seu commit proposto e o commit anterior
$ gc
- verificando suas modificações locais
$ git status
# apresenta uma forma mais condensada do git status
# git status -sb
$ g
- verificando em qual branch você está no momento, e quantos commits está para trás ou para frente em relação ao seu tracking branch (ou
upstream
branch)
# normal: mostra apenas em qual branch você está
$ git branch
# alias: mostra todos os branches locais, os tracking branches, e para quais commits cada respectivo branch está apontando
$ gg
# normal
$ git log
# atalho: formato muito mais condensado e completo, com cores que diferenciam diferentes categorias de informação, mostra as referências, etc...
$ gl
- perceba a diferença entre o
git log
normal e o atalhogl
- Bonus: você pode inspecionar o repositório considerando o
reflog
, em que o git considera as referências não alcançáveis como alcançáveis:
# mesma coisa que gl --reflog
$ glr
- você pode verificar o que mudou da sua working copy para o seu INDEX com o comando git diff
# ou simplesmente $ gd
$ git diff
- para que você verifique o que mudou do INDEX para o HEAD, escreva:
$ dit diff --cached
- veja como fica o diff no terminal:
- você pode comparar duas refs quaisquer com git diff. por exemplo
# o que mudou de 2 commits para trás até agora?
$ git diff HEAD~2 HEAD
- você pode amarrar branches de desenvolvimento que bifurcaram no grafo com um novo commit. Basta escrever:
# suponha que você esteja em master e suponha que feature seja um branch que divergiu de master.
git merge feature
# pronto. você acabou de incorporar as modificações contidas em feature para dentro do branch master.
-
você também pode optar por deixar seu histórico de commits mais limpo com
git rebase
. -
com
git rebase
você pede para que o git faça umreplay
de todos os commits a partir do ancestral comum entre o seu branch atual e o branch para o qual vc quer fazer rebase. -
com isso você terá um histórico com uma linha mais reta.
-
como um exemplo, suponha que você esteja em um branch
feature
. -
suponha que você queira incorporar as alterações em
feature
paramaster
. -
suponha também que
feature
emaster
divergiram de forma que umgit merge
criaria um novo commit amarrando os dois branches (não seria umfast-forward
). -
para incorporar as alterações em feature para dentro de master de forma que a linha de histórico de commits continue reta, basta escrever:
$ git rebase master
# fast forward. poderia utilizar git merge feature também. o efeito é o mesmo.
$ git checkout master
$ git rebase feature
- IMPORTANTE: git rebase é uma forma de reescrever a história de um repo.
- então você só pode reescrever a história de um repo em um branch local seu, ou em um branch remote a que somente você tenha acesso (ou você combinou com todos no projeto que só faria push nesse branch.)
- se você já fez git push dos commits cuja história vc está reescrevendo, você terá que mandar um
git push -f
(f
de force). Ou seja, os commits reescritos serão apagados do remote. (porque não haverá referências apontando para eles. eles se tornarão inalcançáveis). - logo, se alguém baseou um commit em um outro commit que você estará apagando do remote, esse algúem ficará muito desapontado com você.
- então use o git rebase com cautela.
- suponha que você tenha um repositório clonado, e com o branch
master
em checkout. - para criar um novo branch e fazer o checkout desse novo branch, digite
$ git branch feature
$ git checkout feature
- suponha que você fez algumas alterações, add, commit e queira fazer o push do branch feature para o origin
- suponha que você queira ainda setar o
origin/feature
para ser o tracking branch dofeature
# o -u manda o git setar o origin/feature, que será criado nesse comando, para ser o tracking branch de feature
$ git push -u origin feature
-
lembre-se que um tracking branch (ou upstream branch) é um branch de comparação. O git status vai te dizer quantos commits para trás ou para frente você está em relação sempre a um tracking branch.
-
você pode remover um branch local
$ git branch -d feature
- para renomear o branch atual em que você está:
$ git branch -m <novonomedobranch>
- suponha que você queira que o
master
aponte para um commit SHA arbitrário. - basta escrever:
# no lugar de <commit SHA> você pode colocar qualquer ref: branch, tag, etc...
$ git reset --hard <commit SHA>
- você pode usar referências relativas:
# faz o HEAD (e o branch que é apontando pelo HEAD) apontar para o commit imediatamente anterior
$ git reset --hard HEAD~
Você encontra mais dicas de git no meu repo do github.