{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Intro to git\n", "## August Guang" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## What is git\n", "\n", " - open source version control tool written by Linus Torvalds ()\n", " - **version control:** tracks and manages changes to documents, computer programs, and other collections of information" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Why use git?\n", "\n", " * Tracking changes over time\n", " * Helps with collaboration on the same software\n", " * Keep your code on Oscar and locally in sync\n", " * Protect stable/production code from bugs" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Webhosts\n", "\n", "[](https://about.gitlab.com)\n", "*Gitlab*\n", "[](https://github.com)\n", "*Github*\n", "[](https://bitbucket.org)\n", "*Bitbucket*" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## git basics - Forking\n", "\n", " * First, let's create our own copy of the repository this presentation is hosted on by **forking** it.\n", " * Forking a repository is done when you want to a copy of a repository that someone else owns but you want to make your own changes to it for your own purposes.\n", "\n", "Go to the Github repo of this tutorial: [https://github.com/dscov-tutorials/gitintro](https://github.com/dscov-tutorials/gitintro)." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Click on the Fork button in the upper right.\n", "\n", "![](img/fork.png)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "It will ask where you want to fork it to. Pick your own account.\n", "\n", "![](img/wherefork.png)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "After a bit, Github will redirect you to a complete copy of this repo, but now owned by you. You can tell it is a fork because it will say at the top in small font \"forked from dscov-tutorials/gitintro\".\n", "\n", "![](img/forkedfrom.png)\n", "\n", "Go ahead and clone the repository by going to the terminal and typing in the below.\n", "\n", "```bash\n", "git clone https://github.com/$USERNAME/gitintro.git\n", "```\n", "\n", "(In general you can get a clone address by clicking the green **Clone or download** icon on your repo's github page)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## git basics\n", "\n", " * **repository or repo:** where documents, software, etc is stored and the changes are tracked\n", "\n", "```text\n", "gitintro\n", "├── img\n", "| └── images.png\n", "├── PITCHME.md\n", "└── README.md\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "![](img/git-local-remotes.png)\n", "[https://hoantran-it.blogspot.com/2016/06/git-tutorial-1-git-committing-and.html](https://hoantran-it.blogspot.com/2016/06/git-tutorial-1-git-committing-and.html)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "```bash\n", "# check status of your git repo including what's changed\n", "# and what's not being tracked\n", "git status\n", "# add file contents to be ready to be committed\n", "git add FILE \n", "# commit file contents to the local repository\n", "git commit FILE\n", "# commit all added/modified/deleted file contents with\n", "# specific message\n", "git commit -a -m \"commit message\"\n", "# push file contents to the remote (i.e. cloud) repository\n", "git push \n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "`git status` reveals that everything is up to date.\n", "\n", "```diff\n", "On branch master\n", "Your branch is up to date with 'origin/master'.\n", "\n", "nothing to commit, working tree clean\n", "```\n", "\n", "```diff\n", "Working Directory | Local | Remote\n", " --- | --- |\n", "gitintro | gitintro | gitintro\n", "├── img | ├── img | ├── img \n", "| └── images.png | └── images.png | └── images.png\n", "├── PITCHME.md | ├── PITCHME.md | ├── PITCHME.md \n", "└── README.md | └── README.md | └── README.md \n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Let's create a file.\n", "\n", "```bash\n", "echo \"test\" > test.txt\n", "git status\n", "```\n", "\n", "```diff\n", "On branch master\n", "Your branch is up to date with 'origin/master'.\n", "\n", "Untracked files:\n", " (use \"git add ...\" to include in what will be committed)\n", "\n", " - test.txt\n", "\n", "nothing added to commit but untracked files present (use \"git add\" to track)\n", "```\n", "\n", "```diff\n", "Working Directory | Local | Remote\n", " --- | --- |\n", " gitintro | gitintro | gitintro \n", " ├── img | ├── img | ├── img\n", " | ├── images.png | | ├── images.png | | ├── images.png\n", " ├── test.txt | └── README.md | └── README.md\n", " └── README.md | |\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "`git add test.txt` adds the file to the staging area.\n", "\n", "```bash\n", "git add test.txt\n", "git status\n", "```\n", "\n", "```bash\n", "On branch master\n", "Your branch is up to date with 'origin/master'.\n", "\n", "Changes to be committed:\n", " (use \"git reset HEAD ...\" to unstage)\n", "\n", " new file: test.txt/\n", "```\n", "\n", "```diff\n", "Working Directory | Local | Remote\n", " --- | --- |\n", " gitintro | gitintro | gitintro \n", " ├── img | ├── img | ├── img\n", " | ├── images.png | | ├── images.png | | ├── images.png\n", " ├── test.txt | └── README.md | └── README.md\n", " └── README.md | |\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "`git commit -a -m \"test.txt\"` actually commits it to local repo.\n", "\n", "```bash\n", "git commit -a -m \"test.txt\"\n", "git status\n", "```\n", "\n", "```diff\n", "On branch master\n", "Your branch is ahead of 'origin/master' by 1 commit.\n", " (use \"git push\" to publish your local commits)\n", "\n", "nothing to commit, working tree clean\n", "```\n", "\n", "```diff\n", "Working Directory | Local | Remote\n", " --- | --- |\n", " gitintro | gitintro | gitintro \n", " ├── img | ├── img | ├── img\n", " | ├── images.png | | ├── images.png | | ├── images.png\n", " ├── test.txt | ├── test.txt | └── README.md \n", " └── README.md | └── README.md | \n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "`git log` will show a log of everyone's commits and messages.\n", "\n", "```diff\n", "commit 335531d99fd3987a169121307965e28e75de4dbf (HEAD -> master, origin/master, origin/HEAD)\n", "Author: August Guang \n", "Date: Wed Mar 13 13:56:59 2019 -0400\n", "\n", " test.txt\n", "\n", "(and so on)\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## git push\n", "\n", "`git push origin master` pushes everything from the local repository to the remote repository.\n", "\n", "```bash\n", "git push origin master\n", "```\n", "\n", "```diff\n", "Counting objects: 3, done.\n", "Delta compression using up to 8 threads.\n", "Compressing objects: 100% (2/2), done.\n", "Writing objects: 100% (3/3), 274 bytes | 274.00 KiB/s, done.\n", "Total 3 (delta 1), reused 0 (delta 0)\n", "remote: Resolving deltas: 100% (1/1), completed with 1 local object.\n", "To https://github.com/aguang/gitintro.git\n", " 2fb5c0d..335531d master -> master\n", "```\n", "\n", "```bash\n", "git status\n", "```\n", "\n", "```diff\n", "On branch master\n", "Your branch is ahead of 'origin/master' by 1 commit.\n", " (use \"git push\" to publish your local commits)\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## git push\n", "\n", "```text\n", "Working Directory | Local | Remote\n", " --- | --- |\n", " gitintro | gitintro | gitintro \n", " ├── img | ├── img | ├── img\n", " | ├── images.png | | ├── images.png | | ├── images.png\n", " ├── test.txt | ├── test.txt | ├── test.txt \n", " └── README.md | └── README.md | └── README.md\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## local remote\n", "\n", "![](img/git-local-remotes.png)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Commands for pulling from remote\n", "\n", "```bash\n", "# pull data from remote repo into local repo\n", "git fetch\n", "# tells you what branch you have locally and what\n", "# branch your working directory is on\n", "git branch\n", "# tells you what branch you have remotely\n", "git branch -r\n", "# used to navigate between branches on the local repo\n", "# need to run git fetch first to pull in branches\n", "git checkout branch\n", "# merges data from local repo into working directory\n", "git merge\n", "# used to create a new branch\n", "git checkout -b NEW_BRANCH\n", "# combines fetch & merge all at once\n", "git pull\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Let's first make a new branch called `example` on Github and add a file `newfile`. Go back to the view of your repository on the browser. It should look like you have a file `test.txt` in it now.\n", "\n", "![](img/test.png)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Click on the Branch: **master** icon. A window will appear with the ability to type in a new branch name. Type in `example`.\n", "\n", "![](img/newbranch.png)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Now you are on a new branch called `example`. Click on the \"Create new file\" icon. This will take you to an editing screen. Type in \"newfile\" inside Name your file... and put whatever you want into the blank text underneath.\n", "\n", "![](img/newfile.png)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Then scroll down and hit the green \"Commit new file\" button.\n", "\n", "![](img/commitnew.png)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "You have now created a new file `newfile` inside the branch `example` *remotely*. So how do we get it into local?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Current structure\n", "\n", "```diff\n", "+ remote\n", "master | example \n", " --- | --- \n", " gitintro | gitintro \n", " ├── img | ├── img \n", " | ├── images.png | | ├── images.png \n", " ├── test.txt | ├── newfile\n", " └── README.md | └── README.md \n", " \n", "\n", "- local\n", "master\n", " --- \n", " gitintro \n", " ├── img \n", " | ├── images.png\n", " ├── test.txt \n", " └── README.md \n", "\n", "- working directory\n", "master\n", " --- \n", " gitintro \n", " ├── img \n", " | ├── images.png \n", " ├── test.txt \n", " └── README.md \n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "`git branch` tells you what branch you are on. `git branch -r` tells you what you have in your remote.\n", "\n", "```bash\n", "git branch\n", "git branch -r\n", "```\n", "\n", "```bash\n", "(base) aguang@cis240l0htdh:~/CORE/workshops/dscov/test/gitintro$ git branch\n", "* master\n", "(base) aguang@cis240l0htdh:~/CORE/workshops/dscov/test/gitintro$ git branch -r\n", " origin/HEAD -> origin/master\n", " origin/master\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "`git fetch` pulls data from remote repo into local repo.\n", "\n", "```bash\n", "git fetch\n", "```\n", "\n", "```bash\n", "From https://github.com/aguang/gitintro\n", " * [new branch] example -> origin/example\n", " ```\n", "\n", "```diff\n", "+ remote\n", "master | example \n", " --- | --- \n", " gitintro | gitintro \n", " ├── img | ├── img \n", " | ├── images.png | | ├── images.png \n", " ├── test.txt | ├── newfile \n", " └── README.md | └── README.md \n", "\n", "- local\n", "master | example \n", " --- | --- \n", " gitintro | gitintro \n", " ├── img | ├── img \n", " | ├── images.png | | ├── images.png \n", " ├── test.txt | ├── newfile \n", " └── README.md | └── README.md \n", "\n", "- working directory\n", "master\n", " --- \n", " gitintro \n", " ├── img \n", " | ├── images.png \n", " └── README.md \n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "```bash\n", "git branch\n", "git branch -r\n", "```\n", "\n", "```bash\n", "(base) aguang@cis240l0htdh:~/CORE/workshops/dscov/test/gitintro$ git branch\n", "* master\n", "(base) aguang@cis240l0htdh:~/CORE/workshops/dscov/test/gitintro$ git branch -r\n", " origin/HEAD -> origin/master\n", " origin/example\n", " origin/master\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "`git checkout example` pulls in an exact copy from local.\n", "\n", "```bash\n", "git checkout example\n", "```\n", "\n", "```bash\n", "Branch 'example' set up to track remote branch 'example' from 'origin'.\n", "Switched to a new branch 'example'\n", "```\n", "\n", "```diff\n", "+ remote\n", "master | example \n", " --- | --- \n", " gitintro | gitintro \n", " ├── img | ├── img \n", " | ├── images.png | | ├── images.png \n", " ├── test.txt | ├── newfile \n", " └── README.md | └── README.md \n", "\n", "- local\n", "master | example \n", " --- | --- \n", " gitintro | gitintro \n", " ├── img | ├── img \n", " | ├── images.png | | ├── images.png \n", " ├── test.txt | ├── newfile \n", " └── README.md | └── README.md \n", "\n", "- working directory\n", "example\n", " --- \n", " gitintro \n", " ├── img \n", " | ├── images.png\n", " ├── newfile \n", " └── README.md\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "`git merge $BRANCH` merges everything from local current branch $BRANCH into working directory.\n", "\n", "```diff\n", "+ remote\n", "master | example \n", " --- | --- \n", " gitintro | gitintro \n", " ├── img | ├── img \n", " | ├── images.png | | ├── images.png \n", " ├── test.txt | ├── newfile \n", " └── README.md | └── README.md \n", "\n", "- local\n", "master | example \n", " --- | --- \n", " gitintro | gitintro \n", " ├── img | ├── img \n", " | ├── images.png | | ├── images.png \n", " ├── test.txt | ├── newfile \n", " └── README.md | └── README.md \n", "\n", "- working directory\n", "example\n", " --- \n", " gitintro \n", " ├── img \n", " | ├── images.png\n", " ├── newfile\n", " ├── test.txt \n", " └── README.md\n", "```\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "If some of your files get overwritten you may get merge conflicts. These you will have to fix file by file and line by line to decide which version you want to keep. The merge conflicts will be marked with text like\n", "\n", "```diff\n", ">>>>>>>>>>>HEAD\n", "code_version1\n", "<<<<<<<<<< [stack overflow](http://www.stackoverflow.com) is where I have acquired all of my git knowledge.\n", " * Atlassian also has [great explanations of everything](https://www.atlassian.com/git/tutorials/using-examplees/git-checkout)\n", "\n", "## Integrations\n", "\n", " * Can integrate with Slack: subscribe a channel to a Github repository so everyone in the channel sees commits, pushes, etc and can comment on them\n", " * Useful for individual projects\n", " * Github-actions and codecov/coveralls will allow you to have continuous integration and view your test coverage for your software" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "
" ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.7" } }, "nbformat": 4, "nbformat_minor": 2 }