Workflow para os commits
Em primeiro lugar sempre cheque se está tudo certo com seu
repositório, se seu trabalho local está sincronizado com seu trabalho
remoto. Para tanto pode digitar na linha de comando do terminal
Se sua working tree estiver no status clean, quer
dizer que você está sincronizada com o origin
Faça algumas modificações e depois vamos fazer a mesma sequencia de
ações que fizemos anteriormente (stage, commit, push), mas agora usando
a linha de comando. Para tanto podemos fazer assim
git add .
git commit -m "uma mensagem informativa"
git push
Pronto, fizemos a mesma coisa que anteriormente, mas agora utilizando
o terminal :)
Amend
Lembra que muitos commits podem te deixar muito lento na escalada? E
poucos commits podem ser pouco informativos caso queira reconstruir o
que aconteceu com o repositório? Pois então, existe uma estratégia
interessante para realizar commits, chamada de amend
Em um amend nós basicamente adicionamos um commit a um outro já
existente. Por exemplo, imagine que fez apenas algumas poucas
modificações de código que não necessitam necessariamente de um commit
dedicada exclusivamente para tais, você pode fazer o seguinte:
1 - stage o arquivo que modificou
2 - faça um commit
Note que coloquei WIP neste commit, por que? WIP é
uma sigla usada comumente no versionamente para Working In Progress.
Sempre que tiver um commit desse quer dizer que o commit que fez ainda
está sendo trabalhado.
Ainda não faça o push. Faça mais algumas modificações, e, digamos que
agora fez modificações relevantes no código que merecem um commit
dedicado. Mas lembre-se que o último commit é um WIP. O que fazemos
agora é um amend ao WIP
3 - faça um amend
git commit --amend -m "Aqui um commit com uma mensagem informativa, como sempre"
git push
Pronto, agora temos uma mensagem informativa que foi adicionada ao
WIP e não precisamos fazer um push do passo intermediário (WIP),
deixando nossa escalada mais rápida
Viajando entre commits
Uma das maiores potencialidades dos commits é a possibilidade que
podemos navegar entre commits. Ou seja, podemos navegar entre estados
distintos do nosso trabalho a medida que ele é desenvolvido. Podemos
checar esse histórico tanto na nossa página do repositório no GitHub
quanto usando o RStudio, como mostrado na imagem a seguir

Para tanto você precisa apenas abrir a aba do Git no RStudio, como
vimos anteriormente, e clicar em History no canto
superior esquerdo da janela de revisões. Tudo o que vemos são todos os
commits que foram realizados desde que esse repositório foi formado pela
primeira vez.
Elementos importantes do commit
Alguns elementos presentes no commit são importantes. O principal
deles é a chave SHA-1. Esta se trata de um identificador único do
commit. Com ela podemos viajar entre commits, ou referenciar um dado
commit em uma discussão no github. Por exemplo, supondo que estamos
trabalhando colaborativamente (como nesse site :)), e eu gostei
particularmente mais da versão do site que está há alguns commits atrás.
Uma opção é abrir uma Issue (veremos isso mais tarde), e referenciar
esse número. Ou simplesmente dizer para meu colaborador “Hey dê uma
olhada no commit número XXXXXX”. Na imagem abaixo está em destaque a
chave SHA.

Você pode abrir o arquivo no estado em que ele se encontrava em um
dado commit clicando no arquivo modificado naquele commit selecionado.
Por exemplo, digamos que eu queira ver o arquivo chamado
rmarkdown-basics
deste site editado dia 02 de Agosto, só
precisamos clicar no arquivo, como mostrado na imagem abaixo:

Back to the future: revertendo o trabalho do repositório e
voltando
Existem situações que gostariamos de reverter não só um arquivo em
específico, mas o estado inteiro de um repositório em
um dado momento no tempo.
Por exemplo, digamos que você fez um push quando não deveria. Ou
mudou muitos arquivos de uma só vez, o que tornaria bastante trabalhoso
reverter arquivo por arquivo (ainda que possível, utilizando o método
apresentado anteriormente). Nesta situação podemos reverter o nosso
repositório para algum momento do tempo. Para fazer isso precisamos,
primeiro, identificar o momento do tempo que gostaríamos de retornar. E
como isso é possível? Utilizando os commits. Como dito
anteriormente, os commits são momentos do seu repositório (mais um
motivo para utilizar commits informativos).
Existem algumas formas de retornar ao passado, da mais radical para a
menos radical:
Deletar tudo e clonar novamente o repositório
O método mais radical, mas útil quando não fazemos ideia do que está
errado, consiste em:
- salvar os arquivos em uma pasta temporária
- deletar o diretório local
- clonar novamente o repositório a partir do github
Isso irá, obviamente, retornar o seu repositório para o estado que
ele se encontrava no último push
realizado para o
GitHub
Resetando
Resetar na linguagem do versionamento significa, basicamente,
realizar um CTR + Z no seu repositório. Em termos mais técnicos
do versionamento isso equivale a mover o HEAD para o último commit
realizado. Esse movimento para o passado pode ser feito de duas
formas.
- Movendo para o passado mas mantendo o trabalho localmente
- Movendo para o passado e deletando o trabalho
localmente
O que quer dizer esta sintaxe? Basicamente estamos movendo nosso HEAD
(último commit) um commit no passado (HEAD~1). Se quisermos nos mover
para commits mais antigos, por exemplo, dois commits anteriores, apenas
mudamos o número 1 para 2 após o ~
.
Outra opção que tem sido minha escolha preferida é o uso do git
reflog juntamente com o reset. Digite o seguinte no terminal
Isso irá fazer com que apareça no seu terminal um histórico de todos
os commits que foram feitos até o presente momento. A figura a seguir
mostra esse histórico para o repositório deste site.

Com o reflog você pode usar o index
do commit para
navegar no tempo. O index é o número que aparece logo após o
HEAD@{index}
. Esse index pode ser utilizado em conjunto com
a função reset
que vimos anteriormente. Por exemplo, se eu
quiser voltar para o commit número 11, devo usar o seguinte código
git reset --soft HEAD@{11}
Isso retornará 11 commits em relação ao commit atual. Você pode
voltar ao commit atual usando a mesma sintaxe. Lembrando que o argumento
--soft
retorna para o estado desejado mas mantém os
arquivos no seu diretório local.
NOTE: Acesse o site Oh Shit, Git!? para uma série de dicas
muito úteis sobre erros comuns quando estamos usando o Git
Atividade
Explore um pouco os commits que realizaram. Abra a página do github e
também através do Rstudio, veja as diferenças, as vantangens e
desvantagens de cada uma das abordagens
Throwback Commit
Vamos supor que realizamos um commit errado, e agora queremos voltar
ao commit anterior, mas sem perder o trabalho que fizemos nos arquivos.
Para isso podemos usar a abordagem anterior, navegando entre os arquivos
e selecionando o arquivo que queremos em um determinado estado,
substituimos pelo arquivo atual e fazemos um novo commit. Esta opção
pode ser a mais segura se estamos começando a mexer no versionamento.
Outra opção é explorar as funções do git chamadas reset
. As
funções reset basicamente move o HEAD do seu diretório para um commit no
passado. Esta abordagem pode causar algumas dores de cabeça no início,
portanto recomendo usa-lá com cautela. Para mais informações sobre isso
dê uma olhada nesse
site.)
LS0tCnRpdGxlOiAnRXhwbG9yYW5kbyBtZWxob3Igb3MgY29tbWl0cycKYXV0aG9yOiAiR2FicmllbCBOYWthbXVyYSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6IGh0bWxfZG9jdW1lbnQKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBmaWcuYWxpZ24gPSAiY2VudGVyIikKYGBgCgpgYGB7ciBrbGlwcHksIGVjaG89RkFMU0UsIGluY2x1ZGU9VFJVRX0Ka2xpcHB5OjprbGlwcHkoKQpgYGAKCiMgQXByZXNlbnRhw6fDo28KCk5lc3RhIHNlw6fDo28gaXJlbW9zIGV4cGxvcmFyIHVtIHBvdWNvIG1haXMgbyBwb2RlciBxdWUgb3MgY29tbWl0cyBub3Mgb2ZlcmVjZW0sIGluY2x1aW5kbyBib2FzIHByw6F0aWNhcyBwYXJhIGZhemVyIGNvbW1pdHMgbm9zIG5vc3NvcyBhcnF1aXZvcyBlIGNvbW8gInZpYWphciIgZW50cmUgY29tbWl0cyBwYXNzYWRvcyBlIHByZXNlbnRlLiBFc3RlIG1vbWVudG8gdGFtYsOpbSBzZXJ2aXLDoSBwYXJhIGZpY2FybW9zIHVtIHBvdWNvIG1haXMgZmFtaWxpYXJpemFkb3MgY29tIG8gdXNvIGRvIGdpdCBhdHJhdsOpcyBkbyB0ZXJtaW5hbC4gVmFtb3MgdXRpbGl6YXIgbyB0ZW1pbmFsIHZpc3RvIHF1ZSBhbGd1bWFzIGNvaXNhcyBxdWUgZmFyZW1vcyBhcXVpIG7Do28gcG9kZW0gc2VyIGZlaXRhcyBhdHJhdsOpcyBkbyBSU3R1ZGlvLgoKU2VtcHJlIGFvIGZhemVyIGNvbW1pdHMgdmFsZSBsZW1icmFyIGVzc2FzIHBhbGF2cmFzOgoKYGBge3IgZWNobz1GQUxTRSwgZXZhbD1UUlVFLG91dC53aWR0aD0iNzAlIn0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiZmlncyIsICJjb21taXQtc2FmZS5wbmciKSkKYGBgCgojIFdvcmtmbG93IHBhcmEgb3MgY29tbWl0cyAKCkVtIHByaW1laXJvIGx1Z2FyIHNlbXByZSBjaGVxdWUgc2UgZXN0w6EgdHVkbyBjZXJ0byBjb20gc2V1IHJlcG9zaXTDs3Jpbywgc2Ugc2V1IHRyYWJhbGhvIGxvY2FsIGVzdMOhIHNpbmNyb25pemFkbyBjb20gc2V1IHRyYWJhbGhvIHJlbW90by4gUGFyYSB0YW50byBwb2RlIGRpZ2l0YXIgbmEgbGluaGEgZGUgY29tYW5kbyBkbyB0ZXJtaW5hbAoKYGBge3IgZWNobz1ULGV2YWw9RkFMU0V9CmdpdCBzdGF0dXMKYGBgCgpTZSBzdWEgKndvcmtpbmcgdHJlZSogZXN0aXZlciBubyBzdGF0dXMgKmNsZWFuKiwgcXVlciBkaXplciBxdWUgdm9jw6ogZXN0w6Egc2luY3Jvbml6YWRhIGNvbSBvICpvcmlnaW4qCgpGYcOnYSBhbGd1bWFzIG1vZGlmaWNhw6fDtWVzIGUgZGVwb2lzIHZhbW9zIGZhemVyIGEgbWVzbWEgc2VxdWVuY2lhIGRlIGHDp8O1ZXMgcXVlIGZpemVtb3MgYW50ZXJpb3JtZW50ZSAoc3RhZ2UsIGNvbW1pdCwgcHVzaCksIG1hcyBhZ29yYSB1c2FuZG8gYSBsaW5oYSBkZSBjb21hbmRvLiBQYXJhIHRhbnRvIHBvZGVtb3MgZmF6ZXIgYXNzaW0KCmBgYHtyIGVjaG89VFJVRSxldmFsPUZBTFNFfQpnaXQgYWRkIC4KZ2l0IGNvbW1pdCAtbSAidW1hIG1lbnNhZ2VtIGluZm9ybWF0aXZhIgpnaXQgcHVzaApgYGAKClByb250bywgZml6ZW1vcyBhIG1lc21hIGNvaXNhIHF1ZSBhbnRlcmlvcm1lbnRlLCBtYXMgYWdvcmEgdXRpbGl6YW5kbyBvIHRlcm1pbmFsIDopCgojIyBBbWVuZAoKTGVtYnJhIHF1ZSBtdWl0b3MgY29tbWl0cyBwb2RlbSB0ZSBkZWl4YXIgbXVpdG8gbGVudG8gbmEgZXNjYWxhZGE/IEUgcG91Y29zIGNvbW1pdHMgcG9kZW0gc2VyIHBvdWNvIGluZm9ybWF0aXZvcyBjYXNvIHF1ZWlyYSByZWNvbnN0cnVpciBvIHF1ZSBhY29udGVjZXUgY29tIG8gcmVwb3NpdMOzcmlvPyBQb2lzIGVudMOjbywgZXhpc3RlIHVtYSBlc3RyYXTDqWdpYSBpbnRlcmVzc2FudGUgcGFyYSByZWFsaXphciBjb21taXRzLCBjaGFtYWRhIGRlIGBhbWVuZGAKCkVtIHVtIGFtZW5kIG7Ds3MgYmFzaWNhbWVudGUgYWRpY2lvbmFtb3MgdW0gY29tbWl0IGEgdW0gb3V0cm8gasOhIGV4aXN0ZW50ZS4gUG9yIGV4ZW1wbG8sIGltYWdpbmUgcXVlIGZleiBhcGVuYXMgYWxndW1hcyBwb3VjYXMgbW9kaWZpY2HDp8O1ZXMgZGUgY8OzZGlnbyBxdWUgbsOjbyBuZWNlc3NpdGFtIG5lY2Vzc2FyaWFtZW50ZSBkZSB1bSBjb21taXQgZGVkaWNhZGEgZXhjbHVzaXZhbWVudGUgcGFyYSB0YWlzLCB2b2PDqiBwb2RlIGZhemVyIG8gc2VndWludGU6CgoxIC0gc3RhZ2UgbyBhcnF1aXZvIHF1ZSBtb2RpZmljb3UKCmBgYHtyIGVjaG89VFJVRSxldmFsPUZBTFNFfQpnaXQgYWRkIHBhdGgvdG8vZmlsZQpgYGAKCjIgLSBmYcOnYSB1bSBjb21taXQgCgpgYGB7ciBlY2hvPVRSVUUsZXZhbD1GQUxTRX0KZ2l0IGNvbW1pdCAtbSAiV0lQIgpgYGAKCk5vdGUgcXVlIGNvbG9xdWVpICoqV0lQKiogbmVzdGUgY29tbWl0LCBwb3IgcXVlPyBXSVAgw6kgdW1hIHNpZ2xhIHVzYWRhIGNvbXVtZW50ZSBubyB2ZXJzaW9uYW1lbnRlIHBhcmEgV29ya2luZyBJbiBQcm9ncmVzcy4gU2VtcHJlIHF1ZSB0aXZlciB1bSBjb21taXQgZGVzc2UgcXVlciBkaXplciBxdWUgbyBjb21taXQgcXVlIGZleiBhaW5kYSBlc3TDoSBzZW5kbyB0cmFiYWxoYWRvLgoKQWluZGEgbsOjbyBmYcOnYSBvIHB1c2guIEZhw6dhIG1haXMgYWxndW1hcyBtb2RpZmljYcOnw7VlcywgZSwgZGlnYW1vcyBxdWUgYWdvcmEgZmV6IG1vZGlmaWNhw6fDtWVzIHJlbGV2YW50ZXMgbm8gY8OzZGlnbyBxdWUgbWVyZWNlbSB1bSBjb21taXQgZGVkaWNhZG8uIE1hcyBsZW1icmUtc2UgcXVlIG8gw7psdGltbyBjb21taXQgw6kgdW0gV0lQLiBPIHF1ZSBmYXplbW9zIGFnb3JhIMOpIHVtIGFtZW5kIGFvIFdJUAoKMyAtIGZhw6dhIHVtIGFtZW5kCgpgYGB7ciBlY2hvPVRSVUUsZXZhbD1GQUxTRX0KZ2l0IGNvbW1pdCAtLWFtZW5kIC1tICJBcXVpIHVtIGNvbW1pdCBjb20gdW1hIG1lbnNhZ2VtIGluZm9ybWF0aXZhLCBjb21vIHNlbXByZSIKZ2l0IHB1c2gKYGBgCgpQcm9udG8sIGFnb3JhIHRlbW9zIHVtYSBtZW5zYWdlbSBpbmZvcm1hdGl2YSBxdWUgZm9pIGFkaWNpb25hZGEgYW8gV0lQIGUgbsOjbyBwcmVjaXNhbW9zIGZhemVyIHVtIHB1c2ggZG8gcGFzc28gaW50ZXJtZWRpw6FyaW8gKFdJUCksIGRlaXhhbmRvIG5vc3NhIGVzY2FsYWRhIG1haXMgcsOhcGlkYQoKIyMgVmlhamFuZG8gZW50cmUgY29tbWl0cwoKVW1hIGRhcyBtYWlvcmVzIHBvdGVuY2lhbGlkYWRlcyBkb3MgY29tbWl0cyDDqSBhIHBvc3NpYmlsaWRhZGUgcXVlIHBvZGVtb3MgbmF2ZWdhciBlbnRyZSBjb21taXRzLiBPdSBzZWphLCBwb2RlbW9zIG5hdmVnYXIgZW50cmUgZXN0YWRvcyBkaXN0aW50b3MgZG8gbm9zc28gdHJhYmFsaG8gYSBtZWRpZGEgcXVlIGVsZSDDqSBkZXNlbnZvbHZpZG8uIFBvZGVtb3MgY2hlY2FyIGVzc2UgaGlzdMOzcmljbyB0YW50byBuYSBub3NzYSBww6FnaW5hIGRvIHJlcG9zaXTDs3JpbyBubyBHaXRIdWIgcXVhbnRvIHVzYW5kbyBvIFJTdHVkaW8sIGNvbW8gbW9zdHJhZG8gbmEgaW1hZ2VtIGEgc2VndWlyCgpgYGB7ciBlY2hvPUZBTFNFLCBldmFsPVRSVUUsb3V0LndpZHRoPSI3MCUifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJmaWdzIiwgImdpdGh1Yi1oaXN0b3J5LnBuZyIpKQpgYGAKClBhcmEgdGFudG8gdm9jw6ogcHJlY2lzYSBhcGVuYXMgYWJyaXIgYSBhYmEgZG8gR2l0IG5vIFJTdHVkaW8sIGNvbW8gdmltb3MgYW50ZXJpb3JtZW50ZSwgZSBjbGljYXIgZW0gKipIaXN0b3J5Kiogbm8gY2FudG8gc3VwZXJpb3IgZXNxdWVyZG8gZGEgamFuZWxhIGRlIHJldmlzw7Vlcy4gVHVkbyBvIHF1ZSB2ZW1vcyBzw6NvIHRvZG9zIG9zIGNvbW1pdHMgcXVlIGZvcmFtIHJlYWxpemFkb3MgZGVzZGUgcXVlIGVzc2UgcmVwb3NpdMOzcmlvIGZvaSBmb3JtYWRvIHBlbGEgcHJpbWVpcmEgdmV6LgoKIyMgRWxlbWVudG9zIGltcG9ydGFudGVzIGRvIGNvbW1pdAoKQWxndW5zIGVsZW1lbnRvcyBwcmVzZW50ZXMgbm8gY29tbWl0IHPDo28gaW1wb3J0YW50ZXMuIE8gcHJpbmNpcGFsIGRlbGVzIMOpIGEgY2hhdmUgU0hBLTEuIEVzdGEgc2UgdHJhdGEgZGUgdW0gaWRlbnRpZmljYWRvciDDum5pY28gZG8gY29tbWl0LiBDb20gZWxhIHBvZGVtb3MgdmlhamFyIGVudHJlIGNvbW1pdHMsIG91IHJlZmVyZW5jaWFyIHVtIGRhZG8gY29tbWl0IGVtIHVtYSBkaXNjdXNzw6NvIG5vIGdpdGh1Yi4gUG9yIGV4ZW1wbG8sIHN1cG9uZG8gcXVlIGVzdGFtb3MgdHJhYmFsaGFuZG8gY29sYWJvcmF0aXZhbWVudGUgKGNvbW8gbmVzc2Ugc2l0ZSA6KSksIGUgZXUgZ29zdGVpIHBhcnRpY3VsYXJtZW50ZSBtYWlzIGRhIHZlcnPDo28gZG8gc2l0ZSBxdWUgZXN0w6EgaMOhIGFsZ3VucyBjb21taXRzIGF0csOhcy4gVW1hIG9ww6fDo28gw6kgYWJyaXIgdW1hIElzc3VlICh2ZXJlbW9zIGlzc28gbWFpcyB0YXJkZSksIGUgcmVmZXJlbmNpYXIgZXNzZSBuw7ptZXJvLiBPdSBzaW1wbGVzbWVudGUgZGl6ZXIgcGFyYSBtZXUgY29sYWJvcmFkb3IgIkhleSBkw6ogdW1hIG9saGFkYSBubyBjb21taXQgbsO6bWVybyBYWFhYWFgiLiBOYSBpbWFnZW0gYWJhaXhvIGVzdMOhIGVtIGRlc3RhcXVlIGEgY2hhdmUgU0hBLgoKYGBge3IgZWNobz1GQUxTRSwgZXZhbD1UUlVFLG91dC53aWR0aD0iNzAlIn0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiZmlncyIsICJnaXQtc2hhLWtleS5wbmciKSkKYGBgCgpWb2PDqiBwb2RlIGFicmlyIG8gYXJxdWl2byBubyBlc3RhZG8gZW0gcXVlIGVsZSBzZSBlbmNvbnRyYXZhIGVtIHVtIGRhZG8gY29tbWl0IGNsaWNhbmRvIG5vIGFycXVpdm8gbW9kaWZpY2FkbyBuYXF1ZWxlIGNvbW1pdCBzZWxlY2lvbmFkby4gUG9yIGV4ZW1wbG8sIGRpZ2Ftb3MgcXVlIGV1IHF1ZWlyYSB2ZXIgbyBhcnF1aXZvIGNoYW1hZG8gYHJtYXJrZG93bi1iYXNpY3NgIGRlc3RlIHNpdGUgZWRpdGFkbyBkaWEgMDIgZGUgQWdvc3RvLCBzw7MgcHJlY2lzYW1vcyBjbGljYXIgbm8gYXJxdWl2bywgY29tbyBtb3N0cmFkbyBuYSBpbWFnZW0gYWJhaXhvOgoKYGBge3IgZWNobz1GQUxTRSwgZXZhbD1UUlVFLG91dC53aWR0aD0iNzAlIn0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiZmlncyIsICJnaXQtaGlzdG9yeS1maWxlLnBuZyIpKQpgYGAKCiMjIEJhY2sgdG8gdGhlIGZ1dHVyZTogcmV2ZXJ0ZW5kbyBvIHRyYWJhbGhvIGRvIHJlcG9zaXTDs3JpbyBlIHZvbHRhbmRvCgpFeGlzdGVtIHNpdHVhw6fDtWVzIHF1ZSBnb3N0YXJpYW1vcyBkZSByZXZlcnRlciBuw6NvIHPDsyB1bSBhcnF1aXZvIGVtIGVzcGVjw61maWNvLCBtYXMgbyAqKmVzdGFkbyoqIGludGVpcm8gZGUgdW0gcmVwb3NpdMOzcmlvIGVtIHVtIGRhZG8gbW9tZW50byBubyB0ZW1wby4KClBvciBleGVtcGxvLCBkaWdhbW9zIHF1ZSB2b2PDqiBmZXogdW0gcHVzaCBxdWFuZG8gbsOjbyBkZXZlcmlhLiBPdSBtdWRvdSBtdWl0b3MgYXJxdWl2b3MgZGUgdW1hIHPDsyB2ZXosIG8gcXVlIHRvcm5hcmlhIGJhc3RhbnRlIHRyYWJhbGhvc28gcmV2ZXJ0ZXIgYXJxdWl2byBwb3IgYXJxdWl2byAoYWluZGEgcXVlIHBvc3PDrXZlbCwgdXRpbGl6YW5kbyBvIG3DqXRvZG8gYXByZXNlbnRhZG8gYW50ZXJpb3JtZW50ZSkuIE5lc3RhIHNpdHVhw6fDo28gcG9kZW1vcyByZXZlcnRlciBvIG5vc3NvIHJlcG9zaXTDs3JpbyBwYXJhIGFsZ3VtIG1vbWVudG8gZG8gdGVtcG8uIFBhcmEgZmF6ZXIgaXNzbyBwcmVjaXNhbW9zLCBwcmltZWlybywgaWRlbnRpZmljYXIgbyBtb21lbnRvIGRvIHRlbXBvIHF1ZSBnb3N0YXLDrWFtb3MgZGUgcmV0b3JuYXIuIEUgY29tbyBpc3NvIMOpIHBvc3PDrXZlbD8gVXRpbGl6YW5kbyBvcyAqKmNvbW1pdHMqKi4gQ29tbyBkaXRvIGFudGVyaW9ybWVudGUsIG9zIGNvbW1pdHMgc8OjbyBtb21lbnRvcyBkbyBzZXUgcmVwb3NpdMOzcmlvIChtYWlzIHVtIG1vdGl2byBwYXJhIHV0aWxpemFyIGNvbW1pdHMgaW5mb3JtYXRpdm9zKS4KCkV4aXN0ZW0gYWxndW1hcyBmb3JtYXMgZGUgcmV0b3JuYXIgYW8gcGFzc2FkbywgZGEgbWFpcyByYWRpY2FsIHBhcmEgYSBtZW5vcyByYWRpY2FsOgoKIyMjIERlbGV0YXIgdHVkbyBlIGNsb25hciBub3ZhbWVudGUgbyByZXBvc2l0w7NyaW8KCk8gbcOpdG9kbyBtYWlzIHJhZGljYWwsIG1hcyDDunRpbCBxdWFuZG8gbsOjbyBmYXplbW9zIGlkZWlhIGRvIHF1ZSBlc3TDoSBlcnJhZG8sIGNvbnNpc3RlIGVtOgoKMS4gc2FsdmFyIG9zIGFycXVpdm9zIGVtIHVtYSBwYXN0YSB0ZW1wb3LDoXJpYQoyLiBkZWxldGFyIG8gZGlyZXTDs3JpbyBsb2NhbAozLiBjbG9uYXIgbm92YW1lbnRlIG8gcmVwb3NpdMOzcmlvIGEgcGFydGlyIGRvIGdpdGh1YgoKSXNzbyBpcsOhLCBvYnZpYW1lbnRlLCByZXRvcm5hciBvIHNldSByZXBvc2l0w7NyaW8gcGFyYSBvIGVzdGFkbyBxdWUgZWxlIHNlIGVuY29udHJhdmEgbm8gw7psdGltbyBgcHVzaGAgcmVhbGl6YWRvIHBhcmEgbyBHaXRIdWIKCiMjIyBSZXNldGFuZG8KClJlc2V0YXIgbmEgbGluZ3VhZ2VtIGRvIHZlcnNpb25hbWVudG8gc2lnbmlmaWNhLCBiYXNpY2FtZW50ZSwgcmVhbGl6YXIgdW0gKkNUUiArIFoqIG5vIHNldSByZXBvc2l0w7NyaW8uIEVtIHRlcm1vcyBtYWlzIHTDqWNuaWNvcyBkbyB2ZXJzaW9uYW1lbnRvIGlzc28gZXF1aXZhbGUgYSBtb3ZlciBvIEhFQUQgcGFyYSBvIMO6bHRpbW8gY29tbWl0IHJlYWxpemFkby4gRXNzZSBtb3ZpbWVudG8gcGFyYSBvIHBhc3NhZG8gcG9kZSBzZXIgZmVpdG8gZGUgZHVhcyBmb3JtYXMuIAoKMS4gTW92ZW5kbyBwYXJhIG8gcGFzc2FkbyBtYXMgbWFudGVuZG8gbyB0cmFiYWxobyBsb2NhbG1lbnRlIAoKYGBge3IgZWNobz1UUlVFLCBldmFsPUZBTFNFfQpnaXQgcmVzZXQgLS1zb2Z0IEhFQUR+MQpgYGAKCjIuIE1vdmVuZG8gcGFyYSBvIHBhc3NhZG8gZSAqKmRlbGV0YW5kbyoqIG8gdHJhYmFsaG8gbG9jYWxtZW50ZQoKYGBge3IgZWNobz1UUlVFLCBldmFsPUZBTFNFfQpnaXQgcmVzZXQgLS1oYXJkIEhFQUR+MQpgYGAKCk8gcXVlIHF1ZXIgZGl6ZXIgZXN0YSBzaW50YXhlPyBCYXNpY2FtZW50ZSBlc3RhbW9zIG1vdmVuZG8gbm9zc28gSEVBRCAow7psdGltbyBjb21taXQpIHVtIGNvbW1pdCBubyBwYXNzYWRvIChIRUFEfjEpLiBTZSBxdWlzZXJtb3Mgbm9zIG1vdmVyIHBhcmEgY29tbWl0cyBtYWlzIGFudGlnb3MsIHBvciBleGVtcGxvLCBkb2lzIGNvbW1pdHMgYW50ZXJpb3JlcywgYXBlbmFzIG11ZGFtb3MgbyBuw7ptZXJvIDEgcGFyYSAyIGFww7NzIG8gYH5gLgoKT3V0cmEgb3DDp8OjbyBxdWUgdGVtIHNpZG8gbWluaGEgZXNjb2xoYSBwcmVmZXJpZGEgw6kgbyB1c28gZG8gZ2l0IHJlZmxvZyBqdW50YW1lbnRlIGNvbSBvIHJlc2V0LiBEaWdpdGUgbyBzZWd1aW50ZSBubyB0ZXJtaW5hbAoKYGBge3IgZWNobz1UUlVFLGV2YWw9RkFMU0V9CmdpdCByZWZsb2cKYGBgCgpJc3NvIGlyw6EgZmF6ZXIgY29tIHF1ZSBhcGFyZcOnYSBubyBzZXUgdGVybWluYWwgdW0gaGlzdMOzcmljbyBkZSB0b2RvcyBvcyBjb21taXRzIHF1ZSBmb3JhbSBmZWl0b3MgYXTDqSBvIHByZXNlbnRlIG1vbWVudG8uIEEgZmlndXJhIGEgc2VndWlyIG1vc3RyYSBlc3NlIGhpc3TDs3JpY28gcGFyYSBvIHJlcG9zaXTDs3JpbyBkZXN0ZSBzaXRlLgoKYGBge3IgZWNobz1GQUxTRSxldmFsPVRSVUV9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImZpZ3MiLCAicmVmbG9nLWZpZy5wbmciKSkKYGBgCgpDb20gbyByZWZsb2cgdm9jw6ogcG9kZSB1c2FyIG8gYGluZGV4YCBkbyBjb21taXQgcGFyYSBuYXZlZ2FyIG5vIHRlbXBvLiBPIGluZGV4IMOpIG8gbsO6bWVybyBxdWUgYXBhcmVjZSBsb2dvIGFww7NzIG8gYEhFQURAe2luZGV4fWAuIEVzc2UgaW5kZXggcG9kZSBzZXIgdXRpbGl6YWRvIGVtIGNvbmp1bnRvIGNvbSBhIGZ1bsOnw6NvIGByZXNldGAgcXVlIHZpbW9zIGFudGVyaW9ybWVudGUuIFBvciBleGVtcGxvLCBzZSBldSBxdWlzZXIgdm9sdGFyIHBhcmEgbyBjb21taXQgbsO6bWVybyAxMSwgZGV2byB1c2FyIG8gc2VndWludGUgY8OzZGlnbwoKYGBge3IgZWNobz1UUlVFLGV2YWw9RkFMU0V9CmdpdCByZXNldCAtLXNvZnQgSEVBREB7MTF9CmBgYAoKSXNzbyByZXRvcm5hcsOhIDExIGNvbW1pdHMgZW0gcmVsYcOnw6NvIGFvIGNvbW1pdCBhdHVhbC4gVm9jw6ogcG9kZSB2b2x0YXIgYW8gY29tbWl0IGF0dWFsIHVzYW5kbyBhIG1lc21hIHNpbnRheGUuIExlbWJyYW5kbyBxdWUgbyBhcmd1bWVudG8gYC0tc29mdGAgcmV0b3JuYSBwYXJhIG8gZXN0YWRvIGRlc2VqYWRvIG1hcyBtYW50w6ltIG9zIGFycXVpdm9zIG5vIHNldSBkaXJldMOzcmlvIGxvY2FsLgoKPiAqKl9OT1RFOl8qKiAgQWNlc3NlIG8gc2l0ZSBbT2ggU2hpdCwgR2l0IT9dKGh0dHBzOi8vb2hzaGl0Z2l0LmNvbS8pIHBhcmEgdW1hIHPDqXJpZSBkZSBkaWNhcyBtdWl0byDDunRlaXMgc29icmUgZXJyb3MgY29tdW5zIHF1YW5kbyBlc3RhbW9zIHVzYW5kbyBvIEdpdAoKCiMjIEF0aXZpZGFkZQoKRXhwbG9yZSB1bSBwb3VjbyBvcyBjb21taXRzIHF1ZSByZWFsaXphcmFtLiBBYnJhIGEgcMOhZ2luYSBkbyBnaXRodWIgZSB0YW1iw6ltIGF0cmF2w6lzIGRvIFJzdHVkaW8sIHZlamEgYXMgZGlmZXJlbsOnYXMsIGFzIHZhbnRhbmdlbnMgZSBkZXN2YW50YWdlbnMgZGUgY2FkYSB1bWEgZGFzIGFib3JkYWdlbnMKCgojIyBUaHJvd2JhY2sgQ29tbWl0CgpWYW1vcyBzdXBvciBxdWUgcmVhbGl6YW1vcyB1bSBjb21taXQgZXJyYWRvLCBlIGFnb3JhIHF1ZXJlbW9zIHZvbHRhciBhbyBjb21taXQgYW50ZXJpb3IsIG1hcyBzZW0gcGVyZGVyIG8gdHJhYmFsaG8gcXVlIGZpemVtb3Mgbm9zIGFycXVpdm9zLiBQYXJhIGlzc28gcG9kZW1vcyB1c2FyIGEgYWJvcmRhZ2VtIGFudGVyaW9yLCBuYXZlZ2FuZG8gZW50cmUgb3MgYXJxdWl2b3MgZSBzZWxlY2lvbmFuZG8gbyBhcnF1aXZvIHF1ZSBxdWVyZW1vcyBlbSB1bSBkZXRlcm1pbmFkbyBlc3RhZG8sIHN1YnN0aXR1aW1vcyBwZWxvIGFycXVpdm8gYXR1YWwgZSBmYXplbW9zIHVtIG5vdm8gY29tbWl0LiBFc3RhIG9ww6fDo28gcG9kZSBzZXIgYSBtYWlzIHNlZ3VyYSBzZSBlc3RhbW9zIGNvbWXDp2FuZG8gYSBtZXhlciBubyB2ZXJzaW9uYW1lbnRvLiBPdXRyYSBvcMOnw6NvIMOpIGV4cGxvcmFyIGFzIGZ1bsOnw7VlcyBkbyBnaXQgY2hhbWFkYXMgYHJlc2V0YC4gQXMgZnVuw6fDtWVzIHJlc2V0IGJhc2ljYW1lbnRlIG1vdmUgbyBIRUFEIGRvIHNldSBkaXJldMOzcmlvIHBhcmEgdW0gY29tbWl0IG5vIHBhc3NhZG8uIEVzdGEgYWJvcmRhZ2VtIHBvZGUgY2F1c2FyIGFsZ3VtYXMgZG9yZXMgZGUgY2FiZcOnYSBubyBpbsOtY2lvLCBwb3J0YW50byByZWNvbWVuZG8gdXNhLWzDoSBjb20gY2F1dGVsYS4gUGFyYSBtYWlzIGluZm9ybWHDp8O1ZXMgc29icmUgaXNzbyBkw6ogdW1hIG9saGFkYSBbbmVzc2Ugc2l0ZV0oaHR0cHM6Ly9kZXZjb25uZWN0ZWQuY29tL2hvdy10by1naXQtcmVzZXQtdG8taGVhZC8jOn46dGV4dD1UbyUyMGhhcmQlMjByZXNldCUyMGZpbGVzJTIwdG8sb3B0aW9uJTIwYW5kJTIwc3BlY2lmeSUyMHRoZSUyMEhFQUQuJnRleHQ9VGhlJTIwcHVycG9zZSUyMG9mJTIwdGhlJTIwJUUyJTgwJTlDZ2l0LGJlZm9yZSUyMEhFQUQlMjBhbmQlMjBzbyUyMG9uKS4pCgo=