Git: A Version Control System
Have you ever experienced to manage versions on just one file? How hard is it to maintain many copies of a file by giving them different names? What if there are many files and many people collaborate in these files to build or create something? Can you imagine how challenging is it to resolve the code conflicts manually together in different versions of codes? Git comes into the play!
Git was created by Linus Torvalds in 2005 for development of the Linux kernel, with other kernel developers contributing to its initial development. It is there to help us deliver our code out of our local machine and it’s been there forever.
In this post, we will see how does Git help Software Engineers to maintain different versions of a codebase and help collaborations.
Git Basic Flow
In this section, we will cover some of Git commands which are often used.
You can start to work with Git by telling Git with git init command, then Git will start tracking changes on your current directory.
Alternatively, if there is already repository of your project, you can just clone it to your current working directory.
# Clone local repository
git clone <PATH_TO_REPOSITORY># Clone remote repository by HTTPS
git clone <REPOSITORY_URL># Clone remote repository by SSH
git clone <USERNAME>@<HOST>:<PATH_TO_REPOSITORY>
After working for some hours, you want to tell Git to add or remove the changes into / from Staging Area.
# Add changes to staging area based on path
git add <PATH># Add changes to staging area for all files in current working directory
git add *# Remove changes from staging area based on path
git rm <PATH># Remove changes from staging area for all files in current working directory
git rm *
Your files’ current status can be seen by git status command.
If you’ve already sure with the changes in Staging Area, you can commit the changes.
git commit -m <YOUR_COMMIT_MESSAGE>
If your local repository hasn’t connected yet with remote repository, add it to your remote list.
git remote add <REMOTE_NAME> <REMOTE_URL>
Implementing new features can be done in separate branch. Thus, all changes you’ve made doesn’t interrupt the main (master) branch.
# Create and move to new branch from specified branch
git checkout -b <NEW_BRANCH_NAME> <FROM_BRANCH_NAME># Create new branch without moving from current branch
git branch <NEW_BRANCH_NAME># Switch to another branch
git checkout <BRANCH_NAME>
You can save your new branch (or changes made in it) to remote repository by pushing it.
git push <REMOTE_NAME> <REMOTE_BRANCH_NAME>
When there is any changes from your desired branch, you can pull the changes into your local repository.
# Pull changes from REMOTE_BRANCH_NAME in REMOTE_NAME remote repository into current branch in local repository
git pull <REMOTE_NAME> <REMOTE_BRANCH_NAME>
We’ll cover more about Synchronization and Branching in the next section.
You can merge branches with git merge or git rebase command.
# Merge current branch with ANOTHER_BRANCH_NAME
git merge <TARGET_BRANCH_NAME> <WITH_OTHER_BRANCH_NAME># Rebase current branch with ANOTHER_BRANCH_NAME
git rebase <TARGET_BRANCH_NAME> <WITH_OTHER_BRANCH_NAME>
For example, we do this:
git merge feature master
git rebase master feature
What is the difference? git merge creates a new merge commit in feature branch that ties together the history of both branches.
In the example command above, git rebase moves the entire feature branch to begin on the tip of the master branch. Instead of using a merge commit, git rebase create brand new commits for each commit in the original branch. Here’s the illustration.
You can check all commit histories with git log command.
You can undo commits or changes that haven’t been pushed into remote repository with git reset command.
# Undo last commit in local and keep the changes
git reset --soft ^HEAD# Undo last commit in local and restore the changes
git reset --hard ^HEAD# Undo the specified commit
git reset <COMMIT_HASH>
If you’ve already pushed your changes and other developers have pulled the changes, you need to git revert and push the changes.
git revert <COMMIT_HASH>
If you want to undo changes but you haven’t made commit yet, you can use git restore command.
# Discard changes
git restore .# Move from Staged area into Unstaged
git restore --staged .
git stash command is used if you have changes and want to switch branches.
# Add changes into stash
git stash# Apply changes
git stash apply
Imagine we have one codebase, work remotely, and need to create or build something. Synchronization is required to keep our local codebase updated with other developers in our team. Hence, we need a remote repository to store changes and keep updated with the other developers. There are several git commands that help us with synchronization: git remote, git fetch, git pull, and git push.
The git remote command lets us create, view, and delete connections with more than one remote repositories.
Examples below demonstrate working with git remote command.
# Show list of our connection with remote repositories
git remote -v# Create connection with remote repository
git remote add <name> <url># Remove connection with remote repository
git remote rm <name># Rename a remote connection from old to new
git remote rename <old-name> <new-name># Show detailed configurations output with remote repository
git remote show <name>
Once we set the remote repository configurations with git remote, we can pass the remote repository’s name to other three commands: git fetch, git pull, and git push.
git fetch & git pull
Both git fetch, and git pull can be used to read from a remote repository. These commands are used to download commits, refs, and files from remote repository into our local repository. The difference is git fetch doesn’t force us to merge changes into our local repository, where git pull always merge changes (doing git fetch and followed by git merge). Here are some examples to work with git fetch and git pull.
# Fetch all branches from remote repository
git fetch <remote># Fetch specified branch from remote repository
git fetch <remote> <branch># Pull and apply changes from remote repository to local repository's current branch
git pull <remote># Pull and apply changes from remote repository's specified branch to local repository's current branch
git pull <remote> <branch>
This command is used to write local changes to a remote repository. This command transfers commits from local repository to a remote repository.
Here are some examples of git push usage.
# Push specified branch to a remote repository
git push <remote> <branch># Push all local branches to a remote repository
git push <remote> --all# Push all local tags to a remote repository
git push <remote> --tags
Branching & Merge Requests
Git branches is one of the main feature of Git to support collaborations. Suppose at some point, you want to implement feature FA. On the other time, before you finished your work on feature FA, person B in your team wants to implement feature FB. Branches come into the play!
Git stores a branch as a reference to a commit. That makes branch represents a series of commits.
With this workflow, each branch is isolated from other branches, and also encapsulate our changes inside it. It’s not only possible to work in parallel, but branches also keep the main branch free from questionable code.
Here are some examples of git branch usage.
# List of all branches in our repository
git branch -v# List of all branches
git branch -a# Create branch from specified branch
git checkout -b <new-branch> <from-branch># Switch to another branch
git checkout <other-branch># Rename current local branch
git branch -m <branch># Delete local branch
git branch -d <branch># Delete remote branch
git push <repo-name> --delete <branch>
On more complex projects, each developer in a team can work individually without disrupt the main code. As a result, faster and less-error developments can be achieved.
After one developer finished his/her work on a branch, the developer can create a Merge Request (on GitLab) or a Pull Request (on GitHub). This feature is where mostly collaboration is happened. It is not only about merging source branch into the target branch, Merge Request also encourages discussion proposed changes before integrating them into the official project, one of the example is Code Review.
Implementation in Software Engineering Project Course 2021 Fasilkom UI
Our team — Magic People — uses Git with branching model according to the guide from the course.
We also work to implement the Product Backlog Items (PBI) in parallel with branches.
The staging branch is derived from master branch, and then all of the PBIs are implemented in separate branch derived from staging. After the PBI is finished, I created Merge Request and the request will be merged after reviewed by two other developers in my team.
Git, with its Version Control System, really encourages collaborations between developers in building projects. Because each file in the project is tracked by Git, we don’t need to create naming versions for each file like the past did. This really saves time to running back or searching for specific version of files with Git, because of its implementation as a series of commits.
Git branches also help developers to work independently on separate branch without disturbing other branches. This can deliver faster development.
Merge Request (or Pull Request) also encourages collaboration by discussing or code review before merging the branch to the main branch. As a result, Merge Request made developers know other developer implementations, better knowledge sharing. If there is a bug, discussion on Merge Request also helps to find it fast.
Thank you for reading! Hope you find this power of Git is great!