Git: A great invention of all time
Have you ever did the thing above to keep track of separate versions of your work? Some years ago I did, and it was for a single .cpp file. Then someone came to me and said, “You obviously don’t know Git.” And they were right.
That was just for a file. What if we are now in the Computer Science field, working with the whole software project consisting of lots of files where we need to collaborate with others, too! Well, we can always send the whole folder to them, and then they make the changes and send it back to us. But as the most advanced species on earth that human is, can we do better?
The answer is we can. And just like the title, we can solve it with Git! 🎉
Git is software used to track file changes in a project. We can visualize Git as the tree-like structure above that keeps track of the project history and manages the version control for us. At some point, we can “branch” from the current position and work independently of the other branches to make the new feature. The reason for this would be to keep it simple instead of mixing our unfinished change and our friends’ which can result in a very complicated situation. It’s better to work independently and once we’re done, we can merge it back so that the master branch will have the complete set of features.
This section discusses how we actually utilize Git to our advantage. Git comes with several commands, some of which will modify the underlying tree structure. Please find below the summary of Git commands that are commonly used.
- Git Clone (download a project from a remote repository, e.g. GitHub/GitLab)
git clone <https://repository-link>
- Git Add (add the files that we changed to be included in next commit)
This command just includes the files and will not(!) modify the repo yet.
git add <file> // adding a single file
git add . // adding all changed files in the current directory
- Git Commit (set a checkpoint = create a circle in the illustration above) Saving changes locally but they’re not yet pushed to the remote repo.
git commit -m "commit message" // commit message explain the changes
- Git Push (push our local commits to the remote repository)
git push <remote> <branch-name> // e.g. git push origin master
git push --set-upstream <remote> <new-branch-name> // for new branch
- Git Pull (pull the changes from the remote repository to our local repo)
- Git Branch (to create, view, and delete branches)
git branch <branch-name> // creates new branch
git branch // viewing branches
git branch -d <branch-name> // deleting a branch
- Git Checkout (move to another branch or a particular commit state)
git checkout <branch-name> // moves to branch-name
git checkout -b <branch-name> // creates a branch and moves there
git checkout <file-name> // undoes changes in a file
git checkout <commit-hash> // moves to a particular commit state
- Git Merge (merge changes in a branch to another branch)
git merge <branch-name> // merge the changes in branch-name to
// the branch that we are currently at
- Git Rebase (apply changes in a branch to another branch consecutively)
Similar to Git Merge excepts the merged commits will be stacked on top.
git rebase <branch-name> // stack the changes in branch-name on top
// of the branch that we are currently at
- Git Revert (undo a commit)
git revert <commit-hash> // creates a commit that undoes the commit
// specified by the commit hash
- Git Remote (connect our local repository to a remote repository)
git remote add origin <https://repository-link> // create new remote
git remote -v // list remote repositories that our repo connects to
- Git Stash (save current state of work for use later without committing)
git stash // save our current state of work onto a stack
git stash pop // apply the topmost state of the stack and remove it
git stash apply // apply the topmost state of the stack
git stash drop // remove the topmost state of the stack
We can git stash our work in progress and git stash apply / git stash pop later to return to that state. Git stash pop will remove an entry from the stash stack.
Git Merge vs Git Rebase
Both Git merge and Git rebase are used to integrate changes. However, the commits will form a different structure if we use git merge or git rebase. Git rebase will produce a straight structure where the integrated changes are stacked on the tip of the straight line whereas git merge will just literally merge the branches and the commits are still sorted chronologically.
Git merge and Git rebase have their pros and cons. As mentioned before, git rebase will result in a straight line structure that looks neater. However, in order to produce this neat structure, git rebase definitely modifies history. This is because the initial chronological order in the illustration above is not all yellow and then all pink, but git rebase makes it like that. In contrast, git merge really does not modify history and creates a new commit to merge it instead. So here comes the trade-off: preserving history vs neat structure. No method is the best for everyone, we should choose the one that is the most suitable for our project.
This article is written for Individual Review PPL CS University of Indonesia ‘21
Git for PPL (Software Engineering Project) course
My PPL group is working on the Liwat Project consisting of 2 repositories for the frontend and backend code. We are utilizing the Git repositories for our development workflow as a team. In addition to the above convenience that Git offers, another great thing about these online Git-repositories is that it doesn’t only serve as a repository but also comes with easy integration capability, like Gitlab CI that allows automatic deployment.
We have created around 20 branches beforehand as a place to develop our features later. We hope to utilize Git fully in a pragmatic manner.
Git Merge vs Git Rebase: Continued
Continuing the Git merge vs rebase topic before, my group uses Git Merge. We have several reasons for this. First, we are more familiar with git merge so we expect a smoother process if we use git merge which we are already used to. Second, we don’t prefer the way git rebase can modify history that makes us lose the actual chronological ordering of the commit history.
Just like mentioned, we must face the trade-off. The structure can get fairly complicated like guitar strings, but we can see the actual chronology.