GIT
Last updated: 2020-05-03
- Settings
- Ignore Files
- Branching and Merging
- Forks
- Push
- Stash
- Remote
- Show
- Conflicts
- Reset
- Log
- Tags
- Pruning
- Cleanup
- References
Settings
The first thing you should do when you install Git is to set your user name and e-mail address. This is important because every Git commit uses this information, and it’s immutably baked into the commits you pass around:
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
Command Alias
git config --global alias.shortcut command
# example
git config --global alias.co checkout
git config --global alias.st status
git config --global alias.ci commit
Checking Your Settings
If you want to check your settings, you can use the git config –list command to list all the settings Git can find at that point:
git config --list
user.name=Scott Chacon
user.email=schacon@gmail.com
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
Ignore Files
Add a .gitignore file to the root of your project. Below is a starter file:
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so
*.sass-cache
# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
# Logs and databases #
######################
*.log
*.sql
*.sqlite
# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
Icon?
ehthumbs.db
Thumbs.db
# Custom #
node_modules
Branching and Merging
git checkout -b iss53
Switched to a new branch "iss53"
This is shorthand for
git branch iss53
git checkout iss53
You work on your web site and do some commits. Doing so moves the iss53 branch forward, because you have it checked out.
vim index.html
git commit -a -m 'added a new footer [issue 53]'
Switch back to your master branch
git checkout master
Switched to branch "master"
Run tests and merge if good to go.
git merge hotfix
Updating f42c576..3a0874c
Fast forward
README | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
Delete the old unneeded branch.
git branch -d hotfix
Deleted branch hotfix (3a0874c).
If you have to merge only specific files from a feature branch, you can use git checkout with the name of the feature branch and the file(s) you need to merge
git branch
* master
feature_branch
git checkout feature_branch path/to/file1 path/to/file2
git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# new file: path/to/file1
# new file: path/to/file2
#
git commit -m "Merge message"
[master]: created 4d3e37b: "'Merge' update code from 'feature_branch' branch"
4 files changed, 72 insertions(+), 0 deletions(-)
create mode 100644 path/to/file1
create mode 100644 path/to/file2
Seeing which local branches are tracking a remote branch
git remote show origin
Update local branch with remote content
git merge origin/master
I screwed up, how do I reset my checkout?
git checkout -f
Reset to a specific commit
git reset --hard {SHA1}
A file is staged, I need to unstage it
git reset filename
Show differences in branches
git diff --name-status branch_name_1 branch_name_2
git diff --stat --color branch_name_1 branch_name_2
If you want to see what would change in detail if you merged in a particular branch:
git diff (branch)
# show a specific file
git diff (branch) (filename)
Show a file from a different branch without checking it out
git show branch:file
git show branch:file > export_file
Show what branches have been merged
git branch --merged
git branch --no-merged
Merge a branch –dry-run
git merge --no-commit --no-ff branchtomergein
Remove, Reset and Rollback Commits
Use git log
to see the most recent commits. Let's say you want to rever the last three commits:
git reset --hard HEAD-3
If you only want the last commit to be removed:
git reset --hard HEAD-1
It's also possible to roll back to a specific commit by using the SHA hash:
git reset --hard d3fla8
In case you already pushed your changes to a remote repository, you can't use git reset, because it will wreak havoc with other people's repositories later. Instead, you could revert your commit (e.g. create a new commit, undoing a previous one).
Note that git revert does not walk back into history, but only works on a specific commit or range of commits. To use my previous examples:
git revert HEAD~3..HEAD
git revert HEAD~1..HEAD
git revert d3f1a8..master
Optionally specify the --no-commit
option to see what's being reverted.
Forks
Configuring a remote fork (upstream)
To sync changes you make in a fork with the original repository, you must configure a remote that points to the upstream repository in Git.
Open Terminal (for Mac users) or the command prompt (for Windows and Linux users).
List the current configured remote repository for your fork.
git remote -v # origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch) # origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (push)
Specify a new remote upstream repository that will be synced with the fork.
git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git
Verify the new upstream repository you've specified for your fork.
git remote -v # origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch) # origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (push) # upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (fetch) # upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (push)
Syncing A Fork
Open Terminal (for Mac users) or the command prompt (for Windows and Linux users).
Change the current working directory to your local project.
Fetch the branches and their respective commits from the upstream repository. Commits to
master
will be stored in a local branch,upstream/master
.git fetch upstream # remote: Counting objects: 75, done. # remote: Compressing objects: 100% (53/53), done. # remote: Total 62 (delta 27), reused 44 (delta 9) # Unpacking objects: 100% (62/62), done. # From https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY # * [new branch] master -> upstream/master
Check out your fork's local master branch.
git checkout master # Switched to branch 'master'
Merge the changes from
upstream/master
into your localmaster
branch. This brings your fork'smaster
branch into sync with the upstream repository, without losing your local changes.git merge upstream/master # Updating a422352..5fdff0f # Fast-forward # README | 9 ------- # README.md | 7 ++++++ # 2 files changed, 7 insertions(+), 9 deletions(-) # delete mode 100644 README # create mode 100644 README.md
If your local branch didn't have any unique commits, Git will instead perform a "fast-forward":
git merge upstream/master
# Updating 34e91da..16c56ad
# Fast-forward
# README.md | 5 +++--
# 1 file changed, 3 insertions(+), 2 deletions(-)
Push
So let’s say you have checked out a new branch, committed some awesome changes, but now you need to share this branch though with another developer. You can push the branch up to a remote very simply:
git push origin newfeature
Deleting is also a pretty simple task (despite it feeling a bit kludgy):
git push origin :newfeature
Push all branches at once
git push --all origin
Stash
Now you want to switch branches, but you don’t want to commit what you’ve been working on yet; so you’ll stash the changes. To push a new stash onto your stack, run git stash
.
git stash
Saved working directory and index state \
"WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")
To see which stashes you’ve stored, you can use git stash list:
git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051... Revert "added file_size"
stash@{2}: WIP on master: 21d80a5... added number to log
In this case, two stashes were done previously, so you have access to three different stashed works. You can reapply the one you just stashed by using the command shown in the help output of the original stash command: git stash apply. If you want to apply one of the older stashes, you can specify it by naming it, like this: git stash apply stash@{2}. If you don’t specify a stash, Git assumes the most recent stash and tries to apply it:
git stash apply
# On branch master
# Changes not staged for commit:
# (use "git add ..." to update what will be committed)
#
# modified: index.html
# modified: lib/simplegit.rb
You can manually delete stashes with:
git stash drop
Or delete all of the stored stashes with:
git stash clear
Remote
Remote show
git remote show origin
Push new local branch to remote repo
git push origin plugin
Push to existing remote branch
git push -u origin
Checkout a remote branch
git fetch origin
git checkout --track origin/plugin
Merge remote branch
git fetch
git merge origin/master
Delete remote branch
git push origin :newfeature
Seeing which local branches are tracking a remote branch
git remote show origin
Merging an upstream repository into your fork
Open Terminal.
Change the current working directory to your local project.
Check out the branch you wish to merge to. Usually, you will merge into master.
git checkout master
Pull the desired branch from the upstream repository. This method will retain the commit history without modification.
git pull https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git BRANCH_NAME
If there are conflicts, resolve them. For more information, see "Addressing merge conflicts".
Commit the merge.
Review the changes and ensure they are satisfactory.
Push the merge to your GitHub repository.
git push origin master
Show
Show a file from a different branch without checking it out
git show branch:file
git show branch:file > export_file
Get a file from a specific revision
git show branch:path/to/file
So let’s say we want to go back four commits from our current HEAD, and we want the index.html file.
git show HEAD~4:index.html
You could of course pass any valid treeish into the command. It will accept the actual SHA1 of the blob as well.
git show 7da184bbb00c094e08df8714604fa273e51cf4fa:./src/pages/filename.html
# save the output to a file
git show 7da184bbb00c094e08df8714604fa273e51cf4fa:./src/pages/filename.html ~/Desktop/myfile.html
Conflicts
List the conflicted files in git
git ls-files -u
Reset
git checkout -f
git checkout -f path/file
Delete untracked files/directories
# remove files
git clean -f
# remove files and directories
git clean -f -d .
# remove ignored files also
git clean -f -x .
Log
git log
If you pass the –stat option to ‘git log’, it will show you which files have changed in that commit and how many lines were added and removed from each.
git log --stat
View the history of a specific file
git log -p filename
Get the commit ID of the last commit:
git log --format="%H" -n 1
Get a list of the files included in the last commit:
git diff-tree --no-commit-id --name-only -r commit_id
Formatting the Log
You can also format the log output almost however you want. The ‘–pretty’ option can take a number of preset formats, such as ‘oneline’.
git log --pretty=oneline
git log --pretty="short
git log --pretty="format: '%h : %s' --graph
Log Statistics
git shortlog
Show the log for n number of commits. For example, git log -2 for the last two commits.
git log -
Show the log with output for files changed and insertions/deletions. Basically the normal output of git commit appended to each message.
git log --stat
Attaches SVN-like add/modified/deleted for each commit. Very basic but still gives a decent idea about what’s changed.
git log --name-status
Compresses each commit to its SHA1 and message on one line. Pipe to wc -l if you want to count commits!
git log --pretty=oneline
See if there’s any commits that have not been pushed to your origin remote.
git log origin..HEAD
See all commits that affected only the file given.
git log
See all commits that dave has worked on, and ignore any merge commits to reduce noise.
git log --no-merges --author=dave
View commits that have happened since last week. Could easily be replaced with yesterday, 1 year ago, 3 months ago, 1/20/09 and so on. There’s also other time based options: –after, –until, and –before if you want to get creative.
git log --since="1 week ago"
Search through commit messages to find ones that start with the string “Bump”. This will take in any regular expression, so if you’re looking for that one commit you did and all you can remember is a part of the message, –grep will find it.
git log --grep='^Bump'
Don’t want to use less to view your commits? This option will just give you the straight output if you need it
git --no-pager log
Show all of the details of the commits
git log -p```
Show only a specific subdirectory log
```bash
git log -p -- path/to/directory > outputFile.txt
Use the gitk
command to review the history of a specific document using the Wish comparison application:
gitk [filename]
Tags
Git has three different type of tags:
- Lightweight tags
- Annotated tags
- Signed tags
Let’s start with lightweight tags.
Lightweight tags
In the previous cheat sheet only the lightweight local tags were discussed. A lightweight tag is nothing more than a reference to a particular revision or SHA1 object name in the repository. This kind of tag is quick and easy and very usable for local development to mark places in your commit history.
Creating a lightweight tag is easy:
git tag tag_name
Viewing available tags is done with -l:
git tag -l
Annotated tags
Annotated tags are almost like lightweight tags, the big difference is that they contain a message. Normally this message indicated why this tag is interesting. Use the -a option to create an annotated tag.
git tag -a tag_name
Since a message is required for annotated tags, you will be prompted with an editor to enter a message, or you can use the -m option to specify one directly.
git tag -a -m "Tagging release 1.0" v1.0
To view annotated tags you can use the same -l option as before, but you have to instruct git to show the annotation messages as well:
git tag -l -n1
This will not only show the messages for the annotated tags, it will also show the commit message of the revisions tagged with lightweight tags as well.
Signed tags
Signed tags take annotated tags a step further, they include an OpenPG signature to provide trust. While gits SHA1 tags provide integrity for the repository, the OpenPG signature makes sure that a trustworthy person created the tag.
To create a signed tag you’ll need to have GPG or some other OpenPG tool setup and use the -s option to sign the tag:
git tag -s -m "Tagging release 2.0" v2.0
The -s options implies the -a option, so here too a message is required.
To verify a signed tag you can run the following:
git tag -v v2.0
Deleting tags
There are times when you want to remove tags as well. This quite easy:
git tag -d tag_name
To remove a tag on a remote repository, you should do a special push:
git push origin :refs/tags/tag_name
Pushing tags
To push your tags to a remote repository, use the following command to push all tags:
git push origin --tags
Pruning
git remote show origin
Remote branches:
feature_branch tracked
master tracked
refs/remotes/origin/feature_old stale (use 'git remote prune' to remove)
Sometimes branches are deleted from a remote repo. By default, git fetch will not remove any remote-tracking branches that have been deleted on the remote repo. Running git remote prune REMOTENAME will delete these tracking branches.
git remote prune origin
Password:
Pruning origin
URL: https://...
* [pruned] feature_old
Use the –dry-run flag to review what will be pruned.
Cleanup
git gc
Runs a number of housekeeping tasks within the current repository, such as compressing file revisions (to reduce disk space and increase performance) and removing unreachable objects which may have been created from prior invocations of git add.
Users are encouraged to run this task on a regular basis within each repository to maintain good disk space utilization and good operating performance.