Getting along with Git & Github
A no non-sense reference for developers by a developer.
Photo by Annie Theby on Unsplash
Yet another post on git? Don't we already have enough out there?
There is no dearth of resources on Git and GitHub. But most of them fall on the two extremes: Either they are too basic that you can’t rely on them for your everyday work or they are too advanced and complex that they scare you away right at the door.
Wouldn’t it be wonderful if we had a human-understandable, simple reference that we could use every day? This is not an elaborate guide that explains every single command with every single parameter. It's a reference of a subset of commands, the only ones you’ll need every day at work. Let's jump right in…
But first, make yourself comfortable with the terminal
Git is a command-line tool, which means it was meant to be used from your terminal/command prompt to unleash its true power. Relax! you only need to know the basics. Here’s a quick and easy cheat sheet.
So then what is git?
Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. — git-scm.com
In simple terms, Git is a tool that tracks and stores changes to your files. It allows you to look at the history of a file for changes and revert it to a state at any point in that history. So if you screw up a file you can go back to when it was good!
Its distributed, which means it allows more than one person to work on a file. Almost every company uses git. Be it software developers tracking their source code or non-technical teams versioning their documents, you’ll find git everywhere. Just learn it there is no way out!
Fun fact : Git was created by Linus Torvalds, the creator of Linux to manage the source code for linux kernel project. The name git means nothing, it was the shortest key combination he could find which was not already a reserved linux command.
Arent git and GitHub the same?
No! Git is the actual version control software/tool and Github is a repository hosting service.
Here’s a quick analogy. Imagine if Git were McDonald's burger, then GitHub is a food delivery service like Ubereats. It delivers you the burger but it isn't the burger!
GitHub allows you to store your repository on their servers and access, add changes etc over the internet. Along with this GitHub also provides additional features like automatic deployment of code etc.
OK, but what is a repository (a.k.a Git Repo)?
When you ask git to track changes to a file, It stores all the changes and the history of changes you make to files in a secret hidden folder. This folder is called a git repository and it's managed and updated by git.
When you hear — The file is in the git repository. It means that git is tracking all the changes to the file and you can see its history and retrieve it in its latest state or in any state in history.
What is a commit?
Commit is a snapshot of your file at a given time. When you commit a file to Git the file’s state is captured and saved on the git timeline into the Git repository.
Do I need to install git?
Yes, If isn't already installed. Just follow the instruction at this link from Github. If you still feel confused just do a search on youtube. You got this!
The basics — foundational commands
The commands in this section are the ones you’ll use almost every day. Make sure you practice them. Better still…print this section and stick it on the wall!
How to initialize a git repository?
When You initialize a git repo, you are essentially asking git to start tracking files in that folder. You need to initialize a repository before you can do any other git operations.
Just open the terminal and then enter the following command, replace the name of the repo with what you wish to call the repo. As a best practice, the folder name is mostly the same as repo.
$ git init <name of repo>
You need to init a repo only once at the beginning
You can also init an existing folder as a git repo by navigating into the folder and using the following command. .
is an alias for the current directory.
$ git init .
Let’s understand the Git States
When you start tracking files in a folder for a project with Git. It logically divides your project into three areas
- Working directory — This is the area where you work with your actual files, edit them modify them etc. Think of this as your kitchen where you prepare the food.
- Staging area — When you are ready for git to track any file or changes it is first moved into a staging area. This is the last waiting area before the changes are committed into git repo. Think of this as your kitchen island where you place prepared food to be stored in the refrigerator for later. You may choose to add more food or remove it as you please.
- Repository — This is the final resting place for your file’s changes and its history. The refrigerator!
- Remote Repository — This comes into the picture when you are using GitHub. You are essentially keeping a mirror image of your local repo on GitHub servers and vice-versa. This may be like the refrigerator at your mom’s where even your siblings store their food!
Check the current status
Before adding any changes to the repo it's always good to check what files are added/modified. What files are in the staging area etc. Use the git status command
$ git status
Add selected file to the staging area
To add a file to be tracked by Git. use the Git add command followed by the file name
$ git add <file name>
If you want to add all untracked files to the staging area you can use the following command
$ git add .
Committing changes to git
When the file is in the staging area you are ready to commit it into the rep. Always add a descriptive commit message on what changes are being committed.
$ git commit -m "Commit message"
If you use the commit command without any flags it will open your default texteditor to add descriptive commit messages.
$ git commit
How to see the commit history
Using git log to shows all the commits that are part of this repository. Press q
to get out of the log command
$ git log
You can see the details of the last commit and also the difference using the git show command
$ git show
List all files git is tracking
If you want to look at all the files GIt is currently tracking use the git ls-files command
$ git ls-files
Express commit to already tracked files
You can use express commit to already tracked and modified files using the a
and m
flags together
$ git commit -am "commit message"
Un-stage changes
If you added a file to the staging area by mistake or changed your mind on a modification un-stage it with the following command
$ git reset HEAD filename.ext
Reverting back to the last good commit for a file
Things get messed up quite often, to revert your file to last good state just use
git checkout -- filename.txt
Git help command
At this point, you might be wondering- what if I need to see other options available for the git command. just use the git help command
$ git help commandname
A better way of seeing commit history
The git log command by itself may not give you a good picture of the commit history. Using it with other options will give you the better information you need.
$ git log --oneline --graph --decorate --all
Create your own git history command with git Alias
Typing long commands are a pain. So git allows you to create short cut/aliases here’s how you can create one for the log command we just saw.
$ git config --global alias.hist "log --oneline --graph --decorate --all"
$ git hist
Checking the history of commits for a particular file with our new alias
$git hist -- filename.ext
Show git global config file
Now you are wondering how do I see all the global configuration settings git. Well just use the config command.
$git config --global --list
Rename, move and delete files
When you have a folder tracked by git, always use the git mv command to rename and move files. If you use the file operations provided by the OS, you may lose the file's commit history. If you rename a file using the OS command git sees it as a deleted file and the renamed file is a new file. To avoid this scenario use:
$git mv filename.ext newfilename.ext
Removing file through git automatically tracks the deletion
$git rm filename.ext
of course you have to commit this action as well with git commit
Renaming and deleting files outside git using OS commands
in case you commit the cardinal sin you can fix it with, of course, it needs a commit after
$ git add -A
See deleted files
$ git add -u
Excluding unwanted files with .gitignore
There are often times when you don't want to track a file like log files, local config files etc. just create a file named .gitignore
. Add file/ folder type
per line to ignore. For example, if you want to ignore all log files you may add an entry as *.log
This brings us to the end of basic git command and operations. Let's look at some advanced concepts that will make your collaboration smoother.
Advanced Git commands
Once you get a good hold of the basic commands, it's time to move on to these more advanced commands.
Checking the difference between two commits
If you want to look at what changes were made between two commits, you use the diff command
$ git diff commitid commitid
Instead of commit id, it can be branch names too. To watch the differences in diff tool. A diff tool like P4merge or beyond compare shows you differences between the two files
$git difftool commitid commitid
if we don't provide the second argument then it automatically compares with HEAD. git help diff to know more
Branching and merging
Branching is an essential part of Git, When you want to work on a change on a repository with others you branch out, add your changes and then merge your changes with the main branch.
Think of it like a library where you borrow books. so when you need a new book you check out a book which is like branching and when you are done you return it back to the library or merge it into the main branch.
Branches are commits on a timeline in git. More accurately branches are labels we give to timelines or commit ranges on git.
Types of merge
- fast forward merge: when no changes are done on the main branch
- Automatic merge: git resolves automatic merges
- Manual merge: When git cant resolve conflicts, it asks you to merge manually
Special markers
HEAD is a special marker in git which normally is the last commit of the current branch
Simple branching
To check current branches in a repo you use:
$ git branch
Create and switch to branch at the same time
$git checkout -b branchname
Note that if there were uncommitted changes to the main branch it's carried over to the new branch.
Merging: Integrating changes from any branch to the main branch
First, we need to switch to the main branch, or the branch we want to merge into.
$ git checkout branchname
And then we merge by pulling changes from the new branch to our branch
$git merge newbranch
Once you are done the merged branch is of no use so clean it up. this command delete unwanted branches
$ git branch -d nameofbranch
Marking special events with tagging
You can add tags to your commits for any special event like release or fixes. Tags are just labels that you can put at arbitrary commit points. There are 2 types of tags
- Lightweight tags — juts tag name
Annotated tags — have extra information
$ git tag tagname
to see all tags, use
$ git tag --list
To delete a tag
$ git tag -d tagname
The annotated tag, lets you associate a commit message when you create a tag
$ git tag -a tagname -m "commit message"
To see details of an annotated tag use the git show command
$ git show tagname
When you create tag, the tag associates itself with the last / latest commit. Tags are meant to be immutable so if you do need to add a change to a commit create a new tag say v.1.1.
Saving your unfinished work
You can context switch in between your work without losing any uncommitted work
$ git stash
This is saved in a work in progress or WIP. To see the stashes you use
$ git stash list
To get back where you left off
$ git stash pop
Time travel with reset and reflog
To reset to a commit point you can use the following command. It's called a soft reset. Soft reset just changes where HEAD is pointing, preserves our staging area and working directory
$ git reset a816c62 --soft
There is also a mixed reset
$ git reset d4a3d08 --mixed
If you want to unstage and put everything in the working directory we use a hard reset
$ git reset d4a3d08 --hard
Git reflog shows all the different actions we have taken
$ git reflog
Working with Github
These are just the essential commands you need to work with GitHub
Adding an existing local repo to GitHub.
The git remote command manages all remote connections from local to the remote repository
To check if your local repo already has any remote connections use the remote command with -v
flag
$git remote -v
If it returns nothing then you know that there are no associated remote connections.
$ git remote add origin git@github.com:gitusername/reponame.git
Pushing changes to GitHub
For the first push to GitHub, the following command pushes all changes to the main branch along with the tags and establishes a tracking relationship between your local repository and the GitHub repo.
$ git push -u origin main --tags
Cloning a git repo
Cloning is like creating a local copy of the GitHub repository
$ git clone
url
provide an explicit folder name at the end if you want to clone into a diff folder name other than the remote repo.
Pushing back changes to Github
$ git push origin main
here origin and main are optional, git hub will automatically figure out that you are using into the current branch.
Fetch and pull
Fetch and pull lets you bring in any changes in the GitHub repo to your local repo. Fetch just brings the new changes from remote repo but doesn't merge any conflicts
$ git fetch
Git pull is two commands in one it fetches and merges on one go
$ git pull
Updating reference to the origin
If you need to re-assign the URL for GitHub repository use the command
$ git remote set-url origin newrepourl
Show the details on remote
This shows the details of the current remote URLs
$ git remote show origin
Pushing local branches to Github
$ git push -u origin branchname
Prune dead branches
$ git fetch -p
Conclusion
Working with Git is an essential skill and it's not all that hard to master. It just takes a little practice and these commands become your muscle memory.
Thank you for reading and Happy Hacking!