/
index.qmd
1211 lines (896 loc) · 37.8 KB
/
index.qmd
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: Pull Request Flow with usethis
author: Garrick Aden-Buie
date: '2021-10-07'
slug: pull-request-flow-usethis
categories:
- R
- usethis
- Productivity
- Workflow
description: Choose your own adventure and get in the 'usethis' pull request flow with this flow chart.
image: usethis-pr-flow-social.jpg
source_link: 'https://github.com/gadenbuie/garrickadenbuie-com/tree/main/content/blog/2021/pull-request-flow-usethis/index.Rmd'
keywords: rstats
include-in-header:
text: |
<link href="usethis-adventure.css" rel="stylesheet">
<script src="https://unpkg.com/smoothscroll-polyfill@0.4.4/dist/smoothscroll.min.js" integrity="sha384-EYn4rWu1DHvYD0sSSSbMEtXQmMl58CFJd897806+RT1jJVYbhuZlZMN6yG9nCyFa" crossorigin="anonymous"></script>
editor_options:
chunk_output_type: console
references: ~
toc: false
resources:
- usethis-adventure.css
- usethis-adventure.js
---
[usethis]: https://usethis.r-lib.org
[gert]: https://docs.ropensci.org/gert/
[usethis-pr-docs]: https://usethis.r-lib.org/reference/pull-requests.html
[usethis-pr-article]: https://usethis.r-lib.org/articles/articles/pr-functions.html
```{r setup, include=FALSE}
knitr::opts_chunk$set(
echo = TRUE, warning = FALSE, message = FALSE,
fig.width = 9, fig.height = 10
)
options(htmltools.dir.version = TRUE)
way_point <- function(add_class = TRUE) {
glue::glue(
# '<i class="{cls}fas fa-map-signs" aria-hidden="true" title="Decision Time"></i>',
'<i class="{cls}bi bi-signpost-fill" aria-hidden="true" title="Decision Time"></i>',
'<span class="sr-only">Decision time:</span>',
cls = if (add_class) "way-point " else ""
)
}
back_button <- function() {
glue::glue(
'<i class="bi bi-arrow-left-circle-fill" aria-hidden="true" title="Back"></i>',
'<span class="sr-only">back</span>'
)
}
```
```{r pr-flow-lightbox, echo=FALSE, results = "asis"}
lightbox_img(
"usethis-pr-flow-medium.jpg",
alt = "A flow chart for the pull request functions in the usethis R package.",
caption = "A `usethis` pull request helper function flow diagram. [Download the image](#download) or read a [text version of the flow chart](flowchart/). ([CC BY](http://creativecommons.org/licenses/by/4.0/))"
)
```
## Introduction
The <span class="pkg">[usethis]</span> package is full of incredibly helpful functions
that make life as an R developer easier.
A lot of the package's functions target R package maintainers,
but there's a small cluster of functions that are life changing
for anyone who uses `git` or collaborates with others via GitHub[^or-others].
[^or-others]: I primarily use GitHub, but I think these functions will generally work for other code-hosting platforms as well, like GitLab or others.
These pull request helpers all start with the `pr_` prefix,
but I initially found them a little confusing to use
since they're each designed to be called in a specific context —
for example, when you have local work that isn't associated with a PR
or when a PR exists but you don't have the work locally on your computer.
Once I wrapped my head around the functions, though,
using them has utterly transformed my day-to-day workflow.
I can move in and out of collaborative work seamlessly.
The flow chart above is my personal mental model of this cluster of functions
and I hope it helps you make sense of them, too.
There are other great resources available in the <span class="pkg">usethis</span> documentation.
Beyond the [function documentation][usethis-pr-docs],
there's also the great [_Pull request helpers_ article][usethis-pr-article].
That article walks through a pull request
from the perspective of a contributor
and a package maintainer.
In this blog post, however,
you get to play both roles and choose your own adventure!
## Choose your own pull request adventure {#intro}
Welcome to this choose-your-own-adventure blog post.
<span id="instructions">You don't need to read this one from top to bottom.
Instead, jumping around is encouraged!</span>
Look for the `r way_point(FALSE)` icon.
It tells you that it's time for you make a choice.
But don't worry, there's no wrong choice:
if you take a wrong turn
you can always use your browser's `r back_button()` button
to retrace your steps.
::: decision
`r way_point()` Ready to get started?
<ul id="intro-options">
<li><p>Yes, [I'm ready to go](#get-started)!</p></li>
</ul>
:::
## {#story-container}
<div id="story" aria-live="polite" aria-relevant="additions"></div>
## Prep work {.step}
### Let's get started {#get-started .step}
You open your project in RStudio (or the editor of your choice).
You make a note to yourself to come up with a better name for your package —
for now you're calling it <span class="pkg">acme</span>
because it's mostly a collection of random functions you've written.
Anyway, you're thankful that you closed all of your open files the last time you were working,
but now the empty console beckons.
You're ready to do some work.
Where do you begin? With <span class="pkg">[usethis]</span> of course.
```{r eval=TRUE}
library(usethis)
```
::: decision
`r way_point()` That was easy! [Lets do some work now.](#start)
:::
### What's next? {#start .step}
::: {.decision}
`r way_point()` Now you face a tough decision: what do you actually do next?
- [Start new work](#pr-init)
- [Pick up something you were working on](#pr-resume)
- [Review or collaborate with someone else's work](#pr-fetch-review)
- [Clean up after a PR that's been merged](#pr-finish-start)
:::
### Start new work {#pr-init .step}
Time to start something new.
You scan your project board, issues list, JIRA tickets, slack messages, emails, and post-it notes
and finally settle on something to work on.
Your task: add an example to the documentation for a function you've been working on.
You want to start your work in a new branch,
so you call `pr_init()`,
giving it the name of your new branch.
```{r pr-init, eval=FALSE}
pr_init("add-example")
```
```
✓ Setting active project to '/Users/garrick/work/acme'
ℹ Pulling changes from 'upstream/main'
✓ Creating and switching to local branch 'add-example'
● Use `pr_push()` to create PR.
```
The console output reminds you that <span class="pkg">usethis</span> updated your local repo
and created and switched to a new branch for you.
::: decision
`r way_point()` You're ready to [do some work](#do-work).
:::
### Pick up something you were working on {#pr-resume .step}
You're ready to get back to that thing you were working on.
Which was what again?
You should probably have another sip of your coffee.
You were doing some work in a branch in your local of the project...
::: decision
`r way_point()` Do you remember the name of the branch?
- [I don't remember, remind me](#pr-resume-no-branch)
- [I remember, it's the `add-example` branch](#pr-resume-branch)
:::
### Get to a local branch {#pr-resume-local .step}
git branches, you've made a few.
But which one you do you want to work in?
::: decision
`r way_point()` Do you remember the name of the branch?
- [I don't remember, remind me](#pr-resume-no-branch)
- [I remember, it's the `add-example` branch](#pr-resume-branch)
:::
### Choose a branch and resume working {#pr-resume-no-branch .step}
Don't worry, <span class="pkg">usethis</span> has your back.
Just run `pr_resume()` without any arguments
to get a list of local branches available to you.
`pr_resume()` helpfully sorts the branches by recency of work
and tells you if any of the branches are related to pull requests.
```{r pr_resume-no-branch, eval=FALSE}
pr_resume()
```
```
ℹ No branch specified ... looking up local branches and associated PRs
Which branch do you want to checkout? (0 to exit)
1: add-example --> #11 ('@gadenbuie'): Add an example
2: feature-exploration
Selection: 1
✓ Switching to branch 'add-example'
✓ Pulling from 'origin/add-example'
• Use `pr_push()` to create or update PR.
```
We picked option `1` to keep working in our `add-example` branch.
Notice that, since `add-example` is related to PR `#11`,
`pr_resume()` also did you the extra favor of
making sure that your local copy is up-to-date.
::: decision
`r way_point()` Rock and roll, you're ready to [get back to work](#do-work-yours).
:::
### Get back to the branch {#pr-resume-branch .step}
Look at you, smarty pants.
You remember your git branch names!
I'm proud of you.
Good news,
`pr_resume()` can switch to the `"add-example"` branch for you
and it also makes sure that your local copy is up-to-date!
```{r pr_resume-branch, eval=FALSE}
pr_resume("add-example")
```
```
✓ Switching to branch 'add-example'
✓ Pulling from 'origin/add-example'
• Use `pr_push()` to create or update PR.
```
::: decision
`r way_point()` Sweat deal! Okay, you're ready to [keep on working](#do-work-yours).
:::
### Review or collaborate with someone else's work {#pr-fetch-review .step}
Version control software like git
and collaborative coding platforms like GitHub
are plenty of fun when you're working on your own.
But they really start to shine when you use them to collaborate with others.
The same is true for the <span class="pkg">usethis</span> PR helper functions.
Setting up your local repo to pull down the changes from a collaborator --
changes that probably live in a branch in _their copy_ of the repo --
can be a frustrating experience full of online searching
to remember the specific incantations required
to get your collaborators onto your computer and open in front of you.
But have no fear,
`pr_fetch()` does all of this for you,
in just one command in your R console.
::: decision
`r way_point()` Do you know the pull request number?
- [I don't remember, remind me](#pr-fetch-no-branch)
- [I remember, it's PR `#14`](#pr-fetch-branch)
:::
### Open a remote branch, locally {#pr-fetch .step}
The pull request is open on GitHub
and you can see the changes there,
but you just can't interact with the code in the same way through the browser.
You have to bring that code into your local IDE
where you can hold it in your hand
and poke it with debuggers.
::: decision
`r way_point()` Do you know the pull request number?
- [I don't remember, remind me.](#pr-fetch-no-branch)
- [I remember, it's PR `#14`.](#pr-fetch-branch)
:::
### Choose a PR and bring the changes onto your computer {#pr-fetch-no-branch .step}
Your friend,
who affectionately calls themselves `@wileycoyote` on GitHub,
helpfully contributed a new function
to your bag of tricks package, <span class="pkg">acme</span>.
They sent you a message on Slack letting you know they submitted a PR,
but they didn't mention the PR number.
No big deal —
you can call `pr_fetch()` from your local repository
without any arguments
and `pr_fetch()` will look up any open pull requests
and give you the option to pick the one you want.
```{r pr_fetch-no-branch, eval=FALSE}
pr_fetch()
```
```
ℹ No PR specified ... looking up open PRs
Which PR are you interested in? (0 to exit)
1: 'gadenbuie/acme/#11' (@gadenbuie): 'Add an example'
2: 'gadenbuie/acme/#14' (@wileycoyote): 'Model tuning features'
Selection: 2
✓ Checking out PR 'gadenbuie/acme/#14' (@wileycoyote): 'Model tuning features'
✓ Adding remote 'wileycoyote' as 'git@github.com:wileycoyote/acme.git'
✓ Creating and switching to local branch 'wileycoyote-toone-model'
✓ Setting 'wileycoyote/toone-model' as remote tracking branch
```
You find your friend's PR in the list and choose selection `2`.
Next time you can perform the same steps by providing the PR number —
`pr_fetch(14)` —
or you can use the menu again.
Who has time or brain space to memorize pull request numbers?
Now that you have the code from the PR available to you locally,
you're free to poke around to try out the code and review it.
::: decision
`r way_point()` Okay, you've had a chance to look at the code, what do you want to do next?
- [I want to make some changes to add to the PR.](#do-work-theirs)
- I reviewed the code and left comments for the PR author in the pull request.
- [I'm done with this branch](#pr-forget-theirs).
- [I'm done for now, but I'll probably come back to this branch later](#pr-pause).
:::
### Open a PR locally {#pr-fetch-branch .step}
You've been working with your friend,
`@wileycoyote`,
on a new set of model tuning functions.
They've helpfully started working on a PR,
but since you've been reviewing the code carefully
with them over the past few days,
you actually remember the pull request number.
Lucky number **14**.
```{r pr_fetch-branch, eval=FALSE}
pr_fetch(14)
```
```
✓ Checking out PR 'gadenbuie/acme/#14' (@wileycoyote): 'Model tuning features'
✓ Switching to branch 'wileycoyote-toone-model'
```
You already have a copy of the PR branch in your local project,
so `pr_fetch()` simply switched you into
the `wileycoyote-toone-model` branch
that it created when you first fetched the PR.
Because you might have been doing some work here before,
`pr_fetch()` does not try to update your local branch.
But you haven't done any work yet other than looking at the code,
so you follow up with `pr_pull()` to pull the latest changes into your project.
```{r pr_fetch-pr_pull, eval=FALSE}
pr_pull()
```
```
✓ Pulling from 'wileycoyote/toone-model'
```
::: decision
`r way_point()` Now that you have the latest PR code, what do you want to do next?
- [I want to make some changes to add to the PR.](#do-work-theirs)
- I reviewed the code and left comments for the PR author in the pull request.
- [I'm done with this branch](#pr-forget-theirs).
- [I'm done for now, but I'll probably come back to this branch later](#pr-pause).
:::
### Open your PR on GitHub {#pr-view-yours .step}
You can jump straight to the GitHub pull request page
for the branch you're in with `pr_view()`!
```{r pr_view-yours, eval=FALSE}
pr_view()
```
```
ℹ Current branch ('add-example') is connected to PR #11
✓ Opening URL 'https://github.com/gadenbuie/acme/pull/11'
```
::: decision
`r way_point()` When you're done with the PR on GitHub,
come back here to decide where you're headed next.
- That's it for now, I'm [ready to start the next thing](#pr-pause).
- Hang on, [I found something I need to fix](#fix-something).
- Good news, the pull request was merged and [I'm done with this work](#pr-finish-yours).
- Changes were made in the PR [and now I need to update my local copy](#pr-pull).
- There were updates in the main branch [and now I want to bring them into my PR branch](#pr-merge-main-yours).
- Actually, the pull request was closed and [I can forget about this work](#pr-forget-yours).
:::
### Open their PR on GitHub {#pr-view-theirs .step}
You can jump straight to the GitHub pull request page
for the branch you're in with `pr_view()`!
```{r pr_view-theirs, eval=FALSE}
pr_view()
```
```
ℹ Current branch ('wileycoyote-toone-models') is connected to PR #14
✓ Opening URL 'https://github.com/gadenbuie/acme/pull/14'
```
::: decision
`r way_point()` Welcome back to your project,
I hope everything went well over on GitHub.
Where to next?
- I'm done here for now, let's [start the next thing](#pr-pause).
- Shoot, [I saw something I need to fix](#fix-something-theirs).
- Nothing more with this branch, I can [forget all about this PR](#pr-forget-theirs).
- Changes were made in the PR [and now I need to update my local copy](#pr-pull-theirs).
- There were updates in the main branch [and now I want to bring them into my PR branch](#pr-merge-main-theirs).
- The PR was merged so [I'm all done with this work](#pr-finish-theirs).
:::
## Update your local copy {#do-update .step}
### Update your local copy with a reviewer's changes {#pr-pull .step}
Maybe a reviewer [suggested changes](https://docs.github.com/en/github/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/incorporating-feedback-in-your-pull-request#applying-a-suggested-change)
and you merged them from the PR page on GitHub.
Maybe a GitHub actions workflow
[automatically re-styled your code](https://github.com/r-lib/actions/blob/master/examples/pr-commands.yaml#L45-L75).
Or maybe you did a little side-project updating on your work computer.
However the changes happened,
the code in the PR branch has changed,
and now you want to `pr_pull()` those changes into your local copy.
```{r pr_pull, eval=FALSE}
pr_pull()
```
```
✓ Pulling from 'origin/add-example'
```
::: decision
`r way_point()` That was easy! What's next?
- I'm going to [write some code in this branch](#do-work-yours).
- I'm going to put this down and [work on something else](#pr-pause).
- I just merged this pull request and [I'm all done with this work](#pr-finish-yours).
:::
### Update your local copy with someone else's changes {#pr-pull-theirs .step}
Changes were made and hopefully the code has been improved,
but you'd like to run through the changes yourself
to make sure it works as expected.
Use `pr_pull()` to get the latest changes from the PR branch into your local copy.
```{r pr_pull-theirs, eval=FALSE}
pr_pull()
```
```
✓ Pulling from 'wileycoyote/toone-model'
```
::: decision
`r way_point()` That was easy! What's next?
- I'm going to [write some code in this branch](#do-work-theirs).
- I'm going to put this down and [work on something else](#pr-pause).
- That's all I wanted to do, I can [forget about this PR now](#pr-forget-theirs).
- I just merged this pull request and [I'm all done with this work](#pr-finish-theirs).
:::
### Bring your work up to date with the main branch {#pr-merge-main-yours .step}
While you were working on adding a new example to the documentation,
your friend `@wileycoyote` went and submitted a PR that changes
the function you're working on.
You found out when you looked at your pull request on GitHub
and it said
> <i class="fa fa-exclamation-triangle"><span class="sr-only">Caution:</span></i> This branch has conflicts that must be resolved.
Usually two people can work in the same project on two different areas
without running into each other,
but when both you and someone else want to change the same lines of code,
you run into this issue.
Helpfully,
`pr_merge_main()` can get the latest changes from the main branch of your project
into your current pull request!
```{r pr_merge_main-yours, eval=FALSE}
pr_merge_main()
```
```
✓ Pulling changes from 'origin/main' (default branch of source repo)
There are 1 conflicted files:
* R/atom_arranger.R
Are you ready to sort this out?
If so, we will open the conflicted files for you to edit.
1: Yes, I'm ready to resolve the merge conflicts.
2: No, I want to abort this merge.
Selection: 1
Please fix each conflict, save, stage, and commit.
To back out of this merge, run `gert::git_merge_abort()` (in R) or `git merge --abort` (in the shell).
```
If you need to fix any merge conflicts,
`pr_merge_main()` will alert you
that there are conflicts that need to be addressed.
It also opens the files for you if you want it to,
or you can choose to abort the merge
and find another way to resolve the conflicts.
You want to resolve the conflicts,
so you picked selection `1` to open the conflicted file
where you start looking for blocks in the source code that look like this:
```
<<<<<<< add-example
Code in the first section appears in
our *current* version in the `add-example` branch
=======
Code in the second section appears in
the *incoming* version, i.e. the `main` branch
>>>>>>> main
```
To resolve the conflict, you
1. Edit from `<<<<<<<` to `>>>>>>>`
choosing one or the other or a blend of the two versions
1. Save the file and stage it with `gert::git_add()`
1. Repeat for other files with merge conflicts
1. Commit the updated files with `gert::git_commit()`
or `git commit` in the command line
::: decision
`r way_point()` Great, your branch is up to date with the main branch!
- I'm going to [write some code in this branch](#do-work-yours).
- I want to [update the pull request on GitHub with these changes](#pr-push-yours).
:::
### Bring their work up to date with the main branch {#pr-merge-main-theirs .step}
While you and `@wileycoyote` have been working together on this new feature,
you've been doing some work in other areas of the package.
Since that other work has been added to the `main` branch,
you might want to make sure that everything is up to date
in `@wileycoyote`'s `toone-model` branch.
To do this, run `pr_merge_main()`.
It makes sure your default branch is up to date
and then merges any changes into the current branch.
```{r pr_merge_main-theirs, eval=FALSE}
pr_merge_main()
```
```
✓ Pulling changes from 'origin/main' (default branch of source repo)
Merged origin/main into wileycoyote-toone-model
```
If there aren't any merge conflicts,
you'll get a nice, quick confirmation that the merge went well.
::: decision
`r way_point()` Great, `@wileycote`'s branch is up to date with the main branch!
- I'm going to [write some code in this branch](#do-work-theirs).
- I want to [update the pull request on GitHub with these changes](#pr-push-theirs).
:::
### Get to the right place {#do-choose-branch .step}
Let's make sure we're in the right branch in your local project.
::: decision
`r way_point()`
Which branch do you want to work with right now?
- The one I'm in right now, so
[I'm ready to get to work](#do-work)!
- [A local branch, but not the one I'm in now](#pr-resume-local)
- [A pull request branch I was looking at on GitHub](#pr-fetch)
:::
## Work {.step}
### Do some work {#do-work .step}
You take a sip of your coffee (or the beverage of your choice),
turn up your favorite
[music to write code to](https://open.spotify.com/playlist/1fk6kpO8nb1KAUc1XAkAJ6)
playlist on Spotify,
and line up 25 minutes in your [Pomodoro app](https://pomofocus.io/).
You're ready to get something done!
Go write some code.
⏲️
🧑‍💻
🎧
::: decision
`r way_point()`
Sweet!
Now that you feel good about your work,
you're ready to [take a snapshot of your updates](#git-commit).
:::
### Keep doing some work {#do-work-yours .step}
> Taking breaks and resting is important!
>
> Last night I got caught up in a nested
> [#RStats](https://twitter.com/hashtag/rstats)
> list problem and couldn't solve it.
>
> Wrote the code this morning first shot.
>
> Take breaks! You need them!
>
> --- Nicholas Tierney (@nj_tierney) [April 16,2019](https://twitter.com/nj_tierney/status/1117964839127674881)
Sometimes the best thing you can do to solve a problem is give it some time.
Go for a walk, read something engaging, talk to a friend, take a shower.
And now you're back with fresh eyes, more energy, and a full cup of coffee.
This time, things go better!
You fall easily into a flow and start writing some code.
As you go,
you periodically pause to stage files with `gert::git_add()`
or to commit batches of changes with `gert::git_commit()`.
After a bit you surprise yourself when you realize
that the thing you couldn't figure out when you were tired yesterday
you've knocked out in an hour.
::: decision
`r way_point()`
Happy with your progress, you're ready [update the PR with your latest changes](#pr-push-yours).
:::
### Collaborate with someone else {#do-work-theirs .step}
This is exciting!
Your friend —
which feels like a totally natural way to describe `@wileycoyote`,
a person you know primarily from Twitter —
had a pretty cool idea
and you're feeling the buzz of inspiration.
Even though they started the pull request,
you're about to riff on the ideas they started laying down.
You pick out your [favorite RStudio theme](https://www.garrickadenbuie.com/project/rsthemes/)
and turn up your favorite dance-slash-coding-slash-singing-out-loud music.
As you work,
you pause occasionally to stage files with `gert::git_add()`
and to commit them with `gert::git_commit()`.
Since you're working with someone else,
you remember to
[write good commit messages](https://xkcd.com/1296/),
but since you're having fun you also use
[gitmoji to give each commit a good emoji.](https://gitmoji.dev/)
It's a lot later than you expect when you start wrapping up.
That's okay, `@wileycoyote` is going to be stoked to see what you've been working on!
::: decision
`r way_point()`
Go head and [update the PR with your latest changes](#pr-push-theirs).
:::
### Take a snapshot of your work {#git-commit .step}
_If you like it then you shoulda made a `git commit`._
There are two parts to taking a snapshot of your code.
And really,
it's less like taking a picture and more like sending yourself an email
with a copy of your files.
First, you'll pick the files that you want to add to the snapshot (or commit).
You can do this in the R console using `git_add()` from the <span class="pkg">[gert]</span> package.
Give the function a vector with the paths to the files you changed.
```{r eval=FALSE}
gert::git_add(c("R/atom_arranger.R", "man/atom_arranger.Rd"))
```
In git-speak,
`git_add()` adds the changes in the listed files to a staging area.
Running this command is like dragging a file into the email you're writing.
We haven't officially sent that email yet,
but we have a copy ready to go.
By the way,
you can still make more changes to the file
knowing that there's a temporary copy in that email draft
in case anything goes wrong.
Then, once all the files you want to commit have been added,
you _commit_ the changes.
In our email metaphor,
committing is a lot like pressing send on the email.
And just like an email,
the commit includes a message
where you can describe the updates you made to the files in the email (commit).
For this step you can use
`git_commit()`
(also from the <span class="pkg">[gert]</span> package)
which takes the commit message as a parameter.
Think of this message like the subject of an email to your future self.
```{r eval=FALSE}
gert::git_commit("Add an example to ?atom_arranger()")
```
_P.S. You can do this adding-and-committing dance in the [Git pane in RStudio](https://happygitwithr.com/rstudio-git-github.html), too._
::: decision
`r way_point()` Are you ready to share your work?
- Yes! I'm ready to [push my changes out into the world](#pr-push-new).
- Not yet, I want to [keep on working on this](#do-work).
- Actually, I don't think I'm on the right track here.
I'd [rather back out of this branch and forget all about it](#pr-forget-yours).
:::
### Fix something {#fix-something .step}
Oh no, you need to fix something!
I hope it's just a typo and not a big scary error!
But first...
::: decision
`r way_point()`
This thing that needs to be fixed —
[what branch is it in](#do-choose-branch)?
:::
### Fix something {#fix-something-theirs .step}
Oh no, you need to fix something!
I hope it's just a typo and not a big scary error!
But first...
::: decision
`r way_point()`
This thing that needs to be fixed — what branch is it in?
- The one I'm in right now, so
[I'm ready to get to work](#do-work-theirs)!
- [A local branch, but not the one I'm in now.](#pr-resume-local)
- [A pull request branch I was looking at on GitHub.](#pr-fetch)
:::
### Fix something {#fix-something-yours .step}
Oh no, you need to fix something!
I hope it's just a typo and not a big scary error!
But first...
::: decision
`r way_point()`
This thing that needs to be fixed — what branch is it in?
- The one I'm in right now, so
[I'm ready to get to work](#do-work-yours)!
- [A local branch, but not the one I'm in now](#pr-resume-local)
- [A pull request branch I was looking at on GitHub](#pr-fetch)
:::
## Share your work {#share-your-work .step}
Fantastic!
Your work is awesome and everyone is going to be happy to try it out.
::: decision
`r way_point()` Let's get your work off of your computer and out into the world.
- This [new work you're sharing for the first time](#pr-push-new).
- I'm [updating a pull request that I created](#pr-push-yours).
- I'm [updating a pull request from someone else](#pr-push-theirs).
:::
### Create a new pull request {#pr-push-new .step}
Fantastic!
Your work is awesome and everyone is going to be happy to try it out.
Let's get your work off of your computer and out into the world.
To create a new pull request, you call `pr_push()`.
```{r pr-push-new, eval=FALSE}
pr_push()
```
```
✔ Pushing local 'add-example' branch to 'origin:add-example'
✔ Setting upstream tracking branch for 'add-example' to 'origin/add-example'
✔ Create PR at link given below
✔ Opening URL 'https://github.com/gadenbuie/acme/compare/add-example'
```
`pr_push()` sends the local changes in your new branch to GitHub,
and opens a browser window where you can review your changes once more.
If everything looks good,
go ahead click the _Create Pull Request_ button.
::: decision
`r way_point()` Good job! How are you feeling now?
- I'm on a roll, let's [start the next thing](#pr-pause).
- I'd want to [open the PR on GitHub again](#pr-view-yours).
- Oh shoot, [I saw something I need to fix](#fix-something).
- Great, that pull request was just merged and [I'm done with this work](#pr-finish-yours).
- Changes were made in the PR [and now I need to update my local copy](#pr-pull).
- There were updates in the main branch [and now I want to bring them into my PR branch](#pr-merge-main-yours).
- Actually, the pull request was closed and [I can forget about this work](#pr-forget-yours).
:::
### Update your existing pull request {#pr-push-yours .step}
You just made [and committed](#git-commit)
some changes to an existing PR you created,
and now you'd like to update that PR on GitHub.
`pr_push()` also does this for you!
Helpfully, before it pushes it checks to make sure your local branch is up-to-date.
```{r pr-push, eval=FALSE}
pr_push()
```
```
✔ Checking that local branch 'add-example' has the changes in 'origin/add-example'
✔ Pushing local 'add-example' branch to 'origin:add-example'
✔ View PR at 'https://github.com/gadenbuie/acme/pull/10' or call `pr_view()`
```
::: decision
`r way_point()` Phenomenal! What do you want to do next?
- I want to [take a look at the PR on GitHub](#pr-view-yours).
- Rock on! I'm moving on to [start the next thing](#pr-pause).
- Wait a second, [I saw something I need to fix](#fix-something-yours).
- Changes were made in the PR [and now I need to update my local copy](#pr-pull).
- There were updates in the main branch [and now I want to bring them into my PR branch](#pr-merge-main-yours).
- The PR has been merged and [I'm all done with this work](#pr-finish-yours).
- Never mind, my [PR was closed and I'd like to forget about this work](#pr-forget-yours).
:::
### Update someone else's pull request {#pr-push-theirs .step}
At this point,
you have changes in your local copy of your PR branch
that you need to push out to the source branch for the PR,
which happens to be in `@wileycoyote`'s fork of your repo.
`pr_push()` is very smart and knows how to send the changes to the correct repository,
pushing to the `toone-model` in the `wileycoyote/acme`.
```{r pr-push-theirs, eval=FALSE}
pr_push()
```
```
✔ Checking that local branch 'wileycoyote-toone-model' has the changes in 'wileycoyote/toone-model'
✔ Pushing local 'wileycoyote-toone-model' branch to 'wilecoyote:toone-model'
✔ View PR at 'https://github.com/gadenbuie/acme/pull/14' or call `pr_view()`
```
::: decision
`r way_point()` Phenomenal! What do you want to do next?
- I want to [take a look at the PR on GitHub](#pr-view-theirs).
- Beep, beep! I'm moving on to [start the next thing](#pr-pause).
- Hang on, [I saw something I need to fix](#fix-something-theirs).
- That's all I wanted to do, I can [forget about this PR now](#pr-forget-theirs).
- Changes were made in the PR [and now I need to update my local copy](#pr-pull-theirs).
- There were updates in the main branch [and now I want to bring them into my PR branch](#pr-merge-main-theirs).
- I just merged this pull request and [I'm all done with this work](#pr-finish-theirs).
:::
## Wrap Up {.step}
### Pause your work {#pr-pause .step}
You're done but you have a feeling you'll be back here again soon.
What you need is a little _pause_.
Call `pr_pause()` to switch from the current branch back to the default branch,
and to make sure you've got the latest changes in the default branch.
Don't worry,
the work will be waiting patiently for you in a local branch
when you're ready to come back to it.