The 13 Git Commands I Use Daily
As a Software Engineer one of the tools I interact with on a daily basis is Git. Git is a Version Control System(VCS). A VCS is simply put a software that tracks changes in developers code making it possible to move back and forth on these changes. There are a number of VCS out in the wild, but the most popular among developers is Git.
Everyday at work I find myself using the following Git commands to get my work done. I’m sure you’re already using these commands as well, if not then you can count it your lucky day. You’re welcome to the 13 Git Commands I Use Daily.
#1 Initializing a new repository
I use this command to create a new Git repository. A repository could be for a project or a python package I’m working. A project could typically be a backend project I’m a working on in Flask or Fast API; and if I’m developing something frontend related, maybe VueJS or Angular
Before you initialize a new repository, first change directory into the project folder and run the command below
git init
A git init
will initialize your project folder as a Git repository by generating a hidden folder .git
inside your project folder. This .git
folder contains all essentials needed for version controlling your new project.
#2 Viewing the status of your repository
I use the command below view the states of my project files. Files could be in one of four states.
- Untracked State: This state includes all files that are not yet being tracked and managed by my VCS, i.e Git.
- Modified State: This state includes all files that are already being tracked and managed by Git but have been changed, with such changes yet to be introduced or committed to Git.
- Staged State: This state includes modified files that are being prepared to be introduced to Git with a pending commit.
- Committed State: This state includes staged files that have been committed or already introduced to Git and can be retrieved later if the need arises.
git status
#3 Staging and committing files
As I stated in command #2, my project files could be in one of four states. All my untracked and modified files need to be first staged and later committed into Git versions control. These two actions, staging and committing is achieved with the following
Staging Untracked and Modified Files
# Staging all the files in a repo, both untracked and modified files
git add <project-name>
>> git add . # period here represents the project-name since we've already changed directory into our project-name
# Staging a specific untracked or modified file
git add <filename>
>> git add index.py
Committing Staged Files
# This opens an editor to enter the commit message
git commit
# Commit staged changes without opening an editor
git commit -m"<commit-message>"
>> git commit -m"this is a commit message"
#4 Cloning repositories
I tend to visit the Explore and Trending pages of Github quite often to keep tabs on interesting projects other developers are working on. This is one way I discover concepts and ideas I may not be aware of firsthand.
I sometimes also receive requests from some of my developer friends and associates to review and critique their projects and libraries.
Either of these situations require me to have a copy the project or library locally to conveniently review, and contribute changes and extensions to their project or library. And for this I use git clone
I use git clone
to create a copy of the original project which mostly would be hosted on Github, Gitlab or some other cloud code hosting platform.
# General repository cloning
git clone <repository-url>
>> git clone https://github.com/ofelix03/my-daily-git-commands.git
#5 Viewing commit history
I sometimes find myself need to know the changes that I have committed for a project I’ve been working on. This is sometimes to understand how my project has advanced or in the case where I have made blunder by committing changes that rather breaks my code, I want to know which previous committed changes I can revert to as a way of undoing the current committed changes that is breaking my code. For such scenarios, I turn to git log
.
# Viewing all my commit history for a project.
git log
# Viewing the commit history from a specific author or committer
git log --author <author-name>
>> git log --author "Felix Otoo"
# Viewing the commit histories having a certain text
git log --grep <search-string>
>> git log --grep first-commit
# Viewing the revision history since a specified date
git log --since <date-string>
>> git log --since 2020-10-10
# Viewing the revision history after a specified date
git log --after <date-string>
>> git log --after 2020-10-10
# Viewing revision history between a date range
git log --since <date-string> --until <date-string>
>> git log --since 2020-10-10 --until 2020-11-10
#6 Creating, listing, renaming & deleting branches
Branching makes it possible for me to explore other ways to write a functionality without messing with the main code that I have already implemented or already implementing. It allows me to move development from one branch (which if you have not yet created any branches, your default is already master
or main
for any new repository in 2020 and beyond).
The reason why Github renamed their default repository branch from master
to main
was primarily to stand in solidarity with black folks and offer a sense of belonging to black folks who may not feel comfortable around the word master, due to it long-standing with black slavery. Also, Una Kravets initially made a call to developers on Twitter to consider renaming their master
branch to main
giving among other reasons “it could help black developers from feeling more isolated in the tech community”
# Creating a new branch
git branch <new-branch-name>
>> git branch fix-division-by-zero-bug2
>> git branch fix-property-call-on-undefined-object2
# Listing all branches
git branch
>> git branch
# Listing remote branches
git branch -a
# Renaming an existing branch
git branch -m <old-branch-name> <new-branch-name>
>> git branch fix-division-by-zero-bug2 fix-division-by-zero-bug
>> git branch call-on-undefined-object2 call-on-undefined-object
# Deleting an existing branch
git branch -d <branch-name>
>> git branch fix-division-by-zero
# Deleting an existing branch even when the branch has not fully been merged in its upstream branch
git branch -D <branch-name>
>> git branch -D fix property-call-on-undefined-object
#8 Checking out branches
Checking out is the term used when we change our Git HEAD from one branch to another. This in simple terms is changing your development line from one to another. It also updates your working tree with only the commits history and changes specific to the branch you have change to.
Checking out allows you to switch context when working on a project, from working on a new feature to a new branch to fix a critical bug clogging performance or even worse causing sporadic downtime of your production service.
# Checkout from main branch to a feature-branch
git checkout <branch-name>
>> git checkout feature-branch
# Checkout a branch that is non-existent
# You can the flag -b on git checkout to checkout from your current
# branch into a new branch
git checkout -b <new-branch>
>> git checkout -b feature-branch-v2
#9 Unstagging changes
I sometimes find myself staging changes which include changes from files I am not ready to stage. This happens sometimes when using git add <glob-pattern>
and I don’t pay attention to the glob-pattern and so I ended up staging files that I haven’t intended to stage.
In rectifying this situation and unstaging such files, I use the git command below
# Move every staged files back into your working tree
git reset
# Move only specific staged files back into your working tree
git reset <filename>[, <filename2>, <filename3>, ...]
# Move only staged files in a given folder
git reset <folder-name>
#10 Resetting commit history
There are days where I inadvertently stage and commit changes that I do not intend to. Also I may realize that the immediate commit I have made introduces issues or bugs that I can not figure out how to resolve with code. With any of these two situations I resort to using git reset
with the flag —hard
to undo the immediate commit.
This command reset my Git history moving my HEAD from the immediate commit to the commit preceding that.
git reset --hard
#11 Pushing local changes to upstream repository
Every now and then I push my local commits to the upstream repository. Such changes could be from the main
branch or any of my feature branches I’ve been working on.
git push <remote> <branch-name>
# Push main branch commits to the upstream main branch
>> git push origin main
#12 Pulling changes from the upstream
I work in a team and so its common that my local clone diverges or lags behinds the upstream repository in commit history. Without updating my local repository with the new commits on the centralized upstream, any pull request I make could result in a merge conflict during merge into the centralized repository.
To resolve any potential conflict with my pull requests, I always run git pull
to synchronize my local repo with the centralized upstream.
git pull <remote> <branch-name>
# Pull changes from the main branch of the centralized upstream
# into my local main branch
>> git pull origin main
# Pull changes without performing a three way merge
# This removes temporarily your local commits, applies any upstream # changes first and then replays your local commits on top
# This cleans up your commit history by removing the common [MERGE]
# commit message
git pull --rebase <remote> <branch-name>
>> git pull --rebase origin main
# Pull changes from upstream automatically resolving merge issues
# 1. Merge conflict favorin changes from upstream
git pull -s recursive -X theirs origin main
# 2. Merge conflict favoring local changes
git pull -s recursive -X ours origin main
#13 Stashing away working changes
There are times when your boss throws at you a task whiles you are in the middle of another inside the same project or codebase. When such situations present themselves, depending on the urgency of your boss’ request, you may need to stop whatever it is that you are working on and switch focus.
With such situations comes along git stash
to save the day.
Just like the name, git stash
will stash away your changes in your work directory and index. Once your boss’ request is completed and out of the way, you can restore your stashed work with git stash
adding a few arguments to restore your previous working directory and index.
# Stashing your current work away
git stash
# Viewing all your stashed changes
git stash list
# Restore the most recent stashed changes and deleting it from your # stash
git stash pop
# Restore the most recent stashed changes but still keep it in stash
git stash apply
# Restore a specific stash from your stashed list
git stash <stash-name>
>> git stash stash@{0}
# Clear your entire stash of changes
git stash clear