Git — How to use it efficiently?
What is Source Control?
Source control is the practice of tracking and managing changes to code. Source control management (SCM) systems provide a running history of code development and help resolve conflicts when merging contributions from multiple sources. (Resource from Google).
Git is a free and open-source distributed version control system designed to handle everything from small to huge projects quickly and efficiently.
Source control systems allow developers to track changes to their code over time, revert to previous versions if necessary, and collaborate with others on the same codebase. It also provides a way to manage conflicts when multiple people change the same code simultaneously. (Source ChatGPT)
Now let me infer for you with a simple statement:
Consider it like a manager who manages the employees of an organization. (PS: I am not saying a leader).
Similarly, version control allows devs to track progress, especially the history of their commits, to push code to the remote repositories, collaborate and manage conflicts with each other and work efficiently in a large codebase.
So you have used all the basic features of git(add, commit, push) and might be familiar with the advanced features of git. If not, let’s dig deep into that.
Today’s focus would be branching; I struggled with it initially, but with some time, practicing, and taking help from peers, I now have a better understanding of it.
I will take help from diagrams to explain to you :
So are you familiar with git merge and git rebase?
Then I hope you will take some positive knowledge from here.
I’ll talk about git merge first —
Git merge is used when you have to get the latest changes from the other branch and merge it with your current working branch before pushing it to your repository.
Hello, example, please —
Yeah, Don’t worry about coming to that.
You are working on some new feature in your newly created branch from the main, but in the meanwhile, someone has updated the main branch with new commits.
Now your mind is running with ideas to overcome this situation. And you checked your best friend’s stack overflow suggestion, and it suggested you use git merge.
This is where merging comes into the picture.
For example, you have a My-Branch branch cut from the main branch. This is how you will merge the main into your branch named My-Branch.
git checkout main
git pull origin main
git checkout My-Branch
git merge main
git push origin My-Branch
The steps are simple to pull the main first and then check out your branch and merge it with the main,
Simple, isn’t it?
Now someone asked —
“I want to do it via rebase; I don’t want to use git merge.”
I said let’s also jump onto it and see the git rebase command.
Alternative to merging, one can rebase the feature branch onto the main branch using the following commands:
Git rebase moves the entire My-Branch branch to begin on the tip of the main branch, effectively incorporating all of the new commits in the main. But, instead of using a merge commit, rebasing re-writes the project history by creating brand new commits for each commit in the original branch.
In simple you are moving the sequence of commits and rebasing to the top of the head or where the main branch is currently at.
The operation to perform a Git rebase to the main is simple. It would help if you appended rebase and the branch name with which you want to rebase; in this example, I am rebasing My-Branch with main.
git checkout My-Branch
git rebase main
Refer to the diagram below for more clear explanations of git merge and git rebase.
But you know, with git rebase, there are issues
Should you avoid git rebase?
Now, consider if any library used by My-Branch got removed from the Master.
Now, what will happen?
When My-Branch has rebased onto Master, the first re-applied commit will break your build, but as long as there are no merge conflicts, the rebase process will continue until the operation finishes. But this will result in a chain of broken commits.
And the error will only be discovered when rebase process is finished and can only be fixed by applying a new bug fix commit.
Also, there might be a possibility that you do get conflicts, and it will pause on that conflict, giving you a fair chance to resolve a conflict, but you might have a long chain of commits, and fixing that conflict can consume your lot of time and can also give rise to confusion, another source of pain working in a collaborative environment.
You should use it after an internal discussion with your team if everyone is comfortable; you don’t want to give rise to new bugs while working to achieve linear history. Resolving conflicts can become error-prone and tiring for you when there is a chain of larger commits.
Git Fast Forward
In simple words, if your branch does not diverge yet, git fast-forward merge will move the primary pointer of the Main branch to your working branch (My-Branch in your case).
A Git fast forward is an extremely useful and efficient mechanism for harmonizing your project’s main branch with changes introduced in a given feature branch. Git makes ample use of fast-forwarding merges behind the scenes, speeding up your development workflow in the process.
The diagram will make you more clear.
Remove the file from a commit.
If you have committed a file in your workspace but later thought to remove it, as those changes are not required,
first, use the git reset command.
git reset --soft HEAD^
When you get your files to the staging area, specify which file to remove.
git reset HEAD <filename>
And voila, those files are no longer in your commit.
Check Logs in the git commit.
Git logs help you review and read the history of a repository (project) you have worked on.
The above command shows you the logs that comprise of following data:
1) A commit hash
2) Author Meta Data
3) Date on which that particular commit is done
4) commit comments
git log --oneline
But you said these logs are not customized according to your requirement. Do you want to look git logs like more clearly? The above git logs contain limited information; you want to have a deep understanding of commits history ;
Git provides you with commands to get deep insights into the log, don’t worry.
git log --graph --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%an%C(reset)%C(bold yellow)%d%C(reset) %C(dim white)- %s%C(reset)' --all
I also want to cover git squash how to squash git commits in the next article, but reason is well explained in this article if it should be used or not.https://betterprogramming.pub/why-i-prefer-regular-merge-commits-over-squash-commits-cadd22cff02c
you will squash yourself after reading it.