Here are my notes from watching the video Git for Ages Four and Up. It contains a really good expanation of how Git works under the hood. The speaker (Michael G. Schwern <schwern@pobox.com>) created a new repository, and then created a new file, added some text to it, saved it, closed it, then added it to the Staging Area, and then committed it.
git add
- Adds a file your working directory, to the staging area (the Index), as a BLOB.
git commit
- Creates a “Commit” object from that BLOB.
- That somehow points to the files that are stored in Git.
- The commit contains all of the files in the repot – not just the ones that were just staged.
- That somehow points to the files that are stored in Git.
- And attaches two labels (“References”) to it.
- HEAD
- The name of the most recent Commit.
- Always points to the tip of the branch that you currently have checked-out.
- MASTER
- The name of the currently checked-out Branch.
- The one that advances upon “git commit”.
- HEAD
When you create a branch
- All Git does is attach a new branch label to the Commit currently pointed to by HEAD.
When you perform a “git checkout”
- Git merely switches which branch it’s going to advance when you perform a “git commit”.
- We say the branch becomes active.
- And it moves HEAD to the commit object that has that branch label.
- Git populates your Working Directory with a snapshot of the branches tip commit..
Commit ID
- Content + Author + Date + Log + Previous Commit ID.
- A hexadecimal UUID (Universally Unique Identifier).
- Is a checksum (Hash)
- Git calculates this value by running the bits in the BLOB through a function, which produces a thirty eight digit hexadecimal value.
Staging Area (Index)
- Allows you to build up a commit.
- You can add multiple files to the index, and then commit them (i.e., all files as one commit object).
The basic Git workflow
- You isolate your work from everyone else’s (spawn a new branch to work in).
- Do some work (modify one or more files).
- Update from everyone else (pull from origin).
- Commit your work to your local enlistment (commit).
- Finally, you share your work with everyone else (push to origin).
Merge
- git checkout your local master (feature/api_doc).
- You’ll be bringing your work back into this branch.
- Git performed a Fast Forward.
- Since no merging of content (all modifications added new content).
- A merge object wasn’t created.
- All Git did was move the branch label to the commit from the ‘from’ branch.
- Git also moved the HEAD label, because you have that branch checked out.
- Since no merging of content (all modifications added new content).
git reset –hard HEAD^
- This undoes the last commit.
- But all it does is move reference labels!
- Moves the current branch label (Master), back one commit to HEAD-1.
- –hard does a checkout, so that you end up where you want to be.
git log –graph –decorate –all
git commit does not mean share (inflict).
- Commit is a local operation.
Merge
- Git can merge in many different ways.
- It picks the most convenient way.
- Fast Forward is the simplest.
Working with others
- This is where remote repositories comes in.
- remote commands.
- Push, Fetch, and Pull.
- remote commands.
Clone
- You normally start working on a clone of an existing repository.
- When you clone a repository, git attaches labels to the objects in your local repository to mark the tracking branches.
- origin/MASTER
- Git clones only origin/MASTER (the default branch).
Directed Acyclic Graph
- Graph – a collection of nodes and edges.
- Directed – the edges all point to the previous node.
- Acyclic – there are no cycles. I.e., the path from one commit to any other is unique.
Pull
- Is actually a Fetch followed by a Merge.
- When you’re starting out, it’s often easier to do a pull as two steps (a fetch followed by a merge).
We’re going to create a third repository
- So we can have someone other than us, doing work.
We’ll create a new branch called “bugfix”
- And we’ll create a new file in it called “baz”.
git push origin bugfix
- Sometimes you have a space between “origin” and “bugfix”, and sometimes you have a slash between them.
- The slash version refers to the label (origin/bugfix) on your repository. This is a reference to a tracking branch.
- The space version refers to the remote (origin) branch (bugfix).
Push
- Does two things.
- Git checks to see if the remote repository has the commit object your pushing.
- If it doesn’t, then it checks to see if it has the ancestor commit object(s).
- If it does, then
- Git sends over the commit object (plus a branch label, if it’s on a new branch).
- If it doesn’t, then
- Git send all of the ancestors + the commit object.
- Git checks to see if the remote repository has the commit object your pushing.
- This is where the cool thing about IDs comes in (this is why git is so amazingly fast).
- Every ID is unique.
- Every commit is unique.
- Commits never change.
- This means that every commit can be uniquely identified by its ID.
- Since IDs contain the ID of the previous commit,
- Every commit’s history can be uniquely identified by its ID.
- Two devs push to the same repo without pulling…
- If I have ae123, and you have ae123,
- Then we know everything from ae123 on down is exactly the same.
- If I have ae123, and you have ae123,
Tag
- Tags are good to use when you continually jump back to a particular snapshot.
- E.g., git tag v1.0 bfce7
- All Git does is add a label (reference) to the commit object you want to tag.
- Excep that tag labels never move.
git reflog
- This is your rescue command.
- You can use this command when something gets screwed up, to find a particular commit ID.
- Git shows you the commits you’ve been working on lately.
You can combine git add and git commit into one step
E.g., git commit -a foo.
Rebase
- This is a local operation.
- Example use: instead of fixing a typo and then committing the file again, you can perform a rebase instead.
- Git rebase doesn’t rewrite history. It writes new history (you can’t actually change history in Git).
- Instead, git creates a whole new line of history.
- Interactive rebase.
- Go back two commits.
- git rebase -i HEAD^^
- Git says “I’m going to replay these things as if they were patches, one on top of the other.
- Nothing happened! (because nothing changed).
- You can “squash” a later commit into a previous commit (so the typo fix you made is written on top of the version with the typo).
- I.e., you combine two (in this case) commits into a new commit.
- The original two commits become detached!
- Go back two commits.
Note: Once you have pushed, don’t rebase or you’ll screw up everyone else’s history! So never rebase until after you’ve pulled!