QTM 350 - Data Science Computing

Lecture 07 - More Git Commands, CLI and Git Practice

Danilo Freire

Department of Data and Decision Sciences
Emory University

Hello, everyone! 😊

Recap and lecture overview 📚

Recap of our last lecture

In our last class, we covered

  • How to push and pull changes to and from remote repositories
  • Using .gitignore to avoid tracking certain files
  • Creating and managing branches with git branch and git checkout
  • The difference between clone and fork repositories
  • Resolving conflicts when multiple people change the same code
  • Going back to specific commits with git checkout and git reset
  • Workflow for merging branches back to master

Source: Lodato (2010)

Today’s lecture

Today we will cover:

  • Understanding changes with git diff
  • Amending commits with git commit --amend
  • Cherry-picking commits with, well, git cherry-pick 😅
  • Understanding git rebase and its uses
  • Installing and setting up GitHub CLI
  • GitHub CLI repository management
  • Mock-up quiz!

Understanding changes with git diff 🔍

What is git diff?

  • git diff shows you what has changed between commits, branches, or your working directory
  • It is one of the most useful Git commands for understanding your code changes
  • Helps you review changes before committing
  • The output shows line-by-line differences with + for additions and - for deletions
  • Let’s see how it works with our former my-project repository
  • First, let’s make some changes in the 01-data-cleaning.py file
echo "# This is a data cleaning script" >> ./01-data-cleaning.py
git diff

  • diff --git a/file b/file shows Git is comparing two versions of the same file (a = original, b = modified)
  • --- a/file and +++ b/file indicate the original file (before) and new file (after) being compared
  • @@ -0,0 +1 @@ shows the line numbers affected, with + lines indicating additions and - lines indicating deletions. -0,0 means that the original file had no lines, and +1 means one line was added

Common git diff commands

Basic diff commands:

  • git diff: shows unstaged changes in working directory
  • git diff --staged: shows staged changes ready to commit
  • git diff HEAD: shows all changes since last commit
  • git diff --name-only: shows only filenames that changed

Comparing commits:

  • git diff commit1..commit2: compares two specific commits
  • git diff branch1..branch2: compares two branches
  • git diff --stat: shows summary of changes (files modified, insertions, deletions)

  • @@ -1,4 +1,4 @@ means that in the original file, lines 1 to 4 were present, and in the new file, lines 1 to 4 are also present, but with some changes

Amending and undoing commits 📝

What is git commit --amend?

  • git commit --amend allows you to modify your last commit
  • Useful when you forgot to add files or made a typo in the commit message
  • Can add staged changes to the previous commit
  • Can also change the commit message
  • Use with caution! Only amend commits that haven’t been pushed yet

How to amend commits

Amending the commit message:

git commit --amend -m "New commit message"

Adding forgotten files:

git add forgotten-file.txt
git commit --amend --no-edit

Both together:

git add new-file.txt
git commit --amend -m "Updated commit message"

Important rules:

  • Only amend local commits
  • Never amend commits that have been pushed to a shared repository
  • If you need to modify pushed commits, use git revert instead
  • Always communicate with your team before amending shared history

Undoing commits with git reset

  • If you made a mistake, git allows you to undo commits
  • git reset can move the HEAD pointer to a previous commit
  • --soft keeps changes in the staging area
  • --hard discards all changes after the specified commit
  • Use with caution too! Hard reset will delete uncommitted changes

Undo last commit but keep changes:

git reset --soft HEAD~1

Undo last commit and discard changes:

git reset --hard HEAD~1
  • You can undo as many commits as needed by changing the number after HEAD~, such as HEAD~2 for the last two commits

Cherry-picking commits 🍒

What is git cherry-pick?

  • git cherry-pick allows you to pick specific commits from one branch and apply them to another
  • Useful when you want to apply a bug fix or feature from one branch to another
  • Each commit is applied individually with its own commit message
  • Can be used to backport changes to older versions
  • Creates new commits rather than modifying existing ones

Using git cherry-pick

Basic cherry-pick:

# Cherry-pick a single commit
git cherry-pick abc1234

# Cherry-pick multiple commits
git cherry-pick abc1234 def5678

# Cherry-pick a range of commits
git cherry-pick abc1234..def5678

After cherry-picking:

  • The commit is applied to your current branch
  • It creates a new commit with the same changes
  • Original commit history is preserved

Handling conflicts:

# If conflicts occur during cherry-pick
git cherry-pick --continue  # After resolving conflicts
git cherry-pick --abort     # Cancel the cherry-pick
git cherry-pick --skip      # Skip the current commit

Common use cases:

  • Applying hotfixes to multiple branches
  • Backporting features to release branches
  • Moving specific commits between branches

Understanding git rebase 🔄

Understanding git rebase

  • git rebase allows you to move or combine commits to a new base commit
  • Changes the commit history by replaying commits on top of another base
  • Creates a linear, clean commit history
  • Useful for keeping feature branches up to date with main branch
  • Rewrites commit history - avoid using it on shared or public branches!

Types of rebasing

Interactive rebase:

# Interactive rebase of last 3 commits
git rebase -i HEAD~3

# Interactive rebase to specific commit
git rebase -i abc1234

Rebase onto another branch:

# Rebase current branch onto main
git rebase main

# Rebase feature branch onto main
git checkout feature-branch
git rebase main

During interactive rebase you can:

  • pick: use the commit as-is
  • reword: change the commit message
  • edit: modify the commit contents
  • squash: combine with previous commit
  • drop: remove the commit entirely
  • reorder: change commit order

GitHub CLI - Installation 🖥️

GitHub in the terminal

  • GitHub CLI (gh) is the official command-line tool for GitHub
  • Allows you to work with GitHub directly from your terminal
  • No need to open a web browser for common tasks
  • Works seamlessly with Git workflows
  • Supports authentication and works with your GitHub account

WSL/Ubuntu:

# Install
(type -p wget >/dev/null || (sudo apt update && sudo apt install wget -y)) \
    && sudo mkdir -p -m 755 /etc/apt/keyrings \
    && out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \
    && cat $out | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
    && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
    && sudo mkdir -p -m 755 /etc/apt/sources.list.d \
    && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
    && sudo apt update \
    && sudo apt install gh -y

# Update (if already installed)
sudo apt update && sudo apt install gh -y

macOS (using Homebrew):

# /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install gh

Verify installation:

gh --version

How to connect your terminal to GitHub

Authenticate with GitHub:

gh auth login
  • Select GitHub.com
  • Choose HTTPS Git operations
  • Choose Y to authenticate with a web browser
  • Choose Login with a web browser
  • Press Enter to open the link in your browser and copy the one-time code

  • And you’re all set to use GitHub CLI! 🎉

Working with repositories, pull requests, and issues

Repository operations:

# List your repositories
gh repo list

# Clone a repository
gh repo clone username/repo-name

# Create a new repository
gh repo create 

# View repository details
gh repo view --web

# Fork a repository
gh repo fork

# Star/unstar a repository
gh repo star

# Archive/unarchive a repository
gh repo archive

Pull requests and issues:

# Create a new pull request
gh pr create --title "My PR" --body "Description of my PR"

# List pull requests
gh pr list

# View pull request details
gh pr view 123 --web

# Create a new issue
gh issue create --title "My Issue" --body "Description of my issue"

# List issues
gh issue list

# View issue details
gh issue view 456 --web

GitHub CLI - Practical Examples 💡

Real-world GitHub CLI usage

mkdir new-project && cd new-project
echo "# New project" > README.md
git init && git add . && git commit -m "first commit"

gh repo create
# Follow the prompts
gh repo view --web

Goodbye, GitHub Desktop! 👋

Practice Time! ⏱️

Git and CLI Practice Quiz

Please complete the following tasks:

  1. Create a new directory called git-practice and initialise it as a Git repository
  2. Create a file named README.md with the content “# Git Practice Repository”
  3. Create a subdirectory called src and inside it create an empty file named main.py
  4. Stage and commit all changes with the message “Initial commit with README and main.py”
  5. Create and switch to a new branch called hotfix
  6. In the src directory, create three files using brace expansion: utils.js, utils.css, utils.html
  7. Create a directory called temp and inside it create a file named debug.log
  8. Create a .gitignore file and add temp/ to it
  9. Stage and commit all changes with the message “Add hotfix files and gitignore”
  10. Rename src/main.py to src/app.py
  11. Create a directory called docs and copy README.md into it as guide.md
  12. Delete the temp directory and its contents
  13. Stage and commit all changes with the message “Complete hotfix development”
  14. Switch back to the main branch and merge the hotfix branch
  15. View the commit history in a compact format

After completing these tasks, verify your work by checking the commit history and file structure.

And that’s a wrap! 🎉

Appendix: Quiz answers

Solutions to practice quiz

Here are the answers to the practice quiz. Try to complete the quiz first before checking these answers!

  1. mkdir git-practice && cd git-practice && git init
  2. echo "# Git Practice Repository" > README.md
  3. mkdir src && touch src/main.py
  4. git add . && git commit -m "Initial commit with README and main.py"
  5. git checkout -b hotfix
  6. touch src/utils.{js,css,html}
  7. mkdir temp && touch temp/debug.log
  8. echo "temp/" > .gitignore
  9. git add . && git commit -m "Add hotfix files and gitignore"
  10. mv src/main.py src/app.py
  11. mkdir docs && cp README.md docs/guide.md
  12. rm -rf temp
  13. git add . && git commit -m "Complete hotfix development"
  14. git checkout main && git merge hotfix
  15. git log --oneline

Additional verification commands:

  • Check commit history: git log --oneline
  • View file structure: ls -la
  • Check branch status: git branch
  • View .gitignore contents: cat .gitignore