1 of 18

Advanced git

2 of 18

Disclaimer

We’re getting into the more destructive parts of git.

Please avoid messing up your assignment with the things you’ll learn today

(they are, however, super useful once you get the hang of them)

My github : https://github.com/colinchartier

3 of 18

A little review

Last week you folks had a midterm, so I assume some of you missed that lecture

Some facts from last week:

  • Git stores “things” to help you develop
  • There are things called “commits” that store code changes
  • There are things called “remotes” that are places you can send code (e.g., markus, github)
  • There are things called “branches” that are labels on commits

https://onlywei.github.io/explain-git-with-d3/

4 of 18

How does git work, though?

When you initially “git clone” or “git init”, the directory that git is initialized in contains a directory called “.git”

-- This is a magical, hardcoded name that git uses to store everything! All of your remotes, commits, commit messages, and so on are in that directory

-- If you “git status”, git looks into your parent directory over and over again until it finds the “.git” directory -- that’s why if you “git status” somewhere that isn’t a git repository, git will get confused and give you the cryptic “Filesystem boundary blah” message.

5 of 18

Example git project structure

gitrepo

> .git

> (git’s magical files, don’t worry about these)

> Hello.java

> (your other files)

6 of 18

Editing commits

The basic usage of “git add, git commit, git push” is nice and all, but it gets a bit untenable sometimes:

  • What if you want to undo a commit?
  • What if you want to change a commit message before pushing?
  • What if you *don’t* want to add a file to a commit?

7 of 18

A digression : HEAD, HEAD~1, HEAD^

Before we talk about editing commits, let’s talk about some labels

If you “git log”, you’ll see that every commit has this huge alphanumeric ID that you can use to reference it

(e.g., “git show 5C5EAA51B…” will show you what files that specific commit changed, and how)

It’s tiresome to deal with these huge IDs, so git gives you the ability to say “git show HEAD” (the latest commit), “git show HEAD~1” (the second latest commit), “git show HEAD~2”, (the third latest commit), …

8 of 18

Undoing commits 1 : git reset

“git reset” changes your branch pointer without changing your files

If you are on branch “master” and you “git reset HEAD~1”, you move the “master” branch label to one commit back without changing any files

This means that “git status” will show you some files have been changed from your current commit

9 of 18

Undoing commits 1: git reset

Let’s say you typo a commit message:

git add file.txt

git commit -m “Fixad the problem with file.txt”

git reset HEAD~1

git add file.txt

git commit -m “Fixed the problem with file.txt”

10 of 18

Undoing commits 1: git reset

Let’s say you accidentally modify something you shouldn’t’ve:

git add hello.txt

git add project.iml

git commit -m ‘Add hello.txt file.’

git reset HEAD~1

git add hello.txt

git commit -m ‘Add hello.txt file.’ # note we *didn’t* “git add project.iml” this time.

11 of 18

Undoing commits 1 : git reset

What happens to the commits that are no longer pointed to by anything?

They stick around for a while, and are eventually deleted.

12 of 18

Undoing commits 1 : git reset --hard

The --hard flag makes it so that git changes your files AND the branch to point to the specific commit

For example, after “git reset --hard HEAD~1”, all of the changes in the previous commit get completely erased and go away -- this is good if you made a small commit and want to start again from scratch.

“git add -A; git reset --hard HEAD” would discard any changes that were made after the last time you committed.

13 of 18

Git reset : Interactions with others

What happens if you edit a branch to get rid of some commits and then push your changes?

Consider the following:

git add hello.txt

git commit

git push origin master

git reset HEAD~1

git push origin master # what happens now?

14 of 18

Git reset : Interactions with others

Git won’t delete the commit in the remote -- “git push” by default only allows “constructive” changes -- those that add commits onto whatever was already on the branch

There is, however, a magic flag here as well: “git push -f” (-f for force)

“git push -f origin master” means “make the remote branch exactly the same as my local branch, even if that means deleting commits or getting rid of other people’s work”

15 of 18

Undoing commits 2 : git revert

Sometimes remotes (e.g., markus, github) will block you from “git push -f” certain branches

E.g., we don’t want you to rewrite history to change your teammates commits on markus, so we disallow “git push -f”

The solution here to undo a commit is to “reverse” a commit -- make a new commit that undoes all of its changes

-- this would be constructive, so “git push” would allow it!

The command for this is “git revert (commit)”

16 of 18

How to undo stuff in general

1) Accidentally edited a file without committing or “git add-ing” it?

  • “git checkout -- (file)” (this is in the “git status” message)

2) 1 AND git add-ed it?

  • “git reset HEAD (file); git checkout -- (file)”

3) 2 AND committed it?

  • “Git reset HEAD~1; git add the proper files, git commit a new one”

4) 3 AND pushed it?

  • 2 and “git push -f” (to rewrite history), or
  • “git revert HEAD; git push” to make an undo commit

17 of 18

Links to all of this stuff

My github : https://github.com/colinchartier

Explain git with D3: https://onlywei.github.io/explain-git-with-d3/

18 of 18

Next week

  1. I’ve been banking up some open source contributions, so we’ll work together to make one live
  2. We’ll discuss good topics for personal projects, as well as how to impress a potential employer & generally do it in a useful way.