Using GitHub for Collaboration <p>class: inverse, center, middle</p> <h1>Using GitHub for Collaboration</h1> <h3>Hao Ye</h3> <h3>Health Science Center Libraries, University of Florida</h3> <h3>(updated: 2021-01-28)</h3> <hr /> <h1>Motivations</h1> <ul> <li>One of the advantages for using version control is managing collaborative work.</li> <li>Git is a flexible tool that accommodates many different styles of collaboration... not all of these styles are suitable for small research teams.</li> <li>"GitHub flow" is a workflow that is lightweight and scales well for individuals and small teams.</li> </ul> <hr /> <h1>Learning Outcomes</h1> <ul> <li>describe how merge conflicts originate and how to resolve them</li> <li>apply the "GitHub flow" workflow for collaborating</li> <li>create and navigate branches on GitHub and using GitHub Desktop</li> <li>create and merge pull requests</li> <li>understand "forks" and open-source-community development on GitHub</li> </ul> <hr /> <h1>Prerequisites</h1> <p>This lesson assumes you: <em> have some familiarity making </em>repos<em> and </em>commits<em> </em> know how to synchronize repos from your computer to GitHub</p> <hr /> <p>class: inverse, center, middle</p> <h1>Merge Conflicts</h1> <hr /> <h1>Inviting Collaborators</h1> <ul> <li>I have a github repo, and would like to give my collaborator access to work on the project.</li> <li>From the github repo page:</li> <li><code>Settings</code> -> <code>Manage access</code></li> <li><code>Invite a collaborator</code></li> </ul> <hr /> <p><img src="github-manage-access.png" title="A screenshot of the website https://github.com/ha0ye/portalDS/settings/access, showing that the repo is visible to the public, and that only the owner can contribute to the repository. There is a green button with the text 'Invite a collaborator'." alt="A screenshot of the website https://github.com/ha0ye/portalDS/settings/access, showing that the repo is visible to the public, and that only the owner can contribute to the repository. There is a green button with the text 'Invite a collaborator'." /></p> <hr /> <h1>A Simple Workflow</h1> <p>Two people, A and B, are working together on one repo in GitHub: <em> A makes commits, A pushes the new commits to GitHub. </em> B pulls the latest commits from A, works on new commits, and pushes their new commits back to GitHub. * A pulls the latest commits from B, works on new commits, etc.</p> <hr /> <h1>What happens if you forget to pull?</h1> <p>You get a warning when you try to push to GitHub.</p> <p><img src="newer-commits-warning.png" title="A screenshot of the warning from using GitHub Desktop when trying to push new commits to GitHub, and there are commits on GitHub that have not yet been fetched and merged locally. The warning reads 'Newer Commits on Remote; Desktop is unable to push commits to this branch because there are commits on the remote that are not present on your local branch. Fetch these new commits before pushing in order to reconcile them with your local commits.'" alt="A screenshot of the warning from using GitHub Desktop when trying to push new commits to GitHub, and there are commits on GitHub that have not yet been fetched and merged locally. The warning reads 'Newer Commits on Remote; Desktop is unable to push commits to this branch because there are commits on the remote that are not present on your local branch. Fetch these new commits before pushing in order to reconcile them with your local commits.'" /></p> <hr /> <h1>Merging</h1> <ul> <li>a <code>git merge</code> combine the changes from diverging commits:</li> <li>suppose A and B start with commit: <code>{orig}</code></li> <li>A makes a commit, <code>{a}</code>, with changes</li> <li>B makes a commit, <code>{b}</code>, with changes</li> <li><code>git merge</code> combines <code>{a}</code> and <code>{b}</code> into a new commit <code>{c}</code>, that contains both sets of changes.</li> </ul> <hr /> <h1>Merging (automatically)</h1> <ul> <li>if the changes are in different files</li> </ul> <p>OR different parts of the same files - git is generally able to combine the changes without further intervention</p> <ul> <li>if git is unable to merge automatically, then it is a <code>merge conflict</code></li> </ul> <hr /> <h1>Resolving merge conflicts</h1> <ul> <li>when git cannot combine the changes automatically, you must manually create the merged file: <img src="merge-conflict.png" title="A screenshot of BBedit showing the merge conflict. Line 6 is '<<<<<<< HEAD'<code>' indicating the start of one version of the file. Line 8 is '=======' indicating the end of one version and the beginning of the next. Line 10 shows '&gt;&gt;&gt;&gt;&gt;&gt;&gt;' followed by a hash, indicating the end of the second version." alt="A screenshot of BBedit showing the merge conflict. Line 6 is '&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD'</code>' indicating the start of one version of the file. Line 8 is '=======' indicating the end of one version and the beginning of the next. Line 10 shows '>>>>>>>' followed by a hash, indicating the end of the second version." /></li> </ul> <hr /> <h1>Resolving merge conflicts 2</h1> <ul> <li>After the conflicts are resolved, you need to create a new commit with the merged edits.</li> <li>This merged commit can then be pushed to github without issue.</li> <li>For non-text files, you may need to revert back to one or the other version (whichever is correct)</li> </ul> <hr /> <h1>Summary</h1> <ul> <li>This approach works pretty well when there is one primary contributor, and collaborators rarely make changes.</li> <li>otherwise everyone needs to be constantly pulling and merging, contacting each other through separate channels to let them know you are done pushing changes to GitHub, etc.</li> </ul> <hr /> <p>class: inverse, center, middle</p> <h1>GitHub Flow</h1> <hr /> <h1>Essentials of GitHub Flow</h1> <p>Manage work using branches - <code>merge</code> branches back to the primary branch when ready.</p> <p><img src="github-flow.png" title="A screenshot of the diagram from https://guides.github.com/introduction/flow/, showing conceptually how the 'GitHub flow' workflow works." alt="A screenshot of the diagram from https://guides.github.com/introduction/flow/, showing conceptually how the 'GitHub flow' workflow works." /></p> <hr /> <h1>Steps</h1> <ol> <li>Create a branch and switch to it.</li> <li>Add commits with desired changes.</li> <li>Open a pull request (PR).</li> <li>Review the PR if necessary, and merge.</li> <li>Delete branch if done.</li> </ol> <hr /> <p>class: inverse, center, middle</p> <h1>Navigating Branches</h1> <hr /> <h1>What is a Branch?</h1> <ul> <li>A <code>branch</code> is a label for a set of commits.</li> </ul> <p><img src="git-branch.svg" title="A diagram from https://www.atlassian.com/git/tutorials/using-branches, of a git repo represented in a diagram with commits as circular nodes, with edges between them showing the relationship between commits and their parents. There is a <code>Master</code> branch in light blue, a <code>Little Feature</code> branch in purple with one commit, and a <code>Big Feature</code> branch in green with 3 commits." alt="A diagram from https://www.atlassian.com/git/tutorials/using-branches, of a git repo represented in a diagram with commits as circular nodes, with edges between them showing the relationship between commits and their parents. There is a <code>Master</code> branch in light blue, a <code>Little Feature</code> branch in purple with one commit, and a <code>Big Feature</code> branch in green with 3 commits." width="80%" /> .small[[img: https://www.atlassian.com/git/tutorials/using-branches]]</p> <hr /> <h1>How do branches work?</h1> <ul> <li>By default, you are in the primary branch.</li> <li>each commit has changes from the previous commit</li> <li>a linear sequence of versions of the project</li> <li>When you want to make changes and commits without disrupting the primary branch:</li> <li>create a new branch</li> <li>merge when ready</li> </ul> <hr /> <h1>Creating new branches (GitHub)</h1> <p><img src="github-new-branch.png" title="screenshot of the GitHub interface, when clicking on the pulldown menu to switch branches; this interface also enables one to create new branches." alt="screenshot of the GitHub interface, when clicking on the pulldown menu to switch branches; this interface also enables one to create new branches." /></p> <hr /> <p>class: center, middle</p> <h1>DEMO</h1> <hr /> <h1>Creating new branches (GitHub Desktop)</h1> <p><img alt="screenshot of the GitHub Desktop interface, when clicking on the pulldown menu to switch branches; this interface also enables one to create new branches." src="github-desktop-new-branch.png" /></p> <hr /> <p>class: center, middle</p> <h1>DEMO</h1> <hr /> <p>class: inverse, center, middle</p> <h1>Merging Branches</h1> <hr /> <h1>Merging (branches)</h1> <ul> <li>Nearly the same as merging commits:</li> <li> <p>merge the last commit on another branch to the current branch.</p> </li> <li> <p>switch to the branch that will keep the merged result</p> </li> <li>merge from the other branch</li> </ul> <hr /> <p>class: center, middle</p> <h1>DEMO (GitHub Desktop)</h1> <hr /> <h1>Pull Request (GitHub)</h1> <ul> <li>recommended practice for merges on GitHub</li> <li>lets you document the merge</li> <li>can request official "review"</li> <li>other collaborators can comment, make further changes</li> </ul> <hr /> <p>class: center, middle</p> <h1>DEMO (GitHub)</h1> <hr /> <p>class: inverse, center, middle</p> <h1>Community-oriented Development on GitHub</h1> <hr /> <h1>Issues</h1> <ul> <li>reported bugs, feature requests, etc.</li> <li>anyone can contribute to discussion</li> <li>can be referred to by number in commits and pull requests</li> </ul> <hr /> <p>class: center, middle</p> <h1>DEMO</h1> <hr /> <h1>Forks</h1> <ul> <li>How do you contribute to other people's projects?</li> <li>Fork = clone a repo on GitHub</li> <li>Forks retain memory of original repo (and cannot have their own issues)</li> <li> <p>Pull Requests can merge from across forks.</p> </li> <li> <p>"Fork and PR" is a common phrase indicating how one should contribute to an open-source project.</p> </li> </ul> <hr /> <h1>Thanks</h1> <ul> <li>Let me know what content you'd like to see</li> <li>Contact me for additional questions or consultation requests!</li> <li>Check back in on the libguide for more modules and contact info:</li> <li>https://guides.uflib.ufl.edu/reproducibility @media screen {.remark-slide-container{display:block;}.remark-slide-scaler{box-shadow:none;}} var slideshow = remark.create({ "highlightStyle": "github", "highlightLines": true, "countIncrementalSlides": false }); if (window.HTMLWidgets) slideshow.on('afterShowSlide', function (slide) { window.dispatchEvent(new Event('resize')); }); (function(d) { var s = d.createElement("style"), r = d.querySelector(".remark-slide-scaler"); if (!r) return; s.type = "text/css"; s.innerHTML = "@page {size: " + r.style.width + " " + r.style.height +"; }"; d.head.appendChild(s); })(document);</li> </ul> <p>(function(d) { var el = d.getElementsByClassName("remark-slides-area"); if (!el) return; var slide, slides = slideshow.getSlides(), els = el[0].children; for (var i = 1; i < slides.length; i++) { slide = slides[i]; if (slide.properties.continued === "true" || slide.properties.count === "false") { els[i - 1].className += ' has-continuation'; } } var s = d.createElement("style"); s.type = "text/css"; s.innerHTML = "@media print { .has-continuation { display: none; } }"; d.head.appendChild(s); })(document); // delete the temporary CSS (for displaying all slides initially) when the user // starts to view slides (function() { var deleted = false; slideshow.on('beforeShowSlide', function(slide) { if (deleted) return; var sheets = document.styleSheets, node; for (var i = 0; i < sheets.length; i++) { node = sheets[i].ownerNode; if (node.dataset["target"] !== "print-only") continue; node.parentNode.removeChild(node); } deleted = true; }); })(); (function() { "use strict" // Replace <script> tags in slides area to make them executable var scripts = document.querySelectorAll( '.remark-slides-area .remark-slide-container script' ); if (!scripts.length) return; for (var i = 0; i < scripts.length; i++) { var s = document.createElement('script'); var code = document.createTextNode(scripts[i].textContent); s.appendChild(code); var scriptAttrs = scripts[i].attributes; for (var j = 0; j < scriptAttrs.length; j++) { s.setAttribute(scriptAttrs[j].name, scriptAttrs[j].value); } scripts[i].parentElement.replaceChild(s, scripts[i]); } })(); (function() { var links = document.getElementsByTagName('a'); for (var i = 0; i < links.length; i++) { if (/^(https?:)?\/\//.test(links[i].getAttribute('href'))) { links[i].target = '_blank'; } } })(); // adds .remark-code-has-line-highlighted class to <pre> parent elements // of code chunks containing highlighted lines with class .remark-code-line-highlighted (function(d) { const hlines = d.querySelectorAll('.remark-code-line-highlighted'); const preParents = []; const findPreParent = function(line, p = 0) { if (p > 1) return null; // traverse up no further than grandparent const el = line.parentElement; return el.tagName === "PRE" ? el : findPreParent(el, ++p); };</p> <p>for (let line of hlines) { let pre = findPreParent(line); if (pre && !preParents.includes(pre)) preParents.push(pre); } preParents.forEach(p => p.classList.add("remark-code-has-line-highlighted")); })(document);
slideshow._releaseMath = function(el) { var i, text, code, codes = el.getElementsByTagName('code'); for (i = 0; i < codes.length;) { code = codes[i]; if (code.parentNode.tagName !== 'PRE' && code.childElementCount === 0) { text = code.textContent; if (/^\\\((.|\s)+\\\)$/.test(text) || /^\\\[(.|\s)+\\\]$/.test(text) || /^\$\$(.|\s)+\$\$$/.test(text) || /^\\begin\{([^}]+)\}(.|\s)+\\end\{[^}]+\}$/.test(text)) { code.outerHTML = code.innerHTML; // remove
continue;
}
}
i++;
}
};
slideshow._releaseMath(document);
(function () {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-MML-AM_CHTML';
if (location.protocol !== 'file:' && /^https?:/.test(script.src))
script.src = script.src.replace(/^https?:/, '');
document.getElementsByTagName('head')[0].appendChild(script);
})();
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.