This is a guide for using Git. If you are in a hurry and you want a brief explanation of the commands you must use, this is a good place for you. You can also use it as a Git Cheatsheet.
Print Working Directory
pwd
List all files even the hidden ones
ls -all
Edit Global Git Config File
git config --global -e
Edit Global Git Config File by specifying the address
code ~/.gitconfig
Define Global user for git
git config --global user.name {username}
git config --global user.email {email-id}
Set Default Text Editor
git config --system core.editor {command-that-launches-text-editor}
The help command shows the manual of a particular command
git help {any-git-command}
Note: In Windows, it will open a new tab in the browser with the command's documentation.
To initialize git
to an existing folder
git init
To create a new git
Directory
git init {new-directory-name}
List files that git
is tracking
git ls-files
Type | Color | Identifier | Understanding |
---|---|---|---|
Changes to be committed | Green | modified | Files Added for staging |
Changes not staged for commit | Red | modified | New changes in tracked files |
Untracked files | Red | - | Newly created Files |
- Commits are the snapshots of how your project looked at a particular point in time.
- Commits can only be made locally and then can be pushed to the remote.
- You can not commit to a remote branch. To add a new commit to remote, git has the
push
command.
What is this weird looking string beside a commit?
- It is the SHA-1.
- It is the unique identifier for each commit.
- It is a hexadecimal code of 40 digits.
The basic steps to commit changes
git add {. (recursive) or a file-name}
git commit -m "{The Commit Message}"
If you want to add all files and commit using one command
git commit -am "{The Commit Message}"
You can make any changes to the working directory and add it to the last commit. You can
- Change the commit message
- Modify the files
- Include new files
git commit --amend
It is possible to amend uncommitted changes to previous commit using the following command:
git commit --amend --no-edit
This command doesn’t alters the name of the previous commit. Make sure to stage the files before running this command.
What is a repository?
A repository is a central location in which data is stored and managed.
What is a git repository?
A Git repository is the .git/
folder inside a project.
Name | Type | Operation |
---|---|---|
Upstream | Remote | Global Version |
Origin | Remote | Forked copy of an upstream |
Working Directory | Local | Cloned copy of origin |
The remote
can be origin
or upstream
- Creates a local repository of the remote repository.
- It is preferred to fork a project first and then clone it from
origin
.
git clone {https://github.com/user/repo.git}
List all the remotes
git remote -v
Add a new remote to a project
git remote add {remote} {https://github.com/user/repo.git}
Change the URL of a remote
git remote set-url {remote} {https://github.com/user/repo.git}
- This command simply updates the reference between local and remote repository.
- It downloads the new commits of the
remote
repository but doesn't merges them to the local branch. - It is a non-destructive command unlike
pull
.
git fetch {remote} {branch-name}
Note: The default branch for fetch
is origin
, in case not specified.
- Pulls or downloads the commits from the
remote
repository and merges them into your local branch. - It is two commands in one
fetch
andmerge
.
git pull {remote} {branch-name}
- Pushes or uploads the commits to your
remote
repository.
git push {remote} {branch-name}
First push the branch to the origin
git push origin {branch-name}
Then create a PR using GitHub or other Git-based repository hosting platform.
List local branches
git branch
List all branches
- The
-all
option is an alias of-a
.
git branch -a
Create a new branch
git branch {new-branch-name}
Switch branches
git checkout {branch-name}
Create a new branch and checkout
git checkout -b {new-branch-name}
Rename a branch
- Here
-m
flag represents move.
git branch -m {old-name-of-branch} {new-name-of-branch}
Move branch to a Particular Commit
- Use it with care because the
-f
flag which means forcefully.
git branch -f {branch-name} {commit-hash}
Deleting a local branch
- The
-d
option is an alias for --delete. - It only deletes the branch if it has already been fully merged in its upstream branch.
- You can not delete the branch you're currently checked out to.
git branch -d {branch-name}
Deleting a local branch irrespective of it's merge status
- The
-D
option is an alias for--delete --force
.
git branch -D {branch-name}
Deleting a remote branch
git push {remote} --delete {branch-name}
git push {remote} --all
Merge a branch in the current branch
git merge {branch-to-be-merged}
- This method adds a new commit with the message Merge branch "branch-you-merged".
- It preserves the Graphline.
git merge {branch-to-be-merged} --no-ff
Type | Meaning | Example |
---|---|---|
The Head | It is a reference to the currently checked out commit | HEAD^^ , HEAD~12 , HEAD^2 |
Branch Reference | It refers to the last commit of that branch | master^^^ , bugFix~1 , feature-branch^1 |
Commit Hash | The SHA-1 code that is unique to each commit | 3b49920effa455cbafe8f2d4344e27b9cda09671 |
This method is used to uniquely identify a commit. 7 characters are enough for identification.
3b49920effa455cbafe8f2d4344e27b9cda09671 # Full Commit Hash
3b49920 # Preferred length of Commit Hash
3b4 # Not preferred but may work to uniquely identify
The total number of ^
specifies the total number of commits behind.
HEAD^^^ # 3 commits behind HEAD
bugfix^ # 1 commit behind bugfix branch's last commit
master^^^^^ # 5 commits behind master branch's last commit.
The ~
followed by a number, the number specifies total commits behind.
HEAD~3 # 3 commits behind HEAD
bugfix~ # 1 commit behind bugfix branch's last commit
master~5 # 5 commits behind master branch's last commit.
In case a commit has multiple parents then the number represents the parent.
HEAD^2 # 1 commit behind but 2nd parent
bugfix^^^1 # 3 commit behind branch bugfix's last commit but 1st parent
master^^2 # 2 commits behind master branch's last commit but 2nd parent
It may contain ~
, any number of ^
or a number
HEAD~1^2 # 1 commit behind, 1 more commit behind and 2nd parent
bugfix^3~5^1 # 1 commit behind, 3rd parent, five commit behind, 1st parent
master~1^2~1 # 1 commit behind, 2nd parent, then one commit behind
- For difftool replace
diff
todifftool
. - Difftools like p4merge shows left and right changes, instead of previous or newer.
To see differences b/w Modified (red) to Staged (green)
git diff
To see differences b/w Modified (red) to Committed
git diff HEAD
To see differences b/w Staged (green) to Committed
git diff --staged HEAD
To see differences in one file only
git diff -- {file-name}
To see the difference b/w two commits
git diff {new-commit-hash} {old-commit-hash}
To see the difference b/w two commits using p4merge
git difftool {left-side-commit-hash} {right-side-commit-hash}
To see the difference b/w last and second last commit
git diff HEAD HEAD^
To see the difference b/w two local branches
git diff {working-branch} {branch-with changes}
To see the difference b/w local and remote master
branch
git diff master origin/master
Unstage a Staged File
git reset HEAD {staged-file-name}
Remove modifications of Unstaged File
git checkout -- {unstaged-file-name}
- Use
git mv
overmv
, this allowsgit
to see the changes easily. mv
can be used for moving or renaming.
Renaming a file
git mv {old-file-name} {new-file-name}
Renaming a file using bash and committing
mv {old-file-name} {new-file-name}
git commit -A
Reversing the Rename operation
git mv {new-file-name} {old-file-name}
Tell git that you've renamed a file using explorer
git add -u
By doing so, git understands that file has been renamed instead of deleted and created.
Move a file to one level down
git mv {file-name} {folder-name}
Move a file to one level up
git mv {file-name} ..
Deleting an untracked file
git rm
will fail because git can't delete a file that it isn't tracking.
rm {untracked-file-name}
Reversing the staged delete operation
git reset HEAD {staged-deleted-file}
Reversing the unstaged delete operation
git checkout -- {unstaged-deleted-file}
Staging changes after deleting through bash
git add -A
This command adds and updates any change to the working directory.
Basic Logging
git log
Note: git log -5
will limit to 5 commits.
Beautiful Logging
git log --oneline --graph --decorate --all
Logging Date Wise
git log --since="3 days ago"
Following all the changes to one file-name
git log --follow -- {name-of-the-file}
Show all details of a particular commit
git show {commit-hash}
This command describes where you are relative to the closest tag.
git describe {ref}
Where {ref}
is anything git can resolve into a commit.
If not specified, git just uses where you're checked out right now (HEAD).
The output of the command looks like
{tag}_{numCommits}_g{hash}
Element | Meaning |
---|---|
tag | Closest ancestor tag in history |
numCommits | Number of commits away that tag is |
hash | Hash of the commit used as reference |
Generalized Command for Alias
git config --global alias.{new-command-name} "{previous-command}"
A Useful Example for Alias
git config --global alias.history "log --all --graph --decorate --oneline"
Git Ignore (inside a project)
code .gitignore
The accepted formats for git ignore are
MyFile.ext
*.ext
my-folder/
- Stash saves the uncommitted working state as a temporary commit.
- These changes can be recovered accordingly.
- The stashes are stored in form of a stack.
- While on a branch which has uncommitted changes.
- Stash only stashes the tracked files.
git stash
Stash untracked files also
- Here
-u
is an alias of--include-untracked
.
git stash -u
Naming a Stash
- You can save the stash with a stash message.
- It is similar to a commit message.
git stash save "{stash-message}"
git stash list
- This command makes stashed changes appear again, ready to be further modified and committed.
- After running this command you can make new modifications if necessary and then commit.
git stash apply {stash-code}
Remove Temporary Stash Commits
git stash drop {stash-code}
Remove all Temporary Stash Commits
git stash clear
Note: If you have a single stash then you don't need to provide a stash-code.
- This command performs
apply
anddrop
in the same order. - Thus, applying the stash and deleting it.
git stash pop
- Perform
git stash list
to see all the stashes. - Curly braces are used in this command.
git stash show stash@{<num>}
- The changes of the stash is migrated to a new branch.
git stash branch {new-branch-name}
Uses of Tags:
- Add identification to a commit.
- Mark major milestones like a version number. For Example,
v-1.0
- Used as a Release on GitHub.
Type | Operation | Command |
---|---|---|
Lightweight | Adds tag name beside a commit | git tag {name-of-tag} |
Annotated | It also contains a message | git tag -a {name-of-tag} |
Add a Lightweight Tag
git tag {name-of-tag}
Add a Lightweight Tag to a particular commit
git tag {name-of-tag} {commit-hash}
Add an Annotated Tag
- This command opens a text editor to add a message.
git tag -a {name-of-annotated-tag}
Add an Annotated Tag with a message through the command line
git tag -a {name-of-annotated-tag} -m "{tag-message}"
Add an Annotated Tag to a particular commit
git tag -a {name-of-annotated-tag} {commit-hash}
- The annotated tag can be migrated to a particular commit.
git tag -a {name-of-annotated-tag} -f {commit-hash}
git tag --list
- It shows the details of the commit to which the particular tag points.
git show {name-of-tag}
Remove a tag locally
git tag --delete {name-of-tag}
Remove a tag from remote
- You are pushing nothing to the destination tag, hereby removing it from the remote.
- The tag will be removed from the remote but will remain in the local repository.
git push {remote} :{tag-name}
To push a single tag to remote
- If an unpublished commit is included in the tag, then this command will also push the commit.
git push {remote} {name-of-tag}
Push all the tags
git push {remote} {branch} --tags
Note: The command git push {remote} {master}
won't automatically push the tags. Thus --tags
flag is necessary.
- It provides the history of all the git operations that had been executed.
- The topmost row provides the latest git operation performed.
- It only saves the history of the last 60 days.
git reflog
- Rebase adds the commits from other branches into the current branch and the current branch's commits on top of it.
- The commits of the currently active branch will appear on top.
- The other branch's commits will be added below.
To rebase a different branch into the current branch
git rebase {other-branch-name}
To rebase one branch into another
git rebase {branch-to-appear-below} {branch-to-appear-above}
Note: After rebasing you'll be checked out to the above branch.
- You are working on a feature using branch
myfeature
. - A new commit appeared on the
master
branch. - You want to add this new commit to your
myfeature
branch. - You want your branch commits on top of the
master
branch's new commit.
Either use this command, if you're checked out to myfeature
branch
git rebase master
Or you can use this command, you'll be checked out to myfeature
after that
git rebase master myfeature
- Rebase when branches diverge due to fetching.
If you receive a message after git fetch
, that
Your branch and 'origin/master' have diverged,
and have x and y different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
Then rebase must be done using this command.
git pull --rebase origin master
Note: Its pulling the commits of origin/master
and will put them on top of your local branch's commits.
git rebase --abort
git rebase {conflicting-branch}
Now, the conflicts will appear.
Then solve the rebase similar to the merge conflicts.
git mergetool
After applying your desired changes.
git add .
git rebase --continue
- An interactive form of rebase in which you can edit previous commits.
- It is used for rewriting history.
git rebase -i {ref}
- The reference commit acts as an anchor.
- Provide the reference to that commit which you don't want to get touched.
- The commits on top of it becomes open for alteration.
- A text file will list all the commits in the inverted order of
git log
. - It appears inverted because this text file is a script and runs from top to bottom, thus the oldest commit appears on top.
- From here various operations can be performed on the commits.
Name | Acronym | Action |
---|---|---|
pick |
p |
Include this commit for rebasing |
drop |
d |
Remove this commit for rebasing |
reword |
r |
Change the commit message |
edit |
e |
Stop at this commit for amending |
squash |
s |
Combine this commit into previous commit |
- Use
reword
before the commits in the text file, after that save and close it.
Let's consider an example
The text-editor opens up displaying the following lines
pick f7f3f6d Commit 1
reword 310154e Commit 2
reword a5f4a0d Commit 3
- New text editor will open for every commit that is asked for
reword
. - Now edit the old name to a new one, after that save and close it one by one.
- For fixing very small changes in previous commits,
edit
is used. - Inside the text editor, add
edit
before the commit in which you want to include your small changes.
Let's consider an example
The text-editor opens up displaying the following lines
pick f7f3f6d Commit 1
edit 310154e Commit 2
pick a5f4a0d Commit 3
- The rebase will pause at that commit, now you can make your changes and amend them using this command.
git commit --amend
- It can also be used for renaming commit message through
git commit --amend -m "{new-commit-message}"
. - After editing you can resume the rebase using this command.
git rebase --continue
- The reordering can be performed by reordering the lines of an individual commit in the text editor.
Let's consider an example
The text-editor opens up displaying the following lines
pick f7f3f6d Commit 1
pick 310154e Commit 2
pick a5f4a0d Commit 3
The changes that you make
pick a5f4a0d Commit 3
pick f7f3f6d Commit 1
- If the commit line won't be included, it will be dropped.
- After saving the file, the rebase will start recreating this new commits sequence.
- The conflicts may appear and can be resolved as described above.
- Combining multiple commits or squashing them into one commit.
- The newer commits are squashed into the oldest commit, inside the text editor the oldest commit is listed on top.
- Use
pick
for the top commit which will be used as the face of other commits. - Put
squash
beside all the subsequent commits that you want to combine.
Let's consider an example
The text-editor opens up displaying the following lines
pick f7f3f6d Commit 1
squash 310154e Commit 2
squash a5f4a0d Commit 3
- After that save and close it.
- A new text editor will open which will contain all the commit messages that will be squashed into one.
- The heading will contain the commit message of the oldest commit.
- You can insert a new heading to provide a different name to this commit, if not provided the oldest commit name will be used.
- Squash commits locally with
git rebase -i origin/master~4 master
- Then force push with
git push origin +master
--force | + |
---|---|
It may overwrite refs other than the current branch. | To force a push to only one branch, use a + in front of the refspec to push |
It includes local refs that are even strictly behind their remote counterpart. | It only force pushes to the selected branch. |
- Splitting a commit undoes a commit and then partially stages and commits as many times as commits you want to end up with.
Let's consider an example
The text-editor opens up displaying the following lines
pick f7f3f6d Commit before
edit 310154e Commit middle
pick a5f4a0d Commit after
The rebasing will have paused on the middle commit. Now perform series of commands to break it into multiple commits.
git reset HEAD^ # Soft reset HEAD, allowing you to open the commit's contents
git add file1.ext # Add file(s) for the first part of the commit
git commit -m 'middle part one' # A new commit for the first part of the commit
git add file2.ext # Add file(s) for the second part of the commit
git commit -m 'middle part two' # A new commit for the second part of the commit
git rebase --continue # Resume rebase
The logs of the last four commits.
1c002dd Commit after
9b29157 Commit middle part two
35cfb2b Commit middle part one
f3cc40e Commit before
- The
SHA-1
of all the rebased commits will get changed.
- It resets the changes to the selected commit.
- By default, the last commit is used as {ref} if none provided.
- Both
HEAD
and branch reference moves to a different commit.
It simply makes all committed changes as uncommitted and sometimes results into two branches:
- Main Branch has a working directory same as before reset but as uncommitted changes.
- The other unnamed branch contains all the commits that won't be the part anymore.
git reset {ref}
For Example, to reset the last commit use git reset HEAD^
.
It resets to the particular commit and overwrites all changes in the working directory.
git reset --hard {ref}
State | Soft Reset | Hard Reset |
---|---|---|
Staging Area | Resets to Unstaged | All changes are removed |
Working Directory | No changes will be removed | All changes are removed |
You can resolve it through two methods:
Method 1:
- See logs using
git log --all --oneline
. - Choose the commit and copy the commit hash.
- Perform
git reset {commit-hash}
.
Method 2:
- See previous git operations using
git reflog
. - Select the state from where everything start going wrong.
- Copy the desired commit hash and use
git reset {commit-hash}
or copy the head state and performgit reset HEAD@{<num>}
- Only Moves the
HEAD
to a different commit and not the branch reference. - It results in the detached
HEAD
, which meansHEAD
is detached from the branch reference. - You can make a new branch by using
git branch {branch-name}
. Now HEAD won't be detached anymore. git checkout
is about updating the working tree (to the index or the specified tree).
git checkout {commit-hash}
Why is it called HEAD
detached even though we can see HEAD
pointing to a commit similar to reset
?
HEAD
is like a shadow that follows you everywhere.- What it means by detach is that the
HEAD
is detached from the branch reference. - Unlike
reset
,checkout
doesn't updates the branch reference.
You can create a new branch from the newly checked out commit
git switch -c {new-branch-name}
You can undo the operation using git switch -
or update the branch reference using git checkout {branch-name}
.
- There is a very good explanation on stackoverflow.
- The
git reset {commit-hash}
moves theHEAD
as well as the branch reference to a particular commit. - All the changes of commits on top of the current commit are reflected as the uncommitted changes.
- To revert it, we can find the correct
HEAD
state and reset it usinggit reset HEAD@{<num>}
. - It is used to go back in time to the point the bug carried on.
- The
git checkout {commit-hash}
only moves theHEAD
and thus results in a detachedHEAD
from the branch reference. - It doesn't results in uncommitted changes.
- To revert it we only need to update the
HEAD
to branch reference, we can usegit checkout {branch-name}
. - It is used to create a new branch.
- It simply creates a new commit that is the opposite of an existing commit.
- It leaves the files in the same state as if the commit that has been reverted never existed.
- The new commits can be pushed to
remote
easily thus reverting commits over there also. - In
reset
there isn't a new commit, it simply resets theHEAD
and branch reference to a particular commit.
To revert the last commit on the branch
git revert HEAD
To revert a specific commit
git revert {bad-commit-hash}
To revert multiple commits
git revert {bad-commit-hash1} {bad-commit-hash2}...{bad-commit-hash-n}
Note: Every bad commit will have a new revert commit and its message.
To revert a commit and provide the message inside the command line
git revert --no-commit {bad-commit-hash}
git commit -m "{message}"
- It is used to merge any number of commits in the working tree into the current branch,
- It is similar to picking commits like a cherry from a table.
Cherry-pick only one Commit
git cherry-pick {commit-hash}
Cherry-pick multiple Commits
git cherry-pick {commit-hash-1} {commit-hash-1} ...{commit-hash-3}
Merging | Rebasing |
---|---|
The remote and local branch gives birth to a new commit. | The local commits appear on top of the commits of the remote branch. |
In Merging, the commits have two parents local and remote. | Rebasing makes the remote branch as the parent and local branch as the orphan parent. |
It prevents the confusion of which commit was created first. | It may create confusion that which commit was created first due to the rewritten history. |
The Graphline is preserved. | The Graphline changes. |
The tree becomes non-linear. | The tree stays linear. |
It is preferred when you want to preserve complex Graphline. | It is preferred when you want a clean linear Graphline. |
- You can make any arbitrary local branch track any remote branch.
- For example, you can make a branch named
foo
trackorigin/master
. git pull
will pull changes formremote/branch
git push
will push new commits on this branch toremote/branch
Checkout to a new branch specifying the reference to a remote branch
git checkout -b {totally-not-master} remote/branch
Specify remote reference to the current branch
git branch -u remote/branch
Specify remote reference to an old branch
git branch -u remote/branch {totally-not-master}
Note: Here -u
means upstream.
Pushing commits without specifying anything
- It pushes the code according to it's remote reference.
- Default remote is set to
origin
.
git push
Pushing commits specifying both remote and branch
git push {remote} {branch}
An example
git push origin master
- Go to the local
master
branch, grab all the commits, and then go to the branch namedmaster
onorigin
. - Place whatever commits are missing on that branch and then tell me when you're done.
- By specifying master as the "place" argument, we told git where the commits will come from and where the commits will go.
- Since we specified both arguments, it totally ignores where we are checked out!
- You can push commits specifying remote, source and destination
git push {remote} {source}:{destination}
- Here the source is any {ref} like branch reference or commit hash etc. of the local branch.
- Here destination is the remote branch.
- An example,
git push origin feature-branch^:master
. - If the destination branch is not present on the remote, git will create a new remote branch.
- Pushing nothing to remote, means deleting it.
git push origin :{destination}
- For example, the command
git push origin :bugFix
deletes the branch bugFix from the origin and it makes sense.
Fetching commits without specifying anything
- If git fetch receives no arguments, it just downloads all the commits from the remote onto all the remote branches.
git fetch
Fetching commits specifying both remote and branch
- Downloads all the commits from the remote branch to the local
remote/branch
.
git fetch {remote} {branch}
Note: The commits won't be included to the local branch
but to the local remote/branch
. To merge it to the local branch
, use git pull
.
- You can fetch commits specifying remote, source and destination.
git fetch {remote} {source}:{destination}
- Here the source is any {ref} like branch reference or commit hash etc. of the remote branch.
- Here destination is the local branch.
- An example,
git push origin master~1:feature-branch
. - If the destination branch is not present on the remote, git will create a new local branch.
- Fetching nothing from remote means creating a new local branch.
git fetch origin :{destination}
For example, the command git fetch origin :bugFix
creates the branch bugFix
locally.
pull
is simply two commands in one,fetch
andmerge
.
Pulling commits specifying both remote and branch
- It pulls commits from remote's
branch
and will mergeremote/branch
to checked out branch.
git pull {remote} {branch}
The above command can be written as
git fetch {remote} {branch}
git merge {branch}
- You can pull commits specifying remote, source and destination.
- It is similar to fetching commits by providing all the arguments and then merging
remote/destination
to checked out branch.
git pull {remote} {source}:{destination}
The above command can be written as
git fetch {remote} {source}:{destination}
git merge {destination}
- Here the source is any {ref} like branch reference or commit hash etc. of the remote branch.
- Here destination is the local branch.
- An example,
git pull origin master:feature-branch
. - If the destination branch is not present on the remote, git will create a new local branch.