├── code └── .gitkeep ├── data └── .gitkeep ├── fig ├── .gitkeep ├── phd101212s.png ├── github-create-repo-01.png ├── github-create-repo-02.png ├── github-create-repo-03.png ├── github-find-repo-string.png ├── RStudio_screenshot_commit.png ├── RStudio_screenshot_history.png ├── RStudio_screenshot_review.png ├── github-add-collaborators.png ├── github-change-repo-string.png ├── RStudio_screenshot_editfiles.png ├── RStudio_screenshot_gitignore.png ├── RStudio_screenshot_afterclone.png ├── RStudio_screenshot_newproject.png ├── RStudio_screenshot_viewhistory.png ├── RStudio_screenshot_existingdirectory.png ├── RStudio_screenshot_navigateexisting.png ├── merge.svg ├── conflict.svg ├── play-changes.svg ├── git-staging-area.svg ├── versions.svg └── git-checkout.svg ├── _episodes ├── .gitkeep ├── 12-citation.md ├── 01-basics.md ├── 11-licensing.md ├── 13-hosting.md ├── 14-supplemental-rstudio.md ├── 03-create.md ├── 10-open.md ├── 02-setup.md ├── 08-collab.md └── 06-ignore.md ├── _extras ├── .gitkeep ├── about.md └── figures.md ├── files └── .gitkeep ├── _episodes_rmd ├── .gitkeep └── data │ └── .gitkeep ├── requirements.txt ├── favicon-dc.ico ├── favicon-lc.ico ├── .update-copyright.conf ├── favicon-swc.ico ├── _layouts ├── page.html ├── reference.html ├── lesson.html ├── break.html ├── episode.html ├── base.html └── workshop.html ├── .gitignore ├── assets ├── img │ ├── lc-icon-black.png │ ├── swc-logo-blue.png │ ├── swc-logo-white.png │ ├── lc-icon-black.svg │ ├── swc-icon-blue.svg │ └── dc-icon-black.svg ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── js │ └── lesson.js └── css │ └── lesson.scss ├── CITATION ├── _includes ├── main_title.html ├── episode_title.html ├── dc │ ├── who.html │ ├── intro.html │ ├── schedule.html │ └── syllabus.html ├── sc │ ├── who.html │ ├── intro.html │ ├── schedule.html │ └── syllabus.html ├── lc │ ├── who.html │ ├── intro.html │ ├── schedule.html │ └── syllabys.html ├── episode_keypoints.html ├── episode_break.html ├── all_keypoints.html ├── workshop_footer.html ├── javascript.html ├── episode_overview.html ├── workshop_ad.html ├── episode_navbar.html ├── lesson_footer.html ├── links.md ├── carpentries.html ├── all_figures.html ├── syllabus.html └── navbar.html ├── bin ├── knit_lessons.sh ├── markdown_ast.rb ├── test_lesson_check.py ├── generate_md_episodes.R ├── chunk-options.R ├── extract_figures.py ├── repo_check.py └── util.py ├── setup.md ├── README.md ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── aio.md ├── CONDUCT.md ├── _config.yml ├── AUTHORS ├── index.md ├── .mailmap ├── LICENSE.md ├── reference.md ├── Makefile └── CONTRIBUTING.md /code/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fig/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_episodes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_extras/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_episodes_rmd/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_episodes_rmd/data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | PyYAML 2 | update-copyright 3 | -------------------------------------------------------------------------------- /favicon-dc.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/favicon-dc.ico -------------------------------------------------------------------------------- /favicon-lc.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/favicon-lc.ico -------------------------------------------------------------------------------- /.update-copyright.conf: -------------------------------------------------------------------------------- 1 | [project] 2 | vcs: Git 3 | 4 | [files] 5 | authors: yes 6 | files: no 7 | -------------------------------------------------------------------------------- /favicon-swc.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/favicon-swc.ico -------------------------------------------------------------------------------- /_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 | {% include main_title.html %} 5 | {{content}} 6 | -------------------------------------------------------------------------------- /fig/phd101212s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/phd101212s.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *~ 3 | .DS_Store 4 | .ipynb_checkpoints 5 | .sass-cache 6 | __pycache__ 7 | _site 8 | -------------------------------------------------------------------------------- /assets/img/lc-icon-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/assets/img/lc-icon-black.png -------------------------------------------------------------------------------- /assets/img/swc-logo-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/assets/img/swc-logo-blue.png -------------------------------------------------------------------------------- /assets/img/swc-logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/assets/img/swc-logo-white.png -------------------------------------------------------------------------------- /fig/github-create-repo-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/github-create-repo-01.png -------------------------------------------------------------------------------- /fig/github-create-repo-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/github-create-repo-02.png -------------------------------------------------------------------------------- /fig/github-create-repo-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/github-create-repo-03.png -------------------------------------------------------------------------------- /_extras/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: About 4 | permalink: /about/ 5 | --- 6 | {% include carpentries.html %} 7 | -------------------------------------------------------------------------------- /fig/github-find-repo-string.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/github-find-repo-string.png -------------------------------------------------------------------------------- /_extras/figures.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Figures 4 | permalink: /figures/ 5 | --- 6 | {% include all_figures.html %} 7 | -------------------------------------------------------------------------------- /_layouts/reference.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Reference" 4 | --- 5 | {% include all_keypoints.html %} 6 | {{content}} 7 | -------------------------------------------------------------------------------- /fig/RStudio_screenshot_commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/RStudio_screenshot_commit.png -------------------------------------------------------------------------------- /fig/RStudio_screenshot_history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/RStudio_screenshot_history.png -------------------------------------------------------------------------------- /fig/RStudio_screenshot_review.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/RStudio_screenshot_review.png -------------------------------------------------------------------------------- /fig/github-add-collaborators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/github-add-collaborators.png -------------------------------------------------------------------------------- /fig/github-change-repo-string.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/github-change-repo-string.png -------------------------------------------------------------------------------- /_layouts/lesson.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 | {% include main_title.html %} 5 | {{ content }} 6 | {% include syllabus.html %} 7 | -------------------------------------------------------------------------------- /fig/RStudio_screenshot_editfiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/RStudio_screenshot_editfiles.png -------------------------------------------------------------------------------- /fig/RStudio_screenshot_gitignore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/RStudio_screenshot_gitignore.png -------------------------------------------------------------------------------- /fig/RStudio_screenshot_afterclone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/RStudio_screenshot_afterclone.png -------------------------------------------------------------------------------- /fig/RStudio_screenshot_newproject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/RStudio_screenshot_newproject.png -------------------------------------------------------------------------------- /fig/RStudio_screenshot_viewhistory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/RStudio_screenshot_viewhistory.png -------------------------------------------------------------------------------- /fig/RStudio_screenshot_existingdirectory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/RStudio_screenshot_existingdirectory.png -------------------------------------------------------------------------------- /fig/RStudio_screenshot_navigateexisting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/fig/RStudio_screenshot_navigateexisting.png -------------------------------------------------------------------------------- /assets/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/assets/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /assets/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/assets/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /assets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/assets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /assets/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spacetelescope/git-novice/gh-pages/assets/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /CITATION: -------------------------------------------------------------------------------- 1 | Please cite as: 2 | 3 | Daisie Huang and Ivan Gonzalez (eds): "Software Carpentry: Version 4 | Control with Git." Version 2016.06, June 2016, 5 | https://github.com/swcarpentry/git-novice, 10.5281/zenodo.57467. 6 | -------------------------------------------------------------------------------- /_includes/main_title.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Main title for lesson pages. 3 | {% endcomment %} 4 |

{{ site.title }}{% if page.title %}: {{ page.title }}{% endif %}

5 | -------------------------------------------------------------------------------- /_includes/episode_title.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

{{ page.title }}

6 |
7 |
8 |
9 |
10 | -------------------------------------------------------------------------------- /bin/knit_lessons.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Only try running R to translate files if there are some files present. 4 | # The Makefile passes in the names of files. 5 | 6 | if [ $# -ne 0 ] ; then 7 | Rscript -e "source('bin/generate_md_episodes.R')" 8 | fi 9 | -------------------------------------------------------------------------------- /_includes/dc/who.html: -------------------------------------------------------------------------------- 1 |

2 | Who: 3 | The course is aimed at graduate students and other researchers. 4 | 5 | You don't need to have any previous knowledge of the tools 6 | that will be presented at the workshop. 7 | 8 |

9 | -------------------------------------------------------------------------------- /_includes/sc/who.html: -------------------------------------------------------------------------------- 1 |

2 | Who: 3 | The course is aimed at graduate students and other researchers. 4 | 5 | You don't need to have any previous knowledge of the tools 6 | that will be presented at the workshop. 7 | 8 |

9 | -------------------------------------------------------------------------------- /_includes/lc/who.html: -------------------------------------------------------------------------------- 1 |

2 | Who: 3 | The course is for librarians, archivists, and other information workers. 4 | 5 | You don't need to have any previous knowledge of the tools that 6 | will be presented at the workshop. 7 | 8 |

9 | -------------------------------------------------------------------------------- /_layouts/break.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 | {% include episode_navbar.html episode_navbar_title=true %} 5 |
6 | {% include episode_title.html %} 7 | {% include episode_break.html %} 8 | {{content}} 9 |
10 | {% include episode_navbar.html episode_navbar_title=false %} 11 | -------------------------------------------------------------------------------- /bin/markdown_ast.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # Use Kramdown parser to produce AST for Markdown document. 4 | 5 | require "kramdown" 6 | require "json" 7 | 8 | markdown = STDIN.read() 9 | doc = Kramdown::Document.new(markdown) 10 | tree = doc.to_hash_a_s_t 11 | puts JSON.pretty_generate(tree) 12 | -------------------------------------------------------------------------------- /_includes/episode_keypoints.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Display key points for an episode. 3 | {% endcomment %} 4 |
5 |

Key Points

6 | 11 |
12 | -------------------------------------------------------------------------------- /_layouts/episode.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 | {% include episode_navbar.html episode_navbar_title=true %} 5 |
6 | {% include episode_title.html %} 7 | {% include episode_overview.html %} 8 | {{content}} 9 | {% include episode_keypoints.html %} 10 |
11 | {% include episode_navbar.html episode_navbar_title=false %} 12 | -------------------------------------------------------------------------------- /_includes/episode_break.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Display a break's timings in a box similar to a learning episode's. 3 | {% endcomment %} 4 |
5 |

Overview

6 | 7 |
8 |
9 | Break: {{ page.break }} min 10 |
11 |
12 |
13 |
14 | 15 |
16 | -------------------------------------------------------------------------------- /setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Setup 4 | permalink: /setup/ 5 | --- 6 | 7 | Please see [this section of the workshop template][workshop-setup] 8 | for instructions on installing Git. 9 | 10 | We'll do our work in the `Desktop` folder so make sure you change your working directory to it with: 11 | 12 | ~~~ 13 | $ cd 14 | $ cd Desktop 15 | ~~~ 16 | {: .bash} 17 | 18 | [workshop-setup]: https://swcarpentry.github.io/workshop-template/#git 19 | -------------------------------------------------------------------------------- /_includes/all_keypoints.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Display key points of all episodes for reference. 3 | {% endcomment %} 4 |

Key Points

5 | 6 | {% for episode in site.episodes %} 7 | {% unless episode.break %} 8 | 9 | 12 | 19 | 20 | {% endunless %} 21 | {% endfor %} 22 |
10 | {{ episode.title }} 11 | 13 |
    14 | {% for keypoint in episode.keypoints %} 15 |
  • {{ keypoint|markdownify }}
  • 16 | {% endfor %} 17 |
18 |
23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | git-novice 2 | ========== 3 | 4 | An introduction to version control for novices using Git. 5 | Please see for a rendered version of this material, 6 | [the lesson template documentation][lesson-example] 7 | for instructions on formatting, building, and submitting material, 8 | or run `make` in this directory for a list of helpful commands. 9 | 10 | Maintainers: 11 | 12 | * [Ivan Gonzalez][gonzalez_ivan] 13 | * [Daisie Huang][huang_daisie] 14 | 15 | [gonzalez_ivan]: http://software-carpentry.org/team/#gonzalez_ivan 16 | [huang_daisie]: http://software-carpentry.org/team/#huang_daisie 17 | [lesson-example]: https://swcarpentry.github.io/lesson-example 18 | -------------------------------------------------------------------------------- /bin/test_lesson_check.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import lesson_check 4 | import util 5 | 6 | class TestFileList(unittest.TestCase): 7 | def setUp(self): 8 | self.reporter = util.Reporter() ## TODO: refactor reporter class. 9 | 10 | def test_file_list_has_expected_entries(self): 11 | # For first pass, simply assume that all required files are present 12 | all_filenames = [filename.replace('%', '') 13 | for filename in lesson_check.REQUIRED_FILES] 14 | 15 | lesson_check.check_fileset('', self.reporter, all_filenames) 16 | self.assertEqual(len(self.reporter.messages), 0) 17 | 18 | if __name__ == "__main__": 19 | unittest.main() 20 | -------------------------------------------------------------------------------- /_includes/workshop_footer.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Footer for a standard workshop. 3 | {% endcomment %} 4 | 25 | -------------------------------------------------------------------------------- /_includes/javascript.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Javascript used in lesson and workshop pages. 3 | {% endcomment %} 4 | 5 | 6 | 7 | 15 | -------------------------------------------------------------------------------- /_includes/dc/intro.html: -------------------------------------------------------------------------------- 1 |

2 | Data Carpentry 3 | aims to help researchers get their work done 4 | in less time and with less pain 5 | by teaching them basic research computing skills. 6 | This hands-on workshop will cover basic concepts and tools, 7 | including program design, version control, data management, 8 | and task automation. 9 | Participants will be encouraged to help one another 10 | and to apply what they have learned to their own research problems. 11 |

12 |

13 | 14 | For more information on what we teach and why, 15 | please see our paper 16 | "Best Practices for Scientific Computing". 17 | 18 |

19 | -------------------------------------------------------------------------------- /_includes/sc/intro.html: -------------------------------------------------------------------------------- 1 |

2 | Software Carpentry 3 | aims to help researchers get their work done 4 | in less time and with less pain 5 | by teaching them basic research computing skills. 6 | This hands-on workshop will cover basic concepts and tools, 7 | including program design, version control, data management, 8 | and task automation. 9 | Participants will be encouraged to help one another 10 | and to apply what they have learned to their own research problems. 11 |

12 |

13 | 14 | For more information on what we teach and why, 15 | please see our paper 16 | "Best Practices for Scientific Computing". 17 | 18 |

19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Please delete the text below before submitting your contribution. 2 | 3 | --- 4 | 5 | Thanks for contributing! If this contribution is for instructor training, please send an email to checkout@carpentries.org with a link to this contribution so we can record your progress. You’ve completed your contribution step for instructor checkout just by submitting this contribution. 6 | 7 | Please keep in mind that lesson maintainers are volunteers and it may be some time before they can respond to your contribution. Although not all contributions can be incorporated into the lesson materials, we appreciate your time and effort to improve the curriculum. If you have any questions about the lesson maintenance process or would like to volunteer your time as a contribution reviewer, please contact Kate Hertweck (k8hertweck@gmail.com). 8 | 9 | --- 10 | -------------------------------------------------------------------------------- /_includes/lc/intro.html: -------------------------------------------------------------------------------- 1 |

2 | Library Carpentry 3 | is made by librarians, for librarians to help you: 4 |

5 | 12 |

13 | 14 | Library Carpentry introduces you to the fundamentals of computing 15 | and provides you with a platform for further self-directed learning. 16 | For more information on what we teach and why, please see our paper 17 | "Library Carpentry: software skills training for library professionals". 18 | 19 |

20 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Please delete the text below before submitting your contribution. 2 | 3 | --- 4 | 5 | Thanks for contributing! If this contribution is for instructor training, please send an email to checkout@carpentries.org with a link to this contribution so we can record your progress. You’ve completed your contribution step for instructor checkout just by submitting this contribution. 6 | 7 | Please keep in mind that lesson maintainers are volunteers and it may be some time before they can respond to your contribution. Although not all contributions can be incorporated into the lesson materials, we appreciate your time and effort to improve the curriculum. If you have any questions about the lesson maintenance process or would like to volunteer your time as a contribution reviewer, please contact Kate Hertweck (k8hertweck@gmail.com). 8 | 9 | --- 10 | -------------------------------------------------------------------------------- /_includes/episode_overview.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Display an episode's timings and learning objectives. 3 | {% endcomment %} 4 |
5 |

Overview

6 | 7 |
8 |
9 | Teaching: {{ page.teaching }} min 10 |
11 | Exercises: {{ page.exercises }} min 12 |
13 |
14 | Questions 15 |
    16 | {% for question in page.questions %} 17 |
  • {{ question|markdownify }}
  • 18 | {% endfor %} 19 |
20 |
21 |
22 | 23 |
24 |
25 |
26 |
27 | Objectives 28 |
    29 | {% for objective in page.objectives %} 30 |
  • {{ objective|markdownify }}
  • 31 | {% endfor %} 32 |
33 |
34 |
35 | 36 |
37 | -------------------------------------------------------------------------------- /_includes/workshop_ad.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Advertising box at the top of a workshop website home page. 3 | {% endcomment %} 4 |
5 |
6 |
7 |

{{page.venue}}

8 |
9 |
10 |

{{page.humandate}}

11 |

{% if page.humantime %}{{page.humantime}}{% endif %}

12 |
13 |
14 |

15 | Instructors: 16 | {% if page.instructor %} 17 | {{page.instructor | join: ', ' %}} 18 | {% else %} 19 | to be announced. 20 | {% endif %} 21 |

22 | {% if page.helper %} 23 |

24 | Helpers: 25 | {{page.helper | join: ', ' %}} 26 |

27 | {% endif %} 28 |
29 |
30 |
31 |
32 |
33 | -------------------------------------------------------------------------------- /_includes/lc/schedule.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Day 1

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
09:00 Data Intro for Librarians
10:30 Coffee
12:00 Lunch break
13:00 Shell Lessons for Libraries
14:30 Coffee
16:00 Wrap-up
12 |
13 |
14 |

Day 2

15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
09:00 Git Intro for Librarians
10:30 Coffee
12:00 Lunch break
13:00 OpenRefine for Librarians
14:30 Coffee
16:00 Wrap-up
23 |
24 |
25 | -------------------------------------------------------------------------------- /_includes/dc/schedule.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Day 1

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
09:00 Automating tasks with the Unix shell
10:30 Coffee
12:00 Lunch break
13:00 Building programs with Python
14:30 Coffee
16:00 Wrap-up
12 |
13 |
14 |

Day 2

15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
09:00 Version control with Git
10:30 Coffee
12:00 Lunch break
13:00 Managing data with SQL
14:30 Coffee
16:00 Wrap-up
23 |
24 |
25 | -------------------------------------------------------------------------------- /_includes/sc/schedule.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Day 1

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
09:00 Automating tasks with the Unix shell
10:30 Coffee
12:00 Lunch break
13:00 Building programs with Python
14:30 Coffee
16:00 Wrap-up
12 |
13 |
14 |

Day 2

15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
09:00 Version control with Git
10:30 Coffee
12:00 Lunch break
13:00 Managing data with SQL
14:30 Coffee
16:00 Wrap-up
23 |
24 |
25 | -------------------------------------------------------------------------------- /assets/js/lesson.js: -------------------------------------------------------------------------------- 1 | // Make all tables striped by default. 2 | $("table").addClass("table table-striped"); 3 | 4 | 5 | // Handle foldable challenges and solutions (on click and at start). 6 | $(".solution").click(function(event) { 7 | var trigger = $(event.target).has(".fold-unfold").size() > 0 8 | || $(event.target).filter(".fold-unfold").size() > 0; 9 | if (trigger) { 10 | $(">*:not(h2)", this).toggle(400); 11 | $(">h2>span.fold-unfold", this).toggleClass("glyphicon-collapse-down glyphicon-collapse-up"); 12 | event.stopPropagation(); 13 | } 14 | }); 15 | $(".solution").each(function() { 16 | $(">*:not(h2)", this).toggle(); 17 | var h2 = $("h2:first", this); 18 | h2.append(""); 19 | }); 20 | 21 | 22 | // Handle searches. 23 | // Relies on document having 'meta' element with name 'search-domain'. 24 | function google_search() { 25 | var query = document.getElementById("google-search").value; 26 | var domain = $("meta[name=search-domain]").attr("value"); 27 | window.open("https://www.google.com/search?q=" + query + "+site:" + domain); 28 | } 29 | -------------------------------------------------------------------------------- /_includes/episode_navbar.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Navigation bar for an episode. 3 | {% endcomment %} 4 |
5 |
6 |

7 | {% if page.previous.url %} 8 | previous episode 9 | {% else %} 10 | lesson home 11 | {% endif %} 12 |

13 |
14 |
15 | {% if include.episode_navbar_title %} 16 |

{{ site.title }}

17 | {% endif %} 18 |
19 |
20 |

21 | {% if page.next.url %} 22 | next episode 23 | {% else %} 24 | lesson home 25 | {% endif %} 26 |

27 |
28 |
29 | -------------------------------------------------------------------------------- /_includes/lesson_footer.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Footer for lesson pages. 3 | {% endcomment %} 4 | 39 | -------------------------------------------------------------------------------- /aio.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | permalink: /aio/ 4 | --- 5 | 31 | {% comment %} 32 | Create anchor for each one of the episodes. 33 | {% endcomment %} 34 | {% for episode in site.episodes %} 35 |
36 | {% endfor %} 37 | -------------------------------------------------------------------------------- /bin/generate_md_episodes.R: -------------------------------------------------------------------------------- 1 | generate_md_episodes <- function() { 2 | 3 | if (require("knitr") && packageVersion("knitr") < '1.9.19') 4 | stop("knitr must be version 1.9.20 or higher") 5 | 6 | if (!require("stringr")) 7 | stop("The package stringr is required for generating the lessons.") 8 | 9 | if (require("checkpoint") && packageVersion("checkpoint") >= '0.4.0') { 10 | required_pkgs <- 11 | checkpoint:::scanForPackages(project = "_episodes_rmd", 12 | verbose=FALSE, use.knitr = TRUE)$pkgs 13 | } else { 14 | stop("The checkpoint package (>= 0.4.0) is required to build the lessons.") 15 | } 16 | 17 | missing_pkgs <- required_pkgs[!(required_pkgs %in% rownames(installed.packages()))] 18 | 19 | if (length(missing_pkgs)) { 20 | message("Installing missing required packages: ", 21 | paste(missing_pkgs, collapse=", ")) 22 | install.packages(missing_pkgs) 23 | } 24 | 25 | ## find all the Rmd files, and generate the paths for their respective outputs 26 | src_rmd <- list.files(pattern = "??-*.Rmd$", path = "_episodes_rmd", full.names = TRUE) 27 | dest_md <- file.path("_episodes", gsub("Rmd$", "md", basename(src_rmd))) 28 | 29 | ## knit the Rmd into markdown 30 | mapply(function(x, y) { 31 | knitr::knit(x, output = y) 32 | }, src_rmd, dest_md) 33 | 34 | } 35 | 36 | generate_md_episodes() 37 | -------------------------------------------------------------------------------- /_episodes/12-citation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Citation 3 | teaching: 2 4 | exercises: 0 5 | questions: 6 | - "How can I make my work easier to cite?" 7 | objectives: 8 | - "Make your work easy to cite" 9 | keypoints: 10 | - "Add a CITATION file to a repository to explain how you want your work cited." 11 | --- 12 | 13 | You may want to include a file called `CITATION` or `CITATION.txt` 14 | that describes how to reference your project; 15 | the [one for Software 16 | Carpentry](https://github.com/swcarpentry/website/blob/gh-pages/CITATION) 17 | states: 18 | 19 | ~~~ 20 | To reference Software Carpentry in publications, please cite both of the following: 21 | 22 | Greg Wilson: "Software Carpentry: Getting Scientists to Write Better 23 | Code by Making Them More Productive". Computing in Science & 24 | Engineering, Nov-Dec 2006. 25 | 26 | Greg Wilson: "Software Carpentry: Lessons Learned". arXiv:1307.5448, 27 | July 2013. 28 | 29 | @article{wilson-software-carpentry-2006, 30 | author = {Greg Wilson}, 31 | title = {Software Carpentry: Getting Scientists to Write Better Code by Making Them More Productive}, 32 | journal = {Computing in Science \& Engineering}, 33 | month = {November--December}, 34 | year = {2006}, 35 | } 36 | 37 | @online{wilson-software-carpentry-2013, 38 | author = {Greg Wilson}, 39 | title = {Software Carpentry: Lessons Learned}, 40 | version = {1}, 41 | date = {2013-07-20}, 42 | eprinttype = {arxiv}, 43 | eprint = {1307.5448} 44 | } 45 | ~~~ 46 | {: .source} 47 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Contributor Code of Conduct" 4 | permalink: /conduct/ 5 | --- 6 | As contributors and maintainers of this project, 7 | we pledge to respect all people who contribute through reporting issues, 8 | posting feature requests, 9 | updating documentation, 10 | submitting pull requests or patches, 11 | and other activities. 12 | 13 | We are committed to making participation in this project a harassment-free experience for everyone, 14 | regardless of level of experience, 15 | gender, 16 | gender identity and expression, 17 | sexual orientation, 18 | disability, 19 | personal appearance, 20 | body size, 21 | race, 22 | ethnicity, 23 | age, 24 | or religion. 25 | 26 | Examples of unacceptable behavior by participants include the use of sexual language or imagery, 27 | derogatory comments or personal attacks, 28 | trolling, 29 | public or private harassment, 30 | insults, 31 | or other unprofessional conduct. 32 | 33 | Project maintainers have the right and responsibility to remove, edit, or reject 34 | comments, commits, code, wiki edits, issues, and other contributions 35 | that are not aligned to our [Code of Conduct][coc]. 36 | Project maintainers who do not follow the Code of Conduct may be removed from the project team. 37 | 38 | Instances of abusive, harassing, or otherwise unacceptable behavior 39 | may be reported by following our [reporting guidelines][coc-reporting]. 40 | 41 | 42 | - [Software and Data Carpentry Code of Conduct][coc] 43 | - [Code of Conduct Reporting Guide][coc-reporting] 44 | 45 | {% include links.md %} 46 | -------------------------------------------------------------------------------- /_includes/links.md: -------------------------------------------------------------------------------- 1 | [cc-by-human]: https://creativecommons.org/licenses/by/4.0/ 2 | [cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode 3 | [concept-maps]: http://swcarpentry.github.io/instructor-training/08-memory/ 4 | [contact]: mailto:lessons@software-carpentry.org 5 | [contrib-covenant]: http://contributor-covenant.org/ 6 | [contributing]: {{ site.github.repository_url }}/blob/gh-pages/CONTRIBUTING.md 7 | [cran-checkpoint]: https://cran.r-project.org/web/packages/checkpoint/index.html 8 | [cran-knitr]: https://cran.r-project.org/web/packages/knitr/index.html 9 | [cran-stringr]: https://cran.r-project.org/web/packages/stringr/index.html 10 | [github-importer]: https://import.github.com/ 11 | [importer]: http://import.github.com/new 12 | [jekyll-collection]: https://jekyllrb.com/docs/collections/ 13 | [jekyll-install]: https://jekyllrb.com/docs/installation/ 14 | [jekyll-windows]: http://jekyll-windows.juthilo.com/ 15 | [jekyll]: https://jekyllrb.com/ 16 | [jupyter]: https://jupyter.org/ 17 | [mit-license]: http://opensource.org/licenses/mit-license.html 18 | [morea]: https://morea-framework.github.io/ 19 | [numfocus]: http://numfocus.org/ 20 | [osi]: http://opensource.org 21 | [pandoc]: https://pandoc.org/ 22 | [paper-now]: https://github.com/PeerJ/paper-now 23 | [python-gapminder]: https://swcarpentry.github.io/python-novice-gapminder/ 24 | [pyyaml]: https://pypi.python.org/pypi/PyYAML 25 | [r-markdown]: http://rmarkdown.rstudio.com/ 26 | [rstudio]: https://www.rstudio.com/ 27 | [ruby-install-guide]: https://www.ruby-lang.org/en/downloads/ 28 | [ruby-installer]: http://rubyinstaller.org/ 29 | [rubygems]: https://rubygems.org/pages/download/ 30 | [styles]: https://github.com/swcarpentry/styles/ 31 | [training]: http://swcarpentry.github.io/instructor-training/ 32 | [workshop-repo]: {{ site.workshop_repo }} 33 | [yaml]: http://yaml.org/ 34 | [coc]: https://software-carpentry.org/conduct/ 35 | [coc-reporting]: https://software-carpentry.org/CoC-reporting/ -------------------------------------------------------------------------------- /_layouts/base.html: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% if site.carpentry == "swc" %} 16 | 17 | {% elsif site.carpentry == "dc" %} 18 | 19 | {% elsif site.carpentry == "lc" %} 20 | 21 | {% endif %} 22 | 23 | 24 | 28 | {{ site.title }}{% if page.title %}: {{ page.title }}{% endif %} 29 | 30 | 31 |
32 | {% include navbar.html %} 33 | {{ content }} 34 | {% if site.kind == "workshop" %} 35 | {% include workshop_footer.html %} 36 | {% else %} 37 | {% include lesson_footer.html %} 38 | {% endif %} 39 |
40 | {% include javascript.html %} 41 | 42 | 43 | -------------------------------------------------------------------------------- /_includes/carpentries.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | General description of Software and Data Carpentry. 3 | {% endcomment %} 4 |
5 |
6 | Software Carpentry logo 7 |
8 |
9 | Since 1998, 10 | Software Carpentry 11 | has been teaching researchers in science, engineering, medicine, and related disciplines 12 | the computing skills they need to get more done in less time and with less pain. 13 | Its volunteer instructors have run hundreds of events 14 | for thousands of learners in the past two and a half years. 15 |
16 |
17 |
18 |
19 |
20 | Data Carpentry logo 21 |
22 |
23 | Data Carpentry develops and teaches workshops on the fundamental data skills needed to conduct research. 24 | Its target audience is researchers who have little to no prior computational experience, 25 | and its lessons are domain specific, 26 | building on learners' existing knowledge to enable them to quickly apply skills learned to their own research. 27 |
28 |
29 |
30 |
31 |
32 | Library Carpentry logo 33 |
34 |
35 | Library Carpentry is made by librarians to help librarians 36 | automate repetitive, boring, error-prone tasks; 37 | create, maintain and analyse sustainable and reusable data; 38 | work effectively with IT and systems colleagues; 39 | better understand the use of software in research; 40 | and much more. 41 | Library Carpentry was the winner of the 2016 42 | British Library Labs Teaching and Learning Award. 43 |
44 |
45 | -------------------------------------------------------------------------------- /bin/chunk-options.R: -------------------------------------------------------------------------------- 1 | # These settings control the behavior of all chunks in the novice R materials. 2 | # For example, to generate the lessons with all the output hidden, simply change 3 | # `results` from "markup" to "hide". 4 | # For more information on available chunk options, see 5 | # http://yihui.name/knitr/options#chunk_options 6 | 7 | library("knitr") 8 | 9 | fix_fig_path <- function(pth) file.path("..", pth) 10 | 11 | 12 | ## We set the path for the figures globally below, so if we want to 13 | ## customize it for individual episodes, we can append a prefix to the 14 | ## global path. For instance, if we call knitr_fig_path("01-") in the 15 | ## first episode of the lesson, it will generate the figures in 16 | ## `fig/rmd-01-` 17 | knitr_fig_path <- function(prefix) { 18 | new_path <- paste0(opts_chunk$get("fig.path"), 19 | prefix) 20 | opts_chunk$set(fig.path = new_path) 21 | } 22 | 23 | ## We use the rmd- prefix for the figures generated by the lssons so 24 | ## they can be easily identified and deleted by `make clean-rmd`. The 25 | ## working directory when the lessons are generated is the root so the 26 | ## figures need to be saved in fig/, but when the site is generated, 27 | ## the episodes will be one level down. We fix the path using the 28 | ## `fig.process` option. 29 | 30 | opts_chunk$set(tidy = FALSE, results = "markup", comment = NA, 31 | fig.align = "center", fig.path = "fig/rmd-", 32 | fig.process = fix_fig_path) 33 | 34 | # The hooks below add html tags to the code chunks and their output so that they 35 | # are properly formatted when the site is built. 36 | 37 | hook_in <- function(x, options) { 38 | stringr::str_c("\n\n~~~\n", 39 | paste0(x, collapse="\n"), 40 | "\n~~~\n{: .r}\n\n") 41 | } 42 | 43 | hook_out <- function(x, options) { 44 | x <- gsub("\n$", "", x) 45 | stringr::str_c("\n\n~~~\n", 46 | paste0(x, collapse="\n"), 47 | "\n~~~\n{: .output}\n\n") 48 | } 49 | 50 | hook_error <- function(x, options) { 51 | x <- gsub("\n$", "", x) 52 | stringr::str_c("\n\n~~~\n", 53 | paste0(x, collapse="\n"), 54 | "\n~~~\n{: .error}\n\n") 55 | } 56 | 57 | knit_hooks$set(source = hook_in, output = hook_out, warning = hook_error, 58 | error = hook_error, message = hook_out) 59 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------ 2 | # Values for this lesson. 3 | #------------------------------------------------------------ 4 | 5 | # Which carpentry is this ("swc" or "dc")? 6 | carpentry: "swc" 7 | 8 | # Overall title for pages. 9 | title: "Version Control with Git" 10 | 11 | # Contact email address. 12 | email: lessons@software-carpentry.org 13 | 14 | #------------------------------------------------------------ 15 | # Generic settings (should not need to change). 16 | #------------------------------------------------------------ 17 | 18 | # What kind of thing is this ("workshop" or "lesson")? 19 | kind: "lesson" 20 | 21 | # Magic to make URLs resolve both locally and on GitHub. 22 | # See https://help.github.com/articles/repository-metadata-on-github-pages/. 23 | repository: / 24 | 25 | # Sites. 26 | amy_site: "https://amy.software-carpentry.org/workshops" 27 | dc_site: "http://datacarpentry.org" 28 | swc_github: "https://github.com/swcarpentry" 29 | swc_site: "https://software-carpentry.org" 30 | swc_pages: "https://swcarpentry.github.io" 31 | template_repo: "https://github.com/swcarpentry/styles" 32 | example_repo: "https://github.com/swcarpentry/lesson-example" 33 | example_site: "https://swcarpentry.github.com/lesson-example" 34 | workshop_repo: "https://github.com/swcarpentry/workshop-template" 35 | workshop_site: "https://swcarpentry.github.io/workshop-template" 36 | training_site: "https://swcarpentry.github.io/instructor-training" 37 | 38 | # Surveys. 39 | pre_survey: "https://www.surveymonkey.com/r/swc_pre_workshop_v1?workshop_id=" 40 | post_survey: "https://www.surveymonkey.com/r/swc_post_workshop_v1?workshop_id=" 41 | 42 | # Start time in minutes (0 to be clock-independent, 540 to show a start at 09:00 am) 43 | start_time: 0 44 | 45 | # Specify that things in the episodes collection should be output. 46 | collections: 47 | episodes: 48 | output: true 49 | permalink: /:path/ 50 | extras: 51 | output: true 52 | 53 | # Set the default layout for things in the episodes collection. 54 | defaults: 55 | - values: 56 | root: .. 57 | - scope: 58 | path: "" 59 | type: episodes 60 | values: 61 | layout: episode 62 | 63 | # Files and directories that are not to be copied. 64 | exclude: 65 | - Makefile 66 | - bin 67 | 68 | # Turn off built-in syntax highlighting. 69 | highlighter: false 70 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Alison Appling 2 | Sean Aubin 3 | Pete Bachant 4 | Daniel Baird 5 | Pauline Barmby 6 | Bérénice Batut 7 | Maxim Belkin 8 | Madeleine Bonsma 9 | Jon Borrelli 10 | Andy Boughton 11 | Daina Bouquin 12 | Rudi Brauning 13 | Matthew Brett 14 | Amy Brown 15 | Jane Charlesworth 16 | Billy Charlton 17 | Daniel Chen 18 | Garret Christensen 19 | Ruth Collings 20 | Marianne Corvellec 21 | Matt Davis 22 | Emily Dolson 23 | Laurent Duchesne 24 | Jonah Duckles 25 | Rémi Emonet 26 | Loïc Estève 27 | Emmanouil Farsarakis 28 | Bennet Fauber 29 | Anne Fouilloux 30 | Stuart Geiger 31 | Ivan Gonzalez 32 | Marisa Guarinello 33 | Stéphane Guillou 34 | Jamie Hadwin 35 | Matthias Haeni 36 | Pierre Haessig 37 | Nicholas Hannah 38 | Sumana Harihareswara 39 | Alois Heilmaier 40 | Martin Heroux 41 | Kate Hertweck 42 | Daisie Huang 43 | Yuandra Ismiraldi 44 | Christian Jacobs 45 | Dorota Jarecka 46 | Luke W. Johnston 47 | David Jones 48 | Zbigniew Jędrzejewski-Szmek 49 | Tom Kelly 50 | W. Trevor King 51 | Thomas Kluyver 52 | Bernhard Konrad 53 | Mateusz Kuzak 54 | Arne Küderle 55 | Kathleen Labrie 56 | Hilmar Lapp 57 | Mark Laufersweiler 58 | David LeBauer 59 | Kate Lee 60 | Matthias Liffers 61 | Clara Llebot 62 | Catrina Loucks 63 | Keith Ma 64 | Kunal Marwaha 65 | Ryan May 66 | Bill Mills 67 | Andreas Mueller 68 | Madicken Munk 69 | Juan Nunez-Iglesias 70 | Brenna O'Brien 71 | Catherine Olsson 72 | Michael Panitz 73 | Chris Pawsey 74 | Stefan Pfenninger 75 | Paul Preney 76 | Timothy Rice 77 | Kristina Riemer 78 | Annika Rockenberger 79 | Andrew Rohl 80 | Ariel Rokem 81 | Bill Sacks 82 | Michael Sarahan 83 | Sebastian Schmeier 84 | Hartmut Schmider 85 | Peter Shellito 86 | Patrick C. Shriwise 87 | Raniere Silva 88 | Brendan Smithyman 89 | Nicola Soranzo 90 | Peter Steinbach 91 | Sarah Stevens 92 | Oliver Stueker 93 | Benjamin Stuermer 94 | Tiffany Timbers 95 | Danielle Traphagen 96 | Tim Tröndle 97 | Anelda van der Walt 98 | Steve Vandervalk 99 | Greg Watson 100 | Belinda Weaver 101 | Mark Wheelhouse 102 | Ethan White 103 | Greg Wilson 104 | Steven Wu 105 | Qingpeng Zhang 106 | Andrew Lonsdale 107 | Arnstein Orten 108 | Ben Bolker 109 | Christoph Junghans 110 | David Jennings 111 | James Tocknell 112 | Jonathan Cooper 113 | Katrin Leinweber 114 | Leo Browning 115 | Mary C. Kinniburgh 116 | Matthew Bourque 117 | Matthew Hartley 118 | Raphaël Grolimund 119 | Scott Bailey 120 | Todd Gamblin 121 | Tommy Keswick 122 | Vijay P. Nagraj 123 | Will Usher 124 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: lesson 3 | root: . 4 | --- 5 | 6 | Wolfman and Dracula have been hired by Universal Missions (a space 7 | services spinoff from Euphoric State University) to investigate if it 8 | is possible to send their next planetary lander to Mars. They want to 9 | be able to work on the plans at the same time, but they have run into 10 | problems doing this in the past. If they take turns, each one will 11 | spend a lot of time waiting for the other to finish, but if they work 12 | on their own copies and email changes back and forth things will be 13 | lost, overwritten, or duplicated. 14 | 15 | A colleague suggests using [version control]({{ page.root }}/reference/#version-control) to 16 | manage their work. Version control is better than mailing files back and forth: 17 | 18 | * Nothing that is committed to version control is ever lost, unless 19 | you work really, really hard at it. Since all old versions of 20 | files are saved, it's always possible to go back in time to see 21 | exactly who wrote what on a particular day, or what version of a 22 | program was used to generate a particular set of results. 23 | 24 | * As we have this record of who made what changes when, we know who to ask 25 | if we have questions later on, and, if needed, revert to a previous 26 | version, much like the "undo" feature in an editor. 27 | 28 | * When several people collaborate in the same project, it's possible to 29 | accidentally overlook or overwrite someone's changes. The version control 30 | system automatically notifies users whenever there's a conflict between one 31 | person's work and another's. 32 | 33 | Teams are not the only ones to benefit from version control: lone 34 | researchers can benefit immensely. Keeping a record of what was 35 | changed, when, and why is extremely useful for all researchers if they 36 | ever need to come back to the project later on (e.g., a year later, 37 | when memory has faded). 38 | 39 | Version control is the lab notebook of the digital world: it's what 40 | professionals use to keep track of what they've done and to 41 | collaborate with other people. Every large software development 42 | project relies on it, and most programmers use it for their small jobs 43 | as well. And it isn't just for software: books, 44 | papers, small data sets, and anything that changes over time or needs 45 | to be shared can and should be stored in a version control system. 46 | 47 | > ## Prerequisites 48 | > 49 | > In this lesson we use Git from the Unix Shell. 50 | > Some previous experience with the shell is expected, 51 | > *but isn't mandatory*. 52 | {: .prereq} 53 | -------------------------------------------------------------------------------- /_includes/lc/syllabys.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Data Intro

4 |
    5 |
  • Intro to data
  • 6 |
  • Jargon busting
  • 7 |
  • Keyboard shortcuts
  • 8 |
  • Plain text formats
  • 9 |
  • Naming files
  • 10 |
  • Regular expressions
  • 11 |
  • Reference...
  • 12 |
13 |
14 |
15 |

The Unix Shell

16 |
    17 |
  • Files and directories
  • 18 |
  • History and tab completion
  • 19 |
  • Counting and sorting contents in files
  • 20 |
  • Pipes and redirection
  • 21 |
  • Mining or searching in files
  • 22 |
  • Reference...
  • 23 |
24 |
25 | 26 |
27 | 28 |
29 |
30 |

Version Control with Git

31 |
    32 |
  • Creating a repository
  • 33 |
  • Configuring git
  • 34 |
  • Recording changes to files: add, commit, ...
  • 35 |
  • Viewing state changes with status
  • 36 |
  • Working on the web: clone, pull, push, ...
  • 37 |
  • Where to host work, and why
  • 38 |
  • Reference...
  • 39 |
40 |
41 |
42 |
43 |

Open Refine

44 |
    45 |
  • Introduction to OpenRefine
  • 46 |
  • Importing data
  • 47 |
  • Basic functions
  • 48 |
  • Advanced Functions
  • 49 |
  • Reference...
  • 50 |
51 |
52 |
53 |
54 | 70 | -------------------------------------------------------------------------------- /_layouts/workshop.html: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% if page.redirect %} 21 | 22 | {% endif %} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {% if site.carpentry == "swc" %} 32 | 33 | {% elsif site.carpentry == "dc" %} 34 | 35 | {% elsif site.carpentry == "lc" %} 36 | 37 | {% endif %} 38 | 39 | 40 | 44 | {{ page.venue }}: {{ page.humandate }} 45 | 46 | 47 |
48 | {% include navbar.html %} 49 | {% include workshop_ad.html %} 50 | {{ content }} 51 | {% include workshop_footer.html %} 52 |
53 | {% include javascript.html %} 54 | 55 | 56 | -------------------------------------------------------------------------------- /_includes/all_figures.html: -------------------------------------------------------------------------------- 1 |

Adding Collaborators on GitHub

2 |
3 |

After Creating Clone of Repository

4 |
5 |

The Git Staging Area

6 |
7 |

The Git Commit Workflow

8 |
9 |

Piled Higher and Deeper by Jorge Cham, http://www.phdcomics.com/comics/archive_print.php?comicid=1531

10 |
11 |

Changes Are Saved Sequentially

12 |
13 |

Different Versions Can be Saved

14 |
15 |

Multiple Versions Can be Merged

16 |
17 |

Git Checkout

18 |
19 |

http://figshare.com/articles/How_Git_works_a_cartoon/1328266

20 |
21 |

22 |
23 |

24 |
25 |

26 |
27 |

28 |
29 |

30 |
31 |

32 |
33 |

34 |
35 |

36 |
37 |

38 |
39 |

40 |
41 |

Creating a Repository on GitHub (Step 1)

42 |
43 |

Creating a Repository on GitHub (Step 2)

44 |
45 |

Creating a Repository on GitHub (Step 3)

46 |
47 |

Freshly-Made GitHub Repository

48 |
49 |

Where to Find Repository URL on GitHub

50 |
51 |

Changing the Repository URL on GitHub

52 |
53 |

GitHub Repository After First Push

54 |
55 |

The Conflicting Changes

56 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Abigail Cabunoc Mayes 2 | Abigail Cabunoc Mayes 3 | Alois Heilmaier 4 | Andrew Lonsdale 5 | Andrew Rohl 6 | Ariel Rokem 7 | Arnstein Orten 8 | Bennet Fauber 9 | Bérénice Batut 10 | Bérénice Batut 11 | Bernhard Konrad 12 | Bill Mills 13 | Brenna O'Brien 14 | Chris Pawsey 15 | Christoph Junghans 16 | Daisie Huang 17 | Danielle Traphagen 18 | Dorota Jarecka 19 | Emily Dolson 20 | Emmanouil Farsarakis 21 | Erin Becker 22 | Evan P. Williamson 23 | François Michonneau 24 | Greg Watson 25 | Greg Wilson 26 | Ivan Gonzalez 27 | James Allen 28 | Jane Charlesworth 29 | Kate Lee 30 | Luke W. Johnston 31 | Marisa Guarinello 32 | Mark Wheelhouse 33 | Mary C. Kinniburgh 34 | Mateusz Kuzak 35 | Matthias Haeni 36 | Maxim Belkin 37 | Michael Panitz 38 | Mike Jackson 39 | Nicholas Hannah 40 | Nicola Soranzo 41 | Patrick C. Shriwise 42 | Pauline Barmby 43 | Peter Steinbach 44 | Raniere Silva 45 | Raniere Silva 46 | Rémi Emonet 47 | Rémi Emonet 48 | Sarah Stevens 49 | Sean Aubin 50 | Steve Vandervalk 51 | Tiffany Timbers 52 | Timothée Poisot 53 | Tom Kelly 54 | Vijay P. Nagraj 55 | Yuandra Ismiraldi 56 | zz-abracarambar 57 | -------------------------------------------------------------------------------- /bin/extract_figures.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | import sys 5 | import os 6 | import glob 7 | from optparse import OptionParser 8 | 9 | from util import Reporter, read_markdown, IMAGE_FILE_SUFFIX 10 | 11 | def main(): 12 | """Main driver.""" 13 | 14 | args = parse_args() 15 | images = [] 16 | for filename in args.filenames: 17 | images += get_images(args.parser, filename) 18 | save(sys.stdout, images) 19 | 20 | 21 | def parse_args(): 22 | """Parse command-line arguments.""" 23 | 24 | parser = OptionParser() 25 | parser.add_option('-p', '--parser', 26 | default=None, 27 | dest='parser', 28 | help='path to Markdown parser') 29 | 30 | args, extras = parser.parse_args() 31 | require(args.parser is not None, 32 | 'Path to Markdown parser not provided') 33 | require(extras, 34 | 'No filenames specified') 35 | 36 | args.filenames = extras 37 | return args 38 | 39 | 40 | def get_filenames(source_dir): 41 | """Get all filenames to be searched for images.""" 42 | 43 | return glob.glob(os.path.join(source_dir, '*.md')) 44 | 45 | 46 | def get_images(parser, filename): 47 | """Extract all images from file.""" 48 | 49 | content = read_markdown(parser, filename) 50 | result = [] 51 | find_image_nodes(content['doc'], result) 52 | find_image_links(content['doc'], result) 53 | return result 54 | 55 | 56 | def find_image_nodes(doc, result): 57 | """Find all nested nodes representing images.""" 58 | 59 | if (doc['type'] == 'img') or \ 60 | ((doc['type'] == 'html_element') and (doc['value'] == 'img')): 61 | alt = doc['attr'].get('alt', '') 62 | result.append({'alt': alt, 'src': doc['attr']['src']}) 63 | else: 64 | for child in doc.get('children', []): 65 | find_image_nodes(child, result) 66 | 67 | 68 | def find_image_links(doc, result): 69 | """Find all links to files in the 'fig' directory.""" 70 | 71 | if ((doc['type'] == 'a') and ('attr' in doc) and ('href' in doc['attr'])) \ 72 | or \ 73 | ((doc['type'] == 'html_element') and (doc['value'] == 'a') and ('href' in doc['attr'])): 74 | path = doc['attr']['href'] 75 | if os.path.splitext(path)[1].lower() in IMAGE_FILE_SUFFIX: 76 | result.append({'alt':'', 'src': doc['attr']['href']}) 77 | else: 78 | for child in doc.get('children', []): 79 | find_image_links(child, result) 80 | 81 | 82 | def save(stream, images): 83 | """Save results as Markdown.""" 84 | 85 | text = '\n
\n'.join(['

{0}

'.format(img['alt'], img['src']) for img in images]) 86 | print(text, file=stream) 87 | 88 | 89 | def require(condition, message): 90 | """Fail if condition not met.""" 91 | 92 | if not condition: 93 | print(message, file=sys.stderr) 94 | sys.exit(1) 95 | 96 | 97 | if __name__ == '__main__': 98 | main() 99 | -------------------------------------------------------------------------------- /fig/merge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Licenses" 4 | permalink: /license/ 5 | --- 6 | ## Instructional Material 7 | 8 | All Software Carpentry and Data Carpentry instructional material is 9 | made available under the [Creative Commons Attribution 10 | license][cc-by-human]. The following is a human-readable summary of 11 | (and not a substitute for) the [full legal text of the CC BY 4.0 12 | license][cc-by-legal]. 13 | 14 | You are free: 15 | 16 | * to **Share**---copy and redistribute the material in any medium or format 17 | * to **Adapt**---remix, transform, and build upon the material 18 | 19 | for any purpose, even commercially. 20 | 21 | The licensor cannot revoke these freedoms as long as you follow the 22 | license terms. 23 | 24 | Under the following terms: 25 | 26 | * **Attribution**---You must give appropriate credit (mentioning that 27 | your work is derived from work that is Copyright © Software 28 | Carpentry and, where practical, linking to 29 | http://software-carpentry.org/), provide a [link to the 30 | license][cc-by-human], and indicate if changes were made. You may do 31 | so in any reasonable manner, but not in any way that suggests the 32 | licensor endorses you or your use. 33 | 34 | **No additional restrictions**---You may not apply legal terms or 35 | technological measures that legally restrict others from doing 36 | anything the license permits. With the understanding that: 37 | 38 | Notices: 39 | 40 | * You do not have to comply with the license for elements of the 41 | material in the public domain or where your use is permitted by an 42 | applicable exception or limitation. 43 | * No warranties are given. The license may not give you all of the 44 | permissions necessary for your intended use. For example, other 45 | rights such as publicity, privacy, or moral rights may limit how you 46 | use the material. 47 | 48 | ## Software 49 | 50 | Except where otherwise noted, the example programs and other software 51 | provided by Software Carpentry and Data Carpentry are made available under the 52 | [OSI][osi]-approved 53 | [MIT license][mit-license]. 54 | 55 | Permission is hereby granted, free of charge, to any person obtaining 56 | a copy of this software and associated documentation files (the 57 | "Software"), to deal in the Software without restriction, including 58 | without limitation the rights to use, copy, modify, merge, publish, 59 | distribute, sublicense, and/or sell copies of the Software, and to 60 | permit persons to whom the Software is furnished to do so, subject to 61 | the following conditions: 62 | 63 | The above copyright notice and this permission notice shall be 64 | included in all copies or substantial portions of the Software. 65 | 66 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 67 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 68 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 69 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 70 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 71 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 72 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 73 | 74 | ## Trademark 75 | 76 | "Software Carpentry" and "Data Carpentry" and their respective logos 77 | are registered trademarks of [NumFOCUS][numfocus]. 78 | 79 | [cc-by-human]: https://creativecommons.org/licenses/by/4.0/ 80 | [cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode 81 | [mit-license]: http://opensource.org/licenses/mit-license.html 82 | [numfocus]: http://numfocus.org/ 83 | [osi]: http://opensource.org 84 | -------------------------------------------------------------------------------- /_includes/syllabus.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Display syllabus in tabular form. 3 | Days are displayed if at least one episode has 'start = true'. 4 | {% endcomment %} 5 |
6 |

Schedule

7 | 8 | {% assign lesson_number = 0 %} 9 | {% assign day = 0 %} 10 | {% assign multiday = false %} 11 | {% for episode in site.episodes %} 12 | {% if episode.start %}{% assign multiday = true %}{% break %}{% endif %} 13 | {% endfor %} 14 | {% assign current = site.start_time %} 15 | 16 | 17 | 18 | {% if multiday %}{% endif %} 19 | 20 | 21 | 22 | 23 | {% for episode in site.episodes %} 24 | {% if episode.start %} {% comment %} Starting a new day? {% endcomment %} 25 | {% assign day = day | plus: 1 %} 26 | {% if day > 1 %} {% comment %} If about to start day 2 or later, show finishing time for previous day {% endcomment %} 27 | {% assign hours = current | divided_by: 60 %} 28 | {% assign minutes = current | modulo: 60 %} 29 | 30 | {% if multiday %}{% endif %} 31 | 32 | 33 | 34 | 35 | {% endif %} 36 | {% assign current = site.start_time %} {% comment %}Re-set start time of this episode to general daily start time {% endcomment %} 37 | {% endif %} 38 | {% assign hours = current | divided_by: 60 %} 39 | {% assign minutes = current | modulo: 60 %} 40 | 41 | {% if multiday %}{% endif %} 42 | 43 | 47 | 61 | 62 | {% assign current = current | plus: episode.teaching | plus: episode.exercises | plus: episode.break %} 63 | {% endfor %} 64 | {% assign hours = current | divided_by: 60 %} 65 | {% assign minutes = current | modulo: 60 %} 66 | 67 | {% if multiday %}{% endif %} 68 | 69 | 70 | 71 | 72 |
SetupDownload files required for the lesson
{% if hours < 10 %}0{% endif %}{{ hours }}:{% if minutes < 10 %}0{% endif %}{{ minutes }}Finish
{% if episode.start %}Day {{ day }}{% endif %}{% if hours < 10 %}0{% endif %}{{ hours }}:{% if minutes < 10 %}0{% endif %}{{ minutes }} 44 | {% assign lesson_number = lesson_number | plus: 1 %} 45 | {{ lesson_number }}. {{ episode.title }} 46 | 48 | {% if episode.break %} 49 | Break 50 | {% else %} 51 | {% if episode.questions %} 52 | {% for question in episode.questions %} 53 | {{question|markdownify|strip_html}} 54 | {% unless forloop.last %} 55 |
56 | {% endunless %} 57 | {% endfor %} 58 | {% endif %} 59 | {% endif %} 60 |
{% if hours < 10 %}0{% endif %}{{ hours }}:{% if minutes < 10 %}0{% endif %}{{ minutes }}Finish
73 | 74 |

75 | The actual schedule may vary slightly depending on the topics and exercises chosen by the instructor. 76 |

77 | 78 |
79 | -------------------------------------------------------------------------------- /reference.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: reference 3 | permalink: /reference/ 4 | --- 5 | 6 | ## Git Cheatsheets for Quick Reference 7 | 8 | * A great [printable git cheatsheet](https://services.github.com/on-demand/downloads/github-git-cheat-sheet.pdf) is available in PDF from the 9 | [GitHub training website](https://services.github.com/resources/). 10 | * An [interactive one-page visualisation](http://ndpsoftware.com/git-cheatsheet.html) 11 | about the relationships between workspace, staging area, local repository, upstream repository, and the commands associated with each (with explanations). 12 | * Both resources are also available in other languages e.g. Spanish, French, and more 13 | 14 | ## Glossary 15 | 16 | {:auto_ids} 17 | changeset 18 | : A group of changes to one or more files that are or will be added 19 | to a single [commit](#commit) in a [version control](#version-control) 20 | [repository](#repository). 21 | 22 | commit 23 | : To record the current state of a set of files (a [changeset](#changeset)) 24 | in a [version control](#version-control) [repository](#repository). As a noun, 25 | the result of committing, i.e. a recorded changeset in a repository. 26 | If a commit contains changes to multiple files, 27 | all of the changes are recorded together. 28 | 29 | conflict 30 | : A change made by one user of a [version control system](#version-control) 31 | that is incompatible with changes made by other users. 32 | Helping users [resolve](#resolve) conflicts 33 | is one of version control's major tasks. 34 | 35 | HTTP 36 | : The Hypertext Transfer [Protocol](#protocol) used for sharing web pages and other data 37 | on the World Wide Web. 38 | 39 | merge 40 | : (a repository): To reconcile two sets of changes to a 41 | [repository](#repository). 42 | 43 | protocol 44 | : A set of rules that define how one computer communicates with another. 45 | Common protocols on the Internet include [HTTP](#http) and [SSH](#ssh). 46 | 47 | remote 48 | : (of a repository) A version control [repository](#repository) connected to another, 49 | in such way that both can be kept in sync exchanging [commits](#commit). 50 | 51 | repository 52 | : A storage area where a [version control](#version-control) system 53 | stores the full history of [commits](#commit) of a project and information 54 | about who changed what, when. 55 | 56 | resolve 57 | : To eliminate the [conflicts](#conflict) between two or more incompatible changes to a file or set of files 58 | being managed by a [version control](#version-control) system. 59 | 60 | revision 61 | : A synonym for [commit](#commit). 62 | 63 | SHA-1 64 | : [SHA-1 hashes](http://en.wikipedia.org/wiki/SHA-1) is what Git uses to compute identifiers, including for commits. 65 | To compute these, Git uses not only the actual change of a commit, but also its metadata (such as date, author, 66 | message), including the identifiers of all commits of preceding changes. This makes Git commit IDs virtually unique. 67 | I.e., the likelihood that two commits made independently, even of the same change, receive the same ID is exceedingly 68 | small. 69 | 70 | SSH 71 | : The Secure Shell [protocol](#protocol) used for secure communication between computers. 72 | 73 | timestamp 74 | : A record of when a particular event occurred. 75 | 76 | version control 77 | : A tool for managing changes to a set of files. 78 | Each set of changes creates a new [commit](#commit) of the files; 79 | the version control system allows users to recover old commits reliably, 80 | and helps manage conflicting changes made by different users. 81 | -------------------------------------------------------------------------------- /_includes/dc/syllabus.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

The Unix Shell

4 |
    5 |
  • Files and directories
  • 6 |
  • History and tab completion
  • 7 |
  • Pipes and redirection
  • 8 |
  • Looping over files
  • 9 |
  • Creating and running shell scripts
  • 10 |
  • Finding things
  • 11 |
  • Reference...
  • 12 |
13 |
14 |
15 |

Programming in Python

16 |
    17 |
  • Using libraries
  • 18 |
  • Working with arrays
  • 19 |
  • Reading and plotting data
  • 20 |
  • Creating and using functions
  • 21 |
  • Loops and conditionals
  • 22 |
  • Defensive programming
  • 23 |
  • Using Python from the command line
  • 24 |
  • Reference...
  • 25 |
26 |
27 | 40 | 53 |
54 | 55 |
56 |
57 |

Version Control with Git

58 |
    59 |
  • Creating a repository
  • 60 |
  • Recording changes to files: add, commit, ...
  • 61 |
  • Viewing changes: status, diff, ...
  • 62 |
  • Ignoring files
  • 63 |
  • Working on the web: clone, pull, push, ...
  • 64 |
  • Resolving conflicts
  • 65 |
  • Open licenses
  • 66 |
  • Where to host work, and why
  • 67 |
  • Reference...
  • 68 |
69 |
70 | 86 |
87 |

Open Refine

88 |
    89 |
  • Introduction to OpenRefine
  • 90 |
  • Importing data
  • 91 |
  • Basic functions
  • 92 |
  • Advanced Functions
  • 93 |
  • Reference...
  • 94 |
95 |
96 |
97 | -------------------------------------------------------------------------------- /_includes/sc/syllabus.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

The Unix Shell

4 |
    5 |
  • Files and directories
  • 6 |
  • History and tab completion
  • 7 |
  • Pipes and redirection
  • 8 |
  • Looping over files
  • 9 |
  • Creating and running shell scripts
  • 10 |
  • Finding things
  • 11 |
  • Reference...
  • 12 |
13 |
14 |
15 |

Programming in Python

16 |
    17 |
  • Using libraries
  • 18 |
  • Working with arrays
  • 19 |
  • Reading and plotting data
  • 20 |
  • Creating and using functions
  • 21 |
  • Loops and conditionals
  • 22 |
  • Defensive programming
  • 23 |
  • Using Python from the command line
  • 24 |
  • Reference...
  • 25 |
26 |
27 | 40 | 53 |
54 | 55 |
56 |
57 |

Version Control with Git

58 |
    59 |
  • Creating a repository
  • 60 |
  • Recording changes to files: add, commit, ...
  • 61 |
  • Viewing changes: status, diff, ...
  • 62 |
  • Ignoring files
  • 63 |
  • Working on the web: clone, pull, push, ...
  • 64 |
  • Resolving conflicts
  • 65 |
  • Open licenses
  • 66 |
  • Where to host work, and why
  • 67 |
  • Reference...
  • 68 |
69 |
70 | 86 |
87 |

Open Refine

88 |
    89 |
  • Introduction to OpenRefine
  • 90 |
  • Importing data
  • 91 |
  • Basic functions
  • 92 |
  • Advanced Functions
  • 93 |
  • Reference...
  • 94 |
95 |
96 |
97 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ## ======================================== 2 | ## Commands for both workshop and lesson websites. 3 | 4 | # Settings 5 | MAKEFILES=Makefile $(wildcard *.mk) 6 | JEKYLL=jekyll 7 | PARSER=bin/markdown_ast.rb 8 | DST=_site 9 | 10 | # Controls 11 | .PHONY : commands clean files 12 | .NOTPARALLEL: 13 | all : commands 14 | 15 | ## commands : show all commands. 16 | commands : 17 | @grep -h -E '^##' ${MAKEFILES} | sed -e 's/## //g' 18 | 19 | ## serve : run a local server. 20 | serve : lesson-md 21 | ${JEKYLL} serve 22 | 23 | ## site : build files but do not run a server. 24 | site : lesson-md 25 | ${JEKYLL} build 26 | 27 | # repo-check : check repository settings. 28 | repo-check : 29 | @bin/repo_check.py -s . 30 | 31 | ## clean : clean up junk files. 32 | clean : 33 | @rm -rf ${DST} 34 | @rm -rf .sass-cache 35 | @rm -rf bin/__pycache__ 36 | @find . -name .DS_Store -exec rm {} \; 37 | @find . -name '*~' -exec rm {} \; 38 | @find . -name '*.pyc' -exec rm {} \; 39 | 40 | ## clean-rmd : clean intermediate R files (that need to be committed to the repo). 41 | clear-rmd : 42 | @rm -rf ${RMD_DST} 43 | @rm -rf fig/rmd-* 44 | 45 | ## ---------------------------------------- 46 | ## Commands specific to workshop websites. 47 | 48 | .PHONY : workshop-check 49 | 50 | ## workshop-check : check workshop homepage. 51 | workshop-check : 52 | @bin/workshop_check.py . 53 | 54 | ## ---------------------------------------- 55 | ## Commands specific to lesson websites. 56 | 57 | .PHONY : lesson-check lesson-md lesson-files lesson-fixme 58 | 59 | # RMarkdown files 60 | RMD_SRC = $(wildcard _episodes_rmd/??-*.Rmd) 61 | RMD_DST = $(patsubst _episodes_rmd/%.Rmd,_episodes/%.md,$(RMD_SRC)) 62 | 63 | # Lesson source files in the order they appear in the navigation menu. 64 | MARKDOWN_SRC = \ 65 | index.md \ 66 | CONDUCT.md \ 67 | setup.md \ 68 | $(wildcard _episodes/*.md) \ 69 | reference.md \ 70 | $(wildcard _extras/*.md) \ 71 | LICENSE.md 72 | 73 | # Generated lesson files in the order they appear in the navigation menu. 74 | HTML_DST = \ 75 | ${DST}/index.html \ 76 | ${DST}/conduct/index.html \ 77 | ${DST}/setup/index.html \ 78 | $(patsubst _episodes/%.md,${DST}/%/index.html,$(wildcard _episodes/*.md)) \ 79 | ${DST}/reference/index.html \ 80 | $(patsubst _extras/%.md,${DST}/%/index.html,$(wildcard _extras/*.md)) \ 81 | ${DST}/license/index.html 82 | 83 | ## lesson-md : convert Rmarkdown files to markdown 84 | lesson-md : ${RMD_DST} 85 | 86 | # Use of .NOTPARALLEL makes rule execute only once 87 | ${RMD_DST} : ${RMD_SRC} 88 | @bin/knit_lessons.sh ${RMD_SRC} 89 | 90 | ## lesson-check : validate lesson Markdown. 91 | lesson-check : 92 | @bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md 93 | 94 | ## lesson-check-all : validate lesson Markdown, checking line lengths and trailing whitespace. 95 | lesson-check-all : 96 | @bin/lesson_check.py -s . -p ${PARSER} -l -w 97 | 98 | ## lesson-figures : re-generate inclusion displaying all figures. 99 | lesson-figures : 100 | @bin/extract_figures.py -p ${PARSER} ${MARKDOWN_SRC} > _includes/all_figures.html 101 | 102 | ## unittest : run unit tests on checking tools. 103 | unittest : 104 | python bin/test_lesson_check.py 105 | 106 | ## lesson-files : show expected names of generated files for debugging. 107 | lesson-files : 108 | @echo 'RMD_SRC:' ${RMD_SRC} 109 | @echo 'RMD_DST:' ${RMD_DST} 110 | @echo 'MARKDOWN_SRC:' ${MARKDOWN_SRC} 111 | @echo 'HTML_DST:' ${HTML_DST} 112 | 113 | ## lesson-fixme : show FIXME markers embedded in source files. 114 | lesson-fixme : 115 | @fgrep -i -n FIXME ${MARKDOWN_SRC} || true 116 | 117 | #------------------------------------------------------------------------------- 118 | # Include extra commands if available. 119 | #------------------------------------------------------------------------------- 120 | 121 | -include commands.mk 122 | -------------------------------------------------------------------------------- /_episodes/01-basics.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Automated Version Control 3 | teaching: 5 4 | exercises: 0 5 | questions: 6 | - "What is version control and why should I use it?" 7 | objectives: 8 | - "Understand the benefits of an automated version control system." 9 | - "Understand the basics of how Git works." 10 | keypoints: 11 | - "Version control is like an unlimited 'undo'." 12 | - "Version control also allows many people to work in parallel." 13 | --- 14 | 15 | We'll start by exploring how version control can be used 16 | to keep track of what one person did and when. 17 | Even if you aren't collaborating with other people, 18 | automated version control is much better than this situation: 19 | 20 | [![Piled Higher and Deeper by Jorge Cham, http://www.phdcomics.com/comics/archive_print.php?comicid=1531](../fig/phd101212s.png)](http://www.phdcomics.com) 21 | 22 | "Piled Higher and Deeper" by Jorge Cham, http://www.phdcomics.com 23 | 24 | We've all been in this situation before: it seems ridiculous to have 25 | multiple nearly-identical versions of the same document. Some word 26 | processors let us deal with this a little better, such as Microsoft 27 | Word's [Track Changes](https://support.office.com/en-us/article/Track-changes-in-Word-197ba630-0f5f-4a8e-9a77-3712475e806a), Google Docs' [version 28 | history](https://support.google.com/docs/answer/190843?hl=en), or LibreOffice's [Recording and Displaying Changes](https://help.libreoffice.org/Common/Recording_and_Displaying_Changes). 29 | 30 | Version control systems start with a base version of the document and 31 | then save just the changes you made at each step of the way. You can 32 | think of it as a tape: if you rewind the tape and start at the base 33 | document, then you can play back each change and end up with your 34 | latest version. 35 | 36 | ![Changes Are Saved Sequentially](../fig/play-changes.svg) 37 | 38 | Once you think of changes as separate from the document itself, you 39 | can then think about "playing back" different sets of changes onto the 40 | base document and getting different versions of the document. For 41 | example, two users can make independent sets of changes based on the 42 | same document. 43 | 44 | ![Different Versions Can be Saved](../fig/versions.svg) 45 | 46 | Unless there are conflicts, you can even play two sets of changes onto the same base document. 47 | 48 | ![Multiple Versions Can be Merged](../fig/merge.svg) 49 | 50 | A version control system is a tool that keeps track of these changes for us and 51 | helps us version and merge our files. It allows you to 52 | decide which changes make up the next version, called a 53 | [commit]({{ page.root }}/reference/#commit), and keeps useful metadata about them. The 54 | complete history of commits for a particular project and their metadata make up 55 | a [repository]({{ page.root }}/reference/#repository). Repositories can be kept in sync 56 | across different computers facilitating collaboration among different people. 57 | 58 | > ## The Long History of Version Control Systems 59 | > 60 | > Automated version control systems are nothing new. 61 | > Tools like RCS, CVS, or Subversion have been around since the early 1980s and are used by many large companies. 62 | > However, many of these are now becoming considered as legacy systems due to various limitations in their capabilities. 63 | > In particular, the more modern systems, such as Git and [Mercurial](http://swcarpentry.github.io/hg-novice/) 64 | > are *distributed*, meaning that they do not need a centralized server to host the repository. 65 | > These modern systems also include powerful merging tools that make it possible for multiple authors to work within 66 | > the same files concurrently. 67 | {: .callout} 68 | 69 | > ## Paper Writing 70 | > 71 | > * Imagine you drafted an excellent paragraph for a paper you are writing, but later ruin it. How would you retrieve 72 | > the *excellent* version of your conclusion? Is it even possible? 73 | > 74 | > * Imagine you have 5 co-authors. How would you manage the changes and comments they make to your paper? 75 | > If you use LibreOffice Writer or Microsoft Word, what happens if you accept changes made using the 76 | > `Track Changes` option? Do you have a history of those changes? 77 | {: .challenge} 78 | -------------------------------------------------------------------------------- /_episodes/11-licensing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Licensing 3 | teaching: 5 4 | exercises: 0 5 | questions: 6 | - "What licensing information should I include with my work?" 7 | objectives: 8 | - "Explain why adding licensing information to a repository is important." 9 | - "Choose a proper license." 10 | - "Explain differences in licensing and social expectations." 11 | keypoints: 12 | - "People who incorporate GPL'd software into their own software must make their software also open under the GPL license; most other open licenses do not require this." 13 | - "The Creative Commons family of licenses allow people to mix and match requirements and restrictions on attribution, creation of derivative works, further sharing, and commercialization." 14 | - "People who are not lawyers should not try to write licenses from scratch." 15 | --- 16 | 17 | When a repository with source code, a manuscript or other creative 18 | works becomes public, it should include a file `LICENSE` or 19 | `LICENSE.txt` in the base directory of the repository that clearly 20 | states under which license the content is being made available. This 21 | is because creative works are automatically eligible for intellectual 22 | property (and thus copyright) protection. Reusing creative works 23 | without a license is dangerous, because the copyright holders could 24 | sue you for copyright infringement. 25 | 26 | A license solves this problem by granting rights to others (the 27 | licensees) that they would otherwise not have. What rights are being 28 | granted under which conditions differs, often only slightly, from one 29 | license to another. In practice, a few licenses are by far the most 30 | popular, and [choosealicense.com](http://choosealicense.com/) will 31 | help you find a common license that suits your needs. Important 32 | considerations include: 33 | 34 | * Whether you want to address patent rights. 35 | * Whether you require people distributing derivative works to also 36 | distribute their source code. 37 | * Whether the content you are licensing is source code. 38 | * Whether you want to license the code at all. 39 | 40 | Choosing a license that is in common use makes life easier for 41 | contributors and users, because they are more likely to already be 42 | familiar with the license and don't have to wade through a bunch of 43 | jargon to decide if they're ok with it. The [Open Source 44 | Initiative](http://opensource.org/licenses) and [Free Software 45 | Foundation](http://www.gnu.org/licenses/license-list.html) both 46 | maintain lists of licenses which are good choices. 47 | 48 | [This article][software-licensing] provides an excellent overview of 49 | licensing and licensing options from the perspective of scientists who 50 | also write code. 51 | 52 | At the end of the day what matters is that there is a clear statement 53 | as to what the license is. Also, the license is best chosen from the 54 | get-go, even if for a repository that is not public. Pushing off the 55 | decision only makes it more complicated later, because each time a new 56 | collaborator starts contributing, they, too, hold copyright and will 57 | thus need to be asked for approval once a license is chosen. 58 | 59 | > ## Can I Use Open License? 60 | > 61 | > Find out whether you are allowed to apply an open license to your software. 62 | > Can you do this unilaterally, 63 | > or do you need permission from someone in your institution? 64 | > If so, who? 65 | {: .challenge} 66 | 67 | > ## What licenses have I already accepted? 68 | > 69 | > Many of the software tools we use on a daily basis (including in this workshop) are 70 | > released as open-source software. Pick a project on GitHub from the list below, or 71 | > one of your own choosing. Find its license (usually in a file called `LICENSE` or 72 | > `COPYING`) and talk about how it restricts your use of the software. Is it one of 73 | > the licenses discussed in this session? How is it different? 74 | > - [Git](https://github.com/git/git), the source-code management tool 75 | > - [CPython](https://github.com/python/cpython), the standard implementation of the Python language 76 | > - [Jupyter](https://github.com/jupyter), the project behind the web-based Python notebooks we'll be using 77 | > - [EtherPad](https://github.com/ether/etherpad-lite), a real-time collaborative editor 78 | {: .challenge} 79 | 80 | [software-licensing]: http://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1002598 81 | -------------------------------------------------------------------------------- /_includes/navbar.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Lesson navigation bar. 3 | {% endcomment %} 4 | 85 | -------------------------------------------------------------------------------- /_episodes/13-hosting.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hosting 3 | teaching: 10 4 | exercises: 0 5 | questions: 6 | - "Where should I host my version control repositories?" 7 | objectives: 8 | - "Explain different options for hosting scientific work." 9 | keypoints: 10 | - "Projects can be hosted on university servers, on personal domains, or on public forges." 11 | - "Rules regarding intellectual property and storage of sensitive information apply no matter where code and data are hosted." 12 | --- 13 | 14 | The second big question for groups that want to open up their work is where to 15 | host their code and data. One option is for the lab, the department, or the 16 | university to provide a server, manage accounts and backups, and so on. The 17 | main benefit of this is that it clarifies who owns what, which is particularly 18 | important if any of the material is sensitive (i.e., relates to experiments 19 | involving human subjects or may be used in a patent application). The main 20 | drawbacks are the cost of providing the service and its longevity: a scientist 21 | who has spent ten years collecting data would like to be sure that data will 22 | still be available ten years from now, but that's well beyond the lifespan of 23 | most of the grants that fund academic infrastructure. 24 | 25 | Another option is to purchase a domain and pay an Internet service provider 26 | (ISP) to host it. This gives the individual or group more control, and 27 | sidesteps problems that can arise when moving from one institution to another, 28 | but requires more time and effort to set up than either the option above or the 29 | option below. 30 | 31 | The third option is to use a public hosting service like 32 | [GitHub](http://github.com), [GitLab](http://gitlab.com), 33 | [BitBucket](http://bitbucket.org), or [SourceForge](http://sourceforge.net). 34 | Each of these services provides a web interface that enables people to create, 35 | view, and edit their code repositories. These services also provide 36 | communication and project management tools including issue tracking, wiki pages, 37 | email notifications, and code reviews. These services benefit from economies of 38 | scale and network effects: it's easier to run one large service well than to run 39 | many smaller services to the same standard. It's also easier for people to 40 | collaborate. Using a popular service can help connect your project with 41 | communities already using the same service. 42 | 43 | As an example, Software Carpentry [is on 44 | GitHub]({{ swc_github }}) where you can find the [source for this 45 | page]({{page.root}}/_episodes/13-hosting.md). 46 | Anyone with a GitHub account can suggest changes to this text. 47 | 48 | Using large, well-established services can also help you quickly take advantage 49 | of powerful tools. One such tool, continuous integration (CI), can 50 | automatically run software builds and tests whenever code is committed or pull 51 | requests are submitted. Direct integration of CI with an online hosting service 52 | means this information is present in any pull request, and helps maintain code 53 | integrity and quality standards. While CI is still available in self-hosted 54 | situations, there is much less setup and maintenance involved with using an 55 | online service. Furthermore, such tools are often provided free of charge to 56 | open source projects, and are also available for private repositories for a fee. 57 | 58 | > ## Institutional Barriers 59 | > 60 | > Sharing is the ideal for science, 61 | > but many institutions place restrictions on sharing, 62 | > for example to protect potentially patentable intellectual property. 63 | > If you encounter such restrictions, 64 | > it can be productive to inquire about the underlying motivations 65 | > either to request an exception for a specific project or domain, 66 | > or to push more broadly for institutional reform to support more open science. 67 | {: .callout} 68 | 69 | > ## Can My Work Be Public? 70 | > 71 | > Find out whether you are allowed to host your work openly on a public forge. 72 | > Can you do this unilaterally, 73 | > or do you need permission from someone in your institution? 74 | > If so, who? 75 | {: .challenge} 76 | 77 | > ## Where Can I Share My Work? 78 | > 79 | > Does your institution have a repository or repositories that you can 80 | > use to share your papers, data and software? How do institutional repositories 81 | > differ from services like [arXiV](http://arxiv.org/), [figshare](http://figshare.com/) and [GitHub](http://github.com/)? 82 | {: .challenge} 83 | -------------------------------------------------------------------------------- /assets/css/lesson.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | //---------------------------------------- 5 | // Colors. 6 | //---------------------------------------- 7 | 8 | // branding 9 | $color-brand: #2b3990 !default; 10 | 11 | // code boxes 12 | $color-error: #bd2c00 !default; 13 | $color-output: #303030 !default; 14 | $color-source: #6e5494 !default; 15 | 16 | // blockquotes 17 | $color-callout: #f4fd9c !default; 18 | $color-challenge: #eec275 !default; 19 | $color-checklist: #dfd2a0 !default; 20 | $color-discussion: #eec275 !default; 21 | $color-keypoints: #7ae78e !default; 22 | $color-objectives: #daee84 !default; 23 | $color-prereq: #9cd6dc !default; 24 | $color-solution: #ded4b9 !default; 25 | $color-testimonial: #fc8dc1 !default; 26 | 27 | //---------------------------------------- 28 | // Specialized code blocks. 29 | //---------------------------------------- 30 | 31 | @mixin cdSetup($color) { 32 | color: $color; 33 | border-left: solid 5px $color; 34 | margin-bottom: 0px; 35 | border-radius: 4px 0 0 4px; 36 | } 37 | 38 | .error { @include cdSetup($color-error); } 39 | .output { @include cdSetup($color-output); } 40 | .source { @include cdSetup($color-source); } 41 | 42 | .bash { @include cdSetup($color-source); } 43 | .make { @include cdSetup($color-source); } 44 | .matlab { @include cdSetup($color-source); } 45 | .python { @include cdSetup($color-source); } 46 | .r { @include cdSetup($color-source); } 47 | .sql { @include cdSetup($color-source); } 48 | 49 | .error pre, 50 | .output pre, 51 | .source pre, 52 | .bash pre, 53 | .make pre, 54 | .matlab pre, 55 | .python pre, 56 | .r pre, 57 | .sql pre { 58 | border-radius: 0 4px 4px 0; 59 | } 60 | 61 | //---------------------------------------- 62 | // Specialized blockquote environments for learning objectives, callouts, etc. 63 | //---------------------------------------- 64 | 65 | $codeblock-padding: 5px !default; 66 | 67 | @mixin bkSetup($color, $glyph) { 68 | 69 | $gradientcolor1: $color; 70 | $gradientcolor2: scale-color($color, $lightness: 10%); 71 | 72 | padding-left: $codeblock-padding; 73 | padding-top: 0; 74 | padding-bottom: 0; 75 | padding-right: 0; 76 | border: 1px solid; 77 | border-color: $color; 78 | padding-bottom: $codeblock-padding; 79 | 80 | h2 { 81 | padding-top: $codeblock-padding; 82 | padding-bottom: $codeblock-padding; 83 | font-size: 20px; 84 | background: linear-gradient(to bottom, $gradientcolor1, $gradientcolor2); 85 | border-color: $color; 86 | margin-top: 0px; 87 | margin-left: -$codeblock-padding; // to move back to the left margin of the enclosing blockquote 88 | } 89 | h2:before { 90 | font-family: 'Glyphicons Halflings'; 91 | content: $glyph; 92 | float: left; 93 | padding-left: $codeblock-padding; 94 | padding-right: $codeblock-padding; 95 | display: inline-block; 96 | -webkit-font-smoothing: antialiased; 97 | } 98 | 99 | } 100 | 101 | .callout{ @include bkSetup($color-callout, "\e146"); } 102 | .challenge{ @include bkSetup($color-challenge, "\270f"); } 103 | .checklist{ @include bkSetup($color-checklist, "\e067"); } 104 | .discussion{ @include bkSetup($color-discussion, "\e123"); } 105 | .keypoints{ @include bkSetup($color-keypoints, "\e101"); } 106 | .objectives{ @include bkSetup($color-objectives, "\e085"); } 107 | .prereq{ @include bkSetup($color-prereq, "\e124"); } 108 | .solution{ @include bkSetup($color-solution, "\e105"); } 109 | .testimonial{ @include bkSetup($color-testimonial, "\e143"); } 110 | 111 | //---------------------------------------- 112 | // Override Bootstrap settings. 113 | //---------------------------------------- 114 | 115 | code { 116 | padding: 2px 5px; 117 | color: #3d90d9; 118 | background-color: #e7e7e7; 119 | } 120 | 121 | img { 122 | max-width: 100%; 123 | } 124 | 125 | //---------------------------------------- 126 | // Miscellaneous. 127 | //---------------------------------------- 128 | 129 | .maintitle { 130 | text-align: center; 131 | } 132 | 133 | .footertext { 134 | text-align: center; 135 | } 136 | 137 | img.navbar-logo { 138 | height: 40px; // synchronize with height of navbar 139 | padding-top: 5px; 140 | padding-right: 10px; 141 | } 142 | 143 | div.branding { 144 | color: $color-brand; 145 | } 146 | 147 | ul, 148 | ol { 149 | padding-left: 2em; 150 | } 151 | 152 | span.fold-unfold { 153 | margin-left: 1em; 154 | opacity: 0.5; 155 | } 156 | -------------------------------------------------------------------------------- /_episodes/14-supplemental-rstudio.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Using Git from RStudio 3 | teaching: 10 4 | exercises: 0 5 | questions: 6 | - "How can I use Git with RStudio?" 7 | objectives: 8 | - "Understand how to use Git from RStudio." 9 | keypoints: 10 | - "Create an RStudio project" 11 | --- 12 | 13 | Since version control is so useful when developing scripts, RStudio has built-in 14 | integration with Git. There are some more obscure Git features that you still 15 | need to use the command-line for, but RStudio has a nice interface for most 16 | common operations. 17 | 18 | RStudio let's you create a [project][rstudio-projects] associated with 19 | a given directory. This is a way to keep track of related files. One 20 | of the way to keep track of them is via version control! To get 21 | started using RStudio for version control, let's make a new project: 22 | 23 | ![](../fig/RStudio_screenshot_newproject.png) 24 | 25 | This will pop up a window asking us how we want to create the project. We have 26 | some options here. Let's say that we want to use RStudio with the planets 27 | repository that we already made. Since that repository lives in a directory on 28 | our computer, we'll choose "existing directory": 29 | 30 | ![](../fig/RStudio_screenshot_existingdirectory.png) 31 | 32 | > ## Do You See a "Version Control" Option? 33 | > 34 | > Although we're not going to use it here, there should be a "version control" 35 | > option on this menu. That is what you would click on if you wanted to 36 | > create a project on your computer by cloning a repository from github. 37 | > If that option is not present, it probably means that RStudio doesn't know 38 | > where your Git executable is. See 39 | > [this page](https://stat545-ubc.github.io/git03_rstudio-meet-git.html) 40 | > for some debugging advice. Even if you have Git installed, you may need 41 | > to accept the XCode license if you are using MacOSX. 42 | {: .callout} 43 | 44 | Next, RStudio will ask which existing directory we want to use. Click "browse" 45 | to navigate to the correct directory on your computer, then click "create 46 | project": 47 | 48 | ![](../fig/RStudio_screenshot_navigateexisting.png) 49 | 50 | Ta-da! Now you have an R project containing your repository. Notice the 51 | vertical "Git" menu that is now on the menu bar. This means RStudio has 52 | recognized that this directory is a git repository, so it's giving you tools 53 | to use Git: 54 | 55 | ![](../fig/RStudio_screenshot_afterclone.png) 56 | 57 | To edit the files in your repository, you can click on them from the panel in 58 | the lower right. Let's add some more information about Pluto: 59 | 60 | ![](../fig/RStudio_screenshot_editfiles.png) 61 | 62 | Once we have saved our edited files, we can also use RStudio to commit these changes. Go to the git menu and click 63 | "commit": 64 | 65 | ![](../fig/RStudio_screenshot_commit.png) 66 | 67 | This will bring up a screen where you can select which files to commit (check 68 | the boxes in the "staged" column) and enter a commit message (in the upper 69 | right). The icons in the "status" column indicate the current status of each 70 | file. You can also see the changes to each file by clicking on its name. Once 71 | everything is the way you want it, click "commit": 72 | 73 | ![](../fig/RStudio_screenshot_review.png) 74 | 75 | You can push these changes by selecting "push" from the Git menu. There are 76 | also options there to pull from a remote version of the repository, and view 77 | the history: 78 | 79 | ![](../fig/RStudio_screenshot_history.png) 80 | 81 | > ## Are the Push/Pull Commands Grayed Out? 82 | > 83 | > If this is the case, it generally means that RStudio doesn't know the 84 | > location of any other version of your repository (i.e. the one on GitHub). 85 | > To fix this, open a terminal to the repository and enter the command: 86 | > `git push -u origin master`. Then restart RStudio. 87 | {: .callout} 88 | 89 | If we click on "history", we can see a pretty graphical version of what 90 | `git log` would tell us: 91 | 92 | ![](../fig/RStudio_screenshot_viewhistory.png) 93 | 94 | RStudio creates some files that is uses to keep track of your project. You 95 | generally don't want to track these, so adding them to your .gitignore file 96 | is a good idea: 97 | 98 | ![](../fig/RStudio_screenshot_gitignore.png) 99 | 100 | There are many more features buried in the RStudio git interface, but these 101 | should be enough to get you started! 102 | 103 | [rstudio-projects]: https://support.rstudio.com/hc/en-us/articles/200526207-Using-Projects 104 | -------------------------------------------------------------------------------- /fig/conflict.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /_episodes/03-create.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Creating a Repository 3 | teaching: 10 4 | exercises: 0 5 | questions: 6 | - "Where does Git store information?" 7 | objectives: 8 | - "Create a local Git repository." 9 | keypoints: 10 | - "`git init` initializes a repository." 11 | --- 12 | 13 | Once Git is configured, 14 | we can start using it. 15 | Let's create a directory for our work and then move into that directory: 16 | 17 | ~~~ 18 | $ mkdir planets 19 | $ cd planets 20 | ~~~ 21 | {: .bash} 22 | 23 | Then we tell Git to make `planets` a [repository]({{ page.root }}/reference/#repository)—a place where 24 | Git can store versions of our files: 25 | 26 | ~~~ 27 | $ git init 28 | ~~~ 29 | {: .bash} 30 | 31 | If we use `ls` to show the directory's contents, 32 | it appears that nothing has changed: 33 | 34 | ~~~ 35 | $ ls 36 | ~~~ 37 | {: .bash} 38 | 39 | But if we add the `-a` flag to show everything, 40 | we can see that Git has created a hidden directory within `planets` called `.git`: 41 | 42 | ~~~ 43 | $ ls -a 44 | ~~~ 45 | {: .bash} 46 | 47 | ~~~ 48 | . .. .git 49 | ~~~ 50 | {: .output} 51 | 52 | Git stores information about the project in this special sub-directory. 53 | If we ever delete it, 54 | we will lose the project's history. 55 | 56 | We can check that everything is set up correctly 57 | by asking Git to tell us the status of our project: 58 | 59 | ~~~ 60 | $ git status 61 | ~~~ 62 | {: .bash} 63 | 64 | ~~~ 65 | # On branch master 66 | # 67 | # Initial commit 68 | # 69 | nothing to commit (create/copy files and use "git add" to track) 70 | ~~~ 71 | {: .output} 72 | 73 | > ## Places to Create Git Repositories 74 | > 75 | > Dracula starts a new project, `moons`, related to his `planets` project. 76 | > Despite Wolfman's concerns, he enters the following sequence of commands to 77 | > create one Git repository inside another: 78 | > 79 | > ~~~ 80 | > $ cd # return to home directory 81 | > $ mkdir planets # make a new directory planets 82 | > $ cd planets # go into planets 83 | > $ git init # make the planets directory a Git repository 84 | > $ mkdir moons # make a sub-directory planets/moons 85 | > $ cd moons # go into planets/moons 86 | > $ git init # make the moons sub-directory a Git repository 87 | > ~~~ 88 | > {: .bash} 89 | > 90 | > Why is it a bad idea to do this? (Notice here that the `planets` project is now also tracking the entire `moons` repository.) 91 | > How can Dracula undo his last `git init`? 92 | > 93 | > > ## Solution 94 | > > 95 | > > Git repositories can interfere with each other if they are "nested" in the 96 | > > directory of another: the outer repository will try to version-control 97 | > > the inner repository. Therefore, it's best to create each new Git 98 | > > repository in a separate directory. To be sure that there is no conflicting 99 | > > repository in the directory, check the output of `git status`. If it looks 100 | > > like the following, you are good to go to create a new repository as shown 101 | > > above: 102 | > > 103 | > > ~~~ 104 | > > $ git status 105 | > > ~~~ 106 | > > {: .bash} 107 | > > ~~~ 108 | > > fatal: Not a git repository (or any of the parent directories): .git 109 | > > ~~~ 110 | > > {: .output} 111 | > > 112 | > > Note that we can track files in directories within a Git: 113 | > > 114 | > > ~~~ 115 | > > $ touch moon phobos deimos titan # create moon files 116 | > > $ cd .. # return to planets directory 117 | > > $ ls moons # list contents of the moons directory 118 | > > $ git add moons/* # add all contents of planets/moons 119 | > > $ git status # show moons files in staging area 120 | > > $ git commit -m "add moon files" # commit planets/moons to planets Git repository 121 | > > ~~~ 122 | > > {: .bash} 123 | > > 124 | > > Similarly, we can ignore (as discussed later) entire directories, such as the `moons` directory: 125 | > > 126 | > > ~~~ 127 | > > $ nano .gitignore # open the .gitignore file in the text editor to add the moons directory 128 | > > $ cat .gitignore # if you run cat afterwards, it should look like this: 129 | > > ~~~ 130 | > > {: .bash} 131 | > > 132 | > > ~~~ 133 | > > moons 134 | > > ~~~ 135 | > > {: .output} 136 | > > 137 | > > To recover from this little mistake, Dracula can just remove the `.git` 138 | > > folder in the moons subdirectory. To do so he can run the following command from inside the 'moons' directory: 139 | > > 140 | > > ~~~ 141 | > > $ rm -rf moons/.git 142 | > > ~~~ 143 | > > {: .bash} 144 | > > 145 | > > But be careful! Running this command in the wrong directory, will remove 146 | > > the entire git-history of a project you might wanted to keep. Therefore, always check your current directory using the 147 | > > command `pwd`. 148 | > {: .solution} 149 | {: .challenge} 150 | -------------------------------------------------------------------------------- /assets/img/lc-icon-black.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 10 | 12 | 13 | 19 | 24 | 29 | 34 | 38 | 43 | 46 | 48 | 53 | 58 | 62 | 66 | 71 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /bin/repo_check.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Check repository settings. 5 | """ 6 | 7 | from __future__ import print_function 8 | import sys 9 | import os 10 | from subprocess import Popen, PIPE 11 | import re 12 | from optparse import OptionParser 13 | 14 | from util import Reporter, load_yaml, require 15 | 16 | # Import this way to produce a more useful error message. 17 | try: 18 | import requests 19 | except ImportError: 20 | print('Unable to import requests module: please install requests', file=sys.stderr) 21 | sys.exit(1) 22 | 23 | 24 | # Pattern to match Git command-line output for remotes => (user name, project name). 25 | P_GIT_REMOTE = re.compile(r'upstream\s+[^:]+:([^/]+)/([^.]+)\.git\s+\(fetch\)') 26 | 27 | # Repository URL format string. 28 | F_REPO_URL = 'https://github.com/{0}/{1}/' 29 | 30 | # Pattern to match repository URLs => (user name, project name) 31 | P_REPO_URL = re.compile(r'https?://github\.com/([^.]+)/([^/]+)/?') 32 | 33 | # API URL format string. 34 | F_API_URL = 'https://api.github.com/repos/{0}/{1}/labels' 35 | 36 | # Expected labels and colors. 37 | EXPECTED = { 38 | 'bug' : 'bd2c00', 39 | 'discussion' : 'fc8dc1', 40 | 'enhancement' : '9cd6dc', 41 | 'help-wanted' : 'f4fd9c', 42 | 'instructor-training' : '6e5494', 43 | 'newcomer-friendly' : 'eec275', 44 | 'question' : '808040', 45 | 'template-and-tools' : '2b3990', 46 | 'work-in-progress' : '7ae78e' 47 | } 48 | 49 | 50 | def main(): 51 | """ 52 | Main driver. 53 | """ 54 | 55 | args = parse_args() 56 | reporter = Reporter() 57 | repo_url = get_repo_url(args.source_dir, args.repo_url) 58 | check_labels(reporter, repo_url) 59 | reporter.report() 60 | 61 | 62 | def parse_args(): 63 | """ 64 | Parse command-line arguments. 65 | """ 66 | 67 | parser = OptionParser() 68 | parser.add_option('-r', '--repo', 69 | default=None, 70 | dest='repo_url', 71 | help='repository URL') 72 | parser.add_option('-s', '--source', 73 | default=os.curdir, 74 | dest='source_dir', 75 | help='source directory') 76 | 77 | args, extras = parser.parse_args() 78 | require(not extras, 79 | 'Unexpected trailing command-line arguments "{0}"'.format(extras)) 80 | 81 | return args 82 | 83 | 84 | def get_repo_url(source_dir, repo_url): 85 | """ 86 | Figure out which repository to query. 87 | """ 88 | 89 | # Explicitly specified. 90 | if repo_url is not None: 91 | return repo_url 92 | 93 | # Guess. 94 | cmd = 'git remote -v' 95 | p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, close_fds=True, universal_newlines=True) 96 | stdout_data, stderr_data = p.communicate() 97 | stdout_data = stdout_data.split('\n') 98 | matches = [P_GIT_REMOTE.match(line) for line in stdout_data] 99 | matches = [m for m in matches if m is not None] 100 | require(len(matches) == 1, 101 | 'Unexpected output from git remote command: "{0}"'.format(matches)) 102 | 103 | username = matches[0].group(1) 104 | require(username, 'empty username in git remote output {0}'.format(matches[0])) 105 | 106 | project_name = matches[0].group(2) 107 | require(username, 'empty project name in git remote output {0}'.format(matches[0])) 108 | 109 | url = F_REPO_URL.format(username, project_name) 110 | return url 111 | 112 | 113 | def check_labels(reporter, repo_url): 114 | """ 115 | Check labels in repository. 116 | """ 117 | 118 | actual = get_labels(repo_url) 119 | extra = set(actual.keys()) - set(EXPECTED.keys()) 120 | 121 | reporter.check(not extra, 122 | None, 123 | 'Extra label(s) in repository {0}: {1}', 124 | repo_url, ', '.join(sorted(extra))) 125 | 126 | missing = set(EXPECTED.keys()) - set(actual.keys()) 127 | reporter.check(not missing, 128 | None, 129 | 'Missing label(s) in repository {0}: {1}', 130 | repo_url, ', '.join(sorted(missing))) 131 | 132 | overlap = set(EXPECTED.keys()).intersection(set(actual.keys())) 133 | for name in sorted(overlap): 134 | reporter.check(EXPECTED[name] == actual[name], 135 | None, 136 | 'Color mis-match for label {0} in {1}: expected {2}, found {3}', 137 | name, repo_url, EXPECTED[name], actual[name]) 138 | 139 | 140 | def get_labels(repo_url): 141 | """ 142 | Get actual labels from repository. 143 | """ 144 | 145 | m = P_REPO_URL.match(repo_url) 146 | require(m, 'repository URL {0} does not match expected pattern'.format(repo_url)) 147 | 148 | username = m.group(1) 149 | require(username, 'empty username in repository URL {0}'.format(repo_url)) 150 | 151 | project_name = m.group(2) 152 | require(username, 'empty project name in repository URL {0}'.format(repo_url)) 153 | 154 | url = F_API_URL.format(username, project_name) 155 | r = requests.get(url) 156 | require(r.status_code == 200, 157 | 'Request for {0} failed with {1}'.format(url, r.status_code)) 158 | 159 | result = {} 160 | for entry in r.json(): 161 | result[entry['name']] = entry['color'] 162 | return result 163 | 164 | 165 | if __name__ == '__main__': 166 | main() 167 | -------------------------------------------------------------------------------- /fig/play-changes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /assets/img/swc-icon-blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /assets/img/dc-icon-black.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 28 | 30 | 54 | 59 | 64 | 69 | 74 | 75 | -------------------------------------------------------------------------------- /fig/git-staging-area.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | .git 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 | 48 | 49 | 50 | 53 | 54 | 55 | 58 | 59 | 60 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | git add 82 | 83 | 84 | 85 | 86 | 87 | git commit 88 | 89 | staging area 90 | 91 | repository 92 | 93 | 94 | -------------------------------------------------------------------------------- /bin/util.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | import os 4 | import json 5 | from subprocess import Popen, PIPE 6 | 7 | # Import this way to produce a more useful error message. 8 | try: 9 | import yaml 10 | except ImportError: 11 | print('Unable to import YAML module: please install PyYAML', file=sys.stderr) 12 | sys.exit(1) 13 | 14 | 15 | # Things an image file's name can end with. 16 | IMAGE_FILE_SUFFIX = { 17 | '.gif', 18 | '.jpg', 19 | '.png', 20 | '.svg' 21 | } 22 | 23 | # Files that shouldn't be present. 24 | UNWANTED_FILES = [ 25 | '.nojekyll' 26 | ] 27 | 28 | # Marker to show that an expected value hasn't been provided. 29 | # (Can't use 'None' because that might be a legitimate value.) 30 | REPORTER_NOT_SET = [] 31 | 32 | class Reporter(object): 33 | """Collect and report errors.""" 34 | 35 | def __init__(self): 36 | """Constructor.""" 37 | 38 | super(Reporter, self).__init__() 39 | self.messages = [] 40 | 41 | 42 | def check_field(self, filename, name, values, key, expected=REPORTER_NOT_SET): 43 | """Check that a dictionary has an expected value.""" 44 | 45 | if key not in values: 46 | self.add(filename, '{0} does not contain {1}', name, key) 47 | elif expected is REPORTER_NOT_SET: 48 | pass 49 | elif type(expected) in (tuple, set, list): 50 | if values[key] not in expected: 51 | self.add(filename, '{0} {1} value {2} is not in {3}', name, key, values[key], expected) 52 | elif values[key] != expected: 53 | self.add(filename, '{0} {1} is {2} not {3}', name, key, values[key], expected) 54 | 55 | 56 | def check(self, condition, location, fmt, *args): 57 | """Append error if condition not met.""" 58 | 59 | if not condition: 60 | self.add(location, fmt, *args) 61 | 62 | 63 | def add(self, location, fmt, *args): 64 | """Append error unilaterally.""" 65 | 66 | self.messages.append((location, fmt.format(*args))) 67 | 68 | 69 | def report(self, stream=sys.stdout): 70 | """Report all messages in order.""" 71 | 72 | if not self.messages: 73 | return 74 | 75 | def pretty(item): 76 | location, message = item 77 | if isinstance(location, type(None)): 78 | return message 79 | elif isinstance(location, str): 80 | return location + ': ' + message 81 | elif isinstance(location, tuple): 82 | return '{0}:{1}: '.format(*location) + message 83 | else: 84 | assert False, 'Unknown item "{0}"'.format(item) 85 | 86 | def key(item): 87 | location, message = item 88 | if isinstance(location, type(None)): 89 | return ('', -1, message) 90 | elif isinstance(location, str): 91 | return (location, -1, message) 92 | elif isinstance(location, tuple): 93 | return (location[0], location[1], message) 94 | else: 95 | assert False, 'Unknown item "{0}"'.format(item) 96 | 97 | for m in sorted(self.messages, key=key): 98 | print(pretty(m), file=stream) 99 | 100 | 101 | def read_markdown(parser, path): 102 | """ 103 | Get YAML and AST for Markdown file, returning 104 | {'metadata':yaml, 'metadata_len':N, 'text':text, 'lines':[(i, line, len)], 'doc':doc}. 105 | """ 106 | 107 | # Split and extract YAML (if present). 108 | with open(path, 'r') as reader: 109 | body = reader.read() 110 | metadata_raw, metadata_yaml, body = split_metadata(path, body) 111 | 112 | # Split into lines. 113 | metadata_len = 0 if metadata_raw is None else metadata_raw.count('\n') 114 | lines = [(metadata_len+i+1, line, len(line)) for (i, line) in enumerate(body.split('\n'))] 115 | 116 | # Parse Markdown. 117 | cmd = 'ruby {0}'.format(parser) 118 | p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, close_fds=True, universal_newlines=True) 119 | stdout_data, stderr_data = p.communicate(body) 120 | doc = json.loads(stdout_data) 121 | 122 | return { 123 | 'metadata': metadata_yaml, 124 | 'metadata_len': metadata_len, 125 | 'text': body, 126 | 'lines': lines, 127 | 'doc': doc 128 | } 129 | 130 | 131 | def split_metadata(path, text): 132 | """ 133 | Get raw (text) metadata, metadata as YAML, and rest of body. 134 | If no metadata, return (None, None, body). 135 | """ 136 | 137 | metadata_raw = None 138 | metadata_yaml = None 139 | metadata_len = None 140 | 141 | pieces = text.split('---', 2) 142 | if len(pieces) == 3: 143 | metadata_raw = pieces[1] 144 | text = pieces[2] 145 | try: 146 | metadata_yaml = yaml.load(metadata_raw) 147 | except yaml.YAMLError as e: 148 | print('Unable to parse YAML header in {0}:\n{1}'.format(path, e), file=sys.stderr) 149 | sys.exit(1) 150 | 151 | return metadata_raw, metadata_yaml, text 152 | 153 | 154 | def load_yaml(filename): 155 | """ 156 | Wrapper around YAML loading so that 'import yaml' is only needed 157 | in one file. 158 | """ 159 | 160 | try: 161 | with open(filename, 'r') as reader: 162 | return yaml.load(reader) 163 | except (yaml.YAMLError, FileNotFoundError) as e: 164 | print('Unable to load YAML file {0}:\n{1}'.format(filename, e), file=sys.stderr) 165 | sys.exit(1) 166 | 167 | 168 | def check_unwanted_files(dir_path, reporter): 169 | """ 170 | Check that unwanted files are not present. 171 | """ 172 | 173 | for filename in UNWANTED_FILES: 174 | path = os.path.join(dir_path, filename) 175 | reporter.check(not os.path.exists(path), 176 | path, 177 | "Unwanted file found") 178 | 179 | 180 | def require(condition, message): 181 | """Fail if condition not met.""" 182 | 183 | if not condition: 184 | print(message, file=sys.stderr) 185 | sys.exit(1) 186 | -------------------------------------------------------------------------------- /_episodes/10-open.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Open Science 3 | teaching: 5 4 | exercises: 5 5 | questions: 6 | - "How can version control help me make my work more open?" 7 | objectives: 8 | - "Explain how a version control system can be leveraged as an electronic lab notebook for computational work." 9 | keypoints: 10 | - "Open scientific work is more useful and more highly cited than closed." 11 | --- 12 | 13 | > The opposite of "open" isn't "closed". 14 | > The opposite of "open" is "broken". 15 | > 16 | > --- John Wilbanks 17 | {: .quotation} 18 | 19 | Free sharing of information might be the ideal in science, 20 | but the reality is often more complicated. 21 | Normal practice today looks something like this: 22 | 23 | * A scientist collects some data and stores it on a machine 24 | that is occasionally backed up by her department. 25 | * She then writes or modifies a few small programs 26 | (which also reside on her machine) 27 | to analyze that data. 28 | * Once she has some results, 29 | she writes them up and submits her paper. 30 | She might include her data—a growing number of journals require this—but 31 | she probably doesn't include her code. 32 | * Time passes. 33 | * The journal sends her reviews written anonymously by a handful of other people in her field. 34 | She revises her paper to satisfy them, 35 | during which time she might also modify the scripts she wrote earlier, 36 | and resubmits. 37 | * More time passes. 38 | * The paper is eventually published. 39 | It might include a link to an online copy of her data, 40 | but the paper itself will be behind a paywall: 41 | only people who have personal or institutional access 42 | will be able to read it. 43 | 44 | For a growing number of scientists, 45 | though, 46 | the process looks like this: 47 | 48 | * The data that the scientist collects is stored in an open access repository 49 | like [figshare](http://figshare.com/) or 50 | [Zenodo](http://zenodo.org), possibly as soon as it's collected, 51 | and given its own 52 | [Digital Object Identifier](https://en.wikipedia.org/wiki/Digital_object_identifier) (DOI). 53 | Or the data was already published and is stored in 54 | [Dryad](http://datadryad.org/). 55 | * The scientist creates a new repository on GitHub to hold her work. 56 | * As she does her analysis, 57 | she pushes changes to her scripts 58 | (and possibly some output files) 59 | to that repository. 60 | She also uses the repository for her paper; 61 | that repository is then the hub for collaboration with her colleagues. 62 | * When she's happy with the state of her paper, 63 | she posts a version to [arXiv](http://arxiv.org/) 64 | or some other preprint server 65 | to invite feedback from peers. 66 | * Based on that feedback, 67 | she may post several revisions 68 | before finally submitting her paper to a journal. 69 | * The published paper includes links to her preprint 70 | and to her code and data repositories, 71 | which makes it much easier for other scientists 72 | to use her work as starting point for their own research. 73 | 74 | This open model accelerates discovery: 75 | the more open work is, 76 | [the more widely it is cited and re-used](http://dx.doi.org/10.1371/journal.pone.0000308). 77 | However, 78 | people who want to work this way need to make some decisions 79 | about what exactly "open" means and how to do it. You can find more on the different aspects of Open Science in [this book](http://link.springer.com/book/10.1007/978-3-319-00026-8). 80 | 81 | This is one of the (many) reasons we teach version control. 82 | When used diligently, 83 | it answers the "how" question 84 | by acting as a shareable electronic lab notebook for computational work: 85 | 86 | * The conceptual stages of your work are documented, including who did 87 | what and when. Every step is stamped with an identifier (the commit ID) 88 | that is for most intents and purposes unique. 89 | * You can tie documentation of rationale, ideas, and other 90 | intellectual work directly to the changes that spring from them. 91 | * You can refer to what you used in your research to obtain your 92 | computational results in a way that is unique and recoverable. 93 | * With a distributed version control system such as Git, the version 94 | control repository is easy to archive for perpetuity, and contains 95 | the entire history. 96 | 97 | > ## Making Code Citable 98 | > 99 | > [This short guide](https://guides.github.com/activities/citable-code/) from GitHub 100 | > explains how to create a Digital Object Identifier (DOI) for your code, 101 | > your papers, 102 | > or anything else hosted in a version control repository. 103 | {: .callout} 104 | 105 | > ## How Reproducible Is My Work? 106 | > 107 | > Ask one of your labmates to reproduce a result you recently obtained 108 | > using only what they can find in your papers or on the web. 109 | > Try to do the same for one of their results, 110 | > then try to do it for a result from a lab you work with. 111 | {: .challenge} 112 | 113 | > ## How to Find an Appropriate Data Repository? 114 | > 115 | > Surf the internet for a couple of minutes and check out the data repositories 116 | > mentioned above: [Figshare](http://figshare.com/), [Zenodo](http://zenodo.org), 117 | > [Dryad](http://datadryad.org/). Depending on your field of research, you might 118 | > find community-recognized repositories that are well-known in your field. 119 | > You might also find useful [these data repositories recommended by Nature]( 120 | > http://www.nature.com/sdata/data-policies/repositories). 121 | > Discuss with your neighbor which data repository you might want to 122 | > approach for your current project and explain why. 123 | {: .challenge} 124 | 125 | > ## Can I Also Publish Code? 126 | > 127 | > There are many new ways to publish code and to make it citable. One 128 | > way is described [on the homepage of GitHub itself]( 129 | > https://guides.github.com/activities/citable-code/). 130 | > Basically it's a combination of GitHub (where the code is) and Zenodo (the 131 | > repository creating the DOI). Read through this page while being aware 132 | > that this is only one of many ways to making your code citable. 133 | {: .challenge} 134 | -------------------------------------------------------------------------------- /_episodes/02-setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Setting Up Git 3 | teaching: 5 4 | exercises: 0 5 | questions: 6 | - "How do I get set up to use Git?" 7 | objectives: 8 | - "Configure `git` the first time it is used on a computer." 9 | - "Understand the meaning of the `--global` configuration flag." 10 | keypoints: 11 | - "Use `git config` to configure a user name, email address, editor, and other preferences once per machine." 12 | --- 13 | 14 | When we use Git on a new computer for the first time, 15 | we need to configure a few things. Below are a few examples 16 | of configurations we will set as we get started with Git: 17 | 18 | * our name and email address, 19 | * to colorize our output, 20 | * what our preferred text editor is, 21 | * and that we want to use these settings globally (i.e. for every project) 22 | 23 | On a command line, Git commands are written as `git verb`, 24 | where `verb` is what we actually want to do. So here is how 25 | Dracula sets up his new laptop: 26 | 27 | ~~~ 28 | $ git config --global user.name "Vlad Dracula" 29 | $ git config --global user.email "vlad@tran.sylvan.ia" 30 | $ git config --global color.ui "auto" 31 | ~~~ 32 | {: .bash} 33 | 34 | Please use your own name and email address instead of Dracula's. This user name and email will be associated with your subsequent Git activity, 35 | which means that any changes pushed to 36 | [GitHub](http://github.com/), 37 | [BitBucket](http://bitbucket.org/), 38 | [GitLab](http://gitlab.com/) or 39 | another Git host server 40 | in a later lesson will include this information. 41 | 42 | > ## Line Endings 43 | > 44 | > As with other keys, when you hit the 'return' key on your keyboard, 45 | > your computer encodes this input. 46 | > For reasons that are long to explain, different operating systems 47 | > use different character(s) to represent the end of a line. 48 | > (You may also hear these referred to as newlines or line breaks.) 49 | > Because git uses these characters to compare files, 50 | > it may cause unexpected issues when editing a file on different machines. 51 | > 52 | > You can change the way git recognizes and encodes line endings 53 | > using the `core.autocrlf` command to `git config`. 54 | > The following settings are recommended: 55 | > 56 | > On OS X and Linux: 57 | > 58 | > ~~~ 59 | > $ git config --global core.autocrlf input 60 | > ~~~ 61 | > {: .bash} 62 | > 63 | > And on Windows: 64 | > 65 | > ~~~ 66 | > $ git config --global core.autocrlf true 67 | > ~~~ 68 | > {: .bash} 69 | > 70 | > You can read more about this issue 71 | > [on this GitHub page](https://help.github.com/articles/dealing-with-line-endings/). 72 | {: .callout} 73 | 74 | For these lessons, we will be interacting with [GitHub](http://github.com/) and so the email address used should be the same as the one used when setting up your GitHub account. If you are concerned about privacy, please review [GitHub's instructions for keeping your email address private][git-privacy]. 75 | If you elect to use a private email address with GitHub, then use that same email address for the `user.email` value, e.g. `username@users.noreply.github.com` replacing `username` with your GitHub one. You can change the email address later on by using the `git config` command again. 76 | 77 | Dracula also has to set his favorite text editor, following this table: 78 | 79 | | Editor | Configuration command | 80 | |:-------------------|:-------------------------------------------------| 81 | | Atom | `$ git config --global core.editor "atom --wait"`| 82 | | nano | `$ git config --global core.editor "nano -w"` | 83 | | BBEdit (Mac, with command line tools) | `$ git config --global core.editor "edit -w"` | 84 | | Sublime Text (Mac) | `$ git config --global core.editor "subl -n -w"` | 85 | | Sublime Text (Win, 32-bit install) | `$ git config --global core.editor "'c:/program files (x86)/sublime text 3/sublime_text.exe' -w"` | 86 | | Sublime Text (Win, 64-bit install) | `$ git config --global core.editor "'c:/program files/sublime text 3/sublime_text.exe' -w"` | 87 | | Notepad++ (Win, 32-bit install) | `$ git config --global core.editor "'c:/program files (x86)/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"`| 88 | | Notepad++ (Win, 64-bit install) | `$ git config --global core.editor "'c:/program files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"`| 89 | | Kate (Linux) | `$ git config --global core.editor "kate"` | 90 | | Gedit (Linux) | `$ git config --global core.editor "gedit --wait --new-window"` | 91 | | Scratch (Linux) | `$ git config --global core.editor "scratch-text-editor"` | 92 | | emacs | `$ git config --global core.editor "emacs"` | 93 | | vim | `$ git config --global core.editor "vim"` | 94 | 95 | It is possible to reconfigure the text editor for Git whenever you want to change it. 96 | 97 | > ## Exiting Vim 98 | > 99 | > Note that `vim` is the default editor for many programs. If you haven't used `vim` before and wish to exit a session, type `Esc` then `:q!` and `Enter`. 100 | {: .callout} 101 | 102 | The four commands we just ran above only need to be run once: the flag `--global` tells Git 103 | to use the settings for every project, in your user account, on this computer. 104 | 105 | You can check your settings at any time: 106 | 107 | ~~~ 108 | $ git config --list 109 | ~~~ 110 | {: .bash} 111 | 112 | You can change your configuration as many times as you want: just use the 113 | same commands to choose another editor or update your email address. 114 | 115 | > ## Proxy 116 | > 117 | > In some networks you need to use a 118 | > [proxy](https://en.wikipedia.org/wiki/Proxy_server). If this is the case, you 119 | > may also need to tell Git about the proxy: 120 | > 121 | > ~~~ 122 | > $ git config --global http.proxy proxy-url 123 | > $ git config --global https.proxy proxy-url 124 | > ~~~ 125 | > {: .bash} 126 | > 127 | > To disable the proxy, use 128 | > 129 | > ~~~ 130 | > $ git config --global --unset http.proxy 131 | > $ git config --global --unset https.proxy 132 | > ~~~ 133 | > {: .bash} 134 | {: .callout} 135 | 136 | > ## Git Help and Manual 137 | > 138 | > Always remember that if you forget a `git` command, you can access the list of commands by using `-h` and access the Git manual by using `--help` : 139 | > 140 | > ~~~ 141 | > $ git config -h 142 | > $ git config --help 143 | > ~~~ 144 | > {: .bash} 145 | {: .callout} 146 | 147 | [git-privacy]: https://help.github.com/articles/keeping-your-email-address-private/ 148 | -------------------------------------------------------------------------------- /_episodes/08-collab.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Collaborating 3 | teaching: 25 4 | exercises: 0 5 | questions: 6 | - "How can I use version control to collaborate with other people?" 7 | objectives: 8 | - "Clone a remote repository." 9 | - "Collaborate pushing to a common repository." 10 | keypoints: 11 | - "`git clone` copies a remote repository to create a local repository with a remote called `origin` automatically set up." 12 | --- 13 | 14 | For the next step, get into pairs. One person will be the "Owner" and the other 15 | will be the "Collaborator". The goal is that the Collaborator add changes into 16 | the Owner's repository. We will switch roles at the end, so both persons will 17 | play Owner and Collaborator. 18 | 19 | > ## Practicing By Yourself 20 | > 21 | > If you're working through this lesson on your own, you can carry on by opening 22 | > a second terminal window. 23 | > This window will represent your partner, working on another computer. You 24 | > won't need to give anyone access on GitHub, because both 'partners' are you. 25 | {: .callout} 26 | 27 | The Owner needs to give the Collaborator access. 28 | On GitHub, click the settings button on the right, 29 | then select Collaborators, and enter your partner's username. 30 | 31 | ![Adding Collaborators on GitHub](../fig/github-add-collaborators.png) 32 | 33 | To accept access to the Owner's repo, the Collaborator 34 | needs to go to [https://github.com/notifications](https://github.com/notifications). 35 | Once there she can accept access to the Owner's repo. 36 | 37 | Next, the Collaborator needs to download a copy of the Owner's repository to her 38 | machine. This is called "cloning a repo". To clone the Owner's repo into 39 | her `Desktop` folder, the Collaborator enters: 40 | 41 | ~~~ 42 | $ git clone https://github.com/vlad/planets.git ~/Desktop/vlad-planets 43 | ~~~ 44 | {: .bash} 45 | 46 | Replace 'vlad' with the Owner's username. 47 | 48 | ![After Creating Clone of Repository](../fig/github-collaboration.svg) 49 | 50 | The Collaborator can now make a change in her clone of the Owner's repository, 51 | exactly the same way as we've been doing before: 52 | 53 | ~~~ 54 | $ cd ~/Desktop/vlad-planets 55 | $ nano pluto.txt 56 | $ cat pluto.txt 57 | ~~~ 58 | {: .bash} 59 | 60 | ~~~ 61 | It is so a planet! 62 | ~~~ 63 | {: .output} 64 | 65 | ~~~ 66 | $ git add pluto.txt 67 | $ git commit -m "Add notes about Pluto" 68 | ~~~ 69 | {: .bash} 70 | 71 | ~~~ 72 | 1 file changed, 1 insertion(+) 73 | create mode 100644 pluto.txt 74 | ~~~ 75 | {: .output} 76 | 77 | Then push the change to the *Owner's repository* on GitHub: 78 | 79 | ~~~ 80 | $ git push origin master 81 | ~~~ 82 | {: .bash} 83 | 84 | ~~~ 85 | Counting objects: 4, done. 86 | Delta compression using up to 4 threads. 87 | Compressing objects: 100% (2/2), done. 88 | Writing objects: 100% (3/3), 306 bytes, done. 89 | Total 3 (delta 0), reused 0 (delta 0) 90 | To https://github.com/vlad/planets.git 91 | 9272da5..29aba7c master -> master 92 | ~~~ 93 | {: .output} 94 | 95 | Note that we didn't have to create a remote called `origin`: Git uses this 96 | name by default when we clone a repository. (This is why `origin` was a 97 | sensible choice earlier when we were setting up remotes by hand.) 98 | 99 | Take a look to the Owner's repository on its GitHub website now (maybe you need 100 | to refresh your browser.) You should be able to see the new commit made by the 101 | Collaborator. 102 | 103 | To download the Collaborator's changes from GitHub, the Owner now enters: 104 | 105 | ~~~ 106 | $ git pull origin master 107 | ~~~ 108 | {: .bash} 109 | 110 | ~~~ 111 | remote: Counting objects: 4, done. 112 | remote: Compressing objects: 100% (2/2), done. 113 | remote: Total 3 (delta 0), reused 3 (delta 0) 114 | Unpacking objects: 100% (3/3), done. 115 | From https://github.com/vlad/planets 116 | * branch master -> FETCH_HEAD 117 | Updating 9272da5..29aba7c 118 | Fast-forward 119 | pluto.txt | 1 + 120 | 1 file changed, 1 insertion(+) 121 | create mode 100644 pluto.txt 122 | ~~~ 123 | {: .output} 124 | 125 | Now the three repositories (Owner's local, Collaborator's local, and Owner's on 126 | GitHub) are back in sync. 127 | 128 | > ## A Basic Collaborative Workflow 129 | > 130 | > In practice, it is good to be sure that you have an updated version of the 131 | > repository you are collaborating on, so you should `git pull` before making 132 | > our changes. The basic collaborative workflow would be: 133 | > 134 | > * update your local repo with `git pull origin master`, 135 | > * make your changes and stage them with `git add`, 136 | > * commit your changes with `git commit -m`, and 137 | > * upload the changes to GitHub with `git push origin master` 138 | > 139 | > It is better to make many commits with smaller changes rather than 140 | > of one commit with massive changes: small commits are easier to 141 | > read and review. 142 | {: .callout} 143 | 144 | > ## Switch Roles and Repeat 145 | > 146 | > Switch roles and repeat the whole process. 147 | {: .challenge} 148 | 149 | > ## Review Changes 150 | > 151 | > The Owner push commits to the repository without giving any information 152 | > to the Collaborator. How can the Collaborator find out what has changed with 153 | > command line? And on GitHub? 154 | > 155 | > > ## Solution 156 | > > On the command line, the Collaborator can use ```git fetch origin master``` 157 | > > to get the remote changes into the local repository, but without merging 158 | > > them. Then by running ```git diff master origin/master``` the Collaborator 159 | > > will see the changes output in the terminal. 160 | > > 161 | > > On GitHub, the Collaborator can go to their own fork of the repository and 162 | > > look right above the light blue latest commit bar for a gray bar saying 163 | > > "This branch is 1 commit behind Our-Repository:master." On the far right of 164 | > > that gray bar is a Compare icon and link. On the Compare page the 165 | > > Collaborator should change the base fork to their own repository, then click 166 | > > the link in the paragraph above to "compare across forks", and finally 167 | > > change the head fork to the main repository. This will show all the commits 168 | > > that are different. 169 | > {: .solution} 170 | {: .challenge} 171 | 172 | > ## Comment Changes in GitHub 173 | > 174 | > The Collaborator has some questions about one line change made by the Owner and 175 | > has some suggestions to propose. 176 | > 177 | > With GitHub, it is possible to comment the diff of a commit. Over the line of 178 | > code to comment, a blue comment icon appears to open a comment window. 179 | > 180 | > The Collaborator posts its comments and suggestions using GitHub interface. 181 | {: .challenge} 182 | 183 | > ## Version History, Backup, and Version Control 184 | > 185 | > Some backup software can keep a history of the versions of your files. They also 186 | > allows you to recover specific versions. How is this functionality different from version control? 187 | > What are some of the benefits of using version control, Git and GitHub? 188 | {: .challenge} 189 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | [Software Carpentry][swc-site] and [Data Carpentry][dc-site] are open source projects, 4 | and we welcome contributions of all kinds: 5 | new lessons, 6 | fixes to existing material, 7 | bug reports, 8 | and reviews of proposed changes are all welcome. 9 | 10 | ## Contributor Agreement 11 | 12 | By contributing, 13 | you agree that we may redistribute your work under [our license](LICENSE.md). 14 | In exchange, 15 | we will address your issues and/or assess your change proposal as promptly as we can, 16 | and help you become a member of our community. 17 | Everyone involved in [Software Carpentry][swc-site] and [Data Carpentry][dc-site] 18 | agrees to abide by our [code of conduct](CONDUCT.md). 19 | 20 | ## How to Contribute 21 | 22 | The easiest way to get started is to file an issue 23 | to tell us about a spelling mistake, 24 | some awkward wording, 25 | or a factual error. 26 | This is a good way to introduce yourself 27 | and to meet some of our community members. 28 | 29 | 1. If you do not have a [GitHub][github] account, 30 | you can [send us comments by email][contact]. 31 | However, 32 | we will be able to respond more quickly if you use one of the other methods described below. 33 | 34 | 2. If you have a [GitHub][github] account, 35 | or are willing to [create one][github-join], 36 | but do not know how to use Git, 37 | you can report problems or suggest improvements by [creating an issue][new-issue]. 38 | This allows us to assign the item to someone 39 | and to respond to it in a threaded discussion. 40 | 41 | 3. If you are comfortable with Git, 42 | and would like to add or change material, 43 | you can submit a pull request (PR). 44 | Instructions for doing this are [included below](#using-github). 45 | 46 | ## Where to Contribute 47 | 48 | 1. If you wish to change this lesson, 49 | please work in , 50 | which can be viewed at . 51 | 52 | 2. If you wish to change the example lesson, 53 | please work in , 54 | which documents the format of our lessons 55 | and can be viewed at . 56 | 57 | 3. If you wish to change the template used for workshop websites, 58 | please work in . 59 | The home page of that repository explains how to set up workshop websites, 60 | while the extra pages in 61 | provide more background on our design choices. 62 | 63 | 4. If you wish to change CSS style files, tools, 64 | or HTML boilerplate for lessons or workshops stored in `_includes` or `_layouts`, 65 | please work in . 66 | 67 | ## What to Contribute 68 | 69 | There are many ways to contribute, 70 | from writing new exercises and improving existing ones 71 | to updating or filling in the documentation 72 | and submitting [bug reports][new-issue] 73 | about things that don't work, aren't clear, or are missing. 74 | If you are looking for ideas, 75 | please see [the list of issues for this repository][issues], 76 | or the issues for [Data Carpentry][dc-issues] 77 | and [Software Carpentry][swc-issues] projects. 78 | 79 | Comments on issues and reviews of pull requests are just as welcome: 80 | we are smarter together than we are on our own. 81 | Reviews from novices and newcomers are particularly valuable: 82 | it's easy for people who have been using these lessons for a while 83 | to forget how impenetrable some of this material can be, 84 | so fresh eyes are always welcome. 85 | 86 | ## What *Not* to Contribute 87 | 88 | Our lessons already contain more material than we can cover in a typical workshop, 89 | so we are usually *not* looking for more concepts or tools to add to them. 90 | As a rule, 91 | if you want to introduce a new idea, 92 | you must (a) estimate how long it will take to teach 93 | and (b) explain what you would take out to make room for it. 94 | The first encourages contributors to be honest about requirements; 95 | the second, to think hard about priorities. 96 | 97 | We are also not looking for exercises or other material that only run on one platform. 98 | Our workshops typically contain a mixture of Windows, Mac OS X, and Linux users; 99 | in order to be usable, 100 | our lessons must run equally well on all three. 101 | 102 | ## Using GitHub 103 | 104 | If you choose to contribute via GitHub, 105 | you may want to look at 106 | [How to Contribute to an Open Source Project on GitHub][how-contribute]. 107 | In brief: 108 | 109 | 1. The published copy of the lesson is in the `gh-pages` branch of the repository 110 | (so that GitHub will regenerate it automatically). 111 | Please create all branches from that, 112 | and merge the [master repository][repo]'s `gh-pages` branch into your `gh-pages` branch 113 | before starting work. 114 | Please do *not* work directly in your `gh-pages` branch, 115 | since that will make it difficult for you to work on other contributions. 116 | 117 | 2. We use [GitHub flow][github-flow] to manage changes: 118 | 1. Create a new branch in your desktop copy of this repository for each significant change. 119 | 2. Commit the change in that branch. 120 | 3. Push that branch to your fork of this repository on GitHub. 121 | 4. Submit a pull request from that branch to the [master repository][repo]. 122 | 5. If you receive feedback, 123 | make changes on your desktop and push to your branch on GitHub: 124 | the pull request will update automatically. 125 | 126 | Each lesson has two maintainers who review issues and pull requests 127 | or encourage others to do so. 128 | The maintainers are community volunteers, 129 | and have final say over what gets merged into the lesson. 130 | 131 | ## Other Resources 132 | 133 | General discussion of [Software Carpentry][swc-site] and [Data Carpentry][dc-site] 134 | happens on the [discussion mailing list][discuss-list], 135 | which everyone is welcome to join. 136 | You can also [reach us by email][contact]. 137 | 138 | [contact]: mailto:admin@software-carpentry.org 139 | [dc-issues]: https://github.com/issues?q=user%3Adatacarpentry 140 | [dc-lessons]: http://datacarpentry.org/lessons/ 141 | [dc-site]: http://datacarpentry.org/ 142 | [discuss-list]: http://lists.software-carpentry.org/listinfo/discuss 143 | [github]: http://github.com 144 | [github-flow]: https://guides.github.com/introduction/flow/ 145 | [github-join]: https://github.com/join 146 | [how-contribute]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github 147 | [new-issue]: https://github.com/swcarpentry/git-novice/issues/new 148 | [issues]: https://github.com/swcarpentry/git-novice/issues/ 149 | [repo]: https://github.com/swcarpentry/git-novice/ 150 | [swc-issues]: https://github.com/issues?q=user%3Aswcarpentry 151 | [swc-lessons]: http://software-carpentry.org/lessons/ 152 | [swc-site]: http://software-carpentry.org/ 153 | -------------------------------------------------------------------------------- /_episodes/06-ignore.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ignoring Things 3 | teaching: 5 4 | exercises: 0 5 | questions: 6 | - "How can I tell Git to ignore files I don't want to track?" 7 | objectives: 8 | - "Configure Git to ignore specific files." 9 | - "Explain why ignoring files can be useful." 10 | keypoints: 11 | - "The `.gitignore` file tells Git what files to ignore." 12 | --- 13 | 14 | What if we have files that we do not want Git to track for us, 15 | like backup files created by our editor 16 | or intermediate files created during data analysis. 17 | Let's create a few dummy files: 18 | 19 | ~~~ 20 | $ mkdir results 21 | $ touch a.dat b.dat c.dat results/a.out results/b.out 22 | ~~~ 23 | {: .bash} 24 | 25 | and see what Git says: 26 | 27 | ~~~ 28 | $ git status 29 | ~~~ 30 | {: .bash} 31 | 32 | ~~~ 33 | On branch master 34 | Untracked files: 35 | (use "git add ..." to include in what will be committed) 36 | 37 | a.dat 38 | b.dat 39 | c.dat 40 | results/ 41 | nothing added to commit but untracked files present (use "git add" to track) 42 | ~~~ 43 | {: .output} 44 | 45 | Putting these files under version control would be a waste of disk space. 46 | What's worse, 47 | having them all listed could distract us from changes that actually matter, 48 | so let's tell Git to ignore them. 49 | 50 | We do this by creating a file in the root directory of our project called `.gitignore`: 51 | 52 | ~~~ 53 | $ nano .gitignore 54 | $ cat .gitignore 55 | ~~~ 56 | {: .bash} 57 | 58 | ~~~ 59 | *.dat 60 | results/ 61 | ~~~ 62 | {: .output} 63 | 64 | These patterns tell Git to ignore any file whose name ends in `.dat` 65 | and everything in the `results` directory. 66 | (If any of these files were already being tracked, 67 | Git would continue to track them.) 68 | 69 | Once we have created this file, 70 | the output of `git status` is much cleaner: 71 | 72 | ~~~ 73 | $ git status 74 | ~~~ 75 | {: .bash} 76 | 77 | ~~~ 78 | On branch master 79 | Untracked files: 80 | (use "git add ..." to include in what will be committed) 81 | 82 | .gitignore 83 | nothing added to commit but untracked files present (use "git add" to track) 84 | ~~~ 85 | {: .output} 86 | 87 | The only thing Git notices now is the newly-created `.gitignore` file. 88 | You might think we wouldn't want to track it, 89 | but everyone we're sharing our repository with will probably want to ignore 90 | the same things that we're ignoring. 91 | Let's add and commit `.gitignore`: 92 | 93 | ~~~ 94 | $ git add .gitignore 95 | $ git commit -m "Add the ignore file" 96 | $ git status 97 | ~~~ 98 | {: .bash} 99 | 100 | ~~~ 101 | # On branch master 102 | nothing to commit, working directory clean 103 | ~~~ 104 | {: .output} 105 | 106 | As a bonus, using `.gitignore` helps us avoid accidentally adding to the repository files that we don't want to track: 107 | 108 | ~~~ 109 | $ git add a.dat 110 | ~~~ 111 | {: .bash} 112 | 113 | ~~~ 114 | The following paths are ignored by one of your .gitignore files: 115 | a.dat 116 | Use -f if you really want to add them. 117 | ~~~ 118 | {: .output} 119 | 120 | If we really want to override our ignore settings, 121 | we can use `git add -f` to force Git to add something. For example, 122 | `git add -f a.dat`. 123 | We can also always see the status of ignored files if we want: 124 | 125 | ~~~ 126 | $ git status --ignored 127 | ~~~ 128 | {: .bash} 129 | 130 | ~~~ 131 | On branch master 132 | Ignored files: 133 | (use "git add -f ..." to include in what will be committed) 134 | 135 | a.dat 136 | b.dat 137 | c.dat 138 | results/ 139 | 140 | nothing to commit, working directory clean 141 | ~~~ 142 | {: .output} 143 | 144 | > ## Ignoring Nested Files 145 | > 146 | > Given a directory structure that looks like: 147 | > 148 | > ~~~ 149 | > results/data 150 | > results/plots 151 | > ~~~ 152 | > {: .bash} 153 | > 154 | > How would you ignore only `results/plots` and not `results/data`? 155 | > 156 | > > ## Solution 157 | > > 158 | > > As with most programming issues, there are a few ways that you 159 | > > could solve this. If you only want to ignore the contents of 160 | > > `results/plots`, you can change your `.gitignore` to ignore 161 | > > only the `/plots/` subfolder by adding the following line to 162 | > > your .gitignore: 163 | > > 164 | > > `results/plots/` 165 | > > 166 | > > If, instead, you want to ignore everything in `/results/`, but wanted to track 167 | > > `results/data`, then you can add `results/` to your .gitignore 168 | > > and create an exception for the `results/data/` folder. 169 | > > The next challenge will cover this type of solution. 170 | > > 171 | > > Sometimes the `**` pattern comes in handy, too, which matches 172 | > > multiple directory levels. E.g. `**/results/plots/*` would make git ignore 173 | > > the `results/plots` directory in any root directory. 174 | > {: .solution} 175 | {: .challenge} 176 | 177 | > ## Including Specific Files 178 | > 179 | > How would you ignore all `.data` files in your root directory except for 180 | > `final.data`? 181 | > Hint: Find out what `!` (the exclamation point operator) does 182 | > 183 | > > ## Solution 184 | > > 185 | > > You would add the following two lines to your .gitignore: 186 | > > 187 | > > ~~~ 188 | > > *.data # ignore all data files 189 | > > !final.data # except final.data 190 | > > ~~~ 191 | > > {: .output} 192 | > > 193 | > > The exclamation point operator will include a previously excluded entry. 194 | > {: .solution} 195 | {: .challenge} 196 | 197 | > ## Ignoring all data Files in a Directory 198 | > 199 | > Given a directory structure that looks like: 200 | > 201 | > ~~~ 202 | > results/data/position/gps/a.data 203 | > results/data/position/gps/b.data 204 | > results/data/position/gps/c.data 205 | > results/data/position/gps/info.txt 206 | > results/plots 207 | > ~~~ 208 | > {: .bash} 209 | > 210 | > What's the shortest `.gitignore` rule you could write to ignore all `.data` 211 | > files in `result/data/position/gps`? Do not ignore the `info.txt`. 212 | > 213 | > > ## Solution 214 | > > 215 | > > Appending `results/data/position/gps/*.data` will match every file in `results/data/position/gps` that ends with `.data`. 216 | > > The file `results/data/position/gps/info.txt` will not be ignored. 217 | > {: .solution} 218 | {: .challenge} 219 | 220 | > ## The Order of Rules 221 | > 222 | > Given a `.gitignore` file with the following contents: 223 | > 224 | > ~~~ 225 | > *.data 226 | > !*.data 227 | > ~~~ 228 | > {: .bash} 229 | > 230 | > What will be the result? 231 | > 232 | > > ## Solution 233 | > > 234 | > > The `!` modifier will negate an entry from a previously defined ignore pattern. 235 | > > Because the `!*.data` entry negates all of the previous `.data` files in the `.gitignore`, 236 | > > none of them will be ignored, and all `.data` files will be tracked. 237 | > > 238 | > {: .solution} 239 | {: .challenge} 240 | 241 | > ## Log Files 242 | > 243 | > You wrote a script that creates many intermediate log-files of the form `log_01`, `log_02`, `log_03`, etc. 244 | > You want to keep them but you do not want to track them through `git`. 245 | > 246 | > 1. Write **one** `.gitignore` entry that excludes files of the form `log_01`, `log_02`, etc. 247 | > 248 | > 2. Test your "ignore pattern" by creating some dummy files of the form `log_01`, etc. 249 | > 250 | > 3. You find that the file `log_01` is very important after all, add it to the tracked files without changing the `.gitignore` again. 251 | > 252 | > 4. Discuss with your neighbor what other types of files could reside in your directory that you do not want to track and thus would exclude via `.gitignore`. 253 | > 254 | > > ## Solution 255 | > > 256 | > > 1. append either `log_*` or `log*` as a new entry in your .gitignore 257 | > > 3. track `log_01` using `git add -f log_01` 258 | > {: .solution} 259 | {: .challenge} 260 | -------------------------------------------------------------------------------- /fig/versions.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /fig/git-checkout.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | .git 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | 35 | 36 | 37 | 40 | 41 | 42 | 44 | 45 | 46 | 47 | 48 | 50 | 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | FILE1.txt 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | FILE2.txt 85 | 86 | 87 | HEAD 88 | 89 | HEAD~1 90 | 91 | HEAD~2 92 | 93 | 892134f 94 | 95 | f22b25e 96 | 97 | 3a54f76 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | git checkout HEAD~1or git checkout f22b25e 107 | 108 | 109 | repository 110 | 111 | 112 | --------------------------------------------------------------------------------