Lindsay Gaudinier at Hook 42
Git takes photographs of your data
When you decide you want to keep a change - you tell Git to take another photo
This photo is called a commit
Commits look like this:
commit b69e6a0d77ff0faa92e209e67398b0077f4961cd
Specifically your local computer
This is where you do all your work
It is called your local
The code has Git
.git subdirectory
If not - use git init
These exist on your local
We are still only on your local
Step: 1
Git State:
Modify files
Git Section:
Working Directory
Step: 2
Git State:
Stage the Modified Files
Git Section:
Staging Area
Step: 3
Git State:
Commit these Modified Files
Git Section:
Git Directory
Check the state of the Git Project (Working Directory, Staging Area, and Git Directory)
git status
Make some changes to a CSS file
In the Working Directory
Add these CSS changes to the Staging Area
git add [filename]
Add a completely new PHP file
Add this new file to the Staging Area
git add [filename]
Must add new files to track them in Git
Difference between your Working Directory with your Staging Area
git diff
Difference between your Staging Area and your Git Directory
git diff --staged
When the Staging Area is how you like it and you want to move the changes from the Staging Area to the Git Directory
git commit
Records a snapshot of your project that you can revert back to
git commit
launches a text editor
Write a good commit message
add the -m flag and avoid the editor
git commit -m["Your message goes here"]
Remove the file from your Working Directory
git rm [filename]
Run git commit
after removing a file
git mv [old_file_name][new_file_name]
Run git commit
after renaming a file
.gitignore file
Place the file in the working directory, do not place in .git
Can place the .gitignore file anywhere and have multiple .gitignore files
Unless you have a good reason, place .gitignore at the root of the project
Uses glob patterns
Local settings
Also ignore with .git/info/exclude file
git log
This will display the most recent commits first
There is a lot you can do to modify this
⚠ You cannot always undo your undoes!
git commit --amend
Takes your Staging Area and uses that snapshot for the commit
If there are no file changes - this command will rewrite your previous commit message
git commit -m"Great commit message"
git add forgotten_file
git commit --amend -m["Better commit message goes here"]
You changed two files and added both. But you only want to add one to the commit!
Unstage the file you don't want to commit
git reset HEAD [filename]
⚠ If you add options/flags to
git reset HEAD [filename]
things can get dangerous
Did you make some changes, stage those changes and decide you hate them? Undo it!
⚠ Warning: This is an undo that you cannot undo!
git checkout -- [filename]
A place outside of your local where the code project exists
Receives a full copy of nearly all the data from the remote
git clone [url]
Probably hosted on Acquia, Github, Pantheon, internally, etc
Default name Git gives the remote server you cloned from
Default name Git gives your local Git project (includes Working Directory, Staging Area, and Git Directory)
git remote [-v]
The -v flag will provide the url
If someone on your team made changes to the remote AFTER you got your code
There are two ways to do this:
git fetch [remote-name]
git merge origin/master
OR
git pull origin master
git clone [url]
git add [filename]
git commit -m"Best commit message ever"
Geting your commits up to the remote is known as pushing upstream
git push [remote-name][branch-name]
Using Git defaults
git push origin master
Output with failed to push some refs to [url]
Someone on your team has updated the remote, and you need to get these changes before you push
Get data from the remote
git pull origin master
Now Git gets super cool
Separate from the main line of development and continue to do work without messing up the main line
When you make a commit, Git stores a commit object that point to content changes included in that commit
A branch is just a lightweight movable pointer associated with one commit
Remember how git clone [url]
called your local Git Project master?
The default Git branch is called master
Every branch has its own Working Directory, Staging Area and Git Directory
When you start to make commits, you are given a master branch pointing to the last commit made
Every commit made moves the branch forward
Each commit points back to its parent(s)/ancestor(s)
Master branch
Oldest Commit
Newest Commit
A special unique pointer called HEAD keeps track of what branch you are on
HEAD only points to the most recent commit on your current local branch
Oldest Commit
Newest Commit
Different branches point to different commits
When you switch branches you move your HEAD
git checkout [branch-name]
You are on branch master
You have made several commits
You want to make a new branch to work on a specific feature
git status
Make a branch called feature-branch
git branch feature-branch
Switch your HEAD to that branch
git checkout feature-branch
feature-branch and master are pointing at the same commit
[id][ticket-number][3-to-5-word-summation-of-issue]
h42-1001-header-navigation-styling
Make a commit on feature-branch
feature-branch has moved forward by one commit
If you git checkout master
, the HEAD now points to branch master's lastest commit
Your local files revert to match the files of that commit
Someone on your team has some work and updated master
Your local master branch is now behind the remote
Update your local with git pull
Both branches no longer point to the same commit ancestor/parent
We have decided our feature-branch changes are magical
Let's share this magic - get these changes on our local master and then push up to the remote
git checkout[branch-WANTS-the-changes]
git merge [branch-HAS-the-changes]
We want to be on the master branch and accept the feature-branch changes
git checkout master
git merge feature-branch
Divergent history - Git uses a three-way merge (also called a merge commit)
Git creates a new commit with a new snapshot
This commit has more than one parent
git checkout master
git merge feature-branch
Two branches with non-divergent history
Git will create a fast-forward merge
Git simply moves the pointer forward
After your three-way merge or your fast-forward merge, push up to your remote and everyone can access your changes
Unless. It. All. Goes. Horribly. Wrong.
Not really that big of a deal, but you do need to be careful and deliberate in your actions
If the same part of a file is changed on two branches
Appears when you try to merge these two branches
Git pauses the process and tells you there is a conflict
Still only on your local, so nothing is broken for everyone else (yet)
Git has added conflict markers <<<<<<<, =======, and >>>>>>> in the files
Your HEAD changes appear above the =======
The branch's changes you are trying to merge into your HEAD appears underneath the =======
Solve the conflict by choosing your HEAD changes, the branch changes or select what you want from both
There are a bunch of GUI merge conflict tools
Old school: Edit the file and make sure you remove the conflict markers
After you have resolved the conflict
git add [filename]
Check that you fixed all the file conflicts
git status
Finalize the merge commit
git commit
Integrates changes from one branch into another like merging
Takes all the changes committed on one branch and replays them on another
Makes a cleaner history
We want to rebase the changes feature-branch onto master
git checkout feature-branch
git rebase master
Now we need to do a fast-forward merge
git checkout master
git merge feature-branch
Branches look linear instead of parallel
⚠ Do not rebase commits that exist outside of your repository
⚠ Do not rebase commits that others may have based work off of
A cherry-pick is a rebase for a single commit
Pull in the second commit on feature-branch 45ec9 into master
git checkout master
git cherry-pick 45ec9
This creates a new commit
Current problem is a work in progress, but need to switch branches for a hotfix
Want to fix the hotfix with a clean Working Directory, but still keep the progress you made
Save the state of modified tracked files and staged changes
git stash
Working directory is now clean
List your stashes - most recent stash is first
git stash list
Reapply a stash
git stash apply stash@{1}
Git assumes most recent stash if you don't specify
Use if the stash has been left alone for some time
git stash branch [branch-name] [stash-number]
git stash branch feature-branch stash@{1}
git blame [filename]
Goes through every line and tells you who made the last change to the line
git blame -L [startLineNumber], [endLineNumber] [filename]
git blame -L 40, 60 foo.txt
git help [verb]
git [verb] --help
man git-[verb]