Skip to content

Instantly share code, notes, and snippets.

@LOZORD
Last active August 29, 2015 14:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LOZORD/3f4271e461f6d8aaa99d to your computer and use it in GitHub Desktop.
Save LOZORD/3f4271e461f6d8aaa99d to your computer and use it in GitHub Desktop.
UPLVLS: git, GitHub, and you!

git, GitHub, and you!

A tutorial for the UPL Video Lecture Series

Accompanying slideshow

Video walkthrough

All of the commands below are prefixed by git and are run inside your (Unix-like) terminal (bash, zsh, etc.).

Some commands will appear with a $ at the beginning of the line. Do not type this in, this is the terminal prompting you for input!

I'm assuming you have git installed as well. (Run git --version to verify.) I'm also assuming you know how to use simple commands like cd, pwd, ls, mkdir, and open (or their Window's equivalents) effectively.

Yes, there are GUIs for git, but I prefer the command line for most git-related things.

GUI Downloads:

Let's get started!

START THIS TUTORIAL BY CREATING NEW DIRECTORIES

$ mkdir git_tutorial
$ cd git_tutorial
$ mkdir phase_one
$ cd phase_one

init

git init will create a new git repo in your current directory.

In other words, the folder becomes a "git folder".

This action creates a "hidden" sub-folder named .git; this is where all of the git metadata/magic is stored.

status

git status let's you know what's going on in your repo

  • What files are new, modified, or deleted
  • What branch you're on (more on branches later)
  • Where you are in relation to the remote repo

add

Open a new file (e.g. touch ilovegit.txt).

Run git status and you'll see git notices that you've created a new file.

git add ilovegit.txt will add your file to the index (staging area).

This means that once you commit, git will start tracking changes to ilovegit.txt!

git add . will add all of the modifications since your last commit

git add --patch will let you add your changes in "hunks". I use it for rubber-ducking.

commit

Try to run git commit. You should get an error -- you need to supply a commit message. (Your settings may open a text editor in this case.)

Commit messages let other developers (and your future self) the summary of changes for this commit.

Canonically, the first commit in any repo is "Initial commit". Let's do that!

git commit -m "Initial commit"

The commit should run without error now. If you want to run git add and git commit -m at the same time:

git commit -am "yolo"

For the sanity of people around you, please use coherent commit messages!

push

Let's use one git's future technologies: the ability to have a remote repo.

Go to GitHub, create a new repo.

Don't do any off the advanced settings, just a vanilla repo please!

GitHub should tell you some instructions on setting up your remote.

Look for a git add command with a remote keyword.

When I did it, it was the second set of git commands listed on the page.

Enter these commands in your terminal. These commands allow your computer to link to send changes to GitHub.

They have the "blessèd repo" (i.e. the remote).

To push (send) your repo data to the GitHub remote, just enter git push.

Remember, the git mantra is (roughly):

  • Edit
  • Add
  • Commit
  • Push

pull

Let's say you are working on a project and your friend just pushed some commits.

They usually write good stuff, so you'll take their word for it.

Let's incorporate their changes into your local repo:

Much like how you pushed your stuff earlier, you can git pull their changes from the remote.

checkout

From my experience, git checkout has two major uses:

  • Undoing bad and dirty changes
  • Switching branches

Let's create an "oh crap" moment.

Let's say that rm ilovegit.txt doesn't "Run Magic" like you thought it did, it ReMoves your file!

Luckily, you're a cool person using git, and git notices that you derped.

Just run git status. You can see that you've deleted "ilovegit.txt".

To get it back, just run git checkout ilovegit.txt and your file is magically replaced with the same contents as most recent commit.

Hooray! Yay git!

We can also switch branches using checkout. The default branch is master.

There's nothing inherently important about master, just that it always is created in a new repo.

I've never attempted it before, but DO NOT DELETE master OR YOU WILL HAVE A BAD TIME.

Some people prefer to put "stable" code on the master branch and use custom branches for new features and such.

Other people like to keep development code on master and use branches for stable releases.

branch (and using branches)

Running git branch will show you all visible branches on your local copy.

You should only have master at this point. Let's create a new branch.

git checkout -b my-branch will create a new branch named my-branch and automatically check you "into" it.

Your new branch should look identical from the branch you just branched off of (in our case, master).

However, any changes you make to it will only be applied to the current branch.

Let's create another file: touch mybranchfile.txt

Check the status, add, and commit.

merge

So we've got done what we wanted to on my-branch, let's merge the updates into master.

Get back to master by entering git checkout master.

Now, merge the branch by running git merge my-branch.

Since my-branch is just a "fast-forward" of master, the merge is easy!

There is another type of merge called a three way merge.

Three Way Merges (Merge conflicts)

This type of merge occurs when your local repo has diverged from the remote repo, but has a common ancestor.

This is not just neanderthals becoming homo sapiens. This is:

  1. Everyone is working on SomeAnimal.java

  2. You go into hero mode and implement the Human class in SomeAnimal.java

  3. However, your partner also cranked some energy drinks and though it was better to implement the Dog class in SomeAnimal.java

  4. (Unfortunately) your partner pushes their code first

  5. You can't fast forward (Humans and Dogs aren't compatible after all...), so you need to do a three way merge.

When you pull from the remote, git should alert you that a conflict occured in Animal.java.

It's time to sit down with your partner and talk over the changes.

Let's do this right now!

  1. Get into groups of two

  2. Have one person (A) create a new file called mymerge.txt

  3. A adds one line to the file: octopus

  4. Have the other person (B) clone A's tutorial repo (use git clone and the link provided by GitHub)

  5. B changes octopus to octodad, adds, commits, and pushes

  6. A changes octopus to octocat, adds, and commits

  7. NOW, A attempts to push (shouldn't work)

  8. A first has to pull B's changes, however they've diverged

  9. If you get a 403 error at anytime, or something is broken besides the conflict, A needs to add B as a collaborator to the project.

  10. First, A navigates to the project on GitHub.

  11. Then A clicks on the Settings link on the right hand side of the page.

  12. There should be a Collaborators link on the left hand side of the settings page -- click it.

  13. A adds B as a collaborator using B's GitHub username.

  14. A pulls, git should complain about a merge conflict

  15. Fire up your merge tool (git mergetool) and fix that conflict!

Time to interact with a human!

mergetool

Running git mergetool will open your mergetool, or a program that helps solve a merge conflict.

You can choose to solve the merge conflict by hand, but I don't trust myself enough.

On a Mac, you should have a rudimentary GUI. Meld is a popular tool.

If you're comfortable with vim, vimdiff is also a good tool.

Now, decide with your partner what octoxxx you want. Once you've resolved the merge, add, commit, and push to the remote.

"AHHH, I DON'T HAVE A DEFAULT MERGETOOL!!!"

If your OS doesn't come with a default mergetool, it's time to roll up your sleeves. (Or just look up how to get a mergetool and set it as a default... I don't know everything ...)

git identifies the conflicting code and puts markers around it. Here's GitHub's example:

the number of planets are
<<<<<<< HEAD
nine
=======
eight
>>>>>>> branch-a

Follow their guide and fix the merge by hand. This is equivalent to using a tool (like Meld). Feel free to make decisions based on your preferences!

log

So what are all of these commit messages for anyway?

Using git log you can see all of the commit messages you've made, plus a bunch of other useful information.

If you want less information, git shortlog and git log --oneline are good options.

clone

As you saw earlier, git clone <url> will create a clone repo into a new directory with the repo's name.

This is a really easy way to join a group project (i.e. the codebase already exists).

Cloning also sets up the remote connection, so you can begin pushing and pulling right away!

There also exists the concept of "forking."

Forking

Forking is useful if you want to take an existing project, branch off, and do your own stuff with it.

For example, if I wanted to make Leonux, I would fork the Linux project instead of cloning it. This way, when I make changes, my commits will get pushed to my remote instead of Linus'.

However, if I made some changes to some of Linus' files that I though he would like, I can make a pull request, or PR. He can pull in my changes, which get merged in with his stuff. Yay open source!

blame

Let's say the code you just pulled doesn't work. Oh no!

If only we could find the rascal who pushed broken code and make them pay...

Luckily, there's a nifty tool to do that: git blame.

It shows you, line for line, who updated it last.

The reason I wanted to include it is that our very own Prof Ben Liblit helped create a blame-like tool back in the svn-days.

Misc.

Commands I like:

  1. Clean up git-related garbage -> git gc
  2. Nuke your repo back to head (last commit) -> git reset --hard HEAD
  3. Remove untracked files from the working tree - > git clean

Be sure to check out the manual pages too!

"I don't want this junk repo anymore!"

Ok, ok! Here's what you can do:

To un-git your directory
$ sudo rm -rf ./.git

This command looks scary because it is close to the computer-killing command.

All it's doing is forcefully destroying the .git folder and its contents. It shouldn't touch anything else.

You can check that git is gone by running git status and getting a fatal error about the current directory not being a git repo.

To delete the entire tutorial directory

Please first check that the directory is not your home (~) or root (/) directory!

If there is anything important in it, DO NOT RUN THIS COMMAND!

If you are worried about the effects of this command, find your friendly neighborhood hacker to help you out!

Otherwise, run this command:

$ sudo rm -rf <directory_name, "git_tutorial" for example>

It should not exist anymore.

Thanks for reading/watching, and enjoy git!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment