Intro to Git

This tutorial is meant to take you from being not at all familiar with Git to being functional. When you first encounter Git, it's overwhelming, daunting, and a little scary. This tutorial should help you get past that.

This tutorial is my first presentation done with RevealJS. It uses the Reveal Zoom plugin, which allows you to zoom in on elements with Alt+click (Ctrl+click on Linux). I also had to do some of my own hacking to allow you to zoom in with Ctrl++ and scroll on images.

Oh, and all images can be opened in another window or tab by clicking on them.

What This Covers

  • How Git differs from other central repository systems
  • Cloning, Branching, and Forking
  • The basic workflow on your computer
  • The basic workflow when you're part of an organization
  • The basic workflow when you're not part of an organization, or when the organization is too large.

What This Doesn't Cover

  • How to sign up for a GitHub account
  • The differences between different platforms (GitHub, GitLab, etc.)
  • Git logs
  • This will not make you an expert.

What This Assumes

  • Not very much
  • You're really starting out with Git. This is my no means an in-depth tutorial.
  • That you know that a Repo is short for Repository.
  • That you know a Repo is a set of files that are tracked by the versioning system.

Git vs GitHub

  • Git != GitHub != GitLab
  • Git is the whole distributed system that handles histories, commits, merges, pulls, pushes, etc.
  • GitHub or GitLab are online web-based repository hosts. GitHub and GitLab both use git. There are others.
  • GitLab is both a website (GitLab.com) and an application that can be installed elsewhere. Your organization may have an implementation of GitLab.
  • This tutorial will use GitHub as the default web-based repository system.

Old-School Repository Systems

  • Every copy of the repo knew if it was a copy or the main
  • Only one person could work on a file at a time.
  • They were conceptually simpler and didn't require tutorials like this one.

Old-School Repository Systems

A diagram showing the decentralized nature of old-school repository systems particularely how each instance knew if it was a copy or the main instance.

Git

  • Each copy could be either the main or a copy.
  • Each copy has references to "remotes", which are just other instances of that repository.
  • The main repository is agreed upon by convention; usually at GitHub, GitLab, etc. But doesn't have to be.
  • Several people can work on the same file at the same time.

Git

A diagram showing the decentralized nature of old-school repository systems particularely how each instance knew if it was a copy or the main instance.

Commits

  • A commit represents a snapshot in time of a branch of a repo.
  • It's the changes in all the files since the last commit on that branch.
  • Each comes with a bunch of meta data about that commit, such as a note about the commit, and a hash representing that commit.
  • Commits are just a snapshot. Making a commit doesn't upload it to GitHub, or merge it into another branch.
  • Committing is just telling Git "Okay, remember the state of all these files right.....now!"
  • Committing allows you to merge, or upload your changes to GitHub.

Branching

  • A Branch is an independent line of development.
  • A Branch is a series of commits.
  • Branching is done within an instance of a repo.
  • Everyone with access to that repo instance can see all its branches.
  • Branching creates a copy of all the tracked files at the time of branching.
  • As you edit files in the new branch, the files in the original branch remain unchanged from the time you created the new branch.
  • Anyone with access to that instance of that repo can create a new branch from the original (without your changes) or your new branch (with your changes up to the last commit on your branch); or edit the files in the original branch.

Branching

A repo starts out with a main branch: a set of files with a history of changes (ie: commits).

A main branch with a series of commits

Branching

  • Create a branch when you're going to start doing work (fixing a bug, adding a new feature).
  • Work should rarely, if ever, be done on the main branch.
  • $ git checkout -b branchName
A new branch is created to fix a bug such as a typo.

Branching

  • If you're part way through adding a feature, and need to fix a bug: create a branch from main that won't include any of the unfinished code in your new feature.
  • As long as the changes on the different branches aren't in the same spot in the same file, Git should be smart enough to merge them without issue.
  • If there are changes to the same spot in the same file, then a merge conflict will arise, and will needed to be sorted out manually. That's beyond the scope of this tutorial.
  • $ git checkout main
    then
    $ git branch other_new_branch_name
Another new branch is created from main to fix another typo.

Cloning

  • Cloning creates a copy of the repo on your computer.
  • Downloads all files in the main branch, including config files.
  • Sets the cloned-from repo as the origin remote.
  • Use this (ie: cloning) when you first want to contribute to a repo.
  • Only use once on each computer. Once you've cloned, the repo is there. You have it. From then on, to get the latest code, use git pull or git rebase.
  • $ git clone [git address]

Cloning

Cloning copies a repo from its source, ex GitHub, to your computer.
Cloning copies the main repo from its source, ex GitHub, to your computer.

Forking

  • Forking a repo creates an instance of a repo (branches, commit history, etc.) on your own GitHub account.
  • When forking, your forked repo automagically sets the original repo as "Upstream" allowing you to easily get new changes.
Fork button on GitHub right after the the Watch/Unwatch, and Star buttons near the top of the page below the Github banner at the very top.

Forking

Forking copies a repo to your account within a system such as GitHub.

Forking

Forking copies branches and commit history.

Cloning, Branching, and Forking

Cloning
Copies a repo (files and some configuration) from one computer to another
Used when starting to contribute to a project for the very first time on that computer.
Branching
Creates a copy of all files in a repo so they can be edited without affecting the original files
Used when adding a feature or fixing a bug
Forking
Creates a copy of a repo (on the same system as the original repo) to the forkers account
Used when either creating a brand new thing based on an old thing. (Ex: Waterfox is a fork of Firefox. Waterfox will never merge back into Firefox).
Also can be used where there are a lot of people on a project when "branch hell" and "commit history hell" is to be avoided.
Also can be used when you want to do some experimental things knowing you'll problably throw your copy away when you're done.

Workflows

There are two basic workflows when contributing to a project or repo:

  1. When you have write access to the original repo;
  2. When you don't have write access to the original repo;

The first is usually when you're part of a team that works on a project. No forking is necessary; just cloning and branching.

The second is usually when you're not part of the organization, but want to contribute anyway.

For these examples, assume the repo has already been cloned.

Workflow With Write Access To Repo

  • For our example, Jane Schmoe is part of the organization. She doesn't need to clone (because that was already done before when she first joined the org).
  • But she needs to pull before she gets started.
  • Pulling gets the latest commits from elsehwere and merges them here.
  • In this case, Jane pulls from the origin so she has everything on her computer.
Pulling gets the current state of the branch from which you pull from the remote from which you pull.

Starting Work

  • After pulling, but before starting to work, she creates a new branch. It's dangerous to work on the main branch.
Pulling gets the current state of the branch from which you pull from the remote from which you pull.

Working

Pulling gets the current state of the branch from which you pull from the remote from which you pull.

Your Local Repo

At this point it's worth mentioning how your local repo works.

  • Your local copy has three parts: The Index or Working Directory, Staging, and the repo itself.
  • When you're editing files locally, simply saving them has no effect on the repo itself.
  • When you add a new file into your folder, it still isn't part of the repo. It's not being tracked.
  • All your edits, additions, and removals are all part of the "Working Directory" or the "Index".
  • In order to get Git to start tracking new files and updated files you need to move them to "Staging".
  • Moving to staging can be done by $ git add filename, or to add all at once: $ git add . (inlcuding the ".").
  • Then, once staged, files can be committed to the repo.
  • This can be done with: $ git commit -m "Some notes about the commit here".
  • Once changes have been committed, a new commit (ie: a snapshot in time) is created.
  • This commit can now be merged into another local branch, or pushed to a remote.

Add Changes to Staging

$ git add .

Add changes from the Index or Working Directory to Staging.

Commit Changes to Repo

$ git commit -m "Added a feature"

Commiting changes moves them from Staging to the Repo, and creates a snapshot in time.

Push Changes to Origin

$ git push origin myNewFeature

Pushing the changes moves the commits to a remote.

Pushed Changes to Origin

Now GitHub has Jane's myNewFeature branch.

GitHub has a new branch which Jane just pushed

Merge Changes on Origin

Create a Pull Request on GitHub and delete myNewFeature branch.

Note that myNewFeature branch still exists on Jane's local machine until she deletes it. ($ git branch -D myNewBranch)

Jane's new feature has been added to main, and the myNewBranch is deleted.

Workflow With A Forked Repo

  • For this example, Joe Schmoe is not part of the organization, but still wants to contribute.
  • To get started, he'll need to fork to create his own copy of the repo on GitHub.
Repo-A with branches on Org X on GitHub, and Joe Schmoe's fork of the same thing on his GitHub account

Workflow With A Forked Repo

Then he'll clone to get a copy of the repo on his own computer.

Repo-A with branches on Org X on GitHub, Joe Schmoe's fork of the same thing on his GitHub account, and a copy on Joe's local computer

Local Repo With Two Remotes

Now Joe pulls from the upstream remote (organization's repo) and pushes to the origin remote (Joe's copy on his GitHub account).

Joe Schmoe's local repo with two remotes: origin on Joe's account on GitHub, and upstream, the original repo.  He'll pull from upstream, and push to origin.

Basic Workflow With A Forked Repo

After pushing changes, Joe submits a Pull Request (PR) to have his changes added to the main repo.

Joe Schmoe's local repo with two remotes: origin on Joe's account on GitHub, and upstream, the original repo.  He'll pull from upstream, and push to origin.

Full Workflow With A Forked Branch

Joe Schmoe's local repo with two remotes: origin on Joe's account on GitHub, and upstream, the original repo.  He'll pull from upstream, and push to origin.

Useful git Commands

git status
Tells you what branch you're on, what files are in your working directory, but not staging; staging but not the repo. Sometimes gives you hints as to what to do next.
git checkout [branch_name]
Sets your current working directory to be in the branch called "branch_name".
Example: $ git checkout myNewFeature puts you into the myNewFeature branch. Now all changes you make won't affect any other branch in your repo until you merge the changes into them.

Useful git Commands (cont.)

git pull [remote_name] [branch_name]
Fetches the branch called "branch_name" from the remote called ["remote_name"] into your local repo, and merges the changes into your Working Directory into whatever branch you have checked out at the moment.
Example (continuing from above): $ git pull origin main pulls the main branch of the origin remote into your myNewFeature branch.
git add .
Get's all your changes ready for commiting by adding them from your Working Directory into your Staging Area.

Useful git Commands (cont.)

git commit -m "Commit notes go here"
Makes a snapshop in time; commits your changes to your local copy of the repo. It's ready to be pushed. Note: You can add the -a option to skip the previous step if there are no new files added.
Example: $ git commit -a -m "Fixed a typo identified in Issue #34"
git push [remote_name] [branch_name]
Copies your latest commits to the branch called "branch_name" on the remote called "remote_name". If [branch_name] doesn't exist on [remote_name], then one will be created.
Example (continuing from above): $ git push origin myNewFeature copies your changes in your myNewFeature branch to your repo on GitHub.

In Conclusion

  • Git is a powerful system to allow multiple people to contribute to the same project, whether they'are part of the project group or not.

  • Git is daunting and overwhelming at first. But once you learn it, you'll wonder how you ever lived without it.
  • If you get into trouble, check out Dangit, Git!?!.

Contribute to this repo on GitHub