{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Using `git` with `GitHub`\n", "\n", "We will create a new GitHub repository and simulate its use by two different users `A` and `B` to illustrate how to use a shared repository to collaborate and issues that might arise.\n", "\n", "See Git's extensive [documentation](https://git-scm.com/doc)\n", "\n", "Atlassian provides a detailed [tutorial](https://www.atlassian.com/git/tutorials)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Git cheat sheet\n", "\n", "![Cheat sheet](https://services.github.com/on-demand/downloads/github-git-cheat-sheet.pdf)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Getting help" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git help" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "scrolled": false }, "outputs": [], "source": [ "git help log | head -20" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log --help | head -20" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "scrolled": false }, "outputs": [], "source": [ "git help tutorial | head -20" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tutorial of using git with GitHub" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Set up a student account with GitHub and get [free stuff](https://education.github.com/pack)\n", "- Create a public repository on GitHub called bios-821-git-lesson\n", "- Add a README, and a BSD-3 license" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Note**\n", "\n", "We are doing this in a Jupyter notebook with the `bash` kernel purely for illustration. More typically, you will be giving `git` commands in the `bash` shell. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Cloning" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- **User A** Clone the repository you have just created to your local machine as `bios-821-a`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git clone https://github.com/cliburn/bios-821-git-lesson.git bios-821-a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- **User B** Clone a second copy of the repository as `bios-821-b`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git clone https://github.com/cliburn/bios-821-git-lesson.git bios-821-b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "- Change directory to `bios-821-a`\n", "- Check the status of the repository" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Git basics \n", "\n", "`add`, `commit`, `push`, `pull`, `status`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cd bios-821-a\n", "git status" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Create the following file as `first.txt`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", "This is my first file.\n", "I am so proud of it.\n", "Some day, this file will make me famous.\n", "It is my most favorite file.\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat > first.txt << 'EOF'\n", "This is my first file.\n", "I am so proud of it.\n", "Some day, this file will make me famous.\n", "It is my most favorite file.\n", "EOF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "- Add the file to the repository\n", "- Check the status" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git add first.txt\n", "git status" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Remove the file from the staging area\n", "- Check the status" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git reset HEAD first.txt\n", "git status" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "- Add and commit the file with a commit message `My first upload`\n", "- Check the status" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git add first.txt\n", "git commit -m \"My first upload\"\n", "git status" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Push the file to GitHub" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git push" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Go to the GitHub web page for this repository and look around" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "- Create the following files" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As `second.txt`\n", "\n", "```\n", "This is my second file. Bugs.\n", "I am so proud of it. Bugs.\n", "Some day, this file will make me rich. Bugs.\n", "It is my second favorite file. Bugs.\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat > second.txt << 'EOF'\n", "This is my second file. Bugs.\n", "I am so proud of it. Bugs.\n", "Some day, this file will make me rich. Bugs.\n", "It is my second favorite file. Bugs.\n", "EOF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As `third.txt`\n", "\n", "```\n", "This is my third file.\n", "I am so proud of it.\n", "Some day, this file will make me fat.\n", "It is my third favorite file.\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat > third.txt << 'EOF'\n", "This is my third file.\n", "I am so proud of it.\n", "Some day, this file will make me fat.\n", "It is my third favorite file.\n", "EOF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "\n", "- Add both files to the repository at once by adding the current directory\n", "- Check the status" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git add .\n", "git status" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Commit both files. Write the commit message.\n", "\n", "```\n", "More files uploaded.\n", "\n", "Feeling super-productive.\n", "This will make me famous, rich and fat.\n", "```\n", "\n", "- Check the status" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note: \n", "\n", "`-F` means read from file and the trailing `-` means use standard input as file" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git commit -F- <<'EOF'\n", "More files uploaded.\n", "\n", "Feeling super-productive.\n", "This will make me famous, rich and fat.\n", "EOF" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git status" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Push to GitHub" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git push" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using `git log`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "\n", "- View the log messages" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- View the log messages showing only one line " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log --oneline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- view only the log message for the second commit" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log -1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- View what files were added or modified in the second commit" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log --stat -1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "\n", "Now edit `first.txt` to read\n", "```\n", "This is my first file.\n", "I am so proud of it.\n", "Some day, this file will make me famous.\n", "It is my most favorite file.\n", "Ed Sheeran likes this file.\n", "Taylor Swift mentioned this file in her new album.\n", "President Trump tweeted about this file.\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat > first.txt <<'EOF'\n", "This is my first file.\n", "I am so proud of it.\n", "Some day, this file will make me famous.\n", "It is my most favorite file.\n", "Ed Sheeran likes this file.\n", "Taylor Swift mentioned this file in her new album.\n", "President Trump tweeted about this file.\n", "EOF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "\n", "- Add the revised file to the repository\n", "- Check the status" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git add first.txt\n", "git status" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using `git diff`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Find out what the differences are between the version in the staging area and the version in the repository" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git diff --staged" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Commit the file with the log message `Updates on the way to becoming famous`\n", "- Push to GitHub" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git commit -m \"Updates on the way to becoming famous\"\n", "git push" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User B**\n", "\n", "- Change directory to `bios-821-b`\n", "- Pull from GitHub" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cd ../bios-821-b\n", "git pull" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- List the files in the directory - You should have the changes made in `bios-821-a`\n", "- Check the log messages" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ls" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User B**\n", "\n", "- Add a new file `stuff.junk` containing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", "junk junk junk junk junk\n", "junk junk junk junk\n", "junk junk junk\n", "junk junk\n", "junk\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat > stuff.junk <<'EOF'\n", "junk junk junk junk junk\n", "junk junk junk junk\n", "junk junk junk\n", "junk junk\n", "junk\n", "EOF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User B**\n", "\n", "- Add a filter to `.gitignore` to exclude any file with extension `.junk`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "echo \"*.junk\" >> .gitignore" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Add the current directory to the Git staging area" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git add ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Check the status - only the `.gitignore` file should be added and not `stuff.junk`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git status" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Commit and push to GitHub with message `Exclude junk`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git commit -m \"Exclude junk\"\n", "git push" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "\n", "- Change directory to `bios-821-a`\n", "- Make a new direcotry called `data` and download the following files into it\n", "\n", "```\n", "https://upload.wikimedia.org/wikipedia/en/a/a5/Pokémon_Charmander_art.png\n", "https://vignette.wikia.nocookie.net/pokemon/images/b/b1/393Piplup.png\n", "https://vignette3.wikia.nocookie.net/pokemon/images/4/44/167Spinarak_OS_anime.png\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cd ../bios-821-a\n", "mkdir data\n", "cd data\n", "wget -q https://upload.wikimedia.org/wikipedia/en/a/a5/Pokémon_Charmander_art.png\n", "wget -q https://vignette.wikia.nocookie.net/pokemon/images/b/b1/393Piplup.png\n", "wget -q https://vignette3.wikia.nocookie.net/pokemon/images/4/44/167Spinarak_OS_anime.png\n", "cd .." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Check that the 3 image files are in the data directory" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ls data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Edit .gitignore so that the entire `data` directory is excluded" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "echo \"data/\" >> .gitignore" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Add all contents in `bios-821-a` and check status\n", "- Make sure `data` and the downloaded content are not in the staging area, only the revised `.gitignore`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git add ." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git status" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Commit with a message `No Pokemon allowed in here`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git commit -m \"No Pokemon allowed in here\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Working with merge conflicts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Try to push to GitHub. This should fail. Fix and re-push." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git push" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Fixing failure to push to remote" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git pull" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- See merge conflicts (normally done in text editor or merge-tool)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat .gitignore" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Fix the merge conflcits manually" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat > .gitignore <<'EOF'\n", "data/\n", "*.junk\n", "EOF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Add, commit and push the fixed file" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git add .gitignore" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git commit -m \"Manual merge\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git push" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "\n", "- Edit `first.txt` to read (deleting the word `most`)\n", "\n", "```\n", "This is my first file.\n", "I am so proud of it.\n", "Some day, this file will make me famous.\n", "It is my favorite file.\n", "Ed Sheeran likes this file!\n", "Taylor Swift mentioned this file in her new album!\n", "President Trump tweeted about this file!\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat > first.txt <<'EOF'\n", "This is my first file.\n", "I am so proud of it.\n", "Some day, this file will make me famous.\n", "It is my favorite file.\n", "Ed Sheeran likes this file!\n", "Taylor Swift mentioned this file in her new album!\n", "President Trump tweeted about this file!\n", "EOF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Add and commit the file wiht message `Attack of the Grammar Nazi`\n", "- Push to GitHub" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git add first.txt\n", "git commit -m \"Attack of the Grammar Nazi\"\n", "git push" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User B**\n", "\n", "- Change directory to `bios-821-b`\n", "- Edit `first.txt` to read\n", "\n", "```\n", "This is my first file.\n", "I am so sick of it.\n", "Some day, this file will make me notorious.\n", "It is my least favorite file.\n", "Ed Sheeran hates this file!\n", "Who is Taylor Swift?\n", "President Trump tweeted about this file!\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cd ../bios-821-b" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat > first.txt <<'EOF'\n", "This is my first file.\n", "I am so sick of it.\n", "Some day, this file will make me notorious.\n", "It is my least favorite file.\n", "Ed Sheeran hates this file!\n", "Who is Taylor Swift?\n", "President Trump tweeted about this file!\n", "EOF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Add and commit the file with the message `Winter blues setting in`\n", "- Try to push to GtiHub\n", "- What happens?\n", "- Fix it so that the version in `bios-821-b` is used and push to GitHub with message \"Use User B version\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git add first.txt\n", "git commit -m \"Winter blues setting in\"\n", "git push" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Fixing failure to push to remote" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git pull" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat first.txt" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat > first.txt <<'EOF'\n", "This is my first file.\n", "I am so sick of it.\n", "Some day, this file will make me notorious.\n", "It is my least favorite file.\n", "Ed Sheeran hates this file!\n", "Who is Taylor Swift?\n", "President Trump tweeted about this file!\n", "EOF" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git add first.txt" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git commit -m \"Use User B version\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git push" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "\n", "- Change directory to `bios-802-a`\n", "- Pull from GitHub\n", "- Look at the text of `first.txt`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cd ../bios-821-a" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git pull" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat first.txt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Git as a time machine" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "\n", "- The file looks strangely sad and unfamiliar\n", "- Look for a commit message with the word 'Nazi' in it" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log --grep 'Nazi'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Use your time machine to rest the world to what it looked like when you made the 'Nazi' commit" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git checkout " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Display `first.txt`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat first.txt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Show the log file (one line per commit)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log --oneline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Go back to the original HEAD in master" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git checkout master" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Show the log file (one line per commit)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log --oneline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User B**\n", "\n", "- Pull from GitHub\n", "- Your doctor gave you happy drugs\n", "- You decide to revise first.txt again\n", "\n", "```\n", "This is my first file.\n", "I am so proud of it.\n", "Some day, this file will make me famous.\n", "It is my favorite file.\n", "Ed Sheeran likes this file!\n", "Taylor Swift mentioned this file in her new album!\n", "President Trump tweeted about this file!\n", "What a wonderful world.\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cd ../bios-821-b" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat > first.txt <<'EOF'\n", "This is my first file.\n", "I am so proud of it.\n", "Some day, this file will make me famous.\n", "It is my favorite file.\n", "Ed Sheeran likes this file!\n", "Taylor Swift mentioned this file in her new album!\n", "President Trump tweeted about this file!\n", "What a wonderful world.\n", "EOF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Add and commit with the message \"I love everybody\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git add first.txt\n", "git commit -m \"I love everybody\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Changing commit messages\n", "\n", "Do not do this once the commit is pushed. Once pushed, log messages are public and should not be edited." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User B**\n", "\n", "- Your drugs run out\n", "- Edit the last commit message so that it says `I hate everybody`\n", "- Push to GitHub" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git commit --amend -m \"I hate everybody\"\n", "git push" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Git for disaster recovery" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "\n", "- Delete the directory `bios-821-a` with `rm -rf` to simulate your laptop being lost\n", "- Recover `bios-821-a` by cloning from GitHub" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cd ..\n", "rm -rf bios-821-a\n", "git clone https://github.com/cliburn/bios-821-git-lesson.git bios-821-a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Branching and merging" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "\n", "- Change directory to `bios-821-a`\n", "- View second.txt and see that it has bugs" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cd bios-821-a\n", "cat second.txt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Create a new branch called `bugfix`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git checkout -b bugfix" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- In the `bugfix` branch, edit `second.txt` to remove all bugs." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat > second.txt <<'EOF'\n", "This is my second file.\n", "I am so proud of it.\n", "Some day, this file will make me rich.\n", "It is my second favorite file.\n", "EOF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Add and commit the file with message `Bug fix`\n", "- Push to GitHub" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git commit -a -m \"Bug fix\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git push" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git push --set-upstream origin bugfix" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- In the `master` branch, edit `third.txt` to read\n", "\n", "```\n", "This is my third file.\n", "I am so proud of it.\n", "Some day, this file will make me wise.\n", "It is my third favorite file.\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git checkout master" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cat > third.txt <<'EOF'\n", "This is my third file.\n", "I am so proud of it.\n", "Some day, this file will make me wise.\n", "It is my third favorite file.\n", "EOF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Add and commit the file with message `Fat people are often wise people`\n", "- Push to GitHub" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git commit -a -m \"Fat people are often wise people\"\n", "git push" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User B**\n", "\n", "- Change directory to `bios-821-b`\n", "- Pull from GitHub" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cd ../bios-821-b\n", "git pull" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Do you have the `master` and `bugfix` branhces?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git branch" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git branch -a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Merge the `bugfix` branch back into `master`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git checkout bugfix" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git branch" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git checkout master" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git merge bugfix -m \"Merge with bugfix branch\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Delete the `bugfix` branch both locally and on remote" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git branch -d bugfix" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git push -d origin bugfix" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tagging" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Tag the master branch as \"V1.0\" with the message \"Version 1.0\" and push to remote" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git tag -a V1.0 -m \"Version 1.0\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git push origin V1.0" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git push" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**User A**\n", "\n", "- Change directory to `bios-821-a`\n", "- Pull the changes\n", "- Check that the bugfix branch has been deleted" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cd ../bios-821-a" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git pull\n", "git branch -r" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Mining the log file" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log --stat -5" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log --oneline" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "scrolled": false }, "outputs": [], "source": [ "git log --name-only --oneline" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log --oneline --graph " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git log --grep 'love'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git show" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git tag" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "git remote show origin" ] } ], "metadata": { "kernelspec": { "display_name": "Bash", "language": "bash", "name": "bash" }, "language_info": { "codemirror_mode": "shell", "file_extension": ".sh", "mimetype": "text/x-sh", "name": "bash" } }, "nbformat": 4, "nbformat_minor": 2 }