LukeMainFrame

Knowledge Is Power

Home  Blog Articles  Publications  About Me  Contacts  
11 April 2020

GIT_2 : Workflows: branch and fork

by Lord_evron

In the last article we discussed some basic git concept. Now I want to introduce some Git workflows to be used while developing code in teams, that utilize Pull Requests and code reviewers. In particular, I want to explain how to keep the master history clean and how to avoid all those ugly merges and unnecessary commits that many teams encounter in their master history.

Before we begin, I want to emphasize one point: this discussion focuses on the code workflow within a team. I am not considering multiple branches within the main repository, such as “release,” “staging,” etc., at this time. I am solely focusing on the workflow for bringing code “into” the main master branch of the repository.

However, these principles can be easily extended to more complex scenarios with multiple branches.

In Git, there are two basic workflows:

Even though these workflows employ different concepts, they generally converge on the following five key steps:

  1. Develop the new feature on a new feature branch.
  2. Open a Pull Request from that branch to the main repository.
  3. Address reviewer comments: Repeat this step as necessary.
  4. After the reviewer approve your requests, you can (squash and) merges your request into the master branch.
  5. update your local master branch and delete your feature branch.

These steps are implemented slightly differently depending on whether you are working with branches within the main repository or with forks

Working with Branches

Working with branches is quite common, especially when all developers are from the same company. Typically, there is a master branch that is protected, meaning no one can push code directly to it. Each feature or bug fix is developed in its own branch to ensure the stability of the master branch. When developing a new feature, a developer creates a new branch and starts committing changes to it. If multiple developers are working on the same feature, they can use the same branch and push their changes collaboratively. Once the feature is ready, they open a Pull Request (PR) to merge the changes into the master branch. Code reviewers then examine the proposed changes, leaving comments or requesting modifications. Developers address these comments by updating the code and making additional commits. This iterative process continues until all concerns are resolved. Over time, the feature branch accumulates multiple commits, often including minor fixes and style changes. Meanwhile, other updates, such as hotfixes or bug fixes, may be merged into the master branch. For example, if hotfix/bug1 is merged while the feature branch is still under review, the master branch advances. The developers working on the feature branch must update their branch accordingly before merging their work into master. The goal now is to have only a single commit called “dev:feat1” appended at master Head, without the other branch specific commits. Lets see how to do that.

Develop the New Feature on a New Feature Branch

Before working on a new feature, create a dedicated branch:

# Create and switch to a new branch
git checkout -b feature-branch

Make changes and commit them:

# Stage changes
git add .

# Commit changes
git commit -m "Add new feature"

Open a Pull Request (PR) to the Main Repository

Once your feature is complete, push your branch to the remote repository:

git push origin feature-branch

Then, open a Pull Request to propose merging your changes into master.

Address Reviewer Comments

Reviewers may suggest changes. Implement them by making additional commits:

# Edit files and commit updates
git add .
git commit -m "Address reviewer comments"

git push origin feature-branch

Repeat until all concerns are addressed. when this step is completed we will end up in a situation like this:

hotfix1
Hotfix

Merge the Pull Request into the Master Branch

After approval, we merge the feature branch into master. If needed, squash commits to keep a clean history. This merge process is typically handled directly within the GitHub/GitLab/Bitbucket web interface. These platforms offer options to squash commits (combining them into one) and delete the source branch after merging. It’s generally recommended to enable both of these features, resulting in a clean, single commit (e.g., feat:feature1) and the removal of the now-obsolete feature branch. In case someone else pushed some other hotfix in the master branch like in our example, then we can easily integrate that into the feature branch, before we squash merge

git checkout feature-branch 
git pull origin master  # this will merge the remote master into your local feature-branch
git push origin feature-branch # you can push to your remote branch and will get appended to the Pull request,

Update Your Local Master Branch and Delete the Feature Branch

git checkout master
git pull origin master
git branch -d feature-branch
git push origin --delete feature-branch # if you have not already deleted on merge

If you have done all correct, your master branch history will look like this:

cleanhistory
clean master history

Working with Forks

When working in an open-source project or collaborating with external contributors, developers often do not have direct access to the main repository. Instead, they use a fork-based workflow. A fork is a personal copy of the repository where the developer can freely make changes before proposing them to the original project. working with Forks is basically the same except that you will have your own local copy of the repo , the online forked (origin) and the original repo (upstream). The workflow is this:

Which workflow is better?

Typically, code development within the same team follows a branch-based workflow, while cross-team collaboration or projects that tend to diverge significantly use a fork-based workflow. However, forks provide stronger isolation, which can be beneficial especially if the team is not highly proficient with Git. In such cases, a fork-based approach can also be used for intra-team development. Each developer can create branches and push changes freely to their own fork, while the upstream repository remains clean and branch free. That said, forks can become cumbersome when multiple developers work on the same feature. In such scenarios, teams may either maintain a shared branch on the upstream repository or manage multiple remotes for instance, by pulling code directly from a colleague’s remote repository.

Ultimately, as long as you understand these concepts, the choice of workflow within your team won’t make a significant difference.

Final Remarks

At this point, I just want to highlight a few important takeaways. Several powerful Git commands have been mentioned, so keep these key points in mind:

Well there would be much more to talk about, but I think we can stop here for now. I hope these two articles have been useful.

Happy quarantined Easter!

tags: code - git - technology