Git Product home page Git Product logo

git-crash-course's Introduction

A brief introduction to Git with Unix shell

Installation instructions

  1. Up-to-date installation instructions for Git and Bash are available here: https://libguides.ucmerced.edu/software-carpentry/git/install
  2. Create a Github account here: https://github.com/

Unix Shell

Intro comments about “shell”

  • Broadly speaking, there is a tension between making computer systems fast and making them easy to use.
  • A common solution is to create a 2-layer architecture: A fast, somewhat opaque core surrounded by a more friendly scriptable interface (also referred to as “hooks” or an “API”). Examples of this include video games, Emacs and other highly customizable code editors, and high-level special-purpose languages like Stata and Mathematica.
  • Unix shell is the scriptable shell around the operating system. It provides a simple interface for making the operating system do work, without having to know exactly how it accomplishes that work.

Very brief Bash intro

File system layout

Who are you?

whoami

Where are you?

pwd                             # Print Working Directory

What’s in this directory?

Command flags modify what a command does.

ls                              # List directory contents
ls -a                           # ... and include hidden files

Getting help

man ls                          # Manual for "ls"
ls --help                       # In-line help info; should work in Windows
  • You can navigate through the man page using the space bar and arrow keys
  • Quit man with “q”
  • Online references are available for Windows users who don’t have man pages: https://linux.die.net/

Changing directories

When a command is followed by an argument, it acts on that argument.

cd Desktop
ls *.pdf                        # List all files ending in ".pdf"
cd ..                           # go up one directory

History and pipes

The terminal saves your command history (typically 500 or 1000 commands)

  • You can see previous commands using the up/down arrows
  • You can edit the command that’s currently visible and run it

Once your command history gets big, you might want to search it:

history
history | grep ls               # pipe the output of history into search

Git

Why are we here?

images/snapshots.png

  • Move backwards and forwards in time using snapshots of your code
  • Control what goes into a snapshot
  • Collaborate
  • Explore alternative versions of your project without destroying prior work
  • Useful for text files, less useful for binary files (most of the useful features are text-oriented)

Setup

Identify yourself

All git commands are 2-part verbs, followed by flags and arguments:

git config --global user.name "Gilgamesh"
git config --global user.email "[email protected]"

Line Endings

git config --global core.autocrlf input  # Unix and MacOS
git config --global core.autocrlf true   # Windows

Editor

You can use any text editor, but you want a sensible default in case Git opens one for you:

git config --global core.editor "nano -w"

Updating remotes

Only push the current branch (more about this later):

git config --global push.default "simple"

Inspect your configuration

git config --list                   # or -l
git config --list --show-origin     # where is this setting coming from?

Creating a repository

We are going to create and track plans for our quarantine garden.

Create a directory

cd ~/Desktop
mkdir garden
cd garden

Tell Git to make a repository

git init
ls
ls -a

Git uses this special subdirectory to store all the information about the project, including all files and sub-directories located within the project’s directory. If we ever delete the `.git` subdirectory, we will lose the project’s history.

Check status (we will do this a lot)

git status

Tracking changes

Add a file

touch shopping_list.txt
nano shopping_list.txt
1. Cherry tomatoes

Save and quit. You can verify that you’ve saved your changes in Bash:

ls
cat shopping_list.txt

Commit cycle

git status
git add shopping_list.txt
git status
git commit -m "Start shopping list for garden"
git status
  • Commit messages should be useful; eventually there will be a lot of them (we’ll come back to this)

Draw working tree, staging area (index), and repository commit (no history yet)

Getting help

# Concicse help
git add -h

# Verbose help
man git-add

Add more history

Edit with editor of your choice:

1. Cherry tomatoes
2. Italian basil
git status
git diff

# If you try to commit the file before you add it to the Staging area,
# nothing happens:
git commit -m "Add basil"
git status

# Add file to Staging area, then commit:
git add shopping_list.txt
git commit -m "Add basil"

Update drawing with repository history going back in time (H, H~1, H~2…)

Add more history; look at Staging area vs Workspace

1. Cherry tomatoes
2. Italian basil
3. Jalapenos
# By default, "diff" shows changes to Workspace
git status
git diff

# Once the file is added to Staging, "diff" no longer shows changes
git add shopping_list.txt
git status
git diff

# You can examine Staging instead
git diff --cached               # or "--staged"
git commit -m "Add peppers"
git status
  • Staging area is for creating sensible commits. You can edit multiple files and only add a subset of them to a given commit. This makes it easier to look back at your work.

View commit history in the log

git log
git log --oneline
git log --oneline --graph
git log --author=~Derek Devnich
git log --since=5.days          # or weeks, months, years
  • You can identify commit by unique ID or by HEAD offset
  • HEAD is a pointer to the most recent commit

Directories aren’t content

Try to commit an empty directory:

mkdir flowers
git status
git add flowers
git status

Now add files and try again:

touch flowers/roses flowers/tulips
git status
ls flowers
git add flowers
git commit -m "Initial thoughts on flowers"

Exploring history

Add more text to Workspace

1. Cherry tomatoes
2. Italian basil
3. Jalapenos
4. Cayenne peppers

Inspect our changes

cat shopping_list.txt

# Identical to "git diff" with no argument
git diff HEAD shopping_list.txt

# Show all changes back to this point
git diff HEAD~1 shopping_list.txt
git diff HEAD~3 shopping_list.txt

# Show changes for just HEAD~3
git show HEAD~3 shopping_list.txt

# Show changes in range of commits
git diff HEAD~3..HEAD~1 shopping_list.txt

Range syntax also works for logs

git log HEAD~3..HEAD~1

Using unique ID instead of HEAD offset

git diff f22b25e3233b4645dabd0d81e651fe074bd8e73b shopping_list.txt

# Use reduced ID from "git log --oneline"
git diff f22b25e shopping_list.txt

Restore the Workspace to a clean state

git status                      # We have unstaged changes

# Revert the working tree to the most recent commit
git checkout HEAD shopping_list.txt
cat shopping_list.txt

Moving through time

Checkout old version of a file

git checkout f22b25e shopping_list.txt   # or "git checkout HEAD~3 shopping_list.txt"
cat shopping_list.txt

# These changes are also in the Staging area; do a commit if you want to keep
# this older version
git status
git checkout HEAD shopping_list.txt      # get back the new version

Update drawing with files moving in and out of working tree/staging area

Don’t lose your head

What if you want to see a previous version of the whole project?

# Detached HEAD moves the whole HEAD pointer back to an earlier version
git checkout HEAD~2
git status

# Move HEAD back to latest commit by checking out the branch name
git checkout master
  • Unfortunately some of these terms, like “checkout”, are overloaded. Think about what you want to do to your history, then look up the appropriate command.

Update drawing with moving HEAD pointer

Branching and merging

images/branch-merge.png

Create a new branch and switch to it

git checkout -b feature         # equivalent to "git branch feature" + "git checkout feature"
git branch                      # Show all branches
git status

Create a new file

touch feature.txt
nano feature.txt
This is a new feature we're trying out
git add feature.txt
git commit -m "Added a trial feature"
ls                              # We have a new file

Switch back to master and merge

git checkout master
ls                              # File doesn't exist on the master branch
git merge feature
ls                              # Merging the feature branch adds your changes
  • This is simplest possible case; all of the new changes were in one branch

Draw the branch history with the merge (Fast-Forward merge moves branch tag) Draw a branch history with competing changes (Recursive merge resembles octopus graph)

Ignoring Things

Create some output files

mkdir results
touch a.dat b.dat c.dat results/a.out results/b.out
ls
git status

Create .gitignore

touch .gitignore
ls -a

Ignore some files

*.dat
results/
# We are ignoreing .dat files and tracking .gitignore
git status
git add .gitignore
git commit -m "Ignore output files"
  • Ignoring complicated directory structures can be tricky, come talk to me
  • You should generally ignore archives (zip, tar), images (png, jpg), binaries (dmg, iso, exe), compiler output, log files, and .DS_Store (Mac)

Github

Git != Github

  • easy collaboration
  • sync between machines
  • off-site backup
  • peer review

Set up new repository

Configure remotes and push from local

git remote add origin https://github.com/devnich/garden.git
git remote -v
git push origin master          # you should get a password prompt

If you configure your origin as upstream, you can just do:

git push

Check that you are up to date

git pull
  • pull is a shortcut for fetch + merge

Collaborating

Clone your repository

git clone https://github.com/devnich/garden.git ~/Desktop/garden-clone
cd garden-clone
touch trees.txt

Edit trees.txt

1. Plum
2. Pluot
3. Aprium

Update and push

pwd                             # we are in ~/Desktop/garden-clone
git status
git add trees.txt
git commit -m "I like plums"
git push
cd ../garden                   # now we are in ~/Desktop/garden
ls
git pull
ls

Conflicts

Person 1 edits ~/Desktop/garden/shopping_list.txt

1. Cherry tomatoes
2. Italian basil
3. Jalapenos
4. Scotch bonnet peppers
git add shopping_list.txt
git commit -m "Added more peppers our copy"
git push origin master

Person 2 edits ~/Desktop/garden-clone/shopping_list.txt without pulling

1. Cherry tomatoes
2. Italian basil
3. Jalapenos
4. Garlic
git add shopping_list.txt
git commit -m "Added garlic to rival copy"

# Rejected because Git can't merge changes cleanly
git push origin master

# Pulling results in a local conflict
git pull origin master

Edit conflict, stage, commit, and push

Edit the file to resolve the conflict. You can delete one of the two lines, combine them, or make any other changes. Delete the conflict markers before staging the file (the lines beginning in “<”, “=”, and “>”).

<<<<<<< HEAD
4. Garlic
=======
4. Cayenne peppers
>>>>>>> dabb4c8c450e8475aee9b14b4383acc99f42af1d

You may want to enable a default merge tool:

git config --global merge.tool meld
  • Open source merge tools include Vimdiff, Meld, Kdiff, Gitfiend, Git Cola, etc. There are many other options!
  • Always pull before you push
  • To minimize conflicts, do your work on a separate branch

Version control with source vs. notebooks

  • .ipynb files contain a lot of JSON boilerplate that isn’t code

Next steps (intermediate Git)

Useful commands that you should add to your repertoire

  • git blame: See who changed each line of a file
  • git bisect: Find out when a change was introduced (good man page)
  • git revert: Undo your recent commits (good man page)
  • git add –patch: Stage a part of a file (“hunk”) instead the entire file
  • git -i <command>: Run a command interactively, confirming each step

Potentially dangerous commands that are useful in certain circumstances. Use with caution!

  • git reset: Throw away uncommitted changes (there are many options that affect what gets thrown away; read the documentation)
  • git reset –hard: Throw away some of your commits to get back to an earlier project state. Cannot be undone!
  • git rebase: Rewrite the history of branch A to include branch B. This is different than merging branch B into branch A; merging retains your project history, whereas rebasing rewrites that history.
  • git squash: Convert multiple commits into a single commit. This also rewrites your project history.

Dangerous commands you should avoid

  • git cherry-pick: Copy a single commit from a different branch. This rewrites your project history piecemeal, which can make it difficult to merge branches in the future.

Additional reading

Sources and image credits

git-crash-course's People

Contributors

devnich avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.