Essentials
git init
git clone https://github.com/libgit2/libgit2
git clone https://github.com/libgit2/libgit2 mylibgit
git clone
does the following:
- Clones a Repository to a given directory
- Creates remote tracking branches for each branch (visible using
git branch -r
) - Creates and checks out an initial branch that is forked from the cloned Repository's currently active branch
After the clone, a plain git fetch
without arguments will update all the remote tracking branches, and a git pull
without arguments will in addition merge the remote master branch into the current master branch, if any.
This default configuration is achieved by creating references to the remote branch heads under refs/remotes/origin
and by initializing remote.origin.url
and remote.origin.fetch
configuration variables.
git checkout foo
git show-ref
git show-ref --tags
git show-ref --heads
git status
git status -s
git status --short
When using the -s
or --short
flags the following convention is used:
!!
Ignored files and folders??
New files that are not trackedA
New files that have been added to the Staging AreaM
File that have been modifiedMM
File that have been modified, staged then modified againD
File that have been deletedR
File that have been renamedC
File that have been copiedU
File that have been updated but unmerged
git status -su
git diff
That command compares what is in your working directory with what is in your staging area. The result tells you the changes you’ve made that you haven’t yet staged.
git diff --stat
git diff --shortstat
git diff --dirstat
Compare the Staging Area with the Repository (Changes that are staged which will go into next commit):
git diff --staged
git diff --cached
git log @{u}..
git cherry -v
git cherry -v origin/foo
git diff HEAD
git diff foo master
git log
git add foo.txt
git add *.cs
git add .
git commit -m "initial commit"
git commit --amend -a
Check out data from a Branch (foo) from the Repository to both the Working Area and the Staging Area:
git checkout foo
git mv bar.txt bart.jpeg
git fetch foo
This goes out to the remote project foo and pulls down all the data that you do not have yet. After doing this you should have references to all the branches from that remote which you can then merge or inspect at any time.
git fetch --all
git fetch -p
git push foo master
This pushes any commits you have done back up to the server. The command works only if you cloned from a server to which you have write access and if nobody has pushed in the meantime. If you and someone else clone at the same time and they push upstream and then you push upstream, your push will rightly be rejected. You’ll have to fetch
their work first and incorporate it into yours before you’ll be allowed to push
.
git checkout c5f567~1 -- file1/to/restore file2/to/restore
git checkout c5f567 -- file1/to/restore file2/to/restore
git revert --no-commit <commit-hash>
git revert -n <commit-hash>
The commands above are equal. Note this only reverts the changes to the local repository, don't forget to push the changes back to the server.
Unstaging changes
git rm foo.txt -f
git checkout HEAD foo.txt
Note this command overwrites the foo.txt file in both Working Area and Staging Area by copying it from the Repository.
git rm foo.txt --cached
git reset HEAD foo.txt
git reset --hard HEAD
Note this command copies all the files from the Repository over to the Staging Area as well as the Working Area.
git clean -d -x -f
-d
Untracked files including directories-x
Files ignored by git (.gitignore)-f
Force
git reset HEAD
Note this command copies all the files from the Repository over to the Staging Area but does not touch the Working Area.
git reset e153d3
Make current branch (typically master) to point to a given commit, then make the files in the Working Area and the Staging Area the same as the versions committed in a given commit:
git reset --hard e153d3
Branching (Essentials)
git branch feature/FOO-123
git push -u origin feature/FOO-123
git push
gb -d feature/FOO-123
git push origin --delete feature/FOO-123
git checkout --track origin/feature/FOO-123
or
git checkout -b FOO-123 origin/feature/FOO-123
Rebasing (Essentials)
git checkout feature
git rebase -i HEAD~3
git fetch --all
git rebase origin/master feature/FOO-123 // Incorporate changes from origin/master and include it in local feature branch
git push origin feature/FOO-123:master // Make the origin/master point to the feature branch
Which is the same as:
git fetch --all
git checkout feature/FOO-123
git rebase origin/master
git checkout master
git pull
git rebase feature/FOO-123
git push origin master
git fetch --all
git rebase origin/master feature/FOO-123
git push -f // to push the updated feature branch to remote
Which is the same as:
git fetch --all
git checkout feature/FOO-123
git rebase origin/master
git push -f
Exploring (Essentials)
git log master..
git log origin/master..
git log ..@{u}
git log ..origin/feature/FOO-123
git log feature/FOO-123..origin/feature/FOO-123
Commits on the current branch that are yet to be pushed to it's tracking remote e.g. origin/feature/FOO-123.
git log @{u}..
git log origin/feature/FOO-123..
git log origin/feature/FOO-123..feature/FOO-123
git log origin/master..
git log origin/master..@{u}
git log origin/master..origin/feature/FOO-123
git log ..origin/master
git log @{u}..origin/master
git log origin/feature/FOO-123..origin/master
Branching
git branch
git branch -r
Note remember to run git fetch --all
for getting the latest changes.
git branch -a
git branch -v
git branch -rv
git branch -av
git branch --merged
Note entries in the list produced by above which are missing the *
in front of them are generally fine to delete as you've already incorporated their work into another branch so you are not goint to loose anything.
git branch --no-merged
git branch -vv
git fetch --all
git checkout foo
git checkout --orphan EMPTY
git reset --hard
git commit --allow-empty -m "Created an empty branch"
git push origin EMPTY
git branch foo
Note if you are on master and run the above command it merely creates the foo branch and the HEAD will still point to master.
git checkout foo
This command moves HEAD to point to the foo branch. Note this also reverts the files in the Working Area back to the snapshot that foo points to.
git checkout -b foo
// the above is the same as:
git branch foo
git checkout foo
git checkout -b feature/foo
// then push it to remote
git push -u origin feature/foo
// which is the same as ... git push <remote-name> <local-branch-name>:<remote:branch:name>
git push origin feature/foo:feature/foo
git checkout master
git merge foo
git branch -d foo
git push origin --delete foo
git push origin -d foo
git push origin foo
// you can also change the remote name to bar
git push origin foo:bar
git push --force origin foo
git push -f origin foo
Working with Remote
git remote
git remote -v
git ls-remote
git remote add foo https://github.com/someone/foo
git remote remove foo
git remote rm foo
git remote rename foo bar
git remote set-url origin https://<USER>:<PASS>@github.com/<USER>/<REPOSITORY>.git
git remote show origin
Exploring
gitk --all
The above command shows all the refs(branches, tags etc.).
gitk v2.5.0.. EasyMessageHub\
The above shows the changes since v2.5.0 that changed any file in the EasyMessageHub\ directory.
git reflog
git log --since=2.weeks
git log --since="2017-02-21"
git log --after=2.weeks
git log --after="2017-02-21"
git log --comitter=nima
git log --author=nima
git log --graph --decorate --oneline --all
git log --graph --pretty=format:"%C(yellow)%h%Creset%C(cyan)%C(bold)%d%Creset %C(green)[%cn]%Creset %s %C(cyan)[%ci (%cr)]%Creset"
git log --stat
git log -p foo.txt
gitk foo.txt
Note the above command does not show changes if a file is renamed.
Show the entire history of a file (foo.txt) including history beyond renames and with diffs for each change:
git log --follow -p -- foo.txt
gitk --follow -p -- foo.txt
In other words, if the file named bar was once named foo, then git log -p bar
(without the --follow
option) will only show the file's history up to the point where it was renamed -- it won't show the file's history when it was known as foo. Using git log --follow -p bar
will show the file's entire history, including any changes to the file when it was known as foo. The -p
option ensures that diffs are included for each change.
git blame foo.txt
The command shows the latest commit which changed a given line in the file foo.txt. A ^ signifies the first time the file was added to the project.
git log --patch
git log -p
git log --grep apples --oneline
This filters to only show the logs with the word apples in the commit message.
git log -S apples --patch
git log -G apples --patch
-S
accepts a string and -G
accepts a REGEX; The above shows the logs where the word apples was added or removed from any file.
git log -3 --oneline
git log HEAD~5..HEAD^ --oneline
This commands shows the log between the 5 commits before the HEAD and the parent of the HEAD commit.
git log foo..master --oneline
Shows the commits that are in the master branch but not in the foo branch. E.g. go to from foo to master and show me all the new commits that you see. So if we merge master right now we would get all the displayed commits.
git log Easy.Common-release-v2.9.9..Easy.Common-release-v3.0.0 --oneline
Shows the commits between the given tags.
git show 2cc5405
git show someBranchName
git show HEAD
git show HEAD^
git show HEAD~2
The ^ refers to the parent and it can be used multiple times e.g. HEAD^^
referring to the parent commit of the parent commit of the commit the HEAD is pointing to. The same can be achieve by using ~ for example HEAD~2
.
git show HEAD@{"1 month ago"}
git diff HEAD HEAD~2
The command shows the difference between the current commit and 2 commits earlier.
git diff master someBranch
git diff --color-words 1.txt 2.txt
Fixing Mistakes (DO NOT USE TO CHANGE SHARED HISTORY ONLY LOCAL COMMITS)
git commit --amend -m "ABC-123 fixed: Should work fine"
git commit --amend
This commands ammends the last commit.
Working with Tags
git tag
git tag -l "v1.2.3"
git tag -a v1.4 -m "Stable release"
git tag -a v1.6 38ea264 -m "Stable release"
git show v1.4
git push origin v1.4
git push origin --tags
git checkout -b version1.4Branch v1.4
Note if you run this command and do a commit, your version1.4 branch will be slightly different than your v1.4 tag since it will move forward with your new changes, so do be careful.
git fetch --all
git tag -d v1.4
git push origin :refs/tags/v1.4
Setting proxy
git config --global http.proxy http://user:pass@somewhere.com:1234
SVN to Git Migration
1. git svn init -s https://svn.repo/app ./MyApp
This assumes that under the SVN repo there is the standard folder structure of trunk
, branches
and tags
.
- To pull in new commits from SVN use:
git svn rebase
- To push local commits to SVN use:
git svn dcommit
git svn clone --stdlayout --no-metadata https://svn-repo.com/Something/ ./Awesome
- Add
README.md
- Add
.gitignore
git remote add origin https://github.com/Someone/Awesome.git
git pull origin master --allow-unrelated-histories
git push origin master --force
Git Bundling
git clone --mirror git@example.org:path/repo.git
git bundle create repo.bundle --all
Working with Config
git config -e
git config -e --global
git config --global core.editor "'c:/program files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
Working on a feature branch
- Create a feature branch:
git checkout -b my-feature
- Push branch to remote:
git push -u origin my-feature
Setting up Bare Repositories
- Create an empty repository:
cd C:\My-Git\
git init --bare My-Repo.git
2.a Clone the empty repository to a working directory
git clone C:\My-Git\My-Repo.git My-Repo
2.b Create a working folder from existing files (non git repo)
cd C:\Somewhere\My-Repo2
git init
git add .
git commit -m "some stuff"
git remote add origin C:\My-Git\My-Repo.git
git push -u origin master
Setting up SSH
As per THIS
ssh-keygen -t rsa -b 4096 -C "Nima.Ara@Outlook.com"
eval $(ssh-agent)
ssh-add ~/.ssh/id_rsa
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa
Host github-PRIVATE
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_PV
git@github-PRIVATE:USERNAME/Foo.git
- When you use
pull
, git tries to automatically do your work for you. It is context sensitive, so git will merge any pulled commits into the branch you are currently working in.pull
automatically merges the commits without letting you review them first. If you don’t closely manage your branches, you may run into frequent conflicts. - When you
fetch
, git gathers any commits from the target branch that do not exist in your current branch and stores them in your local Repository. However, it does not merge them with your current branch. This is particularly useful if you need to keep your Repository up to date, but are working on something that might break if you update your files. To integrate the commits into your master branch, you usemerge
.
clone
is for fetching repositories you don't have.checkout
is for switching between branches in a Repository you already have; It can also be used to overwrite a file in your working copy with a version of that file from another revision.
git show
or
git log -1 -p
git show a4c8def:README.md