Git Commands you Should Know if you Plan to Work with Git.
Tags: git, github, versoncontrol, devops
Published: 2023-01-10 14:46:03

Git is a distributed version control system that is free and open source. It is the most widely used version control system in development. 

Version control is a way in which programmers track their code changes. This is done by saving the initial version in git and when an update is made it is saved to git again and again and again, throughout all the code changes within the lifecycle of that project. This is useful to be able to see all the changes that have been made to that code over time. It makes it possible to track down bugs or go back to a previous version if need be.

## Features of Git
:star: Distributed version control
:star: Contributes work between multiple developers.
:star: Keeps track of who made what changes and when.
:star: You can use it to revert to any time so long as it was committed.
:star: Made up of local and remote repos.
:star: Keeps track of code history
:star: Takes "snapshots" of your files.
:star: You can visit any snapshot at any time
:star: You can stage files before committing.
:star: You can create branches.

## Basic and Most Common Git Commands you will use.

:zap: **git init:** This will initialize a git repository, when you go into a folder via your command line or terminal and you run this command, it will create a .git folder in that project and it is hidden by default. You almost never need to go into that folder. Once you initialize that folder as a repository you can then start to run other commands.

#### _To setup your environment with your credentials_

:zap: **git config --global user.name  'your name'**
:zap: **git config --global user.email 'your email'**

:zap: **git config --global --list:**: This lists are your user configurations (username, email etc)

:zap: **git config --global edit**: To open a text editor and edit your global settings

:zap: **git add <_file_>**: This will add the file that you specify to the staging area or the index and then be ready for commit. You can run this command as many times as you need to before committing and it will just keep the files in that staging area.

:zap: **git add *.html** : This add all the files with the .html (or whichever specified) extension to the staging area.

:zap: **git add .** : This will add all the files in the directory (project) to the staging area.

_**To specify a file that won't be committed even if we do git add . we use the .gitignore file.**_

**:zap: create the .gitignore file then write the name of the file(s) you want to ignore in the .gitignore file.**

**:boom: [gitignore.io](https://www.toptal.com/developers/gitignore/) is a useful site to get ideas of files to add to your .gitignore file.**

:zap: **git status**: This command will enable you see what you have in the staging area that is ready for commit. This command will display the differences between the working tree and the staging area or the index.

:zap: **git commit**: This command will take everything that is in the staging area and put it into the local repo.  It would open your default file editor (or prompt you on the CLI) to enter your commit message. 

:zap: **git commit -m "<_your comment_>"**: Use the -m flag along with your commit message with the git commit command to include your commit message all in one step.

:zap: **git commit -am "<_commit message_>"**: This command adds the changes you made to the file and commits it with one command. Note that this only works with staged files not untracked files.

#### More on Commit

A commit in a git repository records a snapshot of all the (tracked) files in your directory. It's like a giant copy and paste, but even better!

Git wants to keep commits as lightweight as possible though, so it doesn't just blindly copy the entire directory every time you commit. It can (when possible) compress a commit as a set of changes, or a "delta", from one version of the repository to the next.

Git also maintains a history of which commits were made when. That's why most commits have ancestor commits above them . Maintaining history is great for everyone working on the project!

:boom:

:zap: **git push**: This will take your local repository that you've created and then push it to a remote repository such as GitHub. You will have to add the credentials to that remote repository. You can also create SSH keys with GitHub so that you don't have to add passwords or anything like that. (Scroll to the bottom of this post to see how to create an SSH and use with your GitHub).

:zap: **git pull**: This command helps you to pull the latest changes from your remote repo to your local repo. 

:warning: **NB**: To use the **git push** and **git pull** commands like this, you need to have set your remote repo already and if you read on you will see how to do that.

:zap: **git clone**: This command will copy a remote repository into your current folder

:zap: **git -- version**: To check the version of git installed on your machine.

:zap: **git rm --cached <_file_>**: To remove a file from the staging area 

:zap: **git reset <_filename_>**: This command will undo the staging of the specified file. Running the command without the name of the file will give you the name of the file(s) that will be unstaged after the reset.

:zap: **git branch**: This command will list all the branches in your directory. The branch with an asterisk is the present branch you are on.

:zap: **git branch <_branch name_>**: To add a new branch. Branches in Git are incredibly lightweight as well. They are simply pointers to a specific commit -- nothing more. This is why many Git enthusiasts chant the mantra:

_“branch early, and branch often”_

Because there is no storage / memory overhead with making many branches, it's easier to logically divide up your work than have big beefy branches. A branch essentially says "I want to include the work of this commit and all parent commits."

:zap: **git branch -d <_branch name_>**: To delete the specified branch. Note that branches that have unmerged changes would produced an additional dialogue telling you that you have unmerged changes and offer you a way to force delete it if you want to go ahead without merging that change. This is particularly useful if the attempted delete was a mistake.

:zap: **git checkout <_name of the branch_>**: This command is used to switch to another branch.

:zap: **git checkout -b <_yourbranchname_>**: This command creates a new branch and switches to the branch immediately with one command.

:zap: **git merge <_branch name_>**: This command is used to merge the branch specified with the master branch. 

:zap: **git remote**: This lists your remote repository, if you have any.

:zap: **git remote show origin (or whatever the name of your remote repository is)**: This command shows you details of your specified remote repo.

#### _**To push all your work to a remote repo (eg GitHub) for the first time**_:
:star: Create a repo on GitHub

:star: Copy the command and run them on git bash esp the **git remote add origin <_link to the remote repository_>.**

:star: Next run the **git branch -M main**: The -M is a flag (shortcut) in this command is for --move --force per the docs page on git branch. It renames the branch main (since the default branch name for repositories created using the command line is master, while those created in GitHub [starting in Oct. 2020] have a default name of main) and forces it (allows renaming of the branch even if the new branch name already exists).

:star: Next run the **git push -u origin main**: The -u flag is used to set an upstream, which is equivalent to '-set-upstream.', meaning this is where you want to push it by default and so going forward you can just run the git push/pull command and it will automatically push to or pull from your main branch in your remote repo.

If you make any new changes to the local repository and what to push it to the remote repository, use the below command
- **git push**

- **git pull**: To download new changes from the remote repo (GitHub) to your local repo on your system.

:zap: **git fetch**: This command pulls down the metadata of the remote repo, which describes all the version history and branch information but it does not actually pull down the newest code changes. It allows you check if there are any changes without actually pulling any changes.

:zap: **git log**: To see your commit history

:zap: **git log --abbrev-commit**: Gives you the abbreviated version of the hashes of your commit history.

:zap: **git diff <_filename_>**: This command will show you what has changed in that file.

:zap: **git diff <_branchname_>..<_branchname_>**: This command shows you the difference between the two branches named.

:zap: **git clean -f**: Will remove all the untracked files 

:zap: **git clean -f --dry-run**: Using this flag shows you what would happen if you run the above command without the **--dry-run** flag. It is safer to use this flag so you know if the resulting action is indeed what you want to happen, to reduce the occurrence of irreversible errors. 

:zap: **git checkout <_filename_>**: This deletes the changes made to a file and restores it to the last commit version.

:zap: **git stash save <_your message_>**: This command is useful for when you have files you are not ready to commit and don't want to delete. This command tells git to save the file without committing it. make sure all your files are currently tracked to use this command.

:zap: **git stash list**: To see what stashes you have. Git uses LIFO (last in first out) queue with stashes.

:zap: **git stash pop**: This command would retrieve the topmost stash (which is the last stash you made and is the zero index stash).

:zap: **git stash pop <_stash name_>**: This command would retrieve the exact stash mentioned in the command.

:zap: **git stash show <_stash name_>**: This shows you what is inside that stash, it is useful for times when you can't remember what you stashed.

:zap: **git stash show -p <_stash name_>**:Adding the **-p** flag to this command displays the content of the files in that stash ie the diff.

:zap: **git cherry-pick <_the hash of the commit you want to copy to this branch_>**: This command allows you to take commits from one branch and pull them over into another branch. You just need the commit hash. 

### Useful: How to Create an SSH key to use with GitHub Instead of a Password.

:star: **ls -la ~/.ssh**: This command can be used to check if you have any SSH keys, if you do it would list them out for you.

:star: **ssh-keygen -t rsa -b 4096 -C "<_your email address_>"** : To generate an SSH key for your GitHub account, after creating this key we need to add it to an agent but first you need to ensure that an agent is running. Use the next command (below) to verify.
-t means type
-b means bits
-C means comment

:star: **eval (ssh-agent -s)**: To verify if an SSH agent is running.

:star: **ssh-add ~/.ssh/id_rsa**: To add the SSH key to the agent.

:star: **ssh -T git@github.com**: To use your SSH for GitHub

:star::star: **Best practice**

When working with a team you shouldn't merge your changes directly to the main branch on your local repository. You should create a pull/merge request in your remote repo.

Using the below command (the command below assumes your remote repository is called origin).

:zap: **git push origin <_branchname_>**: After this is pushed to your remote repo, you can follow the link provided as output of the command to create a pull/merge request on GitHub/GitLab or whatever source control base you use. If you don't follow that link, you can go to GitHub directly and create a pull/merge request there.

:boom::boom:

There you have it guys, the most common commands you will use in the course of your using git. Share with your network if you found this useful.