-
Notifications
You must be signed in to change notification settings - Fork 4
/
cap05.Rmd
1350 lines (1142 loc) · 62 KB
/
cap05.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
title: "Serviços Web para Projetos Git"
author: "PET Estatística UFPR"
graphics: yes
header-includes:
\usepackage{wrapfig}
\usepackage{menukeys}
output:
pdf_document:
template:
highlight: default
toc: true
toc_depth: 2
keep_tex: true
number_sections: true
---
```{r, include=FALSE}
library(knitr)
opts_chunk$set(comment=NA)
```
# Serviços Web para Git #
No capítulo anterior vimos como configurar um repositório remoto em um
servidor. Esse procedimento possibilita trabalho em equipe pois
centraliza o repositório remoto em um servidor que todos têm
acesso. Assim, todos podem clonar, criar branches, subir as
contribuições, etc. Apesar do servidor centralizar o trabalho de todos
os usuários, estes terão que se comunicar e fazer a gestão de tarefas
sobre o projeto de outra forma, como por e-mail direto, lista de
emails/discussão ou chats coletivos. Para que um desenvolvedor veja o
que os outros fizeram, ele terá que periodicamente dar `fetch`, ver os
branches do repositório, navegar no histórico de commits, ver *diffs*
entre arquivos. Se por um lado existe recurso para um fluxo de
desenvolvimento orientado dessa forma, também existem recursos para
tornar o trabalho coletivo mais simples e centralizado. Eles são os
serviços web para projetos Git.
O Git tem vários serviços web voltados para ter um local que centralize
o projeto bem como ofereça recursos administrativos e colaborativos.
Esses serviços possuem contas *free*, alguns planos pagos e diversos
recursos para todo tipo de projeto e equipe.
Os objetivos desse capítulo são: apresentar os serviços web para
repositórios Git, descrever suas principais características, descrever
como criar e configurar uma conta e conectar-se a um repositório
local. Além disso, o *workflow* básico que considera servições web será
discutido, enfatizando os principais recursos desses serviços
voltados à colaboração.
## GitHub ##
O GitHub\footnote{\url{https://github.com/}} é um serviço web para
hospedagem, gestão e compartilhamento de repositórios Git que oferece
recursos para desenvolvimento e colaboração. *"Build software better,
together."* é o principal slogan do GitHub, justamente para enfatizar o
seu principal compromisso: dar suporte ao desenvolvimento colaborativo.
<!-- \begin{wrapfigure}{r}{0.4\textwidth} -->
\begin{figure}[h]
\begin{center}
\includegraphics[width=5cm]{./images/github-octocat.png}
\end{center}
\caption{Octocat é o mascote do GitHub.}
\end{figure}
<!-- \end{wrapfigure} -->
O GitHub foi fundado em 8 de Fevereiro de 2008, em São Francisco, por
quatro pessoas: Tom Preston-Werner, Chris Wanstrath, PJ Hyett e Scott
Chacon. Antes de terminar 2015, o GitHub já havia ultrapassado a marca
de 10 milhões de usuários. De acordo com o <http://githut.info/>, no
quarto trimestre de 2014 haviam 22 milhões de repositórios. A linguagem
`JavaScript` teve o maior número de repositórios ativos (>320 mil) e
total de *pushes*, enquanto que a linguagem `R` teve o maior número de
novas cópias por repositório (6.45).
Diferente da forma tradicional de usar o Git, por linha de comando, o
GitHub é um serviço web com interface gráfica repleta de funções para o
desenvolvimento e acompanhamento de um projeto Git. Tais recursos vão
desde administrar tarefas até permitir a colaboração de outras pessoas,
mesmo sendo desconhecidas. Dentre os principais recursos disponíveis,
têm-se:
* README: é um arquivo que funciona como capa do seu repositório. O
seu conteúdo é texto escrito em linguagem de marcação (Markdown, RST,
Textile, Org, etc) renderizada para exibição pelo GitHub. Como capa,
o conteúdo do README está na *home* do projeto e serve para informar
o visitante dos objetivos do repositório, seus desenvolvedores,
instruções de instalação/uso e formas de colaboração.
* Wiki: a Wiki de cada repositório é um conjunto de páginas que
serve para divulgação e documentação do repositório. Estas também
são escritas em linguagem de marcação, tornando fácil e rápida a
escrita pelo desenvolvedor e simples para o visitante ler e
navegar. Como a Wiki é também um repositório Git, ela pode inclusive
ser editada por meios dos recursos de edição do próprio GitHub, além
de ser versionada. Com isso, não diferente do restante, a edição da
Wiki também é colaborativa.
* *Issues*: pelos *issues* são feitas as notificações de *bug* e
gerenciamento de tarefas. Os usuários criam *issues* para notificar
um *bug* encontrado de forma que ele possa ser rapidamente
corrigido. Criar *issues* também serve como ferramenta de
administração de tarefas nas quais eles descrevem algo a ser
feito por alguém.
* *Milestones*: são pedras de milha, ou seja, marcam um ponto a ser
alcançado. São usadas para descrever o que precisa ser desenvolvido
para que ocorra uma mudança de versão e estabelecer um prazo para
conclusão, por exemplo. As *milestones* agrupam *issues* que indicam
as etapas a serem percorridas.
* *Pull request* ou *merge request* (MR): é uma requisição de
fusão. Os membros da equipe fazem suas contribuições em ramos de
desenvolvimento e ao concluir pedem um MR pela interface. O
responsável por avaliar o MR pode ver os *diffs* nos arquivos e
fazer o merge direto pela interface, de dentro do serviço sem
precisar baixar (*fetch*) o ramo, aplicar o merge (*merge*) e
subi-lo (*push*). Então os desenvolvedores não precisam interromper
o trabalho local para fazer um merge já que ele pode ser feito no
serviço sem modificações no *workspace*.
* *Fork*: é uma forma de se fazer uma cópia do projeto de alguém para
livremente experimentar modificações sem afetar o projeto
original. A cópia vem para a sua conta e funciona como qualquer
outro repositório seu. A ideia do *fork* é dar liberdade de
contribuição (não supervisionada) a qualquer pessoa interessada de
modo que esta possa submeter as contribuições para a origem (por MR)
ou até mesmo usar como ponto de partida para um novo projeto.
De acordo com Klint
Finley\footnote{\url{http://techcrunch.com/2012/07/14/what-exactly-is-github-anyway/}},
*fork* e MR são os recursos que tornam o GitHub tão poderoso. Quando o
mantenedor recebe um MR ele pode ver o perfil do contribuidor onde estão
listados todos os projetos no qual este contribuiu. Ao aceitar o MR, é
acrescentado mais uma colaboração a reputação do colaborador. Esse
mecanismo, então, beneficia as duas partes.
Além dessas características chave, o GitHub permite que você acompanhe
(*watch*) e favorite (*star*) repositórios. Também dá para seguir
pessoas e participar de organizações (grupo de usuários) que podem ter
repositórios próprios, ideal para projetos em equipe.
O perfil de cada usuário registra suas atividades em todos os projetos e
em cada um pode-se acompanhar as contribuições de cada
colaborador. Nos repositórios pode-se navegar pelo histórico de
*commits*, filtrá-los por colaborador, ver as modificações no código
(*diffs*) comparando *commits* e *branches*.
O GitHub não hospeda apenas código fonte mas sim todo e qualquer arquivo
que você tenha sob versionamento. É possível hospedar dados, por
exemplo, em formato texto (csv, txt), e disponibilizá-los por meio da
URL para download ou leitura direta. Para usuários de R, essa é uma
característica que permite não apenas disponibilizar dados, mas também
coleções de funções que podem ser carregadas com um `source()`.
Com o plano *free* do GitHub, você pode ter inúmeros repositórios
públicos, inúmeros colaboradores, ter o *fork* de quantos repositórios
quiser e participar de quantas organizações precisar. Para ter
repositórios privados, o plano mais básico custa U$ 7 por mês e dá direito à 5
repositórios. Existem outros planos individuais, e também planos
organizacionais, para todos os tamanhos de projeto e equipe. Além dessas
opções, pode-se ter o GitHub em um servidor próprio, o GitHub
Interprise\footnote{\url{https://enterprise.github.com}}, com
recursos e vantagens além das já mencionadas
Para muitos programadores, o GitHub é uma fonte de conhecimento. Lá você
encontra *scripts* de todas as linguagens de programação. Você pode
livremente estudar o código dos repositórios, ver como o código evoluiu
*commit* após *commit* e acompanhar como um *bug* foi
resolvido.
Qualquer pessoa, mesmo sem perfil no GitHub, pode clonar um repositório
público. O GitHub reconhece 382 linguagens que compreendem as de
programação (293: C++, Python, R, JavaScript), as de *markup* (34: HTML,
TeX, MarkDown), as de dados (40: JSON, SQL, XML, csv) e aplica os
realces de código (highlights) que facilitam a sua compreensão.
O GitHub é o serviço web para Git mais popular quanto ao número de
projetos hospedados. No entanto, existem serviços com as mesmas
funcionalidades e até com algumas que o GitHub não oferece no plano
básico. O GitLab e o Bitbucket estão entre os 5 mais populares e
permitem, por exemplo, ter alguns repositórios privados com a conta
*free*.
Como hospedamos nossos projetos coletivos do PET-Estatística no GitLab do
C3SL\footnote{\url{https://gitlab.c3sl.ufpr.br/explore}}, não podemos
deixar de falar sobre ele.
## GitLab ##
O GitLab\footnote{\url{https://about.gitlab.com/}}, assim como o GitHub,
é um serviço web para repositórios Git. O GitLab é um projeto *open
source* desenvolvido em Ruby que teve início em 2011 pelo ucraniano
Dmitriy Zaporozhets. Em 2013, a Companhia GitLab tinha uma equipe de 11
funcionários e mais de 10 mil organizações usando o serviço.
<!-- \begin{wrapfigure}{r}{0.4\textwidth} -->
\begin{figure}[h]
\begin{center}
\includegraphics[width=5cm]{./images/gitlab-raccoon.jpg}
\end{center}
\caption{O guaxinim (*raccoon* em inglês) é o mascote do GitLab.}
\end{figure}
<!-- \end{wrapfigure} -->
O GitLab, além de ser um serviço gratuito (com planos extras), é também
um programa que você pode instalar em servidor
local para ter seus repositórios na intraweb. Esse é o caso do GitLab do
C3SL e do GitLab do LEG\footnote{\url{http://git.leg.ufpr.br/explore}}.
O GitLab oferece todos os recursos do
GitHub\footnote{\url{http://technologyconversations.com/2015/10/16/github-vs-gitlabs-vs-bitbucket-server-formerly-stash}}. No
entanto, com uma conta gratuita no <http://gitlab.com>, você pode ter
além de repositórios públicos e colaboradores, ilimitados repositórios
privados sem pagar por nada. Isso faz do GitLab.com o lugar certo para
pequenas equipes com pouco recurso ou que desenvolvem trabalhos sem fins
lucrativos, como é o caso de colaboração em código para análise de dados
para publicação científica. Atualmente existem mais de 69 mil projetos
públicos e 5840 grupos abertos no GitLab.com.
A versão paga do GitLab, *Enterprise Edition* (EE), tem um preço
menor que a equivalente do GitHub.
A versão gratuita do GitLab para servidores, a *Community Edition* (CE),
pode ser instalada em servidores Linux, Windows, máquinas virtuais e
servidores na nuvem, além de outras opções. Os endereços
<https://gitlab.c3sl.ufpr.br/explore> e <http://git.leg.ufpr.br/explore>
são o GitLab CE para servidores rodando no C3SL (Centro de Computação
Científica e Software Livre) e LEG (Laboratório de Estatística e
Geoinformação). Estes GitLabs dão suporte à colaboração em código dentro
dos departamentos de Informática e Estatística para alunos e professores
(C3SL) e para a equipe e colaboradores do LEG.
Em termos financeiros, custa menos um servidor na nuvem da Digital
Ocean\footnote{\url{https://www.digitalocean.com/community/tutorials/how-to-use-the-gitlab-one-click-install-image-to-manage-git-repositories}}
com o GitLab CE (U$ 5/mês) do que ter uma conta para repositórios
privados no GitHub (U$ 7/mês) por 5 repositórios privados). No entanto,
conforme já mencionamos, pequenas equipes podem ter repositórios
privados na conta gratuita do GitLab.com.
Além das características essenciais e comuns aos demais serviços, como
*issues*, *fork*, *merge requests*, *wiki* e *snippets*, o GitLab tem 1)
5 níveis de acesso aos repositórios (*owner*, *master*, *developer*,
*report* e *guess*), 2) revisão comentada de código nos *diffs*, 3)
importação repositórios de outros serviços, 4) adição de *web hooks*
e 5) integração contínua nativa a partir da versão 8.0.
# Criar um perfil #
Criar uma conta no Github é tão simples como uma conta de e-mail ou numa
rede social. Acesse o endereço <https://github.com/join> para preencher
seus dados pessoais e escolher um plano. Nenhum dos planos tem limitação
quanto ao número de repositórios ou colaboradores. O que muda é a
quantidade de repositórios privados. No plano *free*, só são criados
repositórios públicos enquanto que nos planos pagos, o menor deles
permite 5 repositórios privados por um custo de U$ 7 por mês. Acesse
<https://github.com/pricing> para mais detalhes.
Ao preencher o formulário de criação de conta, você receberá um e-mail
com uma url de ativação. Se optar por planos pagos, terá que informar o número
do cartão de crédito para que seja feito o pagamento mensalmente.
Para criar uma conta gratuita no GitLab, acesse
<https://gitlab.com/users/sign_in>. Os serviços GitLab que usamos são
instalações em servidoras próprias (do C3SL e do LEG), no entanto, a
interface do usuário é a mesma, com exceção de alguns privilégios
administrativos.
## Habilitar comunição ##
<!-- http://www.vogella.com/tutorials/GitHosting/article.html -->
<!-- Geração e configuração das chaves públicas. -->
<!-- Incluir screenshots. -->
Uma vez criada uma conta, é necessário habilitar a comunicação entre sua
máquina e o (servidor do) GitHub. A comunicação é feita com protocolo
SSH (*Secure Shell*), o qual já usamos no capítulo anterior para
hospedar o repositório em um servidor remoto.
Para relembrar, a maioria dos servidores suporta a autenticação por
SSH. Para que a conexão entre máquinas seja automática, ou seja, sem
precisar fornecer usuário e senha a cada acesso/transferência, usamos o
recurso de pares de chaves. Este serve para fazer a máquina remota
(servidor) reconhecer a máquina local (sua máquina) via autenticação do
par de chaves. É como se o servidor fosse um cadeado e a sua máquina
local tem a chave que o abre. Uma vez que as chaves são pareadas e
compatíveis, ocorre o acesso ou transferência de arquivos.
Para gerar as chaves públicas, você precisa executar:
```{r, engine="bash", eval=FALSE}
## Gera chaves públicas.
ssh-keygen -t rsa -C "[email protected]"
```
```{r, engine="bash", eval=FALSE}
## Batman gerando chaves públicas.
ssh-keygen -t rsa -C "[email protected]"
```
```
Generating public/private rsa key pair.
Enter file in which to save the key (/home/batman/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/batman/.ssh/id_rsa.
Your public key has been saved in /home/batman/.ssh/id_rsa.pub.
The key fingerprint is:
66:c1:0b:3a:94:25:83:00:81:9f:40:26:f7:aa:af:3a [email protected]
The key's randomart image is:
+--[ RSA 2048]----+
| |
~MMMMMMMMMMMM MMMMMMMMMMMM~
.MMMMMMMMM. MMM .MMMMMMMMM.
MMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMM
.MMMMMMMMMMMMMMMMMMMMMMMMM.
.MMMMMMMMM.
.MMM.
M
| |
+-----------------+
```
O endereço padrão para os arquivos criados é o diretório `~/.ssh/`. Os
arquivos serão reescritos caso já existam arquivos de chaves públicas
lá. Todo novo par de chaves é único. Então, se você reescreveu os
arquivos anteriores, terá que atualizar as chaves públicas em todos os
serviços web que fazem uso desse recurso e com todos os servidores com o
qual você tem autenticação por chaves.
Acesse <https://github.com/settings/ssh> para então adicionar chaves
públicas (Figura \ref{github_sshkeys}) ao seu perfil. Clique em
\menu{Add SSH key}, cole o conteúdo copiado do arquivo `*.pub` no campo
`key`. No campo `Title` identifique a máquina correspondente àquela
chave. Use, por exemplo, `laptop` ou `trabalho` para facilitar o
reconhecimento. É comum trabalhar-se com mais de um máquina, como uma em
casa e outra no trabalho.
\begin{figure}
\begin{center}
\includegraphics{./images/github_sshkeys.png}
\end{center}
\caption{\textit{Printscreen} da página de configurações pessoais do
GitHub. No menu \texttt{SSH Keys} pode-se ver e adicionar chaves
públicas.}
\label{github_sshkeys}
\end{figure}
Para testar a comunicação entre o GitHub e a sua máquina, execute:
```{r, engine="bash", eval=FALSE}
## Testa comunição. Retorna um "Welcome!" em caso positivo.
ssh -T [email protected]
## Se falhar, habilite o modo verbose para rastrear o erro.
ssh -vT [email protected]
```
No GitLab, o cadastro de chaves públicas é um processo semelhante. Uma
vez autenticado, acesse <https://gitlab.c3sl.ufpr.br/profile/keys> para
adicionar chaves públicas. Para testar a comunicação entre o GitLab e a
sua máquina, execute:
```{r, engine="bash", eval=FALSE}
## Testa comunição. Retorna um "Welcome!" em caso positivo.
ssh -T [email protected]
## Se falhar, habilite o modo verbose para rastrear o erro.
ssh -vT [email protected]
```
Lembre-se de que o endereço `gitlab.c3sl.ufpr.br` corresponde ao serviço
GitLab disponibilizado pelo C3SL. Caso você esteja fazendo a conta no
GitLab.com, o endereço muda de acordo.
## Gerenciar repositórios ##
**GitHub**
A comunicação com o GitHub acabou de ser estabelecida. Agora podemos
criar repositórios e começar a mostrar nosso trabalho para o mundo e
colaborar de forma eficiente.
No canto superior direito das páginas do GitHub existe um ícone
\menu{$+$} que permite criar um novo repositório ou uma nova
organização. Clique em \menu{New repository} ou acesse o endereço
<https://github.com/new>. Na janela que abrir, dê um nome para o seu
projeto e adicione uma breve descrição à ele (Figura
\ref{github_new_repo}). Na etapa seguinte, defina o nível de
visibilidade: público ou privado. Lembre-se que os planos *free* só
permitem repositórios públicos. Ao clicar em privado você passará pelos
formulários para efetuar pagamento.
\begin{figure}
\begin{center}
\includegraphics{./images/github_new_repo.png}
\end{center}
\caption{Janela para a criação de um novo repositório no GitHub.}
\label{github_new_repo}
\end{figure}
Para criar o projeto dentro de uma Organização, selecione a Organização
na *drop list* que fica no campo *Owner*, a esquerda do campo para o
nome do repositório.
Você pode inicializar o repositório com um arquivo `README.md`, o que é
altamente recomendado. Como já mencionamos, esse arquivo é a capa do seu
repositório e serve para documentar o seu objetivo, formas de
colaboração, colaboradores, formas de instalação/uso.
Você pode editar o arquivo `README.md` (ou qualquer outro) no próprio
GitHub. As modificações que fizer devem ser *commitadas* para serem
salvas. O arquivo `README.md`, que é linguagem de marcação MarkDown, é
automaticamente renderizado pelo GitHub fazendo com que *urls* sejam
clicáveis e códigos estejam em ambientes de fonte monoespaço, além de
ter títulos com tamanho de fonte apropriado.
Depois de criar o repositório, você já pode cloná-lo para trabalhar
localmente. O endereço do repositório é composto pelo seu nome de
usuário (ou organização) e nome do repositório. O repositório
`bat-rangue` da conta do `batman` pode ser clonado com:
```{r, engine="bash", eval=FALSE}
## Clone pelo protocolo ssh. Requer chaves públicas.
git clone [email protected]:batman/bat-rangue.git
```
Pode-se clonar repositórios pelo protocolo `http` (*Hypertext Transfer
Protocol*). Em geral, para clonar repositórios de outros usuários
e fazer testes, usa-se `http`. Embora você possa usar `http` nos seus
repositórios, prefira o *SSH*. Com `http`, o endereço passa a ser:
```{r, engine="bash", eval=FALSE}
git clone https://github.com/batman/bat-rangue.git
```
Por padrão, ao clonar o repositório, um diretório de mesmo nome é criado
com o projeto em seu interior. Em caso de preferir outro nome para esse
diretório, por exemplo, `bat-bumerangue`, use:
```{r, engine="bash", eval=FALSE}
git clone https://github.com/batman/bat-rangue.git \
bat-bumerangue
```
Existe outra situação que é quando você já tem repositório Git no qual
já está trabalhando e quer tê-lo no GitHub. Nesse caso, você vai criar
um novo repositório mas não irá cloná-lo, apenas copie a url que usaria
para cloná-lo. No repositório local, adicione essa *url* como endereço
do servidor remoto e faça um *push*. Vamos supor que o repositório seja
um artigo científico de nome `Artigo`. Ao criar o repositório com esse
nome no GitHub, o endereço fica
`[email protected]:fulano/Artigo.git`. Então é só adicionar esse endereço
como `origin` do projeto Git:
```{r, engine="bash", eval=FALSE}
## Adiciona endereço de "origin" ao repositório.
git remote add origin [email protected]:fulano/Artigo.git
## Sobe o conteúdo do repositório.
git push -u origin master
```
O seu projeto é configurado em \menu{Settings}. Para renomear, deletar
ou transferir o projeto para outro usuário ou organização, vá em
\menu{Options}. Em \menu{Collaborators} você administra os colaboradores
do projeto. Para gerenciar os ramos de trabalho, como proteger ou
remover ramos, vá em \menu{Branches}. O uso de de serviços web é
configurado no \menu{Webhooks \& services}. O \menu{Deploy keys} permite
adicionar chaves públicas.
Vamos considerar um repositório bem ativo para conhecermos um pouco mais
dos recursos do GitHub. O repositório <https://github.com/yihui/knitr>
(Figura \ref{github_repo_home}) é o sítio de desenvolvimento do pacote
`knitr` do R, o principal pacote para a geração de relatórios
dinâmicos. Nesse repositório tem-se acesso aos fontes.
\begin{figure}
\begin{center}
\includegraphics{./images/github_repo_home.png}
\end{center}
\caption{\textit{Home} de um repositório no GitHub.}
\label{github_repo_home}
\end{figure}
Na figura \ref{github_repo_home}, logo abaixo do título, tem-se quatro
quantificadores:
* *commits*: ao clicar neste item, tem-se o histórico de *commits* com
autor, mensagem e SHA1. É possível comparar estados dos arquivos
(*diff*) ao clicar no SHA1.
* *branches*: este lista os *branches* do projeto, permite comparar
ramos.
* *releases*: documenta as modificações de uma versão para outra e
lista os *commits* que tem *tags*. Essa é uma fonte importante para
saber as maiores mudanças entre versões.
* *contributors*: dá um resumo das atividades dos colaboradores do
projeto. Na aba *members* tem-se uma lista de todos os usuários que
fizeram o *fork* do seu projeto. Falaremos de *fork* adiante.
No menu da direita existem links para acessos a mais informações:
* *Code*: estão visíveis os diretórios e arquivos do projeto. Pode-se
navegar entre eles. Ao visualizar um arquivo, ele é exibido com
realces de acordo com a linguagem para facilitar a compreensão. Ao
abrir um arquivo, no topo aparecem botões de exibição/ação: *Raw* é
para ver o arquivo cru, sem renderização e *highlights*. A *url*
dessa exibição pode ser usada para ler/baixar arquivos de dados ou
scripts direto da web. *Blame* mostra o arquivo com autor para cada
porção do código. O *History* mostra o histórico de *commits*. Os
dos ícones seguintes permitem editar o arquivo ou deletar.
* *Issues*: permite criação e acesso aos *issues* do projeto. Dentro
dessa página tem-se acesso às *Milestones*, que são as coleções de
*issues* por tema.
* *Pull requests*: é o termo que o GitHub usa para requisição de
merge. Nesta página pode-se submeter uma requisição e navegar nas
existentes.
* *Wiki*: na Wiki de um repositório normalmente é feita uma
documentação mais detalhada do projeto. Páginas Wiki de um
repositório também são repositórios Git, portanto, versionáveis.
* *Pulse*: dá um resumo sobre a quantidade de *issues* presentes,
fechados e abertos bem como para as requisições de mescla. Mostra
também um resumo da atividade recente do repositório.
* *Graphics*: exibe gráficos sobre a atividade no repositório, como
frequência de *commits*, total e por autor, instantes do dia de
maior colaboração, etc.
Existem ainda mais coisas sobre o GitHub que não podemos deixar de
comentar: os recursos disponíveis para colaboração. Nas sessões à
frente, trataremos dos recursos de *issue*, *fork* e requisições de
merge. Antes, no entanto, vamos conhecer um pouco do GitLab, um serviço
web para projetos Git que pode ser instalado no seu servidor.
O GitLab é o serviço que nós do PET usamos para colaboração em nossos
projetos. Além disso, é o que os alunos usam para fazerem seus trabalhos
e desenvolverem o TCC. O uso do Git como ferramenta de trabalho passou
ser estimulado no segundo semestre de 2015. Além de reunir os alunos e
professores numa plataforma de colaboração eficiente, o conhecimento de
Git passa ser um diferencial no currículo.
**GitLab**
O GitLab concentra os acessos à outras páginas em um menu do lado
esquerdo. Do lado direito pode haver informações extras. O botão para
criar um novo repositório fica no canto superior direito. Ao lado deste
tem botões para ir para página de configurações, sair, ajuda e explorar
o GitLab.
No menu da direita tem-se acesso aos projetos do usuário (\menu{Yout
Projects} e \menu{Starred Projects}) e aos grupos do qual participa
(\menu{Groups}). As entradas \menu{Milestones}, \menu{Issues} e
\menu{Merge requests} reúnem as informações sobre todos os projetos do
qual o usuário participa.
Assim como acontece com outros serviços web, na página inicial do
projeto é exibido o arquivo de capa, o `README`. Centralizado na página
encontra-se o endereço para clonar o repositório por SSH ou HTTP(S) e as
principais entradas estão no menu da direita:
* *Project*: é a página inicial;
* *Activity* e *Commits*: listam a atividade (predominantemente
*commits*);
* *Files*: apresenta diretórios e arquivos, com opção de mudar o ramo;
* *Network*: o estado de desenvolvimento dos ramos do projeto com uma
lista de todos os *commits*;
* *Graphs*: contém a atividade de cada membro do projeto;
* *Milestones* reúne as marcas de milhas do projeto com progresso de
cada uma;
* *Issues*: pode-se gerenciar os *issues* dos projetos;
* *Merge resquests*: permite criação e acompanhamento das requisições
de mescla;
* *Members*: faz a gestão da equipe de trabalho como adição e
redefinição dos níveis de acesso;
* *Labels* são usados para classificar os *issues* - é comum usar
*bug*, *fix*, *review*.
* *Wiki*: vai para a página Wiki do repositório, onde é possível
editá-la;
* *Settings*: são feitas as configurações gerais do projeto como
definição de nome, descrição, nível de visibilidade e adição e *Web
Hooks*. Nessa mesma página pode-se renomear, transferir ou remover o
projeto.
Agora que conhecemos um pouco da interface dos serviços Git, podemos
descrever o procedimento de trabalho considerando tais interfaces.
# Fluxo de trabalho #
<!-- TODO Deixar os chunks dessa sessão reproduzíveis! TODO -->
O fluxo de trabalho de um projeto Git local usando um servidor remoto
foram apresentados no capítulo anterior. O fluxo com um repositório Git
mantido em um serviço, como o GitHub ou GitLab, não muda muito. A maior
diferença não é sobre o uso de novas instruções Git mas sim a adoção de
uma estratégia de trabalho (*workflow*) baseada nos recursos desses
serviços, como as *milestones* e *issues*. Esse modelos de trabalho
serão descritos em um capítulo à frente.
O fluxo de trabalho com repositórios remotos, em termos de comandos,
acrescenta àqueles necessários para se comunicar com o
repositório. Alguns desses comandos, senão todos, já foram apresentados
no capítulo anterior a esse.
Ao considerar um serviço web, você pode começar um repositório novo de
duas formas: localmente ou pelo serviço.
Pelo serviço, qualquer que seja, crie um novo repositório. GitHub e
GitLab dão instruções resumidas de como proceder logo que você cria um
novo repositório. Eles inclusive, incluem opções como criar um
repositório com arquivo de `README`. Assim que criar, seu repositório
terá um endereço (SSH e HTTP). Na sessão anterior, descremos o processo
de criar e *clonar* o repositório e também de criar local e adicionar a
*url* do repositório remoto (`origin`).
Localmente o repositório segue o ciclo normal de desenvolvimento que
minimamente contém as instruções `git add` e `git commit`. Os fluxos de
trabalho, em geral, preconizam o desenvolvimento a partir de *branches*
de demanda cujo conteúdo será incorporado aos ramos permanentes
(`master`, `devel`) quando forem concluídos. Abaixo ilustramos a
sequência de criar um ramo, desenvolvê-lo e por fim subir o seu conteúdo
para o repositório remoto, que nesse caso é mantido em um servidor web.
```{r, engine="bash", eval=FALSE}
## Cria um ramo chamado issue#10.
git branch issue#10
## Muda do ramo atual para o recém criado.
git checkout issue#10
## Segue a rotina.
git add <arquivos>
git commit -m <mensagem>
## Sempre que quiser, suba o trabalho.
git push origin issue#10
```
Nessa rotina, consideramos `issue#10` um *issue* criado na interface web
para atender uma demanda, como por exemplo, corrigir um *bug*. Da mesma
forma que o ramo default do Git é o `master`, o repositório remoto é por
default chamado de `origin`, então subimos o conteúdo desse ramo para o
servidor que mantém o repositório sob o serviço web.
Não há limites para o número de ramos. Ramos podem ser locais, remotos
ou ambos. Quando você cria um ramo, como nos comandos acima, ele é um
ramo local. Quando você sobre esse ramo, ele passa ter sua parte remota
também. E quando você clona um repositório, você traz todos os ramos que
ele possui, que são ramos remotos. Ao escolher um ramo desse para
trabalhar, ele passa a ser também um ramo local. Segue abaixo, formas de listar
os ramos do projeto.
```{r, engine="bash", eval=FALSE}
## Lista os ramos locais.
git branch -l
## Lista os remostos.
git branch -r
## Lista todos (all).
git branch -a
```
Você pode notar que ramos locais não tem prefixo e que ramos remotos tem
o prefixo `origin/`. Você pode remover um ramo local mas manter sua
parte remota e pode também excluir esse ramo por completo de todo o
sistema, localmente e no servidor, conforme ilustram os códigos abaixo.
```{r, engine="bash", eval=FALSE}
## Remove um ramo local (não mais útil).
git branch -d issue#10
## Remove sua cópia remota (não mais útil também).
git branch -dr origin/issue#10
## Remove um ramo remoto na origem (duas formas).
git push origin --delete issue#10
git push origin :issue#10
```
Até aqui nos referimos ao repositório remoto como `origin` que é o nome
default. No entanto, um projeto Git pode ter mais de um repositório
remoto. Considere o caso simples de um repositório para arquivos de uma
disciplina. Esse repositório contém tanto lista de exercícios para os
alunos como também as provas com as soluções. Para não entregar as
provas de bandeja, o diretório de provas existe no ramo `secret` e é
enviado somente para um repositório privado chamado `provas`. Já o
conteúdo restante (lista de exercícios, notas de aula, scripts),
disponibilizado para os alunos, fica no ramo `master`, mantido em um
repositório aberto chamado de `origin`.
Dois repositórios remotos tem endereços distintos pois são projetos
distintos no serviço web. Você pode ter a parte pública do projeto
(`origin`) no GitHub e a parte privada, as provas (`secret`), no GitLab.
Abaixo tem-se uma série de comandos para listar,
renomear, remover e adicionar endereços para remotos.
```{r, engine="bash", eval=FALSE}
## Lista os remotos.
git remote -v
## Renomeia para um nome melhor
git remote rename origin profs
## Remove.
git remote rm profs
## Adiciona um endereço de remoto (origin)
git remote add origin <url>
git remote add profs <url>
## Adiciona/remove URLs ao origin.
git remote set-url origin --add <url>
git remote set-url origin --delete <url>
```
Quando você trabalha em colaboração ou em mais de uma máquina, vai
sempre precisar atualizar os repositórios com o conteúdo existente no
remoto. Existem duas instruções Git para isso: `git fetch` e `git pull`.
As duas traduções mais frequentes do verbo *to fetch* são buscar e
trazer. A documentação oficial do comando `git
fetch`\footnote{\url{https://git-scm.com/docs/git-fetch}} indica que
esse comando serve para trazer objetos e referências dos repositórios
remotos. Abaixo o comando padrão considerando um remoto de nome `origin`
e algumas variações.
```{r, engine="bash", eval=FALSE}
## Traz todos os ramos do remoto origin.
git fetch origin
## Traz só do ramo devel.
git fetch origin devel
## Traz de todos os remotos: origin, profs.
git fetch --all
```
O comando *fetch* traz os ramos e atualiza a parte remota, por exemplo,
o `origin/devel`. O ramo local `devel` não tem seu conteúdo modificado
após o `fetch`. Para transferir o conteúdo `origin/devel` para o
`devel` tem-se que usar o `git merge`. No entanto, sempre que haver
necessidade, antes do *merge* pode-se verificar as diferenças que
existem entre local e remoto, principalmente quando esse remoto traz
contribuições de algum colaborador. Os comandos abaixo exibem as
diferenças entre os ramos e aplicam o merge entre eles.
```{r, engine="bash", eval=FALSE}
## Muda para o ramo devel.
git checkout devel
## Mostra as diferenças entre devel local e remoto no terminal.
git diff devel origin/devel
## Faz o merge do devel remoto no devel local.
git merge origin/devel
```
Em resumo, para passar o conteúdo de um ramo remoto para um local temos
que fazer `git fetch` e em seguida `git merge`. O comando `git pull` é
esses dois, em um. A documentação do `git
pull`\footnote{\url{https://git-scm.com/docs/git-pull}} dá uma descrição
detalhada do seu uso enquanto que os exemplos abaixo ilustram o uso mais
simples possível.
```{r, engine="bash", eval=FALSE}
## Traz e junta todos os ramos do remoto com os locais.
git pull origin
## Traz e junta só do ramo devel.
git pull origin devel
```
Por fim, para subir o trabalho feito em um ramo, usa-se a instrução `git
push`. Enviar o seu trabalho com frequência é a melhor forma de ter
*backups*, exibir e disponibilizar suas contribuições para os seus
colaboradores. A documentação do `git
push`\footnote{\url{https://git-scm.com/docs/git-push}} é rica em
variações mas a maneira mais simples de usá-lo é para subir um ramo para
o repositório remoto.
```{r, engine="bash", eval=FALSE}
## Sobe o ramo issue#10 para o repositório remoto origin.
git push origin issue#10
## Sobe todos os ramos.
git push --all origin
```
Quando você sobe pela primeira vez um ramo local, a sua parte remota é
criada. Assim, a instrução que colocamos acima criou um ramo remoto
chamado `origin/issue#10`. Essa é a forma mais natural, e até
despercebida, de criar ramos locais com cópias remotas, mas existem outras
maneiras. Abaixo fazemos a criação do remoto a partir do local sem ser
usando o *push*. Esses comandos precisam ser usados uma vez apenas.
```{r, engine="bash", eval=FALSE}
## Conectar o local e remoto.
git branch --set-upstream issue#10 origin/issue#10
## Cria o ramo issue#11 a partir e vinculado ao devel remoto.
git checkout -b issue#11 origin/devel
## Cria ramo local issue#12 a partir do remoto com vínculo.
git checkout --track origin/issue#12
## Mostra as ligações entre pares de ramos: locais e remotos.
git branch -vv
```
# Macanísmos de colaboração #
Os serviços web para Git, mesmo que você trabalhe sozinho, já são
interessantes para ter uma cópia (*backup*) do seu projeto e
disponibilizar seu trabalho. No entanto, um dos principais objetivos dos
serviços web é permitir a colaboração entre pessoas. Já mencionamos o
básico sobre recursos de colaboração quando falamos de *issue*, *fork* e
*merge request*. Nas sessões a seguir, vamos nos aprofundar nesses três
mecanismos chave para a colaboração via serviços web para Git.
## Issues ##
De acordo com o dicionário
Macmillan\footnote{\url{http://www.macmillandictionary.com}}, *issue*
significa um problema que precisa ser considerado. Também significa um
assunto que as pessoas debatem ou o volume de uma revista. Cabe aqui a
primeira definição.
Nos serviços web para Git, *issue* é um recurso da interface que permite
que as pessoas abram um assunto/tópico referente ao projeto. Em geral,
com os *issues* as pessoas externas ao projeto indicam um *bug* - uma
falha a ser corrigida - ou sugerem que o projeto incorpore determinada
característica desejável. O dono do projeto avalia a proposta e pode
discuti-la logo em seguida, mantendo as mensagens reunidas e disponíveis
para outros usuários que acompanham o projeto. Quando a proposta do
*issue* for implementada, o *issue* é fechado. Mesmo assim, o *issue*
continua disponível e pode ser referenciado no futuro, tanto para novos
usuários quanto para incluir no *change log* do projeto (essa versão
corrige o bug descrito no *issue#43*, por exemplo).
Quando um projeto é coletivo, como são alguns dos projetos no PET
Estatística\footnote{\url{https://gitlab.c3sl.ufpr.br/groups/pet-estatistica}},
o recurso de *issue* pode ser usado de outra forma: como gerenciador de
tarefas. Combinado com as *milestones*, cada membro cria um *issue*
correspondente ao que vai fazer no projeto no período de uma semana. Com
isso, todos os demais membros são notificados de que alguém já vai
trabalhar na tarefa A do projeto, eliminando foco duplicado. O *issue* é
parte do fluxo de trabalho do PET-Estatística que será descrito em outro
capítulo.
As *milestones* são uma espécie de coleção de *issues* que tenham algo
em comum. Considere por exemplo o projeto de um livro. As *milestones*
podem ser os capítulos a serem escritos e os *issues* podem ser as
seções. Se for um projeto de software, as *milestones* podem separar os
*issues* referentes ao aperfeiçoamento da documentação e ao
desenvolvimento do mesmo (escrita de código fonte).
Criar um issue é muito simples. Tanto no GitHub quanto no GitLab, existe
um fácil acesso as *issues* do projeto. Na página dos *issues* você pode
criar um novo *issue*, comentar em um já existente e até reabrir um
*issue* que já foi fechado (comum quando acredita-se ter resolvido um
*bug* mas que ainda não foi). Os *issues* são numerados sequencialmente
e isso faz com que cada *issue* seja único dentro do projeto. Os
serviços web até tem formas de fazer *hyperlinks* para os *issues*
dentro das mensagens e *commits*. No GitLab, usa-se um hash seguido do
número identificador (e.g. `#45`) para fazer um *hyperlink* para um
*issue*.
## Fork ##
A palavra *fork*, como substantivo, representa forquilha,
bifurcação. Esse recurso está presente nas interfaces web para permitir
que usuários façam cópias livres de projetos de outras pessoas. Como
essa cópia é do projeto em determinado instante, há grande chance de
divergência entre cópia e original a partir desse instante, por isso é
apropriado a palavra bifurcação.
As finalidades de um *fork* são duas: 1) ter uma cópia na qual se possa
acrescentar modificações e enviar para o dono as contribuições no
projeto original ou 2) usar a cópia como ponto de partida para um outro
projeto, sem intenção de voltar ao projeto original.
No GitHub, o acesso ao *fork* é por um botão que fica mais à direita na
linha de título do projeto. No GitLab, o botão de *fork* fica na página
inicial do projeto logo acima do endereço para clonar. Em qualquer um
desses serviços, uma vez logado, ao pedir um *fork*, uma cópia do
projeto é criada no seu perfil.
Com o *fork* você pode colaborar como um terceiro em um projeto, ou
seja, sem ser colaborador adicionado pelo dono. Nessa cópia você tem
permissões de *owner* pois na realidade, embora seja uma cópia, ela é
toda sua. Você faz sua cópia livre, trabalha como quiser e no prazo que
quiser, e submete ao projeto original o desenvolvido na sua cópia. O dono
do projeto não tem como saber por que você fez o *fork* (mas você pode
criar um *issue*) nem quando irá concluir o que almeja. No entanto,
quando concluir, para que seu trabalho seja incorporado ao original,
você terá que fazer um *merge request* (isso só é possível entre
usuários de um mesmo serviço web).
Uma vez com a cópia, você pode fazer um clone e começar a desenvolver os
projetos. Se a sua intenção é submeter modificações ao original, seja
ainda mais cuidadoso com as mensagens de *issue*. Escreva sempre no
idioma original do projeto. Muitas vezes, antecipando esse tipo de
colaboração, os usuários disponibilizam guias de contribuição
(*contribution guide*) com instruções de como proceder para maior
agilidade.
Os *branchs* que criar serão na sua cópia e os *pushs* que fizer irão para
o seu perfil. Quando o seu trabalho estiver concluído, você pode fazer
um *merge request* que descreveremos a seguir. Se a sua intenção foi
usar o *fork* como ponto de partida para um projeto independente, não se
esqueça de dar os devidos créditos ao dono da cópia, mesmo que lá no
futuro, o seu projeto e o original sejam completamente diferentes.
## Merge Request ##
O *merge request* (requisição de mescla/fusão) é o recurso de
colaboração chave. Ele serve para que pessoas da equipe (segundos) peçam
para incorporar *branches* ao ramo principal (em geral o *master* ou o
*devel*) e terceiros peçam para incorporar o que foi desenvolvido no
*fork*. O GitHub usa o termo *pull request* ao invés de *merge request*
embora não exista diferença alguma.
Os trabalhos coletivos em projetos Git, para serem bem sucedidos,
consideram algum esquema de trabalho. A maioria dos esquemas considera o
desenvolvimento por *branches*. Nada mais justo, já que uma é uma
característica do Git. Existem ramos permanentes, como o
*master*, que recebem o desenvolvimento feito em *branches* auxiliares
ou de demanda. Esses ramos de demanda, como o nome sugere, são criados
para incorporar algo ao projeto e, portanto, não são permanentes - uma
vez incorporados, são removidos.
Nos esquemas de trabalho, os membros são instruídos a fazerem o
desenvolvimentos nos ramos de demanda e jamais nos ramos permanentes. Ao
concluir essa unidade de trabalho, esse *branch* é enviado para o
servidor com um `push`
```{r, engine="bash", eval=FALSE}
## Envia o desenvolvido em um ramo.
git push origin issue#33
```
Na interface web, o membro faz um *merge request* desse ramo para um
ramo permanente, no qual em projetos simples é o *master* mas em
projetos maiores é usualmente o *devel*. Ao clicar em *merge request*,
uma caixa de diálogo abre para que você liste as colaborações que o
*branch* leva.
Em ambos os serviços, o *merge resquest* leva para um página na qual
você escolhe que ramo de demanda (doador) será incorporado a um ramo
permanente (receptor). Ao confirmar os ramos envolvidos, tem-se uma
caixa de texto destinada as informações sobre quais as modificações
devem ser incorporadas. Elas servem para justificar, esclarecer e
informar o responsável pelo *merge* sobre a incorporação. Quando o
projeto é coletivo e não individual, um membro pode ser indicado como
responsável pelo *merge*. O responsável pelo merge avalia as
contribuições, se sentir necessidade vê as *diffs* nos arquivos, e pode
colocar uma mensagem embaixo da sua com questionamentos e até adequações
que precisarem ser feitas para aceitar o *merge request*.
Quando trata-se de *fork*, o processo ocorre de forma semelhante. A
sequência de etapas é: fazer o *fork* do projeto para a sua conta, 2)
clonar o projeto para sua máquina, 3) criar um *branch* e fazer o
desenvolvimento nele, 4) subir o *branch* (*push*) para a sua conta e 5)
fazer um *merge request* para incorporar as modificações. Na hora de
escolher o ramo permanente (receptor) tem-se duas opções: 1) incorporar
ao *master* (ou outro) da sua cópia ou 2) incorporar ao *master* (ou
outro) do original. Outra opção é incorporar ao *master* da sua cópia e
depois pedir um *merge request* do seu *master* para o *master* do
original. Essa última é útil quando a quantidade de modificações é maior
e portanto, o trabalho vai levar mais tempo.
Os próprios serviços web fazem o *merge* diretamente quando não existe
conflito (merge do tipo *fast forward*). Isso facilita bastante o
trabalho. Porém, não haver conflito de *merge* não significa que as
modificações incorporadas estão funcionais, ou seja, as modificações
feitas precisam ser testadas localmente para verificar se surtiram
efeito. É possível habilitar o serviço Git para checar se o projeto é
executável ou funcional. Esse recurso se chama integração contínua e
veremos na próxima sessão.
Em caso de conflito de *merge*, tem-se que baixar os ramos (`git
fetch`). Localmente pode-se comparar as diferenças entre eles para
entender as fontes de conflito. Para isso são recomendáveis as
interfaces para Git que serão discutidas no próximo Capítulo. Uma vez
que o *merge* foi resolvido, deve-se fazer o *push* do ramo permanente
(receptor) para o serviço web que já reconhece que o *merge* foi feito e
fecha a requisição automaticamente.
Recomenda-se que os ramos de demanda sejam removidos após sua
incorporação nos ramos permanentes. Isso torna o projeto mais claro e
concentrado em ramos definitivos colhedores de desenvolvimento. Pode-se
excluir o ramo de demanda incorporado direto pela interface, marcando uma
caixa de confirmação sobre remover o ramo após o merge. Por linha de
comando também é possível.
```{r, engine="bash", eval=FALSE}
## Deleta o branch issue#33 no servidor (origin).
git push origin :issue#33
## Deleta o branch issue#33 localmente.
git branch -d issue#33
## Deleta a cópia do issue#33 que veio do origin.
git branch -dr origin/issue#33
```