├── .Rbuildignore
├── .Rprofile
├── .gitignore
├── CNAME
├── LICENSE.md
├── README.Rmd
├── README.md
├── _brand.yml
├── _quarto.yml
├── img
├── branch-link-rstudio.PNG
├── github-revert-pr.PNG
├── github_conflict.PNG
├── new-project-wizard.PNG
├── rebase_commit_history.PNG
├── show-clone-github.PNG
└── show-fork-github.PNG
├── intro-git-github.Rproj
├── renv.lock
├── renv
├── .gitignore
├── activate.R
└── settings.json
├── session-break-slide.html
├── session-break-slide.qmd
├── session-commit-main.html
├── session-commit-main.qmd
├── session-conflict.html
├── session-conflict.qmd
├── session-fork-clone.html
├── session-fork-clone.qmd
├── session-intro.html
├── session-intro.qmd
├── session-prework.html
├── session-prework.qmd
├── session-pull-requests.html
├── session-pull-requests.qmd
├── session-setup.html
├── session-setup.qmd
├── session-undo-merge.html
├── session-undo-merge.qmd
├── session-usethis-errors.html
├── session-usethis-errors.qmd
├── session-usethis-gert.html
├── session-usethis-gert.qmd
├── session-version-control.html
├── session-version-control.qmd
├── session-version-workflow.html
└── session-version-workflow.qmd
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^renv$
2 | ^renv\.lock$
3 | ^LICENSE\.md$
4 |
--------------------------------------------------------------------------------
/.Rprofile:
--------------------------------------------------------------------------------
1 | source("renv/activate.R")
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 | .Rdata
6 | .httr-oauth
7 | .DS_Store
8 |
9 | /.quarto/
10 |
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | intro-git-github.nhsrcommunity.com
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | ## creative commons
2 |
3 | # CC0 1.0 Universal
4 |
5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER.
6 |
7 | ### Statement of Purpose
8 |
9 | The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work").
10 |
11 | Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others.
12 |
13 | For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights.
14 |
15 | 1. __Copyright and Related Rights.__ A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following:
16 |
17 | i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work;
18 |
19 | ii. moral rights retained by the original author(s) and/or performer(s);
20 |
21 | iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work;
22 |
23 | iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below;
24 |
25 | v. rights protecting the extraction, dissemination, use and reuse of data in a Work;
26 |
27 | vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and
28 |
29 | vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof.
30 |
31 | 2. __Waiver.__ To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose.
32 |
33 | 3. __Public License Fallback.__ Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose.
34 |
35 | 4. __Limitations and Disclaimers.__
36 |
37 | a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document.
38 |
39 | b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law.
40 |
41 | c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work.
42 |
43 | d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work.
44 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | ---
4 |
5 |
6 |
7 | ```{r, include = FALSE}
8 | knitr::opts_chunk$set(
9 | collapse = TRUE,
10 | comment = "#>"
11 | )
12 | ```
13 |
14 | # Introduction to Git and GitHub
15 |
16 |
17 |
18 |
19 | Introduction to Git and GitHub training based on the Forwards workshops:
20 |
21 | [Setting up your system](http://bit.ly/pkg-dev-2) and [Your first package](http://bit.ly/pkg-dev-3) as part of the one-hour package development series.
22 |
23 | ## Part 1
24 |
25 | - [Prework](https://intro-git-github.nhsrcommunity.com/session-prework.html#/title-slide) - Get set up on a computer
26 | - [Introduction](https://intro-git-github.nhsrcommunity.com/session-intro.html#/title-slide) - What is version control?
27 | - [Setting up](https://intro-git-github.nhsrcommunity.com/session-setup.html#/title-slide) - Getting started with Git and GitHub
28 |
29 | ### Break
30 |
31 | [Break](https://intro-git-github.nhsrcommunity.com/session-break-slide.html#/title-slide)
32 |
33 | - [Version Control](https://intro-git-github.nhsrcommunity.com/session-version-control.html#/title-slide) - What is Git/GitHub and how they relate to RStudio along with the ups and downs of Git
34 | - [Workflow](https://intro-git-github.nhsrcommunity.com/session-version-workflow.html#/title-slide) - Brief introduction to the Git and GitHub terminology
35 | - [Workflow with {usethis} and {gert}](https://intro-git-github.nhsrcommunity.com/session-usethis-gert.html#/title-slide) - start work and making a commit
36 |
37 | ## Part 2
38 |
39 | - [Pull Requests (PRs)](https://intro-git-github.nhsrcommunity.com/session-pull-requests.html#/title-slide) - making pull request, pausing, resuming and finishing
40 | - [Merge conflict!](https://intro-git-github.nhsrcommunity.com/session-conflict.html#/title-slide) - repeat steps from previous session and create a conflict merge
41 |
42 | ### Break
43 |
44 | [Break](https://intro-git-github.nhsrcommunity.com/session-break-slide.html#/title-slide)
45 |
46 | - [Commit to main (and undo last commit!)](https://intro-git-github.nhsrcommunity.com/session-commit-main.html#/title-slide) - how committing is possible to the main and undo last commits
47 | - [Undo last merge](https://intro-git-github.nhsrcommunity.com/session-undo-merge.html#/title-slide) - undoing a merge (reverting a pull request)
48 | - [Existing repositories](https://intro-git-github.nhsrcommunity.com/session-fork-clone.html#/title-slide) - Getting copies of existing repositories
49 |
50 | ## Appendix slides
51 |
52 | [{usethis} errors](https://intro-git-github.nhsrcommunity.com/session-usethis-errors.html#/title-slide) - typical errors from set up issues
53 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # Introduction to Git and GitHub
5 |
6 |
7 |
8 |
9 | Introduction to Git and GitHub training based on the Forwards workshops:
10 |
11 | [Setting up your system](http://bit.ly/pkg-dev-2) and [Your first
12 | package](http://bit.ly/pkg-dev-3) as part of the one-hour package
13 | development series.
14 |
15 | ## Part 1
16 |
17 | - [Prework](https://intro-git-github.nhsrcommunity.com/session-prework.html#/title-slide) -
18 | Get set up on a computer
19 | - [Introduction](https://intro-git-github.nhsrcommunity.com/session-intro.html#/title-slide) -
20 | What is version control?
21 | - [Setting
22 | up](https://intro-git-github.nhsrcommunity.com/session-setup.html#/title-slide) -
23 | Getting started with Git and GitHub
24 |
25 | ### Break
26 |
27 | [Break](https://intro-git-github.nhsrcommunity.com/session-break-slide.html#/title-slide)
28 |
29 | - [Version
30 | Control](https://intro-git-github.nhsrcommunity.com/session-version-control.html#/title-slide) -
31 | What is Git/GitHub and how they relate to RStudio along with the ups
32 | and downs of Git
33 | - [Workflow](https://intro-git-github.nhsrcommunity.com/session-version-workflow.html#/title-slide) -
34 | Brief introduction to the Git and GitHub terminology
35 | - [Workflow with {usethis} and
36 | {gert}](https://intro-git-github.nhsrcommunity.com/session-usethis-gert.html#/title-slide) -
37 | start work and making a commit
38 |
39 | ## Part 2
40 |
41 | - [Pull Requests
42 | (PRs)](https://intro-git-github.nhsrcommunity.com/session-pull-requests.html#/title-slide) -
43 | making pull request, pausing, resuming and finishing
44 | - [Merge
45 | conflict!](https://intro-git-github.nhsrcommunity.com/session-conflict.html#/title-slide) -
46 | repeat steps from previous session and create a conflict merge
47 |
48 | ### Break
49 |
50 | [Break](https://intro-git-github.nhsrcommunity.com/session-break-slide.html#/title-slide)
51 |
52 | - [Commit to main (and undo last
53 | commit!)](https://intro-git-github.nhsrcommunity.com/session-commit-main.html#/title-slide) -
54 | how committing is possible to the main and undo last commits
55 | - [Undo last
56 | merge](https://intro-git-github.nhsrcommunity.com/session-undo-merge.html#/title-slide) -
57 | undoing a merge (reverting a pull request)
58 | - [Existing
59 | repositories](https://intro-git-github.nhsrcommunity.com/session-fork-clone.html#/title-slide) -
60 | Getting copies of existing repositories
61 |
62 | ## Appendix slides
63 |
64 | [{usethis}
65 | errors](https://intro-git-github.nhsrcommunity.com/session-usethis-errors.html#/title-slide) -
66 | typical errors from set up issues
67 |
--------------------------------------------------------------------------------
/_brand.yml:
--------------------------------------------------------------------------------
1 | meta:
2 | name:
3 | short: NHSR
4 | full: NHS-R Community
5 | link:
6 | home: https://nhsrcommunity.com/
7 |
8 | # # Download the NHS-R Community logo and store it next to _brand.yml
9 | # # You'll have to update this section with the correct file names
10 | # logo:
11 | # images:
12 | # header: nhsr-logo.svg
13 | # small: nhsr-logo.svg
14 | # medium: header
15 | # large: header
16 |
17 | # NHS-R Community uses the NHS England colour palette
18 | # https://www.england.nhs.uk/nhsidentity/identity-guidelines/colours/ used
19 | # under the OGL Licence v3.0
20 |
21 | color:
22 | palette:
23 | # Core neutrals (Level 2)
24 | white: "#FFFFFF"
25 | black: "#231F20"
26 | grey-dark: "#425563"
27 | grey-mid: "#768692"
28 | grey-pale: "#E8EDEE"
29 |
30 | # Blues (Level 1)
31 | blue-dark: "#003087"
32 | blue: "#005EB8"
33 | blue-bright: "#0072CE"
34 | blue-light: "#41B6E6"
35 | blue-aqua: "#00A9CE"
36 |
37 | # Greens (Level 3)
38 | green-dark: "#006747"
39 | green: "#009639"
40 | green-light: "#78BE20"
41 | green-aqua: "#00A499"
42 |
43 | # Purples and Pinks
44 | purple: "#330072"
45 | pink-dark: "#7C2855"
46 | pink: "#AE2573"
47 |
48 | # Reds
49 | red-dark: "#8A1538"
50 | red: "#DA291C" # Emergency Services Red
51 |
52 | # Yellows and Orange
53 | orange: "#ED8B00"
54 | yellow-warm: "#FFB81C"
55 | yellow: "#FAE100"
56 |
57 | # Bootstrap color aliases - using closest matches without duplication
58 | indigo: blue-dark
59 | cyan: blue-aqua
60 | teal: green-aqua
61 |
62 | foreground: black
63 | background: white
64 | primary: blue
65 | secondary: grey-dark
66 | tertiary: grey-pale
67 | success: green
68 | danger: red
69 | warning: yellow-warm
70 | info: blue-light
71 | light: grey-pale
72 | dark: grey-dark
73 |
74 | typography:
75 | fonts:
76 | # Note: Frutiger is a licensed NHS England font that requires purchasing
77 | # https://www.england.nhs.uk/nhsidentity/identity-guidelines/fonts/
78 | # - family: Frutiger W01
79 | # source: file
80 | # files:
81 | # - path: fonts/FrutigerLTW01-55Roman.ttf
82 | # - path: fonts/FrutigerLTW01-65Bold.ttf
83 | # weight: bold
84 |
85 | - family: Arial
86 | source: system
87 |
88 | base:
89 | family: "Arial, sans-serif"
90 | line-height: 1.5
91 |
92 | headings:
93 | family: "Arial, sans-serif"
94 | weight: 700
95 | line-height: 1.25
96 | color: blue
97 |
98 | defaults:
99 | bootstrap:
100 | defaults:
101 | # NHS-R Community specific variables could be added here
102 | enable-rounded: false
103 |
--------------------------------------------------------------------------------
/_quarto.yml:
--------------------------------------------------------------------------------
1 | project:
2 | title: "intro-git-github"
3 | render:
4 | - "*.qmd"
5 | - "!LICENCE.md"
6 | embed-resources: true
7 | format:
8 | revealjs:
9 | footer: ""
10 | code-link: true
11 | preview-links: true
12 | logo: https://raw.githubusercontent.com/nhs-r-community/assets/main/logo/nhsr-logo.svg
13 | author: "Zoë Turner"
14 | execute:
15 | echo: true
16 | eval: false
17 | title-slide-attributes:
18 | data-background-color: "#43464B"
19 | brand: _brand.yml
20 |
21 | # output-dir: "/slides"
22 |
--------------------------------------------------------------------------------
/img/branch-link-rstudio.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhs-r-community/intro-git-github/aa9fc1313ff123f4396a3568b30da040a9322ee3/img/branch-link-rstudio.PNG
--------------------------------------------------------------------------------
/img/github-revert-pr.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhs-r-community/intro-git-github/aa9fc1313ff123f4396a3568b30da040a9322ee3/img/github-revert-pr.PNG
--------------------------------------------------------------------------------
/img/github_conflict.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhs-r-community/intro-git-github/aa9fc1313ff123f4396a3568b30da040a9322ee3/img/github_conflict.PNG
--------------------------------------------------------------------------------
/img/new-project-wizard.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhs-r-community/intro-git-github/aa9fc1313ff123f4396a3568b30da040a9322ee3/img/new-project-wizard.PNG
--------------------------------------------------------------------------------
/img/rebase_commit_history.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhs-r-community/intro-git-github/aa9fc1313ff123f4396a3568b30da040a9322ee3/img/rebase_commit_history.PNG
--------------------------------------------------------------------------------
/img/show-clone-github.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhs-r-community/intro-git-github/aa9fc1313ff123f4396a3568b30da040a9322ee3/img/show-clone-github.PNG
--------------------------------------------------------------------------------
/img/show-fork-github.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhs-r-community/intro-git-github/aa9fc1313ff123f4396a3568b30da040a9322ee3/img/show-fork-github.PNG
--------------------------------------------------------------------------------
/intro-git-github.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 | ProjectId: 1771fb92-52cc-4c92-97b0-bdb25115a0b3
3 |
4 | RestoreWorkspace: Default
5 | SaveWorkspace: Default
6 | AlwaysSaveHistory: Default
7 |
8 | EnableCodeIndexing: Yes
9 | UseSpacesForTab: Yes
10 | NumSpacesForTab: 2
11 | Encoding: UTF-8
12 |
13 | RnwWeave: Sweave
14 | LaTeX: pdfLaTeX
15 |
--------------------------------------------------------------------------------
/renv.lock:
--------------------------------------------------------------------------------
1 | {
2 | "R": {
3 | "Version": "4.4.1",
4 | "Repositories": [
5 | {
6 | "Name": "CRAN",
7 | "URL": "https://cran.rstudio.com"
8 | }
9 | ]
10 | },
11 | "Packages": {
12 | "R6": {
13 | "Package": "R6",
14 | "Version": "2.5.1",
15 | "Source": "Repository",
16 | "Repository": "CRAN",
17 | "Requirements": [
18 | "R"
19 | ],
20 | "Hash": "470851b6d5d0ac559e9d01bb352b4021"
21 | },
22 | "askpass": {
23 | "Package": "askpass",
24 | "Version": "1.2.1",
25 | "Source": "Repository",
26 | "Repository": "CRAN",
27 | "Requirements": [
28 | "sys"
29 | ],
30 | "Hash": "c39f4155b3ceb1a9a2799d700fbd4b6a"
31 | },
32 | "base64enc": {
33 | "Package": "base64enc",
34 | "Version": "0.1-3",
35 | "Source": "Repository",
36 | "Repository": "CRAN",
37 | "Requirements": [
38 | "R"
39 | ],
40 | "Hash": "543776ae6848fde2f48ff3816d0628bc"
41 | },
42 | "bslib": {
43 | "Package": "bslib",
44 | "Version": "0.8.0",
45 | "Source": "Repository",
46 | "Repository": "CRAN",
47 | "Requirements": [
48 | "R",
49 | "base64enc",
50 | "cachem",
51 | "fastmap",
52 | "grDevices",
53 | "htmltools",
54 | "jquerylib",
55 | "jsonlite",
56 | "lifecycle",
57 | "memoise",
58 | "mime",
59 | "rlang",
60 | "sass"
61 | ],
62 | "Hash": "b299c6741ca9746fb227debcb0f9fb6c"
63 | },
64 | "cachem": {
65 | "Package": "cachem",
66 | "Version": "1.1.0",
67 | "Source": "Repository",
68 | "Repository": "CRAN",
69 | "Requirements": [
70 | "fastmap",
71 | "rlang"
72 | ],
73 | "Hash": "cd9a672193789068eb5a2aad65a0dedf"
74 | },
75 | "cli": {
76 | "Package": "cli",
77 | "Version": "3.6.3",
78 | "Source": "Repository",
79 | "Repository": "CRAN",
80 | "Requirements": [
81 | "R",
82 | "utils"
83 | ],
84 | "Hash": "b21916dd77a27642b447374a5d30ecf3"
85 | },
86 | "clipr": {
87 | "Package": "clipr",
88 | "Version": "0.8.0",
89 | "Source": "Repository",
90 | "Repository": "CRAN",
91 | "Requirements": [
92 | "utils"
93 | ],
94 | "Hash": "3f038e5ac7f41d4ac41ce658c85e3042"
95 | },
96 | "countdown": {
97 | "Package": "countdown",
98 | "Version": "0.4.0",
99 | "Source": "Repository",
100 | "Repository": "CRAN",
101 | "Requirements": [
102 | "htmltools",
103 | "prismatic",
104 | "utils",
105 | "whisker"
106 | ],
107 | "Hash": "b44ad5a5e287637c3b8ca0e9bb64bb18"
108 | },
109 | "crayon": {
110 | "Package": "crayon",
111 | "Version": "1.5.3",
112 | "Source": "Repository",
113 | "Repository": "CRAN",
114 | "Requirements": [
115 | "grDevices",
116 | "methods",
117 | "utils"
118 | ],
119 | "Hash": "859d96e65ef198fd43e82b9628d593ef"
120 | },
121 | "credentials": {
122 | "Package": "credentials",
123 | "Version": "2.0.2",
124 | "Source": "Repository",
125 | "Repository": "CRAN",
126 | "Requirements": [
127 | "askpass",
128 | "curl",
129 | "jsonlite",
130 | "openssl",
131 | "sys"
132 | ],
133 | "Hash": "09fd631e607a236f8cc7f9604db32cb8"
134 | },
135 | "curl": {
136 | "Package": "curl",
137 | "Version": "6.0.1",
138 | "Source": "Repository",
139 | "Repository": "CRAN",
140 | "Requirements": [
141 | "R"
142 | ],
143 | "Hash": "e8ba62486230951fcd2b881c5be23f96"
144 | },
145 | "desc": {
146 | "Package": "desc",
147 | "Version": "1.4.3",
148 | "Source": "Repository",
149 | "Repository": "CRAN",
150 | "Requirements": [
151 | "R",
152 | "R6",
153 | "cli",
154 | "utils"
155 | ],
156 | "Hash": "99b79fcbd6c4d1ce087f5c5c758b384f"
157 | },
158 | "digest": {
159 | "Package": "digest",
160 | "Version": "0.6.37",
161 | "Source": "Repository",
162 | "Repository": "CRAN",
163 | "Requirements": [
164 | "R",
165 | "utils"
166 | ],
167 | "Hash": "33698c4b3127fc9f506654607fb73676"
168 | },
169 | "evaluate": {
170 | "Package": "evaluate",
171 | "Version": "1.0.1",
172 | "Source": "Repository",
173 | "Repository": "CRAN",
174 | "Requirements": [
175 | "R"
176 | ],
177 | "Hash": "3fd29944b231036ad67c3edb32e02201"
178 | },
179 | "farver": {
180 | "Package": "farver",
181 | "Version": "2.1.2",
182 | "Source": "Repository",
183 | "Repository": "CRAN",
184 | "Hash": "680887028577f3fa2a81e410ed0d6e42"
185 | },
186 | "fastmap": {
187 | "Package": "fastmap",
188 | "Version": "1.2.0",
189 | "Source": "Repository",
190 | "Repository": "CRAN",
191 | "Hash": "aa5e1cd11c2d15497494c5292d7ffcc8"
192 | },
193 | "fontawesome": {
194 | "Package": "fontawesome",
195 | "Version": "0.5.3",
196 | "Source": "Repository",
197 | "Repository": "CRAN",
198 | "Requirements": [
199 | "R",
200 | "htmltools",
201 | "rlang"
202 | ],
203 | "Hash": "bd1297f9b5b1fc1372d19e2c4cd82215"
204 | },
205 | "fs": {
206 | "Package": "fs",
207 | "Version": "1.6.5",
208 | "Source": "Repository",
209 | "Repository": "CRAN",
210 | "Requirements": [
211 | "R",
212 | "methods"
213 | ],
214 | "Hash": "7f48af39fa27711ea5fbd183b399920d"
215 | },
216 | "gert": {
217 | "Package": "gert",
218 | "Version": "2.1.4",
219 | "Source": "Repository",
220 | "Repository": "CRAN",
221 | "Requirements": [
222 | "askpass",
223 | "credentials",
224 | "openssl",
225 | "rstudioapi",
226 | "sys",
227 | "zip"
228 | ],
229 | "Hash": "ae855ad6d7be20dd7b05d43d25700398"
230 | },
231 | "gh": {
232 | "Package": "gh",
233 | "Version": "1.4.1",
234 | "Source": "Repository",
235 | "Repository": "CRAN",
236 | "Requirements": [
237 | "R",
238 | "cli",
239 | "gitcreds",
240 | "glue",
241 | "httr2",
242 | "ini",
243 | "jsonlite",
244 | "lifecycle",
245 | "rlang"
246 | ],
247 | "Hash": "fbbbc48eba7a6626a08bb365e44b563b"
248 | },
249 | "gitcreds": {
250 | "Package": "gitcreds",
251 | "Version": "0.1.2",
252 | "Source": "Repository",
253 | "Repository": "CRAN",
254 | "Requirements": [
255 | "R"
256 | ],
257 | "Hash": "ab08ac61f3e1be454ae21911eb8bc2fe"
258 | },
259 | "glue": {
260 | "Package": "glue",
261 | "Version": "1.8.0",
262 | "Source": "Repository",
263 | "Repository": "CRAN",
264 | "Requirements": [
265 | "R",
266 | "methods"
267 | ],
268 | "Hash": "5899f1eaa825580172bb56c08266f37c"
269 | },
270 | "highr": {
271 | "Package": "highr",
272 | "Version": "0.11",
273 | "Source": "Repository",
274 | "Repository": "CRAN",
275 | "Requirements": [
276 | "R",
277 | "xfun"
278 | ],
279 | "Hash": "d65ba49117ca223614f71b60d85b8ab7"
280 | },
281 | "htmltools": {
282 | "Package": "htmltools",
283 | "Version": "0.5.8.1",
284 | "Source": "Repository",
285 | "Repository": "CRAN",
286 | "Requirements": [
287 | "R",
288 | "base64enc",
289 | "digest",
290 | "fastmap",
291 | "grDevices",
292 | "rlang",
293 | "utils"
294 | ],
295 | "Hash": "81d371a9cc60640e74e4ab6ac46dcedc"
296 | },
297 | "httr2": {
298 | "Package": "httr2",
299 | "Version": "1.0.6",
300 | "Source": "Repository",
301 | "Repository": "CRAN",
302 | "Requirements": [
303 | "R",
304 | "R6",
305 | "cli",
306 | "curl",
307 | "glue",
308 | "lifecycle",
309 | "magrittr",
310 | "openssl",
311 | "rappdirs",
312 | "rlang",
313 | "vctrs",
314 | "withr"
315 | ],
316 | "Hash": "3ef5d07ec78803475a94367d71b40c41"
317 | },
318 | "ini": {
319 | "Package": "ini",
320 | "Version": "0.3.1",
321 | "Source": "Repository",
322 | "Repository": "CRAN",
323 | "Hash": "6154ec2223172bce8162d4153cda21f7"
324 | },
325 | "jquerylib": {
326 | "Package": "jquerylib",
327 | "Version": "0.1.4",
328 | "Source": "Repository",
329 | "Repository": "CRAN",
330 | "Requirements": [
331 | "htmltools"
332 | ],
333 | "Hash": "5aab57a3bd297eee1c1d862735972182"
334 | },
335 | "jsonlite": {
336 | "Package": "jsonlite",
337 | "Version": "1.8.9",
338 | "Source": "Repository",
339 | "Repository": "CRAN",
340 | "Requirements": [
341 | "methods"
342 | ],
343 | "Hash": "4e993b65c2c3ffbffce7bb3e2c6f832b"
344 | },
345 | "knitr": {
346 | "Package": "knitr",
347 | "Version": "1.49",
348 | "Source": "Repository",
349 | "Repository": "CRAN",
350 | "Requirements": [
351 | "R",
352 | "evaluate",
353 | "highr",
354 | "methods",
355 | "tools",
356 | "xfun",
357 | "yaml"
358 | ],
359 | "Hash": "9fcb189926d93c636dea94fbe4f44480"
360 | },
361 | "lifecycle": {
362 | "Package": "lifecycle",
363 | "Version": "1.0.4",
364 | "Source": "Repository",
365 | "Repository": "CRAN",
366 | "Requirements": [
367 | "R",
368 | "cli",
369 | "glue",
370 | "rlang"
371 | ],
372 | "Hash": "b8552d117e1b808b09a832f589b79035"
373 | },
374 | "magrittr": {
375 | "Package": "magrittr",
376 | "Version": "2.0.3",
377 | "Source": "Repository",
378 | "Repository": "CRAN",
379 | "Requirements": [
380 | "R"
381 | ],
382 | "Hash": "7ce2733a9826b3aeb1775d56fd305472"
383 | },
384 | "memoise": {
385 | "Package": "memoise",
386 | "Version": "2.0.1",
387 | "Source": "Repository",
388 | "Repository": "CRAN",
389 | "Requirements": [
390 | "cachem",
391 | "rlang"
392 | ],
393 | "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c"
394 | },
395 | "mime": {
396 | "Package": "mime",
397 | "Version": "0.12",
398 | "Source": "Repository",
399 | "Repository": "CRAN",
400 | "Requirements": [
401 | "tools"
402 | ],
403 | "Hash": "18e9c28c1d3ca1560ce30658b22ce104"
404 | },
405 | "openssl": {
406 | "Package": "openssl",
407 | "Version": "2.2.2",
408 | "Source": "Repository",
409 | "Repository": "CRAN",
410 | "Requirements": [
411 | "askpass"
412 | ],
413 | "Hash": "d413e0fef796c9401a4419485f709ca1"
414 | },
415 | "prismatic": {
416 | "Package": "prismatic",
417 | "Version": "1.1.2",
418 | "Source": "Repository",
419 | "Repository": "CRAN",
420 | "Requirements": [
421 | "R",
422 | "farver",
423 | "grDevices",
424 | "graphics"
425 | ],
426 | "Hash": "51967d2e55a523791ae22832e86209ae"
427 | },
428 | "purrr": {
429 | "Package": "purrr",
430 | "Version": "1.0.2",
431 | "Source": "Repository",
432 | "Repository": "CRAN",
433 | "Requirements": [
434 | "R",
435 | "cli",
436 | "lifecycle",
437 | "magrittr",
438 | "rlang",
439 | "vctrs"
440 | ],
441 | "Hash": "1cba04a4e9414bdefc9dcaa99649a8dc"
442 | },
443 | "rappdirs": {
444 | "Package": "rappdirs",
445 | "Version": "0.3.3",
446 | "Source": "Repository",
447 | "Repository": "CRAN",
448 | "Requirements": [
449 | "R"
450 | ],
451 | "Hash": "5e3c5dc0b071b21fa128676560dbe94d"
452 | },
453 | "renv": {
454 | "Package": "renv",
455 | "Version": "0.17.3",
456 | "Source": "Repository",
457 | "Repository": "CRAN",
458 | "Requirements": [
459 | "utils"
460 | ],
461 | "Hash": "4543b8cd233ae25c6aba8548be9e747e"
462 | },
463 | "rlang": {
464 | "Package": "rlang",
465 | "Version": "1.1.4",
466 | "Source": "Repository",
467 | "Repository": "CRAN",
468 | "Requirements": [
469 | "R",
470 | "utils"
471 | ],
472 | "Hash": "3eec01f8b1dee337674b2e34ab1f9bc1"
473 | },
474 | "rmarkdown": {
475 | "Package": "rmarkdown",
476 | "Version": "2.29",
477 | "Source": "Repository",
478 | "Repository": "CRAN",
479 | "Requirements": [
480 | "R",
481 | "bslib",
482 | "evaluate",
483 | "fontawesome",
484 | "htmltools",
485 | "jquerylib",
486 | "jsonlite",
487 | "knitr",
488 | "methods",
489 | "tinytex",
490 | "tools",
491 | "utils",
492 | "xfun",
493 | "yaml"
494 | ],
495 | "Hash": "df99277f63d01c34e95e3d2f06a79736"
496 | },
497 | "rprojroot": {
498 | "Package": "rprojroot",
499 | "Version": "2.0.4",
500 | "Source": "Repository",
501 | "Repository": "CRAN",
502 | "Requirements": [
503 | "R"
504 | ],
505 | "Hash": "4c8415e0ec1e29f3f4f6fc108bef0144"
506 | },
507 | "rstudioapi": {
508 | "Package": "rstudioapi",
509 | "Version": "0.17.1",
510 | "Source": "Repository",
511 | "Repository": "CRAN",
512 | "Hash": "5f90cd73946d706cfe26024294236113"
513 | },
514 | "sass": {
515 | "Package": "sass",
516 | "Version": "0.4.9",
517 | "Source": "Repository",
518 | "Repository": "CRAN",
519 | "Requirements": [
520 | "R6",
521 | "fs",
522 | "htmltools",
523 | "rappdirs",
524 | "rlang"
525 | ],
526 | "Hash": "d53dbfddf695303ea4ad66f86e99b95d"
527 | },
528 | "sys": {
529 | "Package": "sys",
530 | "Version": "3.4.3",
531 | "Source": "Repository",
532 | "Repository": "CRAN",
533 | "Hash": "de342ebfebdbf40477d0758d05426646"
534 | },
535 | "tinytex": {
536 | "Package": "tinytex",
537 | "Version": "0.54",
538 | "Source": "Repository",
539 | "Repository": "CRAN",
540 | "Requirements": [
541 | "xfun"
542 | ],
543 | "Hash": "3ec7e3ddcacc2d34a9046941222bf94d"
544 | },
545 | "usethis": {
546 | "Package": "usethis",
547 | "Version": "3.0.0",
548 | "Source": "Repository",
549 | "Repository": "CRAN",
550 | "Requirements": [
551 | "R",
552 | "cli",
553 | "clipr",
554 | "crayon",
555 | "curl",
556 | "desc",
557 | "fs",
558 | "gert",
559 | "gh",
560 | "glue",
561 | "jsonlite",
562 | "lifecycle",
563 | "purrr",
564 | "rappdirs",
565 | "rlang",
566 | "rprojroot",
567 | "rstudioapi",
568 | "stats",
569 | "utils",
570 | "whisker",
571 | "withr",
572 | "yaml"
573 | ],
574 | "Hash": "b2fbf93c2127bedd2cbe9b799530d5d2"
575 | },
576 | "vctrs": {
577 | "Package": "vctrs",
578 | "Version": "0.6.5",
579 | "Source": "Repository",
580 | "Repository": "CRAN",
581 | "Requirements": [
582 | "R",
583 | "cli",
584 | "glue",
585 | "lifecycle",
586 | "rlang"
587 | ],
588 | "Hash": "c03fa420630029418f7e6da3667aac4a"
589 | },
590 | "whisker": {
591 | "Package": "whisker",
592 | "Version": "0.4.1",
593 | "Source": "Repository",
594 | "Repository": "CRAN",
595 | "Hash": "c6abfa47a46d281a7d5159d0a8891e88"
596 | },
597 | "withr": {
598 | "Package": "withr",
599 | "Version": "3.0.2",
600 | "Source": "Repository",
601 | "Repository": "CRAN",
602 | "Requirements": [
603 | "R",
604 | "grDevices",
605 | "graphics"
606 | ],
607 | "Hash": "cc2d62c76458d425210d1eb1478b30b4"
608 | },
609 | "xfun": {
610 | "Package": "xfun",
611 | "Version": "0.49",
612 | "Source": "Repository",
613 | "Repository": "CRAN",
614 | "Requirements": [
615 | "R",
616 | "grDevices",
617 | "stats",
618 | "tools"
619 | ],
620 | "Hash": "8687398773806cfff9401a2feca96298"
621 | },
622 | "yaml": {
623 | "Package": "yaml",
624 | "Version": "2.3.10",
625 | "Source": "Repository",
626 | "Repository": "CRAN",
627 | "Hash": "51dab85c6c98e50a18d7551e9d49f76c"
628 | },
629 | "zip": {
630 | "Package": "zip",
631 | "Version": "2.3.1",
632 | "Source": "Repository",
633 | "Repository": "CRAN",
634 | "Hash": "fcc4bd8e6da2d2011eb64a5e5cc685ab"
635 | }
636 | }
637 | }
638 |
--------------------------------------------------------------------------------
/renv/.gitignore:
--------------------------------------------------------------------------------
1 | library/
2 | local/
3 | cellar/
4 | lock/
5 | python/
6 | sandbox/
7 | staging/
8 |
--------------------------------------------------------------------------------
/renv/activate.R:
--------------------------------------------------------------------------------
1 |
2 | local({
3 |
4 | # the requested version of renv
5 | version <- "0.17.3"
6 |
7 | # the project directory
8 | project <- getwd()
9 |
10 | # figure out whether the autoloader is enabled
11 | enabled <- local({
12 |
13 | # first, check config option
14 | override <- getOption("renv.config.autoloader.enabled")
15 | if (!is.null(override))
16 | return(override)
17 |
18 | # next, check environment variables
19 | # TODO: prefer using the configuration one in the future
20 | envvars <- c(
21 | "RENV_CONFIG_AUTOLOADER_ENABLED",
22 | "RENV_AUTOLOADER_ENABLED",
23 | "RENV_ACTIVATE_PROJECT"
24 | )
25 |
26 | for (envvar in envvars) {
27 | envval <- Sys.getenv(envvar, unset = NA)
28 | if (!is.na(envval))
29 | return(tolower(envval) %in% c("true", "t", "1"))
30 | }
31 |
32 | # enable by default
33 | TRUE
34 |
35 | })
36 |
37 | if (!enabled)
38 | return(FALSE)
39 |
40 | # avoid recursion
41 | if (identical(getOption("renv.autoloader.running"), TRUE)) {
42 | warning("ignoring recursive attempt to run renv autoloader")
43 | return(invisible(TRUE))
44 | }
45 |
46 | # signal that we're loading renv during R startup
47 | options(renv.autoloader.running = TRUE)
48 | on.exit(options(renv.autoloader.running = NULL), add = TRUE)
49 |
50 | # signal that we've consented to use renv
51 | options(renv.consent = TRUE)
52 |
53 | # load the 'utils' package eagerly -- this ensures that renv shims, which
54 | # mask 'utils' packages, will come first on the search path
55 | library(utils, lib.loc = .Library)
56 |
57 | # unload renv if it's already been loaded
58 | if ("renv" %in% loadedNamespaces())
59 | unloadNamespace("renv")
60 |
61 | # load bootstrap tools
62 | `%||%` <- function(x, y) {
63 | if (is.environment(x) || length(x)) x else y
64 | }
65 |
66 | `%??%` <- function(x, y) {
67 | if (is.null(x)) y else x
68 | }
69 |
70 | bootstrap <- function(version, library) {
71 |
72 | # attempt to download renv
73 | tarball <- tryCatch(renv_bootstrap_download(version), error = identity)
74 | if (inherits(tarball, "error"))
75 | stop("failed to download renv ", version)
76 |
77 | # now attempt to install
78 | status <- tryCatch(renv_bootstrap_install(version, tarball, library), error = identity)
79 | if (inherits(status, "error"))
80 | stop("failed to install renv ", version)
81 |
82 | }
83 |
84 | renv_bootstrap_tests_running <- function() {
85 | getOption("renv.tests.running", default = FALSE)
86 | }
87 |
88 | renv_bootstrap_repos <- function() {
89 |
90 | # get CRAN repository
91 | cran <- getOption("renv.repos.cran", "https://cloud.r-project.org")
92 |
93 | # check for repos override
94 | repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA)
95 | if (!is.na(repos)) {
96 |
97 | # check for RSPM; if set, use a fallback repository for renv
98 | rspm <- Sys.getenv("RSPM", unset = NA)
99 | if (identical(rspm, repos))
100 | repos <- c(RSPM = rspm, CRAN = cran)
101 |
102 | return(repos)
103 |
104 | }
105 |
106 | # check for lockfile repositories
107 | repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity)
108 | if (!inherits(repos, "error") && length(repos))
109 | return(repos)
110 |
111 | # if we're testing, re-use the test repositories
112 | if (renv_bootstrap_tests_running()) {
113 | repos <- getOption("renv.tests.repos")
114 | if (!is.null(repos))
115 | return(repos)
116 | }
117 |
118 | # retrieve current repos
119 | repos <- getOption("repos")
120 |
121 | # ensure @CRAN@ entries are resolved
122 | repos[repos == "@CRAN@"] <- cran
123 |
124 | # add in renv.bootstrap.repos if set
125 | default <- c(FALLBACK = "https://cloud.r-project.org")
126 | extra <- getOption("renv.bootstrap.repos", default = default)
127 | repos <- c(repos, extra)
128 |
129 | # remove duplicates that might've snuck in
130 | dupes <- duplicated(repos) | duplicated(names(repos))
131 | repos[!dupes]
132 |
133 | }
134 |
135 | renv_bootstrap_repos_lockfile <- function() {
136 |
137 | lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock")
138 | if (!file.exists(lockpath))
139 | return(NULL)
140 |
141 | lockfile <- tryCatch(renv_json_read(lockpath), error = identity)
142 | if (inherits(lockfile, "error")) {
143 | warning(lockfile)
144 | return(NULL)
145 | }
146 |
147 | repos <- lockfile$R$Repositories
148 | if (length(repos) == 0)
149 | return(NULL)
150 |
151 | keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1))
152 | vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1))
153 | names(vals) <- keys
154 |
155 | return(vals)
156 |
157 | }
158 |
159 | renv_bootstrap_download <- function(version) {
160 |
161 | # if the renv version number has 4 components, assume it must
162 | # be retrieved via github
163 | nv <- numeric_version(version)
164 | components <- unclass(nv)[[1]]
165 |
166 | # if this appears to be a development version of 'renv', we'll
167 | # try to restore from github
168 | dev <- length(components) == 4L
169 |
170 | # begin collecting different methods for finding renv
171 | methods <- c(
172 | renv_bootstrap_download_tarball,
173 | if (dev)
174 | renv_bootstrap_download_github
175 | else c(
176 | renv_bootstrap_download_cran_latest,
177 | renv_bootstrap_download_cran_archive
178 | )
179 | )
180 |
181 | for (method in methods) {
182 | path <- tryCatch(method(version), error = identity)
183 | if (is.character(path) && file.exists(path))
184 | return(path)
185 | }
186 |
187 | stop("failed to download renv ", version)
188 |
189 | }
190 |
191 | renv_bootstrap_download_impl <- function(url, destfile) {
192 |
193 | mode <- "wb"
194 |
195 | # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715
196 | fixup <-
197 | Sys.info()[["sysname"]] == "Windows" &&
198 | substring(url, 1L, 5L) == "file:"
199 |
200 | if (fixup)
201 | mode <- "w+b"
202 |
203 | args <- list(
204 | url = url,
205 | destfile = destfile,
206 | mode = mode,
207 | quiet = TRUE
208 | )
209 |
210 | if ("headers" %in% names(formals(utils::download.file)))
211 | args$headers <- renv_bootstrap_download_custom_headers(url)
212 |
213 | do.call(utils::download.file, args)
214 |
215 | }
216 |
217 | renv_bootstrap_download_custom_headers <- function(url) {
218 |
219 | headers <- getOption("renv.download.headers")
220 | if (is.null(headers))
221 | return(character())
222 |
223 | if (!is.function(headers))
224 | stopf("'renv.download.headers' is not a function")
225 |
226 | headers <- headers(url)
227 | if (length(headers) == 0L)
228 | return(character())
229 |
230 | if (is.list(headers))
231 | headers <- unlist(headers, recursive = FALSE, use.names = TRUE)
232 |
233 | ok <-
234 | is.character(headers) &&
235 | is.character(names(headers)) &&
236 | all(nzchar(names(headers)))
237 |
238 | if (!ok)
239 | stop("invocation of 'renv.download.headers' did not return a named character vector")
240 |
241 | headers
242 |
243 | }
244 |
245 | renv_bootstrap_download_cran_latest <- function(version) {
246 |
247 | spec <- renv_bootstrap_download_cran_latest_find(version)
248 | type <- spec$type
249 | repos <- spec$repos
250 |
251 | message("* Downloading renv ", version, " ... ", appendLF = FALSE)
252 |
253 | baseurl <- utils::contrib.url(repos = repos, type = type)
254 | ext <- if (identical(type, "source"))
255 | ".tar.gz"
256 | else if (Sys.info()[["sysname"]] == "Windows")
257 | ".zip"
258 | else
259 | ".tgz"
260 | name <- sprintf("renv_%s%s", version, ext)
261 | url <- paste(baseurl, name, sep = "/")
262 |
263 | destfile <- file.path(tempdir(), name)
264 | status <- tryCatch(
265 | renv_bootstrap_download_impl(url, destfile),
266 | condition = identity
267 | )
268 |
269 | if (inherits(status, "condition")) {
270 | message("FAILED")
271 | return(FALSE)
272 | }
273 |
274 | # report success and return
275 | message("OK (downloaded ", type, ")")
276 | destfile
277 |
278 | }
279 |
280 | renv_bootstrap_download_cran_latest_find <- function(version) {
281 |
282 | # check whether binaries are supported on this system
283 | binary <-
284 | getOption("renv.bootstrap.binary", default = TRUE) &&
285 | !identical(.Platform$pkgType, "source") &&
286 | !identical(getOption("pkgType"), "source") &&
287 | Sys.info()[["sysname"]] %in% c("Darwin", "Windows")
288 |
289 | types <- c(if (binary) "binary", "source")
290 |
291 | # iterate over types + repositories
292 | for (type in types) {
293 | for (repos in renv_bootstrap_repos()) {
294 |
295 | # retrieve package database
296 | db <- tryCatch(
297 | as.data.frame(
298 | utils::available.packages(type = type, repos = repos),
299 | stringsAsFactors = FALSE
300 | ),
301 | error = identity
302 | )
303 |
304 | if (inherits(db, "error"))
305 | next
306 |
307 | # check for compatible entry
308 | entry <- db[db$Package %in% "renv" & db$Version %in% version, ]
309 | if (nrow(entry) == 0)
310 | next
311 |
312 | # found it; return spec to caller
313 | spec <- list(entry = entry, type = type, repos = repos)
314 | return(spec)
315 |
316 | }
317 | }
318 |
319 | # if we got here, we failed to find renv
320 | fmt <- "renv %s is not available from your declared package repositories"
321 | stop(sprintf(fmt, version))
322 |
323 | }
324 |
325 | renv_bootstrap_download_cran_archive <- function(version) {
326 |
327 | name <- sprintf("renv_%s.tar.gz", version)
328 | repos <- renv_bootstrap_repos()
329 | urls <- file.path(repos, "src/contrib/Archive/renv", name)
330 | destfile <- file.path(tempdir(), name)
331 |
332 | message("* Downloading renv ", version, " ... ", appendLF = FALSE)
333 |
334 | for (url in urls) {
335 |
336 | status <- tryCatch(
337 | renv_bootstrap_download_impl(url, destfile),
338 | condition = identity
339 | )
340 |
341 | if (identical(status, 0L)) {
342 | message("OK")
343 | return(destfile)
344 | }
345 |
346 | }
347 |
348 | message("FAILED")
349 | return(FALSE)
350 |
351 | }
352 |
353 | renv_bootstrap_download_tarball <- function(version) {
354 |
355 | # if the user has provided the path to a tarball via
356 | # an environment variable, then use it
357 | tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA)
358 | if (is.na(tarball))
359 | return()
360 |
361 | # allow directories
362 | if (dir.exists(tarball)) {
363 | name <- sprintf("renv_%s.tar.gz", version)
364 | tarball <- file.path(tarball, name)
365 | }
366 |
367 | # bail if it doesn't exist
368 | if (!file.exists(tarball)) {
369 |
370 | # let the user know we weren't able to honour their request
371 | fmt <- "* RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist."
372 | msg <- sprintf(fmt, tarball)
373 | warning(msg)
374 |
375 | # bail
376 | return()
377 |
378 | }
379 |
380 | fmt <- "* Bootstrapping with tarball at path '%s'."
381 | msg <- sprintf(fmt, tarball)
382 | message(msg)
383 |
384 | tarball
385 |
386 | }
387 |
388 | renv_bootstrap_download_github <- function(version) {
389 |
390 | enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE")
391 | if (!identical(enabled, "TRUE"))
392 | return(FALSE)
393 |
394 | # prepare download options
395 | pat <- Sys.getenv("GITHUB_PAT")
396 | if (nzchar(Sys.which("curl")) && nzchar(pat)) {
397 | fmt <- "--location --fail --header \"Authorization: token %s\""
398 | extra <- sprintf(fmt, pat)
399 | saved <- options("download.file.method", "download.file.extra")
400 | options(download.file.method = "curl", download.file.extra = extra)
401 | on.exit(do.call(base::options, saved), add = TRUE)
402 | } else if (nzchar(Sys.which("wget")) && nzchar(pat)) {
403 | fmt <- "--header=\"Authorization: token %s\""
404 | extra <- sprintf(fmt, pat)
405 | saved <- options("download.file.method", "download.file.extra")
406 | options(download.file.method = "wget", download.file.extra = extra)
407 | on.exit(do.call(base::options, saved), add = TRUE)
408 | }
409 |
410 | message("* Downloading renv ", version, " from GitHub ... ", appendLF = FALSE)
411 |
412 | url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version)
413 | name <- sprintf("renv_%s.tar.gz", version)
414 | destfile <- file.path(tempdir(), name)
415 |
416 | status <- tryCatch(
417 | renv_bootstrap_download_impl(url, destfile),
418 | condition = identity
419 | )
420 |
421 | if (!identical(status, 0L)) {
422 | message("FAILED")
423 | return(FALSE)
424 | }
425 |
426 | message("OK")
427 | return(destfile)
428 |
429 | }
430 |
431 | renv_bootstrap_install <- function(version, tarball, library) {
432 |
433 | # attempt to install it into project library
434 | message("* Installing renv ", version, " ... ", appendLF = FALSE)
435 | dir.create(library, showWarnings = FALSE, recursive = TRUE)
436 |
437 | # invoke using system2 so we can capture and report output
438 | bin <- R.home("bin")
439 | exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R"
440 | r <- file.path(bin, exe)
441 |
442 | args <- c(
443 | "--vanilla", "CMD", "INSTALL", "--no-multiarch",
444 | "-l", shQuote(path.expand(library)),
445 | shQuote(path.expand(tarball))
446 | )
447 |
448 | output <- system2(r, args, stdout = TRUE, stderr = TRUE)
449 | message("Done!")
450 |
451 | # check for successful install
452 | status <- attr(output, "status")
453 | if (is.numeric(status) && !identical(status, 0L)) {
454 | header <- "Error installing renv:"
455 | lines <- paste(rep.int("=", nchar(header)), collapse = "")
456 | text <- c(header, lines, output)
457 | writeLines(text, con = stderr())
458 | }
459 |
460 | status
461 |
462 | }
463 |
464 | renv_bootstrap_platform_prefix <- function() {
465 |
466 | # construct version prefix
467 | version <- paste(R.version$major, R.version$minor, sep = ".")
468 | prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-")
469 |
470 | # include SVN revision for development versions of R
471 | # (to avoid sharing platform-specific artefacts with released versions of R)
472 | devel <-
473 | identical(R.version[["status"]], "Under development (unstable)") ||
474 | identical(R.version[["nickname"]], "Unsuffered Consequences")
475 |
476 | if (devel)
477 | prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r")
478 |
479 | # build list of path components
480 | components <- c(prefix, R.version$platform)
481 |
482 | # include prefix if provided by user
483 | prefix <- renv_bootstrap_platform_prefix_impl()
484 | if (!is.na(prefix) && nzchar(prefix))
485 | components <- c(prefix, components)
486 |
487 | # build prefix
488 | paste(components, collapse = "/")
489 |
490 | }
491 |
492 | renv_bootstrap_platform_prefix_impl <- function() {
493 |
494 | # if an explicit prefix has been supplied, use it
495 | prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA)
496 | if (!is.na(prefix))
497 | return(prefix)
498 |
499 | # if the user has requested an automatic prefix, generate it
500 | auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA)
501 | if (auto %in% c("TRUE", "True", "true", "1"))
502 | return(renv_bootstrap_platform_prefix_auto())
503 |
504 | # empty string on failure
505 | ""
506 |
507 | }
508 |
509 | renv_bootstrap_platform_prefix_auto <- function() {
510 |
511 | prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity)
512 | if (inherits(prefix, "error") || prefix %in% "unknown") {
513 |
514 | msg <- paste(
515 | "failed to infer current operating system",
516 | "please file a bug report at https://github.com/rstudio/renv/issues",
517 | sep = "; "
518 | )
519 |
520 | warning(msg)
521 |
522 | }
523 |
524 | prefix
525 |
526 | }
527 |
528 | renv_bootstrap_platform_os <- function() {
529 |
530 | sysinfo <- Sys.info()
531 | sysname <- sysinfo[["sysname"]]
532 |
533 | # handle Windows + macOS up front
534 | if (sysname == "Windows")
535 | return("windows")
536 | else if (sysname == "Darwin")
537 | return("macos")
538 |
539 | # check for os-release files
540 | for (file in c("/etc/os-release", "/usr/lib/os-release"))
541 | if (file.exists(file))
542 | return(renv_bootstrap_platform_os_via_os_release(file, sysinfo))
543 |
544 | # check for redhat-release files
545 | if (file.exists("/etc/redhat-release"))
546 | return(renv_bootstrap_platform_os_via_redhat_release())
547 |
548 | "unknown"
549 |
550 | }
551 |
552 | renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) {
553 |
554 | # read /etc/os-release
555 | release <- utils::read.table(
556 | file = file,
557 | sep = "=",
558 | quote = c("\"", "'"),
559 | col.names = c("Key", "Value"),
560 | comment.char = "#",
561 | stringsAsFactors = FALSE
562 | )
563 |
564 | vars <- as.list(release$Value)
565 | names(vars) <- release$Key
566 |
567 | # get os name
568 | os <- tolower(sysinfo[["sysname"]])
569 |
570 | # read id
571 | id <- "unknown"
572 | for (field in c("ID", "ID_LIKE")) {
573 | if (field %in% names(vars) && nzchar(vars[[field]])) {
574 | id <- vars[[field]]
575 | break
576 | }
577 | }
578 |
579 | # read version
580 | version <- "unknown"
581 | for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) {
582 | if (field %in% names(vars) && nzchar(vars[[field]])) {
583 | version <- vars[[field]]
584 | break
585 | }
586 | }
587 |
588 | # join together
589 | paste(c(os, id, version), collapse = "-")
590 |
591 | }
592 |
593 | renv_bootstrap_platform_os_via_redhat_release <- function() {
594 |
595 | # read /etc/redhat-release
596 | contents <- readLines("/etc/redhat-release", warn = FALSE)
597 |
598 | # infer id
599 | id <- if (grepl("centos", contents, ignore.case = TRUE))
600 | "centos"
601 | else if (grepl("redhat", contents, ignore.case = TRUE))
602 | "redhat"
603 | else
604 | "unknown"
605 |
606 | # try to find a version component (very hacky)
607 | version <- "unknown"
608 |
609 | parts <- strsplit(contents, "[[:space:]]")[[1L]]
610 | for (part in parts) {
611 |
612 | nv <- tryCatch(numeric_version(part), error = identity)
613 | if (inherits(nv, "error"))
614 | next
615 |
616 | version <- nv[1, 1]
617 | break
618 |
619 | }
620 |
621 | paste(c("linux", id, version), collapse = "-")
622 |
623 | }
624 |
625 | renv_bootstrap_library_root_name <- function(project) {
626 |
627 | # use project name as-is if requested
628 | asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE")
629 | if (asis)
630 | return(basename(project))
631 |
632 | # otherwise, disambiguate based on project's path
633 | id <- substring(renv_bootstrap_hash_text(project), 1L, 8L)
634 | paste(basename(project), id, sep = "-")
635 |
636 | }
637 |
638 | renv_bootstrap_library_root <- function(project) {
639 |
640 | prefix <- renv_bootstrap_profile_prefix()
641 |
642 | path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA)
643 | if (!is.na(path))
644 | return(paste(c(path, prefix), collapse = "/"))
645 |
646 | path <- renv_bootstrap_library_root_impl(project)
647 | if (!is.null(path)) {
648 | name <- renv_bootstrap_library_root_name(project)
649 | return(paste(c(path, prefix, name), collapse = "/"))
650 | }
651 |
652 | renv_bootstrap_paths_renv("library", project = project)
653 |
654 | }
655 |
656 | renv_bootstrap_library_root_impl <- function(project) {
657 |
658 | root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA)
659 | if (!is.na(root))
660 | return(root)
661 |
662 | type <- renv_bootstrap_project_type(project)
663 | if (identical(type, "package")) {
664 | userdir <- renv_bootstrap_user_dir()
665 | return(file.path(userdir, "library"))
666 | }
667 |
668 | }
669 |
670 | renv_bootstrap_validate_version <- function(version) {
671 |
672 | loadedversion <- utils::packageDescription("renv", fields = "Version")
673 | if (version == loadedversion)
674 | return(TRUE)
675 |
676 | # assume four-component versions are from GitHub;
677 | # three-component versions are from CRAN
678 | components <- strsplit(loadedversion, "[.-]")[[1]]
679 | remote <- if (length(components) == 4L)
680 | paste("rstudio/renv", loadedversion, sep = "@")
681 | else
682 | paste("renv", loadedversion, sep = "@")
683 |
684 | fmt <- paste(
685 | "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.",
686 | "Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.",
687 | "Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.",
688 | sep = "\n"
689 | )
690 |
691 | msg <- sprintf(fmt, loadedversion, version, remote)
692 | warning(msg, call. = FALSE)
693 |
694 | FALSE
695 |
696 | }
697 |
698 | renv_bootstrap_hash_text <- function(text) {
699 |
700 | hashfile <- tempfile("renv-hash-")
701 | on.exit(unlink(hashfile), add = TRUE)
702 |
703 | writeLines(text, con = hashfile)
704 | tools::md5sum(hashfile)
705 |
706 | }
707 |
708 | renv_bootstrap_load <- function(project, libpath, version) {
709 |
710 | # try to load renv from the project library
711 | if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE))
712 | return(FALSE)
713 |
714 | # warn if the version of renv loaded does not match
715 | renv_bootstrap_validate_version(version)
716 |
717 | # execute renv load hooks, if any
718 | hooks <- getHook("renv::autoload")
719 | for (hook in hooks)
720 | if (is.function(hook))
721 | tryCatch(hook(), error = warning)
722 |
723 | # load the project
724 | renv::load(project)
725 |
726 | TRUE
727 |
728 | }
729 |
730 | renv_bootstrap_profile_load <- function(project) {
731 |
732 | # if RENV_PROFILE is already set, just use that
733 | profile <- Sys.getenv("RENV_PROFILE", unset = NA)
734 | if (!is.na(profile) && nzchar(profile))
735 | return(profile)
736 |
737 | # check for a profile file (nothing to do if it doesn't exist)
738 | path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project)
739 | if (!file.exists(path))
740 | return(NULL)
741 |
742 | # read the profile, and set it if it exists
743 | contents <- readLines(path, warn = FALSE)
744 | if (length(contents) == 0L)
745 | return(NULL)
746 |
747 | # set RENV_PROFILE
748 | profile <- contents[[1L]]
749 | if (!profile %in% c("", "default"))
750 | Sys.setenv(RENV_PROFILE = profile)
751 |
752 | profile
753 |
754 | }
755 |
756 | renv_bootstrap_profile_prefix <- function() {
757 | profile <- renv_bootstrap_profile_get()
758 | if (!is.null(profile))
759 | return(file.path("profiles", profile, "renv"))
760 | }
761 |
762 | renv_bootstrap_profile_get <- function() {
763 | profile <- Sys.getenv("RENV_PROFILE", unset = "")
764 | renv_bootstrap_profile_normalize(profile)
765 | }
766 |
767 | renv_bootstrap_profile_set <- function(profile) {
768 | profile <- renv_bootstrap_profile_normalize(profile)
769 | if (is.null(profile))
770 | Sys.unsetenv("RENV_PROFILE")
771 | else
772 | Sys.setenv(RENV_PROFILE = profile)
773 | }
774 |
775 | renv_bootstrap_profile_normalize <- function(profile) {
776 |
777 | if (is.null(profile) || profile %in% c("", "default"))
778 | return(NULL)
779 |
780 | profile
781 |
782 | }
783 |
784 | renv_bootstrap_path_absolute <- function(path) {
785 |
786 | substr(path, 1L, 1L) %in% c("~", "/", "\\") || (
787 | substr(path, 1L, 1L) %in% c(letters, LETTERS) &&
788 | substr(path, 2L, 3L) %in% c(":/", ":\\")
789 | )
790 |
791 | }
792 |
793 | renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) {
794 | renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv")
795 | root <- if (renv_bootstrap_path_absolute(renv)) NULL else project
796 | prefix <- if (profile) renv_bootstrap_profile_prefix()
797 | components <- c(root, renv, prefix, ...)
798 | paste(components, collapse = "/")
799 | }
800 |
801 | renv_bootstrap_project_type <- function(path) {
802 |
803 | descpath <- file.path(path, "DESCRIPTION")
804 | if (!file.exists(descpath))
805 | return("unknown")
806 |
807 | desc <- tryCatch(
808 | read.dcf(descpath, all = TRUE),
809 | error = identity
810 | )
811 |
812 | if (inherits(desc, "error"))
813 | return("unknown")
814 |
815 | type <- desc$Type
816 | if (!is.null(type))
817 | return(tolower(type))
818 |
819 | package <- desc$Package
820 | if (!is.null(package))
821 | return("package")
822 |
823 | "unknown"
824 |
825 | }
826 |
827 | renv_bootstrap_user_dir <- function() {
828 | dir <- renv_bootstrap_user_dir_impl()
829 | path.expand(chartr("\\", "/", dir))
830 | }
831 |
832 | renv_bootstrap_user_dir_impl <- function() {
833 |
834 | # use local override if set
835 | override <- getOption("renv.userdir.override")
836 | if (!is.null(override))
837 | return(override)
838 |
839 | # use R_user_dir if available
840 | tools <- asNamespace("tools")
841 | if (is.function(tools$R_user_dir))
842 | return(tools$R_user_dir("renv", "cache"))
843 |
844 | # try using our own backfill for older versions of R
845 | envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME")
846 | for (envvar in envvars) {
847 | root <- Sys.getenv(envvar, unset = NA)
848 | if (!is.na(root))
849 | return(file.path(root, "R/renv"))
850 | }
851 |
852 | # use platform-specific default fallbacks
853 | if (Sys.info()[["sysname"]] == "Windows")
854 | file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv")
855 | else if (Sys.info()[["sysname"]] == "Darwin")
856 | "~/Library/Caches/org.R-project.R/R/renv"
857 | else
858 | "~/.cache/R/renv"
859 |
860 | }
861 |
862 |
863 | renv_json_read <- function(file = NULL, text = NULL) {
864 |
865 | jlerr <- NULL
866 |
867 | # if jsonlite is loaded, use that instead
868 | if ("jsonlite" %in% loadedNamespaces()) {
869 |
870 | json <- catch(renv_json_read_jsonlite(file, text))
871 | if (!inherits(json, "error"))
872 | return(json)
873 |
874 | jlerr <- json
875 |
876 | }
877 |
878 | # otherwise, fall back to the default JSON reader
879 | json <- catch(renv_json_read_default(file, text))
880 | if (!inherits(json, "error"))
881 | return(json)
882 |
883 | # report an error
884 | if (!is.null(jlerr))
885 | stop(jlerr)
886 | else
887 | stop(json)
888 |
889 | }
890 |
891 | renv_json_read_jsonlite <- function(file = NULL, text = NULL) {
892 | text <- paste(text %||% read(file), collapse = "\n")
893 | jsonlite::fromJSON(txt = text, simplifyVector = FALSE)
894 | }
895 |
896 | renv_json_read_default <- function(file = NULL, text = NULL) {
897 |
898 | # find strings in the JSON
899 | text <- paste(text %||% read(file), collapse = "\n")
900 | pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
901 | locs <- gregexpr(pattern, text, perl = TRUE)[[1]]
902 |
903 | # if any are found, replace them with placeholders
904 | replaced <- text
905 | strings <- character()
906 | replacements <- character()
907 |
908 | if (!identical(c(locs), -1L)) {
909 |
910 | # get the string values
911 | starts <- locs
912 | ends <- locs + attr(locs, "match.length") - 1L
913 | strings <- substring(text, starts, ends)
914 |
915 | # only keep those requiring escaping
916 | strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE)
917 |
918 | # compute replacements
919 | replacements <- sprintf('"\032%i\032"', seq_along(strings))
920 |
921 | # replace the strings
922 | mapply(function(string, replacement) {
923 | replaced <<- sub(string, replacement, replaced, fixed = TRUE)
924 | }, strings, replacements)
925 |
926 | }
927 |
928 | # transform the JSON into something the R parser understands
929 | transformed <- replaced
930 | transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE)
931 | transformed <- gsub("[[{]", "list(", transformed, perl = TRUE)
932 | transformed <- gsub("[]}]", ")", transformed, perl = TRUE)
933 | transformed <- gsub(":", "=", transformed, fixed = TRUE)
934 | text <- paste(transformed, collapse = "\n")
935 |
936 | # parse it
937 | json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]]
938 |
939 | # construct map between source strings, replaced strings
940 | map <- as.character(parse(text = strings))
941 | names(map) <- as.character(parse(text = replacements))
942 |
943 | # convert to list
944 | map <- as.list(map)
945 |
946 | # remap strings in object
947 | remapped <- renv_json_remap(json, map)
948 |
949 | # evaluate
950 | eval(remapped, envir = baseenv())
951 |
952 | }
953 |
954 | renv_json_remap <- function(json, map) {
955 |
956 | # fix names
957 | if (!is.null(names(json))) {
958 | lhs <- match(names(json), names(map), nomatch = 0L)
959 | rhs <- match(names(map), names(json), nomatch = 0L)
960 | names(json)[rhs] <- map[lhs]
961 | }
962 |
963 | # fix values
964 | if (is.character(json))
965 | return(map[[json]] %||% json)
966 |
967 | # handle true, false, null
968 | if (is.name(json)) {
969 | text <- as.character(json)
970 | if (text == "true")
971 | return(TRUE)
972 | else if (text == "false")
973 | return(FALSE)
974 | else if (text == "null")
975 | return(NULL)
976 | }
977 |
978 | # recurse
979 | if (is.recursive(json)) {
980 | for (i in seq_along(json)) {
981 | json[i] <- list(renv_json_remap(json[[i]], map))
982 | }
983 | }
984 |
985 | json
986 |
987 | }
988 |
989 | # load the renv profile, if any
990 | renv_bootstrap_profile_load(project)
991 |
992 | # construct path to library root
993 | root <- renv_bootstrap_library_root(project)
994 |
995 | # construct library prefix for platform
996 | prefix <- renv_bootstrap_platform_prefix()
997 |
998 | # construct full libpath
999 | libpath <- file.path(root, prefix)
1000 |
1001 | # attempt to load
1002 | if (renv_bootstrap_load(project, libpath, version))
1003 | return(TRUE)
1004 |
1005 | # load failed; inform user we're about to bootstrap
1006 | prefix <- paste("# Bootstrapping renv", version)
1007 | postfix <- paste(rep.int("-", 77L - nchar(prefix)), collapse = "")
1008 | header <- paste(prefix, postfix)
1009 | message(header)
1010 |
1011 | # perform bootstrap
1012 | bootstrap(version, libpath)
1013 |
1014 | # exit early if we're just testing bootstrap
1015 | if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA)))
1016 | return(TRUE)
1017 |
1018 | # try again to load
1019 | if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) {
1020 | message("* Successfully installed and loaded renv ", version, ".")
1021 | return(renv::load())
1022 | }
1023 |
1024 | # failed to download or load renv; warn the user
1025 | msg <- c(
1026 | "Failed to find an renv installation: the project will not be loaded.",
1027 | "Use `renv::activate()` to re-initialize the project."
1028 | )
1029 |
1030 | warning(paste(msg, collapse = "\n"), call. = FALSE)
1031 |
1032 | })
1033 |
--------------------------------------------------------------------------------
/renv/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "bioconductor.version": null,
3 | "external.libraries": [],
4 | "ignored.packages": [],
5 | "package.dependency.fields": [
6 | "Imports",
7 | "Depends",
8 | "LinkingTo"
9 | ],
10 | "r.version": null,
11 | "snapshot.type": "implicit",
12 | "use.cache": true,
13 | "vcs.ignore.cellar": true,
14 | "vcs.ignore.library": true,
15 | "vcs.ignore.local": true,
16 | "vcs.manage.ignores": true
17 | }
18 |
--------------------------------------------------------------------------------
/session-break-slide.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - Break"
4 | execute:
5 | echo: false
6 | eval: true
7 | ---
8 |
9 | ```{r}
10 | #| label: "libs"
11 | #| include: false
12 | #| eval: true
13 | #| echo: false
14 | library(countdown)
15 | ```
16 |
17 | ```{r}
18 | countdown::countdown(minutes = 10,
19 | color_border = "#005EB8",
20 | color_text = "#005EB8",
21 | color_running_text = "white",
22 | color_running_background = "#005EB8",
23 | color_finished_text = "#005EB8",
24 | color_finished_background = "white",
25 | margin = "0.9em",
26 | font_size = "2em")
27 | ```
28 |
29 |
--------------------------------------------------------------------------------
/session-commit-main.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - Commit to main (and undo last commit!)"
4 | ---
5 |
6 | ## Not recommended, but sometimes useful
7 |
8 | The `pr_*` functions all relate to Pull Requests but it is possible to commit to main directly
9 |
10 | Commit work using
11 |
12 | ```{r}
13 | gert::git_commit_all("This is a message")
14 |
15 | # or
16 |
17 | gert::git_add("file.qmd")
18 | gert::git_commit("This is a message")
19 |
20 | ```
21 |
22 | and then use the `Push` button in the Git RStudio pane
23 |
24 | ## Accidental commits!
25 |
26 | If you commit by accident to any branch, but particularly `main`, you can undo the last commit
27 |
28 | In fact, you can undo any number of last commits!
29 |
30 | This has to be done in the `Terminal` though ($)!
31 |
32 | ```{bash}
33 | git reset --soft HEAD~1
34 | ```
35 |
36 | :::{.callout-warning collapse=false appearance='default' icon=true}
37 | ## Resetting doesn't delete
38 | Be careful if you are trying to undo something sensitive, a reset is not a deletion
39 | :::
40 |
41 | ## Moving changes from one branch to another
42 |
43 | What if you've made a few changes that you want to keep but committed to `main`?
44 |
45 | - In RStudio create a new branch (which will have all the changes)
46 | - Return to `main`
47 | - Use the `terminal` to reset the commits you don't want
48 |
49 | ## End session
50 |
--------------------------------------------------------------------------------
/session-conflict.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - Conflicts!"
4 | ---
5 |
6 | ## Conflicts!
7 |
8 | Conflicts can happen when you merge a branch and can occur when working with others, or even yourself!
9 |
10 | Let's create a conflict...
11 |
12 | ## Your Turn
13 |
14 | 1. `usethis::pr_init("author_change")`
15 | 2. Replace the author in the Quarto YAML with `author: Person A` and Render
16 | 3. `gert::git_commit_all("Added Person A as author")`
17 | 4. `usethis::pr_push()`
18 | 5. In GitHub create a pull request to `main` using `Merge pull request` and do the merge
19 |
20 | ::: {.callout-warning collapse="false" appearance="default" icon="true"}
21 | ## Not pulling from `main`
22 |
23 | We'll miss the `pr_finish()` part because this function reduces the possibility of conflict as it `pulls` changes made on `main`
24 | :::
25 |
26 | ## Together we will...
27 |
28 | ... create another branch in RStudio, not {usethis}, as we miss the steps that reduce conflicts:
29 |
30 | 1. Go to the `main` branch using the RStudio Git pane
31 | 2. Create a branch in that pane using the button next to `person-b`
32 | 3. Replace the author in the Quarto YAML with `author: Person B` and Render
33 | 4. Tick the box next to the file and commit using the Git pane in RStudio
34 | 5. Push the changes using RStudio Git pane (the button is not greyed out)
35 | 6. In GitHub create a pull request to `main` using `Merge pull request` and do the merge
36 |
37 | ## Conflict in GitHub!
38 |
39 | {fig-alt="Screenshot of GitHub merge conflict with the Resolve Conflict grey section of the Pull Request"}
40 |
41 | ## Looking for the symbols
42 |
43 | To resolve the conflict we need to edit (in this case delete) one of the names and also delete all the merge text:
44 |
45 | ``` markdown
46 | <<<<<< person-b
47 | =======
48 | >>>>>> main
49 | ```
50 | This can be done in GitHub and ends with a new commit.
51 |
52 | ## Seeing the conflict locally
53 |
54 | To see the same conflicted files locally:
55 |
56 | 1. On the branch with the conflict (`person-b`)
57 | 1. Go to the `Console` ($) and type `usethis::pr_merge_main()`
58 |
59 | . . .
60 |
61 | ```markdown
62 | ✔ Pushing local 'author_change' branch to 'origin/author_change'.
63 | • Create PR at link given below
64 | ✔ Opening URL 'https://github.com/Letxuga007/project/compare/author_change'
65 | > usethis::pr_merge_main()
66 | ✔ Pulling changes from 'origin/main'.
67 | Merge has resulted in merge conflict(s).
68 | There are 1 conflicted files:
69 | * 'my_report.qmd'
70 | Are you ready to sort this out?
71 | If so, we will open the conflicted files for you to edit.
72 |
73 | 1: Yes, I'm ready to resolve the merge conflicts.
74 | 2: No, I want to abort this merge.
75 |
76 | Selection:
77 | ```
78 |
79 | ## End session
80 |
--------------------------------------------------------------------------------
/session-fork-clone.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - Getting copies of existing repositories (fork and clone)"
4 | ---
5 |
6 | ## Existing repositories
7 |
8 | All this course has been about you creating a new repository but what about collaboration with existing projects?
9 |
10 | ::: incremental
11 | - your own repository on a new computer (clone)
12 | - a repository from your team which you are a member (clone)
13 | - a repository from someone or somewhere that you don't have rights to change (fork)
14 | :::
15 |
16 | . . .
17 |
18 | ```{r}
19 | usethis::create_from_github(repo_spec = "nhs-r-community/r4ds-ed2-exercise-solutions")
20 | ```
21 |
22 | ::: {.callout-warning collapse="false" appearance="default" icon="true"}
23 | ## Cloud specific folder structure
24 |
25 | On Posit Cloud the project gets saved in \`Cloud\> home \> r99999 (similar) \> r4ds-ed2-exercise-solutions
26 | :::
27 |
28 | ## The benefits of {usethis}
29 |
30 | Using the function `create_from_github()` means that it:
31 |
32 | - Automatically checks if this would be a clone or a fork!
33 | - Automatically goes to the main working directory, mine is in `C:/Users/zoe.turner`
34 | - Opens up a new RStudio session
35 |
36 | ## Clone (access) and Fork (no access)
37 |
38 | Cloned message:
39 |
40 | ``` markdown
41 | ✔ Setting `fork = FALSE`
42 | ✔ Creating 'C:/Users/zoe.turner/r4ds-ed2-exercise-solutions/'
43 | ✔ Cloning repo from 'https://github.com/nhs-r-community/r4ds-ed2-exercise-solutions.git' into 'C:/Users/zoe.turner/r4ds-ed2-exercise-solutions'
44 | ✔ Setting active project to 'C:/Users/zoe.turner/r4ds-ed2-exercise-solutions'
45 | ℹ Default branch is 'main'
46 | ✔ Opening 'C:/Users/zoe.turner/r4ds-ed2-exercise-solutions/' in new RStudio session
47 | ✔ Setting active project to ''
48 | ```
49 |
50 | . . .
51 |
52 | Forked message (will also appear in your GitHub):
53 |
54 | ``` markdown
55 | ✔ Setting `fork = TRUE`
56 | ✔ Creating 'C:/Users/zoe.turner/nhspy-plotthedots/'
57 | ✔ Forking 'nhs-pycom/nhspy-plotthedots'
58 | ✔ Waiting for the fork to finalize before cloning
59 | ✔ Cloning repo from 'https://github.com/Lextuga007/nhspy-plotthedots.git' into 'C:/Users/zoe.turner/nhspy-plotthedots'
60 | ✔ Setting active project to 'C:/Users/zoe.turner/nhspy-plotthedots'
61 | ℹ Default branch is 'main'
62 | ✔ Adding 'upstream' remote: 'https://github.com/nhs-pycom/nhspy-plotthedots.git'
63 | ✔ Pulling changes from 'upstream/main'.
64 | ✔ Setting remote tracking branch for local 'main' branch to 'upstream/main'
65 | ✔ Writing 'nhspy-plotthedots.Rproj'
66 | ✔ Adding '.Rproj.user' to '.gitignore'
67 | ✔ Opening 'C:/Users/zoe.turner/nhspy-plotthedots/' in new RStudio session
68 | ✔ Setting active project to ''
69 | ```
70 |
71 | ## Alternatives - Cloning in GitHub
72 |
73 | Select the green button for `<> Code` and it will give you an option to clone
74 |
75 | This course has used `https` and the copy button to the right takes the whole code
76 |
77 | {fig-alt="Screenshot of the GitHub code menu extended to see the Clone, Open with GitHub Desktop and Download ZIP options"}
78 |
79 | ## Forking in GitHub - then needs Cloning!
80 |
81 | `Fork` to your own repository and then `Clone` from there to your computer:
82 |
83 | {fig-alt="Screenshot of GitHub with the Fork link highlighted"}
84 |
85 | ## In RStudio
86 |
87 | With the copied HTTPS url, in RStudio you will need to start a new Project and use the third option (possibly ignored until now!) for versioning:
88 |
89 | {fig-alt="Screenshot of the 3 options wizard in RStudio for creating a new project"}
90 |
91 | ::: {.callout-warning collapse="false" appearance="default" icon="true"}
92 | ## Posit Cloud is already a project!
93 |
94 | - Creating a project on the Cloud isn't possible because **it is** a project
95 | - Even in RStudio it's not possible to put a project in another project.
96 | :::
97 |
98 | ## End session
99 |
--------------------------------------------------------------------------------
/session-intro.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - Introduction"
4 | execute:
5 | echo: false
6 | ---
7 |
8 | ## Opinionated Course Aims
9 |
10 | ::: incremental
11 | - To set up Git and GitHub using R and RStudio
12 | - To practice a few workflows scenarios (but not all)
13 | - To reassure that mistakes will happen and that's a feature of Git
14 | - [Turn around your Git mistakes in 17 ways](https://dev.to/smitterhane/turn-around-your-git-mistakes-in-17-ways-2mn1)
15 | The following **comes with a language warning!**
16 | - [Oh Shit, Git!?!](https://ohshitgit.com/)
17 | :::
18 |
19 | ## Agenda - session one (about 3.5 hours)
20 |
21 | Chapter overview
22 |
23 | ::: {.fragment .fade-in}
24 | Check prework set up and Introduction
25 | :::
26 |
27 | ::: {.fragment .fade-in}
28 | Setting up
29 | :::
30 |
31 | ::: {.fragment .fade-in}
32 | --------- Break -----------
33 | :::
34 |
35 | ::: {.fragment .fade-in}
36 | Version Control
37 | :::
38 |
39 | ::: {.fragment .fade-in}
40 |
41 | Workflow
42 | :::
43 |
44 | ::: {.fragment .fade-in}
45 | --------- Course end -----------
46 | :::
47 |
48 |
49 | ## Agenda - session two (about 3.5 hours)
50 |
51 | Chapter overview
52 |
53 | ::: {.fragment .fade-in}
54 | Useing R packages {gert} and {usethis}
55 | :::
56 |
57 | ::: {.fragment .fade-in}
58 | Merge conflict!
59 | :::
60 |
61 | ::: {.fragment .fade-in}
62 | --------- Break -----------
63 | :::
64 |
65 | ::: {.fragment .fade-in}
66 | Commit to main (and undo last commit!)
67 | :::
68 |
69 | ::: {.fragment .fade-in}
70 | Undo last merge
71 | :::
72 |
73 | ::: {.fragment .fade-in}
74 | --------- Course end ---------
75 | :::
76 |
77 |
78 | ## This is not a definitive course
79 |
80 | ::: incremental
81 | - Like learning anything, you don't get "everything" all at once
82 | - There are many workflows that are possible but we can only learn a few in this workshop
83 | - This will get you started!
84 | :::
85 |
86 | ## End session
87 |
--------------------------------------------------------------------------------
/session-prework.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - Prework for a computer"
4 | ---
5 |
6 | ## Check Git
7 |
8 | Check if Git is already installed. Run the following in the *Terminal* (not the RStudio Console!)
9 |
10 | ```
11 | which git
12 | ```
13 |
14 | Check the version of your Git
15 |
16 | ```
17 | git --version
18 | ```
19 |
20 | If asked to install the Xcode command line tools, say yes!
21 | Right click to copy on a Terminal line
22 |
23 | ## Downloading Git
24 |
25 | - Download the installer from [https://git-scm.com/downloads](https://git-scm.com/downloads)
26 | - Run keeping all the default settings.
27 |
28 | :::{.callout-note collapse=false appearance='default' icon=true}
29 | ## Installer hangs at 100%
30 |
31 | If the installer hangs with the progress bar at 100%, close the installer with Task Manager (press `Ctrl + Alt + Delete`;
32 | select Task Manager;
33 | find Git for Windows installer and close).
34 | :::
35 |
36 |
37 | ## Connecting RStudio to Git
38 |
39 | - Open RStudio
40 | - In the menus go to `Tools > Global Options > Git/SVN`
41 | - Check RStudio has found Git under "Git executable:"
42 |
43 | You may need to click `Browse` and find the Git executable
44 |
45 | :::{.callout-note collapse=false appearance='default' icon=true}
46 | ## Where to find the git.exe
47 | It may be under `C:\Users\username\AppData\Local\Programs\Git\` - remember if file extensions are hidden it will show as git rather than git.exe.
48 | Restart RStudio before trying to use git.
49 | :::
50 |
51 |
52 | ## GitHub
53 |
54 | Register a GitHub account at [github.com](https://github.com/).
55 |
56 | - Suggest to incorporate your actual name/reuse your username from other contexts (like Social Media)
57 | - Pick a username you will be comfortable revealing to your boss
58 | - Shorter is better
59 | - Be as unique as possible in as few characters as possible
60 | - Make it timeless
61 | - Avoid words laden with special meaning in programming
62 | - Use all lower case letters
63 |
64 | ## Think about security
65 |
66 | Particularly for GitHub and your own account safety
67 |
68 | Set up [2FA (two-factor authentication)](https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication) using an app or save the generated code
69 |
70 | ## Install packages
71 |
72 | The following packages are required for the course:
73 |
74 | ```{r}
75 | install.packages("gert")
76 | install.packages("usethis")
77 | install.packages("gitcreds")
78 | ```
79 |
80 |
81 | ## End session
82 |
83 | # Acknowledgements
84 |
85 | These slides were designed by Mine Çetinkaya-Rundel and Emma Rand for the Forwards Package development module course
86 |
87 | [Your first package](https://forwards.github.io/workshops/package-dev-modules/slides/03-your-first-package/your-first-package.html#1) and
88 | [Setting up your system](https://forwards.github.io/workshops/package-dev-modules/slides/02-setting-up-system/setting-up-system.html#1)
--------------------------------------------------------------------------------
/session-pull-requests.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - Pull Requests"
4 | ---
5 |
6 | ## Pushing to the remote (GitHub)
7 |
8 | We want to `push` the copy branch to GitHub, make a `pull request` to `merge` into main
9 |
10 | ```{r}
11 | usethis::pr_push()
12 | ```
13 |
14 | This open the pull request in GitHub/a browser, select the `Create Pull Request` button
15 |
16 | ::: {.callout-note collapse="false" appearance="default" icon="true"}
17 | ## Draft pull requests
18 |
19 | - For public repositories it's possible to change the pull request to a draft.
20 | - In GitHub click on the down arrow on the green button for `Create pull request` and select Draft
21 | - Click the green button again to make the pull request
22 | :::
23 |
24 | ## Extra unnecessary step?
25 |
26 | ::: incremental
27 | - Creating a pull request to the `main` branch can be seen as an extra step, particularly when you are working alone
28 | - But if you are working with others or the main is a *clean* working branch you need to protect it
29 | - Pull requests will be where your *merge conflicts* will be highlighted
30 | - People can see you are working on things
31 | - You have a remote copy of your work if anything were to happen to your local computer!
32 | - Reverting (undoing) a pull request is really easy in GitHub, even more so if you have a lot of commits
33 | :::
34 |
35 | ## Options to merge - default
36 |
37 | There are three options the default being
38 |
39 | `Create a merge commit` creates a new `merge commit` which isn't very descriptive in the name
40 |
41 | > Merge pull request #1 from Letxuga007/new_work
42 |
43 | but is recommended as an easier way to debug for when things get muddled
44 |
45 | ## Squashing
46 |
47 | `Squash and merge` details multiple commits in one
48 |
49 | > New work (#1) \* First commit for quarto document \* Removed author
50 |
51 | which is a nice way to keep all the commit messages but messages can get long
52 |
53 | ::: {.callout-tip collapse="false" appearance="default" icon="true"}
54 | ## Squashing
55 |
56 | - Atomic committing is a practice in Git versioning where each distinct step is committed
57 | - Squashing is only used in this this practice if things are very closely related:\
58 | \# updated titles\
59 | \# renamed titles\
60 | \# correct spelling in title
61 | :::
62 |
63 | ## Rebase
64 |
65 | `Rebase and merge` keeps all the commits as you created them in a linear way
66 |
67 | The history is more readable but can be tougher to resolve conflicts
68 |
69 | 
70 |
71 | ::: notes
72 | When to use merge versus rebase https://www.gitkraken.com/learn/git/problems/git-rebase-vs-merge
73 |
74 | Rebase seems to be incredibly useful if there are many people working on a project and can see the branches in a visual way. GitHub only presents commits in a linear way anyway so this may not be necessary for many analytical type repositories.
75 | :::
76 |
77 | ## Let's pause!
78 |
79 | Sometimes you need to go back to `main` to get changes from colleagues or create a new branch:
80 |
81 | ```{r}
82 | usethis::pr_pause()
83 | ```
84 |
85 | This does a few things
86 |
87 | ``` markdown
88 | ✔ Setting active project to '/cloud/project'
89 | ✔ Switching back to the default branch.
90 | ✔ Checking that local branch 'new_work' has the changes in 'origin/new_work'
91 | ✔ Switching back to default branch ('main').
92 | ✔ Pulling changes from 'origin/main'
93 | ```
94 |
95 | ## Resuming your PR
96 |
97 | First find the PR to work on:
98 |
99 | ```{r}
100 | usethis::pr_fetch()
101 | ```
102 |
103 | Gives you details of what is open as a PR:
104 |
105 | ``` markdown
106 | ✔ Setting active project to '/cloud/project'
107 | ℹ No PR specified ... looking up open PRs.
108 | Which PR are you interested in? (0 to exit)
109 |
110 | 1: #1 (@Letxuga007): 'New work'
111 | ```
112 |
113 | . . .
114 |
115 | To resume then select the number or if you know the PR before then
116 |
117 | ```{r}
118 | usethis::pr_fetch(1)
119 | ```
120 |
121 | ## Finish with the PR
122 |
123 | - If the PR is set to Draft then, in GitHub, set to review
124 | - If the PR was not a Draf the button `Merge pull request` will be available straight away
125 | - Return to RStudio and type
126 |
127 | ```{r}
128 | usethis::pr_finish()
129 | ```
130 |
131 | Several things gets tidied up all in one function
132 |
133 | . . .
134 |
135 | ``` markdown
136 | ✔ Switching back to default branch ('main').
137 | ✔ Pulling changes from 'origin/main'
138 | ✔ Deleting local 'new_work' branch.
139 | ✔ PR 'Letxuga007/project/#1' has been merged, deleting remote branch 'origin/new_work'
140 | ```
141 | ## You might want to discard a PR
142 |
143 | If you are working on something and change your mind
144 |
145 | ```{r}
146 | usethis::pr_forget()
147 | ```
148 |
149 | when in the branch you want to discard:
150 |
151 | ```markdown
152 | ✔ Switching back to default branch ('main').
153 | ✔ Pulling changes from 'origin/main'
154 | ✔ Deleting local 'mistake-branch' branch.
155 | ```
156 |
157 | :::{.callout-note collapse=false appearance='default' icon=true}
158 | ## PR needs to be tidied in GitHub
159 | - Because local is different to remote you will need to close any PR on GitHub
160 | :::
161 |
162 | ## Local and remote branches
163 |
164 | Local and Remote branches are distinct things so although `new_work` branch has been deleted and the remote has been merged, the connection in RStudio remains
165 |
166 | {fig-alt="Screenshot of the drop down of branches in the RStudio git pane where under the greyed out (REMOTE: ORIGIN) new_work can be seen"}
167 |
168 | To tidy, in the Terminal type:
169 |
170 | ```{bash}
171 | git remote prune origin
172 | ```
173 |
174 | ## End session
175 |
176 | ## Acknowledgements
177 |
178 | [Happy Git and GitHub](https://happygitwithr.com/) for the useR by Jenny Bryan
179 |
180 | [Pull Request Flow with usethis](https://www.garrickadenbuie.com/blog/pull-request-flow-usethis/?interactive=) by Garrick Aden-Buie
181 |
182 | ## End session
183 |
184 | ## Acknowledgements
185 |
186 | [Happy Git and GitHub](https://happygitwithr.com/) for the useR by Jenny Bryan
187 |
188 | [Pull Request Flow with usethis](https://www.garrickadenbuie.com/blog/pull-request-flow-usethis/?interactive=) by Garrick Aden-Buie
189 |
--------------------------------------------------------------------------------
/session-setup.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - Getting started with Git and GitHub"
4 | ---
5 |
6 | ## Configure Git
7 |
8 | Configure `user.name` and `user.email`
9 |
10 | ```{r}
11 | library(usethis)
12 | usethis::use_git_config(
13 | user.name = "github_name", # Make sure this matches your GitHub account
14 | user.email = "jane@example.com" # Use the email associated with GitHub account
15 | )
16 | ```
17 |
18 | ## Check Git configuration
19 |
20 | Ask for a **sit**uation **rep**ort.
21 |
22 | ```{r}
23 | usethis::git_sitrep()
24 | ```
25 |
26 | A lot of information will appear in the RStudio Console!
27 |
28 | . . .
29 |
30 | ```
31 | Git config (global)
32 | • Name:
33 | • Email:
34 | • Global (user-level) gitignore file:
35 | • Vaccinated: FALSE
36 | ℹ See `?git_vaccinate` to learn more
37 | ℹ Defaulting to 'https' Git protocol
38 | • Default Git protocol: 'https'
39 | • Default initial branch name:
40 | GitHub
41 | • Default GitHub host: 'https://github.com'
42 | • Personal access token for 'https://github.com':
43 | • To create a personal access token, call `create_github_token()`
44 | • To store a token for current and future use, call `gitcreds::gitcreds_set()`
45 | ℹ Read more in the 'Managing Git(Hub) Credentials' article:
46 | https://usethis.r-lib.org/articles/articles/git-credentials.html
47 | Git repo for current project
48 | • Active usethis project: '/cloud/project'
49 | ℹ Active project is not a Git repo
50 | ```
51 |
52 | ## Vaccinate
53 |
54 | ```{r}
55 | usethis::git_vaccinate()
56 | ```
57 |
58 | . . .
59 |
60 | Adds .DS_Store, .Rproj.user, .Rdata, .Rhistory, and .httr-oauth to your global (a.k.a. user-level) .gitignore. This is good practice as it decreases the chance that you will accidentally leak credentials to GitHub. git_vaccinate() also tries to detect and fix the situation where you have a global gitignore file, but it's missing from your global Git config.
61 |
62 | ## Personal access token
63 |
64 | - Communicating with GitHub will require authentication
65 |
66 | - Instead of typing in your username and password each time, use a **PAT** (personal access token)
67 |
68 | ## Create a PAT
69 |
70 | - To amend/delete existing tokens go to: [https://github.com/settings/tokens](https://github.com/settings/tokens)
71 | - Give the token a descriptive name like `connect-posit-github`
72 | - Copy and also store this token somewhere (you won't be able to see it again!)
73 |
74 | ```{r}
75 | usethis::create_github_token()
76 | ```
77 |
78 | :::{.callout-warning collapse=false appearance='default' icon=true}
79 | ## PAT tokens on the cloud
80 | - These will get deleted automatically at regular intervals
81 | - For the purpose of the course this will need to be added a few times!
82 | :::
83 |
84 |
85 | ## Store your PAT
86 |
87 | When you use the following code you'll get a prompt, copy the token with no quotes.
88 |
89 | ```{r}
90 | gitcreds::gitcreds_set()
91 | ```
92 |
93 | :::{.callout-note collapse=false appearance='default' icon=true}
94 | ## Deleting a PAT
95 | If you are using the Cloud or want to delete the PAT from your system use `gitcreds::gitcreds_delete()`
96 | :::
97 |
98 | ## Starting Git from an existing project
99 |
100 | To make our project a Git repository, or 'repo' on our local machine we use
101 |
102 | ```{r}
103 | usethis::use_git()
104 | ```
105 |
106 | :::{.callout-note collapse=false appearance='default' icon=true}
107 | ## A word on R Projects
108 | - Git needs to be in an R Project to work in RStudio (it's good practice to use them)
109 |
110 | ``` markdown
111 | ✔ Initialising Git repo
112 | Error: Path 'C:/Users/zoe.turner/OneDrive - Midlands and Lancashire CSU/Documents/' does not appear to be inside a project or package.
113 | Read more in the help for `proj_get()`.
114 | ```
115 |
116 | - The Cloud workspace _is_ a project so already has the `.Rproj` file set up for Projects
117 | :::
118 |
119 | ## Verbose feedback
120 |
121 | ```
122 | √ Initialising Git repo
123 | √ Adding '.Rdata', '.httr-oauth', '.DS_Store' to '.gitignore'
124 | There are 2 uncommitted files:
125 | • '.gitignore'
126 | • 'git_project.Rproj'
127 | Is it ok to commit them?
128 |
129 | 1: Yeah
130 | 2: Absolutely not
131 | 3: No
132 | ```
133 |
134 | :::{.callout-note collapse=false appearance='default' icon=true}
135 | ## Changing selections
136 | Choose the positive option (these change so might say `I agree` instead of `Yes`)
137 | :::
138 |
139 | ## Initial commit
140 |
141 | ```
142 | √ Adding files
143 | √ Commit with message 'Initial commit'
144 | • A restart of RStudio is required to activate the Git pane
145 | Restart now?
146 |
147 | 1: Nope
148 | 2: Definitely
149 | 3: No
150 | ```
151 |
152 | - Choose the positive option (which changes!)
153 | - The save workspace option to `.Rdata` can be either no for this, more info at [intro-r course](https://intro-r-rstudio.nhsrcommunity.com/session-rstudio.html#/tools-options-workspace)
154 | - A new file for `.gitignore` will appear in the Files pane
155 |
156 | ## Connect this to GitHub
157 |
158 | To create a copy on GitHub
159 |
160 | ```{r}
161 | usethis::use_github()
162 | ```
163 |
164 | This will open up the GitHub page in your default browser
165 |
166 | ## Message about ssh and https
167 |
168 | If you get this:
169 |
170 | ```
171 | ✔ Checking that current branch is 'main'
172 | Which git protocol to use? (enter 0 to exit)
173 | 1: ssh <-- presumes that you have set up ssh keys
174 | 2: https <-- choose this if you don't have ssh keys (or don't know if you do)
175 | ```
176 |
177 | Choose 2 at the moment.
178 |
179 | ## GitHub connected message in RStudio
180 |
181 | ```
182 | ℹ Defaulting to 'https' Git protocol
183 | ✔ Setting active project to '/cloud/project'
184 | ✔ Creating GitHub repository 'Lextuga007/project'
185 | ✔ Setting remote 'origin' to 'https://github.com/Lextuga007/project.git'
186 | ✔ Pushing 'master' branch to GitHub and setting 'origin/master' as upstream branch
187 | ✔ Opening URL 'https://github.com/Lextuga007/project'
188 | ```
189 |
190 | ## master or main?
191 |
192 | The branch is called `master` here as default but conventionally people have moved to `main`
193 | To rename this branch:
194 |
195 | ```{r}
196 | usethis::git_default_branch_rename(from = "master", to = "main")
197 | ```
198 |
199 | :::{.callout-note collapse=false appearance='default' icon=true}
200 | ## Details of where the change has occurred
201 | - This function changes GitHub (on the web) not your local project
202 | :::
203 |
204 |
205 | ## Changing the branch name locally
206 |
207 | Repeat the code and a different message appears
208 |
209 | ```
210 | ✖ It's weird that the current default branch for your local repo and the source repo are different:
211 | 'master' (local) != 'main' (source)
212 | Are you sure you want to proceed?
213 |
214 | 1: yes
215 | 2: no
216 | ```
217 |
218 | This is our first insight into how Git sees local and remote as two separate things!
219 |
220 | ## Set future default branches to main
221 |
222 | This won't affect other projects in the cloud but is useful on a computer
223 |
224 | ```{r}
225 | usethis::git_default_branch_configure()
226 | ```
227 |
228 | ## Updating historic repositories
229 |
230 | If you want to update a lot of old repository default branches from `master` to `main` this can be done using a [Shiny app](https://www.garrickadenbuie.com/blog/branchmover/) built by Garrick Aden-Buie, Software Engineer for Shiny at Posit.
231 |
232 |
233 | ## End session
234 |
235 | # Acknowledgements
236 |
237 | These slides were designed by Mine Çetinkaya-Rundel and Emma Rand for the Forwards Package development module course
238 |
239 | [Your first package](https://forwards.github.io/workshops/package-dev-modules/slides/03-your-first-package/your-first-package.html#1) and
240 | [Setting up your system](https://forwards.github.io/workshops/package-dev-modules/slides/02-setting-up-system/setting-up-system.html#1)
241 |
242 | CDU Data Science [Personal Access Tokens blog](https://cdu-data-science-team.github.io/team-blog/posts/2021-12-18-personal-access-tokens/)
243 |
--------------------------------------------------------------------------------
/session-undo-merge.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - Undo last merge"
4 | ---
5 |
6 | ## The benefit of working in increments
7 |
8 | Working in small chunks, committing and using pull requests means that there are more points to revert back to if things go wrong
9 |
10 | In GitHub, find the pull request and at the bottom is a button `Revert` and this doesn't disappear over time
11 |
12 | ## Revert button
13 |
14 | {fig-alt="Screenshot of a day old GitHub Pull Request with the Revert button highlighted"}
15 |
16 | ## History of mistakes
17 |
18 | - Using `Revert` in GitHub (and other ways to undo work) creates a new commit
19 |
20 | ::: incremental
21 | - This means that your commit history is a record of all your work, even mistakes
22 | - It's absolutely ok and not something to be anxious about (when it's code)
23 | - But if you do commit information that is sensitive this needs to be removed this needs to be treated as an incident or breach
24 | :::
25 |
26 | ## Removing sensitive data from a repository
27 |
28 | It's a thing that every user of GitHub needs to consider and GitHub has [guidance](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository) but does refer to a [tool](https://rtyley.github.io/bfg-repo-cleaner/) that needs installing
29 |
30 | > If this isn't available to you it is still possible to purge a file and its commit history but as there are many different scenarios... [TiddlyWiki](http://sukima.github.io/GitFixUm/).
31 |
32 | is like a choose your own adventure.
33 |
34 | ::: notes
35 | Acknowledge making a mistake is scary and not an adventure! There will be people to help though, through the NHS-R Community and people should definitely feel they can ask for help.
36 | :::
37 |
38 | ## When in doubt - make it private
39 |
40 | You can change the visibility of a repository through the `Settings` tab in GitHub
41 |
42 | It's possible to move a public repository to private and back again any number of times
43 |
44 | ## End session
45 |
46 | ### Acknowledgements
47 |
48 | CDU Data Science Team blog [When things go wrong in GitHub](https://cdu-data-science-team.github.io/team-blog/posts/2022-11-09-when-things-go-wrong-in-github/)
49 |
--------------------------------------------------------------------------------
/session-usethis-errors.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - {usethis} errors"
4 | ---
5 |
6 | ## Error in "stop_bad_github_remote_config()"
7 |
8 | If you get this
9 |
10 | ```
11 | ✔ Setting active project to '/cloud/project'
12 | Error in `stop_bad_github_remote_config()`:
13 | ! Unsupported GitHub remote configuration: 'no_github'
14 | • Host = NA
15 | • origin =
16 | • upstream =
17 | • Neither 'origin' nor 'upstream' is a GitHub repo.
18 |
19 | Read more about the GitHub remote configurations that usethis supports at:
20 | 'https://happygitwithr.com/common-remote-setups.html'
21 | Run `rlang::last_trace()` to see where the error occurred.
22 | ```
23 |
24 | It's because GitHub connections (including personal access tokens) haven't been set up.
25 | The {usethis} functions won't work though as they require a connection to GitHub
26 |
27 | You can use Git locally (F5 refresh in the Cloud).
28 |
29 | ## If they continue
30 |
31 | In the Terminal (starts with `$` on the command line
32 |
33 | ```{bash}
34 | git remote -v
35 | ```
36 |
37 | Gives details of the remote branch, if nothing shows and both the `push` and `pull` buttons in RStudio are grey
38 |
39 | ```{bash}
40 | git remote add origin
41 | ```
42 |
43 | with the url coming from the HTTPS url from GitHub's green button `Code` on the repo.
44 |
45 | ## Posit Cloud repos are called `project`
46 |
47 | Particularly because Posit Cloud repos are called `project`, if you have set up a connection to GitHub before you will geta message
48 |
49 | > Error: Repo 'Lextuga007/project' already exists on 'github.com'
50 |
51 | It's best to delete the GitHub repo (check for any work you want to keep!) and start again when using Posit Cloud.
52 |
53 | In GitHub, under the Settings tab and scroll down to the `Danger Zone`.
54 | You may need to Restart the R session as a refresh.
55 |
56 | ## Pop up for username for `https://github.com`
57 |
58 | This is because the Personal Access Token hasn't been set up correctly.
59 | It might have expired or deleted.
60 | Best resolved by resetting the PAT details.
61 |
62 | ## Unable to confirm the GitHub remote configuration is "pull request ready"
63 |
64 | ```
65 | Unable to confirm the GitHub remote configuration is "pull request ready".
66 | You probably need to configure a personal access token for 'github.com'.
67 | See `gh_token_help()` for help.
68 | (Or maybe we're just offline?)
69 | Unexpected GitHub remote configuration: 'maybe_ours_or_theirs'
70 | Host = 'https://github.com'
71 | origin = 'nhs-r-community/intro-git-github'
72 | upstream =
73 | 'origin' is a GitHub repo and 'upstream' is either not configured or is not a GitHub repo.
74 |
75 | We may be offline or you may need to configure a GitHub personal access
76 | token. `gh_token_help()` can help with that.
77 |
78 | Read more about what this GitHub remote configurations means at:
79 | 'https://happygitwithr.com/common-remote-setups.html'
80 |
81 | 1: Yes, I want to proceed. I know what I'm doing.
82 | 2: No, I want to stop and straighten out my GitHub remotes first.
83 | ```
84 |
85 | Trying `pr_pull()` may give this:
86 |
87 | ```
88 | Error: Unable to get GitHub info for these remotes: 'origin'
89 | Are we offline? Is GitHub down? Has the repo been deleted?
90 | Otherwise, you probably need to configure a personal access token (PAT) for 'github.com'
91 | See `?gh_token_help` for advice
92 | ```
93 |
94 | which suggests the PAT has been removed/deleted or is unobtainable by the project.
95 |
96 | It may be that an alternative place to save the PAT is needed
97 |
98 | ## Storing the PAT in .Renviron
99 |
100 | This is no longer a recommended way of saving a PAT but is required in some circumstances (linux servers)
101 |
102 | ```{r}
103 | usethis::edit_r_environ()
104 | ```
105 |
106 | will open a blank document in RStudio
107 |
108 | ## Text in .Renviron
109 |
110 | With no spaces, returns or any spacing the PAT is added to the file like
111 |
112 | > GITHUB_PAT=ghp_gobbledygookgeneratedbygithub
113 |
114 | Restart the R session (Ctrl+Shift+F10)
115 |
116 | Running `Sys.getenv("GITHUB_PAT")` in the Console will show the PAT code
117 |
118 | ## "Error in libgit2::git_branch_create"
119 |
120 | With the error:
121 |
122 | >Error in libgit2::git_branch_create :
123 | the given reference name 'refs/heads/Add render specifics to _quarto.yml' is not valid
124 |
125 | Check that the name given in the command `usethis::pr_init()` is in the branch format
126 |
127 | ```{r}
128 | usethis::pr_init("update-quarto-yml")
129 |
130 | ```
131 |
132 | not like a commit format (with spaces often)
133 |
134 | ```{r}
135 | usethis::pr_init("Add render specifics to _quarto.yml")
136 | ```
137 |
138 | ## Error: The `pr_*()` functions facilitate pull requests.
139 |
140 | This may be where the function `pr_push()` is being used but from the main branch
141 |
142 | If changes are required (for example to reinstate the greyed out `push` and `pull` in RStudio)
143 |
144 | On the Git Terminal (where the command line starts with `$`)
145 |
146 | ```{bash}
147 | git push --set-upstream origin main
148 | ```
149 |
150 | Refresh the RStudio git pane to ensure the buttons are no longer greyed out
151 | ## End session
152 |
--------------------------------------------------------------------------------
/session-usethis-gert.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - Workflow with {usethis} and {gert}"
4 | ---
5 |
6 | ## Not the command line!
7 |
8 | - Many courses in Git refer to the Command line
9 | - This is under the `Terminal` tab in RStudio
10 | - There are many resources available for Git commands but perhaps the hardest part is the workflow
11 | - Which is where R packages can make things a little friendlier...
12 |
13 | ## Getting started
14 |
15 | Using two packages:
16 |
17 | ```{r}
18 | library(usethis)
19 | library(gert)
20 | ```
21 |
22 | ::: {.callout-tip collapse="false" appearance="default" icon="true"}
23 | ## Terminal or Console?
24 |
25 | The `Console` starts with `>` and is for `R`\
26 | The `Terminal` starts with `$` and is for `git` but other things too like `quarto`
27 | :::
28 |
29 | ## Set up a project
30 |
31 | ::: {.callout-tip collapse="false" appearance="default" icon="true"}
32 | ## Remember!
33 |
34 | - On Posit Cloud the workspace *is* a project!
35 | :::
36 |
37 | - [Setting up a project on your own computer](https://nhs-r-community.github.io/intro-r-rstudio/session-projects.html#/title-slide)
38 | - The Files should have a file called `*.Rproj` if it's a project
39 |
40 | ## Start new work
41 |
42 | Rather than working on the `main` branch we need a copy called "new_work"
43 |
44 | ```{r}
45 | usethis::pr_init("new_work")
46 | ```
47 |
48 | 1. Next [create a quarto file](https://intro-r-rstudio.nhsrcommunity.com/session-quarto.html#/open-a-new-quarto-file)
49 | 2. include a title and author
50 | 3. Render it (which will require you to also save it)
51 |
52 | ## Commit the new files
53 |
54 | In the Git pane three new items will have appeared
55 |
56 | - the `*.qmd` file
57 | - an `*.html` file from the rendered quarto
58 | - a folder for the corresponding html (because this isn't self-contained)
59 |
60 | ## Making a quarto html self-contained
61 |
62 | Add to the YAML (the first few lines at the top)
63 |
64 | ```{r}
65 | #| code-line-numbers: "5"
66 | title: "My report"
67 | author: "Zoë Turner"
68 | format: html
69 | editor: visual
70 | embed-resources: true
71 | ```
72 |
73 | And render again - the folder will disappear.
74 |
75 | ## Staging the new files
76 |
77 | Individual new files can be `staged` with code or by ticking the box next to the file in the RStudio Git pane
78 |
79 | ```{r}
80 | gert:git_add("name_of_file.qmd")
81 | ```
82 |
83 | ## Adding multiple files - first method
84 |
85 | - Using [RStudio](https://nhsrcommunity.com/rstudio-and-git-selecting-many-files/) can be done in the Git pane by clicking on the first file name (highlighting it)
86 | - Then use `Shift` and click the second file to highlight down (or arrow down)
87 | - Select one of the tick boxes and they all get selected
88 |
89 | ## Commit
90 |
91 | This records the changes with a message in Git
92 |
93 | ```{r}
94 | gert::git_commit(message = "First commit for quatro document")
95 | ```
96 |
97 | ## Adding multiple files - second method
98 |
99 | Stage everything and do the commit message at the same time!
100 |
101 | ```{r}
102 | gert::git_commit_all(message = "First commit for quatro document")
103 | ```
104 |
105 | ::: {.callout-warning collapse="false" appearance="default" icon="true"}
106 | ## Watch out!
107 |
108 | This will only `stage` files that have already been "seen" as in committed.
109 |
110 | New files will get missed by this command.
111 | :::
112 |
113 | ## Oops mistake in the message!
114 |
115 | Let's correct the misspelling of `quatro` to `quarto` using a feature of RStudio
116 |
117 | ::: incremental
118 | - Click on the `Commit` button in the Git pane of RStudio (a pop up will appear)
119 | - Select the box `Amend previous commit` under the Commit message (starts off blank)
120 | - Correct `quarot` for `quarto` and then click the Commit button.
121 | :::
122 |
123 | ## Work in progress
124 |
125 | Committing frequently is beneficial but can create a lot of history (commits)
126 |
127 | ::: incremental
128 | - A recommended way of working can be to commit with a message "WIP" and update the one commit
129 | - RStudio can be used to both change the message and add/delete files
130 | :::
131 |
132 | ## Make a change as WIP
133 |
134 | - Change the title of the quarto document and save
135 | - Note the appearance of the file in the Git pane with an `M` icon next to it
136 | - Stage the file using `gert::git_add("name_of_file.qmd")` or tick in RStudio
137 | - Commit using the RStudio button and select `Amend previous commit`
138 |
139 | ## Look at the history
140 |
141 | - In the Git pane of RStudio click on `History`
142 | - Show Diff will need to be selected as the files are new
143 | - Two links will appear for the `*.qmd` and `*.html`, click on the qmd file
144 | - You will see your most recent Title name and there is no reference to that because the commit was changed
145 |
146 | ## A scenario for use
147 |
148 | ::: incremental
149 | - In building this course and the slides the content has changed a lot!
150 | - Slides were merged and split out into topics but the content wasn't always changed
151 | - WIP on a branch shared on GitHub can show you are still working on this as it's good practice to never have a WIP commit on `main`
152 | :::
153 |
154 | ## Your turn!
155 |
156 | - Remove the author of the quarto document, save and Render
157 | - Create a new Quarto presentation and save
158 | - Use `gert::git_commit_all("Removed author and created slides")`
159 | - Stage and commit either as a new commit or amend the last
160 |
161 | ## End session
162 |
163 | ## Acknowledgements
164 |
165 | [Happy Git and GitHub](https://happygitwithr.com/) for the useR by Jenny Bryan
166 |
167 | [Pull Request Flow with usethis](https://www.garrickadenbuie.com/blog/pull-request-flow-usethis/?interactive=) by Garrick Aden-Buie
168 |
--------------------------------------------------------------------------------
/session-version-control.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - What is version control?"
4 | ---
5 |
6 | ## Git - the version control system
7 |
8 | > “Track Changes” features from Microsoft Word
9 |
10 | . . .
11 |
12 | > on steroids
13 |
14 | . . .
15 |
16 | Source: [Happy Git and GitHub for the useR](https://happygitwithr.com/big-picture.html?q=version%20control#big-picture) by Jenny Bryan
17 |
18 | ## Managing your files
19 |
20 | Is this familiar?
21 |
22 | ::: {.fragment .fade-in}
23 | file_v1.0.doc
24 | :::
25 | ::: {.fragment .fade-in}
26 | file_v1.1.doc
27 | :::
28 | ::: {.fragment .fade-in}
29 | file_v1.0.1.doc
30 | :::
31 | ::: {.fragment .fade-in}
32 | file_final_1.0.doc
33 | :::
34 | ::: {.fragment .fade-in}
35 | file_final_final.doc
36 | :::
37 | ::: {.fragment .fade-in}
38 | Inspired by comic cartoons like [xkcd](https://xkcd.com/1459/)
39 | :::
40 |
41 | ## Git learning downside
42 |
43 | Git may not really make sense if you are working on your own
44 |
45 | >A solo data analyst, working on a single computer, will benefit from adopting version control. But not nearly enough to justify the pain of installation and workflow upheaval. There are much easier ways to get versioned back ups of your files, if that’s all you’re worried about.
46 |
47 | [Happy Git and GitHub for the userR](https://happygitwithr.com/big-picture.html) - Jenny Bryan
48 |
49 | ## Reasons why Git and GitHub hurts
50 |
51 | ::: incremental
52 | - requires a completely new and longer workflow to your analysis
53 | - collaborating with others can cause **merge conflicts**
54 | - you can cause your own merge conflicts mess (we will do that in this course!)
55 | :::
56 |
57 | . . .
58 |
59 | > this is not a one-time pain, this could be a dull ache for a long time
60 |
61 | Source: Happy Git and GitHub for the useR - [Is it going to hurt](https://happygitwithr.com/big-picture.html?q=version%20control#is-it-going-to-hurt) by Jenny Bryan
62 |
63 | ## So why bother?
64 |
65 | ::: incremental
66 | - Personal exposure: sharing publicly can feel scary because you assume people will judge, but you'll soon find the judgement is positive as people are grateful for your sharing
67 | - Team exposure: there is a lot of repeated code for tasks duplicated across many organisations (particularly in the public sector)
68 | - Be keener: you can use other people's work (with the right [licences](https://nhs-r-community.github.io/statements-on-tools/open-code-in-the-nhs.html#licenceslicenses)) and keep up to date with all the work through GitHub for any changes, developments or improvements
69 | - Collaboration: we can work together!
70 | :::
71 |
72 | ## Git benefits
73 |
74 | :::incremental
75 | - Are important if you want to share/communicate with others
76 | - Are paramount if you want to collaborate
77 | - Combined with RStudio, GitHub and R packages, can be a little easier to get started
78 | :::
79 |
80 | ## GitHub
81 |
82 | :::incremental
83 | - Uses Git but is a separate platform (other services are available)
84 | - It's a web hosted site for public and private repositories
85 | - GitHub is a very friendly user interface and is being updated with new features
86 | - Individuals and [organisations](https://github.com/nhs-r-community) can have accounts
87 | - You can have public and private repositories
88 | :::
89 |
90 | ## RStudio benefits
91 |
92 | As with so many things, other IDEs (Integrated development environment) are available
93 |
94 | :::incremental
95 | - Never having to leave one program: clean data, visualise it and do statistics in one place!
96 | - Also allows version control and use of Git/GitHub without having to open another program
97 | :::
98 |
99 | ## End session
100 |
101 | ## Acknowledgements
102 |
103 | [Happy Git and GitHub](https://happygitwithr.com/) for the useR by Jenny Bryan
104 |
105 | Material adapted from the [Git training](https://github.com/nhs-r-community/git_training/blob/main/guides/workshop_slides/Part%201-Intro%20to%20Git-Version%20Control.pdf) delivered at the NHS-R Community conference 2022.
--------------------------------------------------------------------------------
/session-version-workflow.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to Git and GitHub"
3 | subtitle: "Session - Versioning workflow"
4 | ---
5 |
6 | ## Snapshots
7 |
8 | It's good to practice regular saving of files when you work - whatever the program
9 |
10 | :::incremental
11 | - But what if you want to take a snapshot before you do something major?
12 | - You could save files as version 1, version 2 and so on
13 | - Git allows whole project snapshots of many documents
14 | :::
15 |
16 | ## Not just for new material
17 |
18 | Have you ever commented out code that you don't want to use but want to keep - just in case?
19 |
20 | :::incremental
21 | - Git allows things to be deleted and add a message as to why you did that
22 | - Roll backs are also available!
23 | - And if you want to find the old code but not roll back - Git has that history, it keeps everything
24 | :::
25 |
26 | ## Local and Remote
27 |
28 | Once you have a snapshot stored locally (Git) you can **push** the snapshot to a remote site (GitHub)
29 |
30 | This is like:
31 |
32 | ::: incremental
33 | - sending file updates by email and also
34 | - sharing on something like DropBox
35 | :::
36 |
37 | ## An unnecessary extra step?
38 |
39 | The tendency for much of analysis work is to share once something is finished
40 |
41 | But **commits** (snapshots):
42 |
43 | ::: incremental
44 | - allow others to contribute with your work in progress
45 | - forces you to think clearly about code as others will see it
46 | - give the opportunity to **revert** (roll back) to something that was better
47 | :::
48 |
49 | ## Private or public repository?
50 |
51 | GitHub offers the possibility of having private repositories
52 |
53 | ::: {.fragment .fade-in}
54 | They have a few restrictions on functionality (unless in a paid account)
55 | :::
56 | ::: {.fragment .fade-in}
57 | Still should never have any identifiable information for security
58 | :::
59 | ## End session
60 |
61 | # Acknowledgements
62 |
63 | [Happy Git and GitHub](https://happygitwithr.com/) for the useR by Jenny Bryan
64 |
--------------------------------------------------------------------------------