Advanced git
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
A little review
Last week you folks had a midterm, so I assume some of you missed that lecture
Some facts from last week:
https://onlywei.github.io/explain-git-with-d3/
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.
Example git project structure
gitrepo
> .git
> (git’s magical files, don’t worry about these)
> Hello.java
> (your other files)
Editing commits
The basic usage of “git add, git commit, git push” is nice and all, but it gets a bit untenable sometimes:
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), …
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
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”
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.
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.
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.
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?
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”
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)”
How to undo stuff in general
1) Accidentally edited a file without committing or “git add-ing” it?
2) 1 AND git add-ed it?
3) 2 AND committed it?
4) 3 AND pushed it?
Links to all of this stuff
My github : https://github.com/colinchartier
Explain git with D3: https://onlywei.github.io/explain-git-with-d3/
Next week