# Git cheatsheet

Git is one of the version control systems, and it's a prerequisite for development jobs. This post covers most of the git commands I use.

### Configuration

* Set user configuration for every project if you use multiple accounts
    
    ```bash
    git config user.name "<USERNAME>"
    git config user.email "<EMAIL_ADDRESS>"
    ```
    
* Use the current branch for push commands
    
    ```bash
    git config --global push.default current
    ```
    

#### SSH keys setup

* Generate separate SSH keys for Github and Bitbucket with the following command, type the filename path and passphrase.
    
    ```bash
    ssh-keygen
    ```
    
* Add generated public keys to [Github](https://github.com/settings/ssh/new) and [Bitbucket](https://bitbucket.org/account/settings/ssh-keys/)
    
* Run the following commands to activate SSH keys
    
    ```bash
    eval `ssh-agent -s`
    ssh-add ~/.ssh/id_rsa_github
    ssh-add ~/.ssh/id_rsa_bitbucket
    ```
    

### Basic commands

* The repository setup
    
    * Initialize a git repository
        
        ```bash
        git init
        ```
        
    * Clone an existing repository
        
        ```bash
        # git clone <REPOSITORY_URL>
        git clone git@github.com:zsevic/pwa-starter.git
        ```
        
    * Add the remote repository
        
        ```bash
        # git remote add <REMOTE_NAME> <REPOSITORY_URL>
        git remote add origin git@github.com:zsevic/pwa-starter.git
        git remote add upstream git@github.com:zsevic/pwa-starter.git
        ```
        
    * Update the URL for the remote repository
        
        ```bash
        # git remote set-url <REMOTE_NAME> <REPOSITORY_URL>
        git remote set-url origin git@github.com:zsevic/pwa-starter.git
        ```
        
    * Get a list of configured remote connections
        
        ```bash
        git remote -v
        ```
        
* Branches
    
    * Get a list of the branches
        
        ```bash
        git branch
        ```
        
    * Create and switch to the new branch
        
        ```bash
        git checkout -b new-branch
        ```
        
    * Checkout to a specific commit and create a new branch out of it
        
        ```bash
        git log # find a hash from a specific commit
        git checkout <COMMIT_HASH>
        git switch -c <NEW_BRANCH_NAME>
        ```
        
    * Switch to another branch
        
        ```bash
        git checkout existing-branch
        ```
        
    * Rename the current branch
        
        ```bash
        git branch -m <NEW_BRANCH_NAME>
        ```
        
    * Delete branch
        
        ```bash
        git branch -D other-existing-branch
        ```
        
    * Fetch all the remote branches
        
        ```bash
        git fetch --all
        ```
        
* Get the status of the local changes
    
    ```bash
    git status
    ```
    
* Add new changes
    
    ```bash
    git add some-file.js
    git add .
    ```
    
* Commits
    
    * Commit the changes
        
        ```bash
        git commit -m "Commit message"
        ```
        
    * Empty commit without any files
        
        ```bash
        git commit --allow-empty -m "Trigger CI pipeline"
        ```
        
    * Commit the changes and skip running git hooks
        
        ```bash
        git commit -m "Commit message" --no-verify
        ```
        
    * Update the latest commit message and add new changes to the latest commit
        
        ```bash
        git commit -m "Commit message" --amend
        ```
        
* Push the changes to the remote repository
    
    * Push the changes to the current branch when the current branch is configured as the default one
        
        ```bash
        git push
        ```
        
    * Push the changes to the remote branch
        
        ```bash
        # git push <REMOTE_NAME> <BRANCH_NAME>
        git push origin master
        ```
        
    * Force push the changes to the feature branch
        
        ```bash
        # git push <REMOTE_NAME> <FEATURE_BRANCH_NAME>
        git push origin feature-branch -f
        ```
        
* Fetch and merge remote changes to the local branch
    
    ```bash
    # git pull <REMOTE_NAME> <BRANCH_NAME>
    git pull origin master
    ```
    
* Remove (unstage) the changes from the local stage
    
    ```bash
    git reset some-file.js
    git reset
    ```
    
* Differences between commits
    
    * Get a difference compared to the latest commit
        
        ```bash
        git diff some-file.js
        git diff
        ```
        
    * Get a difference between the last two commits
        
        ```bash
        git diff HEAD^ HEAD
        ```
        
* Revert the file changes
    
    ```bash
    git checkout -- some-file.js
    ```
    
* Merge the specified branch into the current one
    
    ```bash
    git merge <BRANCH_NAME>
    ```
    
* Revert specific commit. The following command creates a new commit
    
    ```bash
    git revert <COMMIT_HASH>
    ```
    

### Miscellaneous

* Resets
    
    * Soft reset (commits are removed, but changes from the removed commits are staged)
        
        ```bash
        # git reset --soft HEAD~{NUMBER_OF_COMMITS_TO_SOFT_REMOVE}
        git reset --soft HEAD~2
        ```
        
    * Hard reset (both commits and changes are removed)
        
        ```bash
        # git reset --hard HEAD~{NUMBER_OF_COMMITS_TO_HARD_REMOVE}
        git reset --hard HEAD~1 # equal as git reset --hard HEAD^
        ```
        
    * Get the latest remote changes when pulling doesn't work
        
        ```bash
        git reset --hard origin/<BRANCH_NAME>
        ```
        
* Stashing
    
    ```bash
    git add .
    git stash save <STASH_NAME>
    git stash list
    git stash apply --index 0
    ```
    
* Tags
    
    * Remove the following tag locally
        
        ```bash
        git tag -d v0.13.29
        ```
        
* Find removed commits
    
    ```bash
    git reflog
    git checkout <COMMIT_HASH>
    ```
    
* Remove the initial commit
    
    ```bash
    git update-ref -d HEAD
    ```
    
* Patching
    
    * Create a patch from the latest commits
        
        ```bash
        # git format-patch -{NUMBER_OF_COMMITS}
        git format-patch -1
        ```
        
    * Apply the patches
        
        ```bash
        git apply 0001-latest-commit.patch
        ```
        
* Git submodules
    
    * Add git submodule
        
        ```bash
        # git submodule add -- <REPOSITORY_URL> <DIRECTORY_PATH>
        git submodule add -- git@github.com:zsevic/pwa-starter.git template
        ```
        
    * Retrieve the latest changes for the git submodule
        
        ```bash
        # git submodule update --remote <DIRECTORY_PATH>
        git submodule update --remote template
        ```
