Below is a cheatsheet for Git so we don't become like the guys in this comic:
Similar Commands To SVN
These commands just need to be prepended with git, instead of svn:
- mv instead of move
- rm instead of delete
- init instead of svnadmin create
Check if Out of Date
git remote update git status
If you are out of date, then run the following:
git pull # Alternatively git fetch git merge
If you want to see the differences that haven't been staged yet against the "base", use:
If you wish to see the differences that you have staged for committing, then use:
git diff --staged
Restore A Deleted File
If you have various outstanding changes, and want to restore/revert a file that you had deleted at some point and have not committed yet, run the command below to get it back in its last committed form:
git checkout [filename]
Revert a File
If you want to revert any staged changes to a file, you can revert them with the same command we used to restore a deleted file:
git checkout [filename]
... there is also the option to use:
Unstage A File
If you wish to just unstage a file that may or may not already exist in the repo, and you wish to keep the local changes to that file locally, then use:
git reset HEAD [filename]
You may think the command below is an "alias" of the one above for unstaging a file. If the file hasn't been committed, then it would unstage the file and keep it locally. However, if it does already exist in the repo, it would actually stage it for removal!
git rm --cached myFile.txt
By default this will not wrap messages in your terminal. If you want to do this, use
git log | less
Also, if you want a visual representation of your branches/history the following command is extremely useful:
git log --oneline \ --abbrev-commit \ --all \ --graph \ --decorate \ --color
Quickly Initialize Code In Git
If you have a bunch of code that is not currently under git/version control, then using these commands inside the directory will set up git AND add all the current files to it:
git init git add . git commit
The command below will list local branches:
... and this one will include remote branches:
git branch -a
Create A Local Branch (Not on Remote)
git branch [a new branch name]
Create A Local Branch That Tracks Remote
git checkout [name of branch on remote but doesn't exist locally]
git checkout [name of a local branch]
Delete a Local branch
git branch -d the_local_branch
Delete a Remote branch
git push [remote identifier] --delete [branch name]
git push origin --delete my-branch
Delete All Local Tracking Branches That Aren't On Remote
git remote prune origin
Push a Local Branch To Remote and Set to Track
Perform this command if you created a local branch that doesn't exist on remote.
git push -u origin [local branch name]
Create A Local Branch That Mirrors Remote
If you have a branch in your central repository, such as Github, then chances are that you want to use the following code to create a local branch of the same name that will track the remote one.
git checkout -t origin/[branch name]
Checkout a Remote Branch
The command below will allow you to checkout a remote branch and give it a different name, but I recommend you just use the previous command for creating a local branch that mirrors remote instead.
git checkout -b \ $LOCAL_BRANCH_NAME origin/$REMOTE_BRANCH_NAME
Merge a branch and automatically commit if successful:
git merge [branch name]
If you wish to be able to review the changes before commiting the merge (and possibly make some last minute changes), then use:
git merge --no-commit --no-ff branchname
If you are not ready to merge a whole branch, but need to grab some of the changes/commits, you want to use the cherry-pick command on each change that you desire. For example:
git cherry-pick 87bafa9
You may wish to do this multiple times and commit as a single commit. In such a case just make sure to use the
--no-commit flag on each cherry-pick, and then manually commit when you are done.
git cherry-pick 87bafa9 --no-commit git cherry-pick 52a08a4 --no-commit git cherry-pick afa6635 --no-commit git cherry-pick 1cb5f92 --no-commit git commit
Unlike SVN, git has a concept of tagging built-in. This means that when creating a release of a php package, you don't branch off into the /tags directory, but simply run:
git tag -a [tag name]
If you want to see the tags/releases, run:
If you want to switch to a tag, execute:
git checkout [tag name]
Tags do not get pushed to the remote repository automatically with commits. You need to manually run:
git push --tags
If you want to delete a local tag then use
git tag --delete [tag name]
Deleting a tag does not result in it being pushed. To delete a remote tag, you need to specify it specifically:
git push --delete [remote name] [tag name]
If you want to create a tag, but want to give a specific description other than the log on the revision you are tagging, you can use the following:
git tag -a [tag name] -m "[tag description/log]"
git remote -v
Delete a Remote
git remote rm [remote name]
Add a Remote (SSH)
git remote add --mirror=push [remote name] [user]@[hostname or IP]:[path to repo] git remote add --mirror=fetch [remote name] [user]@[hostname or IP]:[path to repo]
git remote add --mirror=push origin firstname.lastname@example.org:/home/git/my-repo git remote add --mirror=fetch origin email@example.com:/home/git/my-repo
Note: You can specify just push or fetch if you only intend to perform one of those.
If you moved your remote repository, then you can just update the remote instead of adding the new location and removing the old one.
git remote set-url origin ssh://firstname.lastname@example.org:23825/user/project-name.git
Rebase Vs Merge
When you want to update a branch from upstream (usually master), you have two options. Merge and rebase. Rebase can be confusing for newcomers coming from SVN, so I just wanted to provide this diagram of the difference.
As you can see, the rebase will give you a much cleaner looking history. However, the diagram does not clearly convey the point that in a rebase, each point in the branch's history (purple points) will be considered a new commit after a rebase operation. This is why its okay to rebase your local branches, but it's not okay to rebase something that has gone public. Merging is perfectly okay for things that have been pushed publicly.
I found the section on git rebase from Atlassian most useful.
Use Meld for diffs
Read about how to do it here.
To globally set your default 'username' for commits across all projects run the following code:
git config --global user.name [username]
Note: This will be overriden by the 'local' scale if it exists. To set your username at a local scale, you can run the following command from inside your repo:
git config --local user.name [username]
Alternatively, you could edit the
.git/config file directly.
git config --global user.email "email@example.com"
Enable Colour Coding!
To enable the use of colour for things like diffs:
git config --global color.ui auto
It is possible to configure colour coding on only certain aspects, or even change the colours themselves, but that is beyond the scope of this tutorial.
Set Default Editor
git config --global core.editor $EDITOR_NAME_HERE
Git allows you to set aliases. e.g.
git config --global alias.cp cherry-pick
This would allow you to run git cp instead of git cherry-pick. However this would likely cause confusion with the linux copy command which is also cp.
There are two types of repositories:
- Bare - Nobody directly uses the repo, but is used for a centralized area for multiple developers to push and pull from. (Like your SVN repo).
- Shared - This is a "normal" repo that you have set up yourself, and users within the same group can 'pull' (update your code from) or 'push' (apply changes) to it. Likewise you can pull from/push to other peoples shared repos.
These types are indicated with
--shared respectively on the git init command. When not specified, git init will create a shared repository. Click here if you need more info.
Although git can detect renames, using the
mv command on a file, it's probably best just to think of this as deleting a file and creating a new one.
- If substantial changes are made to the file before the mv, it may not be picked up as a rename
- Due to the fact that detecting renames is expensive, it is turned off by default and the
-Mswitch has to be given to
git logif you do want to see renaming.
The following command is your best friend:
You may wish to configure meld to act as your merge tool.
Also, you may wish to have 3 files checked out to act like SVN and manually do your diff/merging.
FILENAME="filename.txt" git show :1:./$FILENAME > ./$FILENAME.base git show :2:./$FILENAME > ./$FILENAME.working git show :3:./$FILENAME > ./$FILENAME.remote
The above command gives you all the variations of the file, but usually I find that I just want the following:
FILENAME="filename.txt" git show :2:./$FILENAME > ./$FILENAME.working git show :3:./$FILENAME > ./$FILENAME.remote rm $FILENAME
It is important to note that the Git protocol does not support authentication. To restrict people's access to your codebase, you need to use the other tools at your disposal. E.g. Setting up an SSH account(s) for the other colleagues to access your repo on. This is unlike SVN, whereby for each Repo, you can configure specific username/password pairs which were used for the 'authors' in the logs.
sudo apt-get install git
Git Data Transport Command Diagram
Install RabbitVCS GUI (Ubuntu)
sudo add-apt-repository ppa:rabbitvcs/ppa -y sudo apt-get update sudo apt-get install rabbitvcs-nautilus3
In Ubuntu 13, you may need to perform these extra steps.
- Git Pocket Guide By Richard E. Silverman
- Stack Overflow - Push a new local branch to a remote Git repo and track it too
- Stack Overflow - Delete a Git branch both locally and remotely
- Stack Overflow - Why are there 2 ways to unstage a file in git?
- Stack Overflow - Review the result of git-merge before the actual merge
- Stack Overflow - How do I show the changes which have been staged?