# Quick reference of useful Git commands

## Configuration Management

| Commands                                                                  | Description                                                                                                                                                                                                                                                                                                                                                              |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `git config --list –show-origin`                                          | To view all of your Git settings and location of config file the parameters are coming from.                                                                                                                                                                                                                                                                             |
| `git config --show-origin <parameter>`                                    | Query the config setting for a parameter.                                                                                                                                                                                                                                                                                                                                |
| `git config --global <parameter> <value>`                                 | Eg: **git config --global user.name "sample name” (quotes for space)** and **git config --global user.email sample@example.com**, to set your user name and email address respectively. If you want to override this with different name or email address for specific projects, you can run the command **without the --global** option when you’re in that repository. |
| `git config --global core.editor <pathtoeditor>`                          | Eg: **git config --global core.editor “c:/program files/notepad++/notepad++.exe”** To configure the default text editor that will be used when git needs you to type in a message, as in commit message editor like `emacs`, `vim` etc.                                                                                                                                  |
| `git config --list`                                                       | To list your configuration settings.                                                                                                                                                                                                                                                                                                                                     |
| `git help <verb>`, `git <verb> --help`, `man git-<verb>`, `git <verb> -h` | To get the comprehensive manual page (manpage) help for any of the Git commands verb.                                                                                                                                                                                                                                                                                    |
| `git config --global alias.<alias-name> <original-command>`               | To set up an alias for each command using git config, if you want to run an external command, rather than a Git sub-command. In that case, you start the command with a **!** character, eg: **git config --global alias.visual '!gitk'**                                                                                                                                |
| `git config --global credential.helper cache`                             | To not type password every time we make changes in remote repository. This command sets up a credential cache which makes it possible to keep the credential in memory for a few minutes.                                                                                                                                                                                |

## Local Repository Management

| Commands                                          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `git init`                                        | Initializing a repository in an existing directory, which you want to track. This creates a new sub-directory named **.git** that contains all of your necessary repository files — a git repository skeleton.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `git clone <url> <directory_name>`                | eg: **git clone https://github.com/libgit2/libgit2**. To get a copy of an existing Git repository — for example, a project you’d like to contribute to, `<directory_name>` is optional. If included it will clone the repository from the url to one’s local machine with `<directory_name>` as the folder name.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `git clone <url> -o <remote-name>`                | This creates a Git clone of a remote repository with remote repo’s name as `<remote-name>`. By default `<remote-name>` is origin.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `git status`                                      | To determine which files are in which state, new files that aren’t tracked have a **??** next to them. New files that have been added to the staging area have an **A** next to them. Modified files have an **M** and so on. There are two columns to the output — the left-hand column indicates the status of the staging area and the right-hand column indicates the status of the working tree. Eg: **MM**, modified and staged and then again modified in the working directory.                                                                                                                                                                                                                                                                                                               |
| `git status -s`                                   | Short-format output for above command.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `git add <path_to_filename/path_to_directory>`    | To begin tracking a new file or directory mentioned in `<path_to_filename/path_to_directory>` or to stage an already tracked file which has been modified.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `git add -u`                                      | To add only modified/deleted files from the existing repository.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `git diff`                                        | To compare 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 --staged`                               | To see what you’ve staged that will go into your next commit.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `git commit`                                      | To commit your changes, this basically opens up configured/system defined editor which helps you to enter a meaningful commit message.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `git commit -v`, `git commit -m`, `git commit -a` | **-v option** gives you a more explicit reminder of what has been modified. **-m option** lets you make an inline commit message, **-a option** lets git automatically stage every file that is already tracked before doing the commit, letting you skip the git add part. Every time you perform a commit, you’re recording a snapshot of your project that you can revert to or compare to later.                                                                                                                                                                                                                                                                                                                                                                                                  |
| `git commit --amend`                              | If you want to redo a recently done commit, make the additional changes you forgot, stage them, and commit again using the **--amend** option. This command takes your staging area and uses it for the commit. If you’ve made no changes since your last commit (for instance, you run this command immediately after your previous commit) then your snapshot will look exactly the same, and all you’ll change is your commit message. **It’s important to understand that when you’re amending your last commit, you’re not so much fixing it as replacing it entirely with a new, improved commit that pushes the old commit out of the way and puts the new commit in its place. Effectively, it’s as if the previous commit never happened, and it won’t show up in your repository history.** |
| `git rm <filename>`                               | To remove it from your tracked files (more accurately, remove it from your staging area).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `git rm --cached <filename>`                      | To keep the file on your machine but not have Git track it anymore.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `git mv <from_file> <to_file>`                    | To move the file/directory smartly rather than running following 3 commands, **mv from\_file to\_file**, **git rm from\_file**, **git add to\_file**.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |

## Branch Management

| Commands                                                                                        | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `git branch`                                                                                    | To get a simple listing of your current branches.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `git branch <branch-name>`                                                                      | To create a new branch with `<branch-name>`. Creating a new branch is as quick and simple as writing 41 bytes to a file (40 characters and a newline).                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `git checkout <branch-name>`                                                                    | To switch to an existing branch with `<branch-name>` This moves HEAD to point to the `<branch-name>`. This command does two things. It moves the HEAD pointer to point to `<branch-name>` and reverts the files in your working directory back to the snapshot of `<branch-name>` . It’s important to note that when you switch branches in Git, files in your working directory will change. If you switch to an older branch, your working directory will be reverted to look like it did the last time you committed on that branch. If Git cannot do it cleanly, it will not let you switch at all. |
| `git checkout –b <new-branch-name>`                                                             | To create a new branch and want to switch to that new branch at the same time.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `git merge <branch-name>`                                                                       | Join two or more development histories together. Incorporates changes from the named commits into the current branch.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `git branch -v`                                                                                 | To see the last commit on each branch.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `git branch --merged`                                                                           | To see which branches are already merged into the branch you’re currently on.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `git branch --no-merged`                                                                        | To see all the branches that contain work you haven’t yet merged in. The options described, `--merged` and `--no-merged` will, if not given a commit or branch name as an argument, show you what is, respectively, merged or not merged into your current checked out branch. You can always provide an additional argument to ask about the merge state with respect to some other branch without checking that other branch out first, as in, what is not merged into the master branch?                                                                                                             |
| `git branch -d <branch-name>`                                                                   | To delete branch that has already been merged. Note that, if the branch is not merged with current branch that you are on, this command might fail. To delete the branch forcefully and lose the work which has not been merged **use `-D` option rather than `-d`**.                                                                                                                                                                                                                                                                                                                                   |
| `git push <remote> <branch-name>`                                                               | Git automatically expands the `<branch-name>` out to `refs/heads/<branch-name>:refs/heads/<branch-name>`, which means, _"Take my `<branch-name>` local branch and push it to update the remote’s branch."_                                                                                                                                                                                                                                                                                                                                                                                              |
| `git push origin <local-branch-name-1>:<remote-branch-name-2>`                                  | To push a local branch named `<local-branch-name-1>` into a remote branch that is named differently as in this example `<remote-branch-name-2>` _(i.e. the local-branch is now named differently in remote)_.                                                                                                                                                                                                                                                                                                                                                                                           |
| `git checkout –b <local-branch> <remote-name>/<branch-name>`                                    | If you want your own `<local-branch>` that you can work on, you can base it off your remote-tracking branch. This gives you a local branch that you can work on that starts where `<remote>/<branch-name>` is. The `<local-branch>` doesn’t have to be of same name as remote `<branch-name>`. In that case, the remote `<branch-name>` has different branch name than local branch.                                                                                                                                                                                                                    |
| `git checkout --track <remote>/<branch-name>`                                                   | Same as the above command, but creates branch with same name as remote `<branch-name>`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `git branch –u <remote>/<branch-name>` OR `git branch --set-upstream-to <remote>/<branch-name>` | To change a local branch’s currently tracked remote branch to new remote branch.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `git branch -vv`                                                                                | To see what tracking branches you have set up, option **-vv** means very verbose.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `git push <remote> --delete <remote-branch-name>`                                               | To delete a remote branch.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `git rebase <base-branch>`                                                                      | To rebase a branch on to another branch. Checkout the branch you want to rebase and run the command with the branch on to which you want the checked out branch to be rebased. Then merge on to the base-branch.                                                                                                                                                                                                                                                                                                                                                                                        |
| `git rebase <base-branch> <topic-branch>`                                                       | To rebase `<topic-branch>` on to the `<base-branch>`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `git push origin +otherfeature:newfeature`                                                      | To replace an existing remote branch with new name                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |

## Repository revertion

| Commands                   | Description                                                                                                    |
| -------------------------- | -------------------------------------------------------------------------------------------------------------- |
| git reset                  | Its better to refer [this](https://www.atlassian.com/git/tutorials/undoing-changes/git-reset)                  |
| `git revert <commit-hash>` | A forward-moving undo operation that offers a safe method of undoing changes to a repository's commit history. |

## Repository Commit Logs Analysis

| Commands                                     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `git log -n`                                 | To look back to see what has happened, basically viewing commit history in reverse chronological order. _-n option_, which is optional lets you to limit the number of entries displayed.                                                                                                                                                                                                                                                                      |
| `git log --stat`                             | The `--stat` option prints below each commit entry a list of modified files, how many files were changed, and how many lines in those files were added and removed. It also puts a summary of the information at the end.                                                                                                                                                                                                                                      |
| `git log --pretty=value`                     | This option changes the log output to formats other than the default. Value can be: `oneline` which prints each commit on a single line, the `short`, `full`, and `fuller` options show the output in roughly the same format but with less or more information. `format`, which allows you to specify your own log output format. Eg: **git log --pretty=format: "%h - %an, %ar : %s"** for information on format specifier read **man git log** _(line 750)_ |
| `git log --graph`                            | This option displays an ASCII graph of the branch and merge history beside the log output. Time-limiting options such as `--since` and `--until` and many more options are also available. _(read man page or pro git book for more info.)_                                                                                                                                                                                                                    |
| `git log -S <string>`                        | `-S` option which takes a `<string>` and shows only those commits that changed the number of occurrences of that `<string>`. This option is called as an **pickaxe** option.                                                                                                                                                                                                                                                                                   |
| `git reset HEAD <file_name>`                 | To unstage a `<file_name>` from the staging area.                                                                                                                                                                                                                                                                                                                                                                                                              |
| `git checkout --<file_name>`                 | To revert the file back to what it looked like when you last committed/cloned. This file should not be present in the staging area. If it is, then it has to be unstaged and then this command needs to be run.                                                                                                                                                                                                                                                |
| `git log <branch-name>`                      | To show commit history for a branch with `<branch-name>`, if you are not in the same branch of which you need the history.                                                                                                                                                                                                                                                                                                                                     |
| `git log <branch-name> --all`                | To show all of the branch’s history.                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `git log --oneline --decorate --graph --all` | To print out the history of your commits, showing where your branch pointers are print out the history of your commits, showing where your branch pointers are.                                                                                                                                                                                                                                                                                                |

## Remote Management

| Commands                                                           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `git remote`                                                       | To see the remote servers you have configured, you can run the Git remote command. To see the more verbose output you can use `-v` option with it as in, `git remote -v`                                                                                                                                                                                                                                                                        |
| `git remote add <remote-short-name> <url>`                         | To add a new remote Git repository with a short name. Note that short name only act as another way of representing the `<url>` of the remote repository.                                                                                                                                                                                                                                                                                        |
| `git push <remote-repo> <local-branch>`                            | To push the local repository branch upstream to the remote repository. This 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 pull <remote-repo> <remote-branch>`                           | To pull the data from remote Git repository into your local repository branch, and it also tries to merge them.                                                                                                                                                                                                                                                                                                                                 |
| `git remote show <remote-repo-name>`                               | To see more information about a particular remote repository.                                                                                                                                                                                                                                                                                                                                                                                   |
| `git fetch <remote-short-name>`                                    | To fetch all the information from the remote for which the short-name is used as the url. Please note that no merge is done when this command is run. When cloned this **remote-short-name** is named as **origin** by default.                                                                                                                                                                                                                 |
| `git remote rename <oldname> <newname>`                            | To change a remote’s oldname to new-name.                                                                                                                                                                                                                                                                                                                                                                                                       |
| `git ls-remote <remote-name>` OR `git remote show <remote-name>`   | To get a full list of remote references.                                                                                                                                                                                                                                                                                                                                                                                                        |
| `git remote remove <remote-name>` OR `git remote rm <remote-name>` | To delete a remote along with all remote-tracking branches and configuration settings associated with that remote.                                                                                                                                                                                                                                                                                                                              |
| `git fetch --all`                                                  | To fetch from all the remotes that are being tracked by current repository.                                                                                                                                                                                                                                                                                                                                                                     |

## Tags Management

| Commands                                  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `git tag (with optional -l)`              | Listing the existing tags in repository, `-l` option becomes mandatory once the wildcard is being used.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `git tag -a <tag-name> -m <message>`      | To create a Git annotated tag with tag message.                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `git show <tag-name>`                     | To show the information about `<tag-name>`                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `git tag <tag-name>`                      | To create a Git light-weight tag with `<tag-name>`                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `git tag -a <tag-name> <commit hash>`     | To add tags to commits after you’ve moved past them i.e., already commited                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `git push <remote> <tag-name>`            | To push tags to remote repository. The `git push` command doesn’t transfer tags to remote servers. You will have to explicitly push tags to a shared server after you have created them. This process is called tag sharing.                                                                                                                                                                                                                                                                                    |
| `git push <remote> --tags`                | To push all the tags at once, we can use this option. This will transfer all of your tags to the remote server that are not already there.                                                                                                                                                                                                                                                                                                                                                                      |
| `git tag -d <tag-name>`                   | To delete a tag on your local repository. Note that this does not remove the tag from any remote servers.                                                                                                                                                                                                                                                                                                                                                                                                       |
| `git push <remote> :refs/tags/<tag-name>` | To remove the tag from the remote repository. This command is interpreted as _to read it as the null value before the colon is being pushed to remote tag name, effectively deleting it._                                                                                                                                                                                                                                                                                                                       |
| `git push <remote> --delete <tag-name>`   | Alternative(and more intuitive) way, to delete a remote tag.                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `git checkout <tag-name>`                 | To view the versions of files a tag is pointing to. Note that this makes the repository in detached HEAD state. In “detached HEAD” state, if you make changes and then create a commit, the tag will stay the same, but your new commit won’t belong to any branch and will be unreachable, except by the exact commit hash. Thus, if you need to make changes — say you’re fixing a bug on an older version, for instance — you will generally want to create a branch: `git checkout -b branch-name tag-name` |

## Advanced Operations

| Commands                        | Description                                                                                       |
| ------------------------------- | ------------------------------------------------------------------------------------------------- |
| `git ls-files -s`               | To examine the state of staging index tree. `-s` option here means, staging area.                 |
| `git cat-file -p <commit-hash>` | Pretty print the contents of Git objects based on its type.                                       |
| `git cherry-pick <commit-hash>` | Enables arbitrary Git commits to be picked by reference and appended to the current working HEAD. |

## Git Resources

* Tutorial:
  * [Altassian](https://www.atlassian.com/git)
  * [Cern ppt](https://indico.cern.ch/event/288437/contributions/1642636/attachments/538025/741708/git-best-practices.pdf)
* Official docs
  * [Git scm](https://git-scm.com/docs)
