loading...
Cover image for How to use git efficiently

How to use git efficiently

adityasridhar profile image Aditya Sridhar Originally published at medium.freecodecamp.org Updated on ・1 min read

This post was originally published in medium.freecodecamp.org

The code was working yesterday but today it is not

The code got deleted

A weird bug has been introduced suddenly and no-one knows how

If you have been in any of the above situations then this post is for you.

Apart from knowing git add, git commit , and git push , there are a bunch of other important techniques in Git. Knowing these will help a lot in the long run. Here I will be covering some of the things which will enable you to make the best use of Git.

Git workflows

Whenever multiple developers are involved in a project it is necessary to use the right workflow for Git. Here I will be covering one workflow which is very effective in big projects with multiple developers.

Git Workflow

Hopefully this workflow chart I created will help you visualize the process :)

Scenario

All of a sudden you have become the tech lead for a project in which you are planning to build the next Facebook. The team has three developers:

  1. Alice: has one year of experience and knows programming

  2. Bob: has one year of experience and knows programming

  3. John: has 3 years of experience and knows programming well

  4. You: assigned as tech lead for this project

Development process in Git

Master branch

  1. The Master Branch should always have a copy of the existing code in Production.

  2. No-one — including the tech lead — should be coding directly in the master branch since it is a copy of production code.

  3. The actual code is written in other branches.

Release branch

  1. When the project begins the first thing to do is to create a release branch for the project. The release branch is created from the master branch.

  2. All code pertaining to this project will be in the release branch. The release branch is just a normal branch with the prefix release/.

  3. Let’s call the release branch for this example release/fb.

  4. It’s possible that there are multiple projects running on the same code base. So, for each project, a separate release branch is created. Let’s say there is one more project running in parallel. Then that project can have a separate release branch like release/messenger

  5. The reason to have a release branch is that the same code base can have multiple projects running in parallel — there should be no conflict between the projects.

Feature branch

  1. For every feature that is built in the application a separate feature branch is created. This ensures that the features can be built independently

  2. Feature branch is just like any other branch but with the prefix feature/

  3. Now you, being the tech lead, have asked Alice to build a login screen for Facebook. So she creates a new feature branch for this. Lets call the feature branch feature/login. Alice would write the entire login code only in this feature branch.

  4. The feature branch is generally created from the release branch

  5. Bob has been tasked with building the “Friend” request page. So Bob creates a feature branch called feature/friendrequest

  6. John’s task is to build the news feed. So John creates a feature branch called feature/newsfeed

  7. All of the developers code in their individual feature branches. So far so good 😃

  8. Now, let’s say that Alice finished her task and the login code is ready. She needs to send her code to the release branch release/fb from her feature branch feature/login. This is done through a pull request.

Pull request

First and foremost, a pull request is not to be confused with git pull .

The developer cannot push the code directly into the release branch. The tech lead needs to review the feature code before it goes into the release branch. This is done through a pull request.

Alice can raise the pull request as follows in GitHub — these steps are specifically for GitHub.

Pull Request Step 1

Right next to the branch name there is an option called “New pull request”. Clicking on this opens a new screen shown below:

Pull Request Step 2

Here:

  • the compare branch should be Alice’s feature branch feature/login

  • the base branch should be the release branch release/fb.

Once this is done, Alice needs to enter a title and description for the pull request, and finally click on “Create Pull Request”. Alice also needs to assign a reviewer for this pull request. She enters your name as the reviewer since you are the tech lead.

The tech lead then reviews the code in the pull request, and merges the code from the feature branch into the release branch

So now you have merged the code from the feature/login branch tothe release/fb branch and Alice is pretty happy that her code has been merged. 😃

Code Conflicts 😠

  1. Bob has completed his code as well, and has raised a pull request from feature/friendrequest to release/fb.

  2. Since the release branch already has the login code, code conflicts occur. It is the responsibility of the reviewer to resolve these code conflicts and merge the code. In this case, you as the tech lead need to resolve these code conflicts and merge the code.

  3. Now John has also completed his code and wants to add his code to the release branch. But John is pretty good at handling code conflicts. John takes the Latest code from release/fb branch into his own feature branch feature/newsfeed ( either through git pull or git merge ). John resolves all the conflicts that are present. Now the feature/newsfeed branch has all the code present in release/fb as well.

  4. Finally, John raises a pull request. This time there are no code conflicts in the pull request since John has already resolved them.

So there are two ways to resolve code conflicts:

  • First method: the reviewer of the pull request needs to resolve the code conflicts.
  • Second method: the developer ensures that latest code from the release branch is merged into the feature branch and resolves the conflicts themselves.

In Enterprise projects beginner developers can initially start with First Method and eventually move to the second method. Second method is the preferred method

Master branch again

Once the project is completed, the code from the release branch is merged back into the master branch. The code is then deployed to production. Thus, the code in production and the code in the master branch are always in sync. This also ensures that, for any future project, the up-to-date code is available in master.

References

More information about pull requests is here.

Congrats 😄

You now know about git workflows. Git has some other concepts like amending commits, and rebasing which are also useful. But Git workflow is pretty important for big projects to be successful.

For small projects this workflow can seem to be like an overhead. So other alternatives can be used in small projects.

Feel free to connect with me in LinkedIn or follow me in twitter.

If you liked this post, you can checkout my website https://adityasridhar.com for other similar posts

Discussion

pic
Editor guide
Collapse
theluk profile image
Lukas Klinzing

Good post, thank you!

Generally I disagree that the reviewer should solve conflicts. I had to do that and it's the hardest thing on planet when you have not written the actual code.

Conflicts happen when two or more people work in the same sphere. They should be able to handle it. The reviewer should only review the code that works.

Collapse
adityasridhar profile image
Aditya Sridhar Author

Ideal approach is the developers resolve the conflict themselves :).

But that said, if a developer is a beginner, then they will find it hard to resolve conflicts. So in that case the tech lead can resolve the conflicts. With more experience the developer will be able to resolve the conflicts by themselves :)

Collapse
karlkras profile image
Karl Krasnowsky

100% agree. Why should the reviewer be tasked with resolving the conflicts?

Collapse
melezhik profile image
Alexey Melezhik

I'd not say that GitFlow has real advantages for me, the thing is you might end up with a lot of branch merging which is a real chore and always delays the speed of the development. In practice there is lot more merges b/w branches back and forth if one follow a git flow based approach.

You might consider trunk based development as an alternative.

Collapse
rbukovansky profile image
Richard Bukovansky

But the trunk based development doesn't allow me to manage what goes to release, you take what's in trunk branch and create a release from it (few of our product managers just fainted), you never know if your trunk is stable etc.

Merging between branches with git-flow is a chore if you let it be a chore (there are few git-flow scripts/tools that help with it).

Collapse
adityasridhar profile image
Aditya Sridhar Author

Till now haven't faced any issues with gitflow workflow. But in case issues do come will look into implementing something like trunk based development :)

Collapse
melezhik profile image
Alexey Melezhik

yeah. just a few questions:

  • how often you make prod releases? ( daily, weekly, few times a month or less frequent )
  • what is a frequency of commits? ( say per day )
  • average size of developers team? ( per one project )
  • if you have a hotfixes ( urgent bugs ) how do you deal with them in terms of SCM flow ... ?
Thread Thread
adityasridhar profile image
Aditya Sridhar Author
  • A monthly release

  • Maybe 10 to 20 commits a day max by all devs combined :D.

  • Varies. 4 to 8 depending on the requirement.

  • Current approach is to create a hotfix branch directly from master and make the change for high priority bugs. Low priority ones are generally pushed to the next release

There are situations where the codebase is shared between multiple projects and teams. That's one of the reason this approach worked well till now.

Thread Thread
melezhik profile image
Alexey Melezhik

Current approach is to create a hotfix branch directly from master and make the change for high priority bugs. Low priority ones are generally pushed to the next release

Ok. You did not say here. Do you propagate hotfix commits back to dev and release branches ?

Do you make production release immediately once new release branch is created? Do you continue to merge from dev to release after a new release branch is created?

There are situations where the codebase is shared between multiple projects and teams. That's one of the reason this approach worked well till now.

not sure, what you mean. please specify ...

Thread Thread
rbukovansky profile image
Richard Bukovansky

Git-flow:

1) The hotfix branches are cut from master branch and merged back to master and then to develop branch.

2) You do production release when the hotfix branch from 1) is merged back to master.

3) You don't merge develop branch once you cut release branch from it. This release branch is then just for fixes devs create against it directly or with PRs. Release branch in git-flow is used to QA testing and resolving bugs they find to stabilize that release. When it's signed off then it's merged to master and followed by merge to develop.

Thread Thread
melezhik profile image
Alexey Melezhik

Hi Richard. I am replying here to both of your comments. All it boils down to the fact that gitflow is hard to maintain. You have many branches that you have to merge back and forth in right order. It's not immediately seen on simple projects but it becomes painful as soon as frequency of releases and quantity of projects piles up. There is more about this here - endoflineblog.com/gitflow-consider...

In trunk based development there is one main branch ( I am not talking here about short leaving features branches and release / hotfix branches that also exist, anyway ... ) which radically simplifies and increasers the speed of development cycle. And trunk branch is always stable, you can read more about this on the mentioned site or other resources.

Yeah TBD has some tradeoffs but they are incomparable with disadvantages introduced by gitflow.

Thread Thread
rbukovansky profile image
Richard Bukovansky

Sorry, but what is hard on following commands to create a release branch and then close it?

gitflow release start "2.10.1"
gitflow release end "2.10.1"

Similar for hotfix branch:

gitflow hotfix start "2.10.1.1"
gitflow hotfix end "2.10.1.1"

Similar for creating short-lived feature or bugfix branch:

gitflow feature start "feat/new-login-page"
gitflow feature end "feat/new-login-page"

Sure, it's one of my scripts that does all the hard work, but I don't need to think about merging...

Sorry again, but people who do write off git-flow because they think it's complicated, they simply don't understand its beauty, sophistication, and advantages. And when you combine it with GitHub Flow (Fork&Pull Request), it can't simply be beaten.

And believe me, with TBD you get your trunk/master messy and unstable if anybody can merge there, I tried implementing that many times.
And I ask you again: How do you manage what goes to release when everybody is merging to one branch whatever and whenever they decide?

Thread Thread
melezhik profile image
Alexey Melezhik

Well, the shortcuts you have here is just smallest and easiest part of the workflow, the hardest part is merge branches not creating them. In classical git flow https://jeffkreeftmeijer.com/git-flow/git-flow.png you have 5 types of branches you have to merge and create in specific order and in specific times. If you don't follow the rules strictly you end up with the mess.

While it's probably easy to follow gitflow with small projects and low frequency of releases, it is way too harder to keep this approach with frequent releases and large code base. This is why companies with large code base and frequent releases like Google practice kinda TDB methodologies ( with variations ) instead of gitflow.

And believe me, with TBD you get your trunk/master messy and unstable if anybody can merge there, I tried implementing that many times.

It's not true. Pull requests / Code Reviews are still here to fence main code from junior developers direct commits ( though you might not need this with mature teams, anyway )
Also if a build is broken - it's ok, but you have to stop all the current development and make a fix OR rollback - it's what all the pretty textbook stuff devops methodologies teach us. There is no problem with broken build, there is a problem with recklessness about it. Add here automatic tests triggered by CI/CD, pre commits / push hooks tests and you will get even more layer of confidence ...

And last thing:

Sure, it's one of my scripts that does all the hard work, but I don't need to think about merging...

Actually you do, but not about technical aspects of merging, but about WHAT you merge, even the fact you have no conflicts or resolved ones does not mean the resulted code is right. Don't get me wrong I am not against merging, but merging is still hard ( not technically but logically ), TBD tries to avoid a lot of merging while gitflow upholds.

And I ask you again: How do you manage what goes to release when everybody is merging to one branch whatever and whenever they decide?

The same as with gitflow. At some point you cut off from main branch and create release one.

Collapse
havarem profile image
André Jacques

Pretty good. I have one question about a project with multiple version alive (like apache 2.0.x, 2.2.x and 2.4.x) that are developed concurrently.

  • I have the master branch that holds the latest stable version.
  • I have RC branches (or staging) for debug and delivery.
  • I have hot-fix branch that by-pass directly from master.
  • I have my dev branch with all the stories that has been completed with unit test passing (usually) and
  • feature and bug-fix branches.

What strategy should be implemented in a case like Apache HTTPd server, where 3 main versions are maintained? Should we use 3 different repositories, or should we have three master branch (master20, master22 and master24 for exemple?). Is there other options?

Collapse
rbukovansky profile image
Richard Bukovansky

Well, 3 repos if you don't trust your developers they will create their feature/bugfix branches from correct develop branch, and code lieutenants responsible for accepting PRs or merging from and to correct branches.

Otherwise with git-flow and if you develop new features to all those releases, you will need to have 6 branches (master2_0 => develop2_0, master2_2 => develop2_2, master2_4 => develop2_4). Actually, if you want develop new "main" version, you will end up with 8 branches, with additional branches like master-next and develop-next, where you develop new features which are going to next main release, like 2.6.

If you just maintaining those master2_2 and master2_4 branches for security fixes, you should be OK with just master2_2 and master2_4 without develop2_2 and develop2_4 branches and with classic git-flow hotfix branches.

Collapse
havarem profile image
André Jacques

That was basically my concern with one repo, it felt really troublesome for not many advantages. It seems for me that 3 repos are the way to go. The repo is cleaner, less confusing.

Collapse
adityasridhar profile image
Aditya Sridhar Author

Interesting question.

Never worked on any project with multiple active versions.

I am guessing if the development is concurrent on all the versions, and if the versions have different features then its better to have separate repos for them like angularjs and angular.

Again, never worked on projects with multiple active version. It's better if someone who has actually worked on this answers :D

Collapse
evanboissonnot profile image
Evan BOISSONNOT

it’s easy to ready
thank you :)

Collapse
adityasridhar profile image
Aditya Sridhar Author

thanks. Happy it is easy to read :)

Collapse
coolman1011 profile image
CooLmAn1011

Nice post!
But i do hv a questions on feature -> release
in one of my new project
i expect some features will only be POC and may never implement into production
but user still want to test it first
my current approach is to create a develop branch which act as a UAT environment for user to test out features if feasible or not and only merge into release if they feel good about it
is it a good approach or not?

Thanks!

Collapse
adityasridhar profile image
Aditya Sridhar Author

I Have been in similar situations :D

I did exactly what you have mentioned.

The only catch is that it works very well for independent features. But if you have dependent features then we had to deal with it by manually changing the code. Still figuring out the best way of handling this

Collapse
coolman1011 profile image
CooLmAn1011

actually i think there may be a issue..
variation of develop and release will become greater and greater
and at some point, we may be forced to merge release into develop
just to get things a bit easier to work with..

hv any ideas about it?
maybe rebase can do the trick? but im not familiar with it

Thread Thread
adityasridhar profile image
Aditya Sridhar Author

Rebase is generally used to update the code in local with the latest code in remote. Using Rebase in the remote can create issues since it overwrites history.

I have written about rebase as well. You can check it out here
adityasridhar.com/posts/how-to-bec...

I guess one option is to handle it in the code itself rather than trying it with git. You can have a config to say which features to enable and disable.

So when users say they don't want a feature, you just go to the code config and disable it. In the future, they may want the feature back. In that case go to the config and enable it :D

I think having a config like that makes it easier than handling it with git. What is your take on this?

Thread Thread
coolman1011 profile image
CooLmAn1011

omg😲
using config file is a brilliant idea!
why i hvnt thought of this before!

i know rebase will overwrite the history, maybe i will just stick to local rebase first

Thank you!😘

Collapse
agevaled profile image
Pablo de la Vega

Nice post, thanks for sharing!

I have a question, what is the pros and cons of using forks (with branches) instead of new branches in the "upstream" repository?

Regards,
-Pablo

Collapse
adityasridhar profile image
Aditya Sridhar Author

Thanks you

Generally in open source projects you would fork the repo, make your changes and then raise a pull request to the original repo. The reason for this is that you would not have write access to the original open source repo. Unless you have write ( collaborator ) access you cannot create branches in the original repo.

What I have explained in this article in a branching strategy which can be used provided you have write access to the repo :). This is easily applicable to enterprise projects.

Collapse
agevaled profile image
Pablo de la Vega

Yes, I know that, on the company I'm working I always recommend to fork the project and then work on the forked one, the devs don't have write access to the original repo, I like to keep clean the original repo and only have the branches I (or the Technical lead) want to keep.

For me the Pros i found:

  • Have clean original repo (few branch)
  • Each Branch belong to the developer how worked on that

Cons:

  • Extra steps to update your local code.
  • You can't prevent the dev work on master or developer branch.
    • Easy to brake the master/developer branch.

What do you think? you add more pros and cons?

Thanks for your time, regards.
-Pablo

Thread Thread
adityasridhar profile image
Aditya Sridhar Author

Thanks for mentioning them :)

You have pretty much covered the pros and cons. Here Will list out some more as well

Pros of forking:

The dev's do not need to worry much about breaking the code by mistake Since they wont have access to the original repo

cons

as you mentioned, it can be more time consuming to update local code

But I did come across branch level permissions as well. So one thing which can be done is only the tech lead and some senior devs have write access to the master and the release branch.

All the other developers will have complete access to feature branches, but a read only access to master and release branch. This will ensure the code in master branch and release branch are reviewed and tested code

What do you think about branch level permissions instead of forking in enterprise projects?

Open source I guess forking is the way to go, Since there will be an explosion of branches if every single open source developer gets their own branch in the original repo :D

Thread Thread
agevaled profile image
Pablo de la Vega

Agreed with you, I'm currently thinking on what is the best approach using fork or branch access on upstream.

As you say OS project is the way to go, but I'm thinking if we will use fork or branch, due the ore junior devs have a lot of issues when they need to update the code :/

Thanks,
-Pablo

Thread Thread
adityasridhar profile image
Aditya Sridhar Author

Either one should be fine :)

Use the method the team is more comfortable with :)

Collapse
benenewton profile image
Ben Newton

One more thing I’d add is make sure the expected git flow is documented. I’ve found that devs will have their own ideas on branching and before you know it you have 3 different naming schemes going for branches. You can explain it once, but they will forget or go back to their way after a long weekend. Great article!

Collapse
karlkras profile image
Karl Krasnowsky

Document? What's that?

Collapse
adityasridhar profile image
Aditya Sridhar Author

Good point. Yes it needs to be documented :)

Collapse
rbukovansky profile image
Richard Bukovansky

Sorry, but this "It is the responsibility of the reviewer to resolve these code conflicts and merge the code. In this case, you as the tech lead need to resolve these code conflicts and merge the code." is fundamentally wrong and that's not how Pull Requests work.

Before any Pull Request can be merged it has to have resolved any conflict with code in target branch (I believe GitHub wouldn't allow merge before the conflicts are resolved). And that is PR author's, no matter if begginer or senior, responsibility. This has been workflow for Linus, for GitHub and its clones, actually everybody for years.

Collapse
adityasridhar profile image
Aditya Sridhar Author

What you are saying is absolutely right for open source projects :)

But in enterprise projects, in case the developer is a beginner , it is better if the tech lead resolves the conflicts. Over time with experience the developer would learn how to resolve conflicts.

I guess i haven't mentioned that clearly in the post. Thanks for pointing out. Will make that more clear in the article

Collapse
rbukovansky profile image
Richard Bukovansky

What I have written is valid for both, open-source or enterprise...

If you developer is a beginner, he can ask somebody to help him with resolving of conflict which is anyway on his branch, not on develop branch. If the TechLead will always resolve those conflicts, those kids will never learn how to do that and would always dump that conflict on Tech Lead. Bad idea...

Thread Thread
adityasridhar profile image
Aditya Sridhar Author

That is a valid point :)

Maybe the right way of putting it in the article would be "The Tech lead can resolve the conflicts in case the deadlines are tight. But best practise is to ensure beginner devs take the help of someone to resolve conflicts so that they learn the process as well"

Collapse
jnareb profile image
Jakub Narębski

There is another method for developer to resolve conflicts, namely rebase his or her changes on top of the current state of main line of development (with interactive rebase the developer would also be able to clean up history to make for easier review). When doing a pull request from rebased branch, it should be able to be merged cleanly.

Collapse
adityasridhar profile image
Aditya Sridhar Author

Yup. I Have written about rebase in this article
adityasridhar.com/posts/how-to-bec...

Will soon post it in dev.to as well

Collapse
t0nyba11 profile image
Tony B

Close to the approach I like, but missing aspects some projects need. If you need to have some sort of Freeze where only fixes to a release are made, but you don't want everyone to stop using the shared branch, you need a branch for the Release Candidate itself. Then naming the branches Production, Release_XX, and Development makes it easier for most people to understand the processes. Makes patches to releases easier too - especially if different releases are in the wild.

Also, ask any 2 developers what Master branch is for, and you will get 3 answers. Best to use a different name. :)

Collapse
adityasridhar profile image
Aditya Sridhar Author

Agreed :D

That will make things more easier to follow

Collapse
guerreroandres profile image
Andres Guerrero

Thanks for this outstanding article.

Actually, in my current company we're implementing Git workflow and it is a good material to my coworkers.

Regards from Ecuador

Collapse
adityasridhar profile image
Aditya Sridhar Author

Happy it helps :)

Collapse
bharris profile image
Benjamin Harris

I'd caution against using / in your branch names. It can cause conflicts with existing files and branches.

coderwall.com/p/qkofma/a-caution-a...

Collapse
adityasridhar profile image
Aditya Sridhar Author

Thanks for sharing :)

Collapse
vlasales profile image
Vlastimil Pospichal

Where is a branch bugfix?

Collapse
adityasridhar profile image
Aditya Sridhar Author

good point. Bugfix process is important as well :)

I was evaluating whether to add bugfix in this article or to have a separate article only for that.
Thought of writing a separate article for bug fix since I wanted to cover some other things as well along with that.

You can checkout atlassian.com/git/tutorials/compar...
for the bugfix process

Collapse
djdany01 profile image
Dani J. Pérez

Hey!
I think this is the best and easy to read explication of Git Workflows I read.

Thank you!!

Collapse
adityasridhar profile image
Aditya Sridhar Author

Thanks for reading the article :)

Collapse
tinsoldier6 profile image
Jason Gade

This was a very clear description of git workflow, thanks!

Collapse
adityasridhar profile image
Collapse
mrtechlust profile image
Alex Atkinson

Just do GitFlow, GitHub Flow, or GitLab Flow. These are industry standards. If you're the edge case new project that one of these doesn't satisfy, less hear about it. :p

Collapse
adityasridhar profile image
Aditya Sridhar Author

This is a slightly changed version of gitflow workflow
atlassian.com/git/tutorials/compar...

Had to make some changes to meet the needs when we worked on projects:D

But yes the ones you mentioned are the industry standards

Collapse
kozkondev profile image
Konstantin Kožokar

Fun fact: Main photo of this article has been taken in subway Rajská Zahrada - Prague

Collapse
apenlor profile image
Info Comment marked as low quality/non-constructive by the community. View code of conduct
Alex

Great post for beginners in Git like me.
Thank you!!

Collapse
adityasridhar profile image
Aditya Sridhar Author

Thank you for reading. Happy it is helpful