A while back a #devdiscuss post by @ThePraticalDev sparked a great discussion on the advice users have for getting the most out of Github. Either for personal use, team use, open source, career advancement and more. I took the liberty to compile some of the best advice and write this post.
Branches
The first topic I was interested in was branching. At the time, I was getting started on a project that had 30+ branches, mostly abandoned. My first question was, what is the proper way to use branches? What works best? Do they work well at all?
Everyone seemed to agree that branches were the way to go. Here’s the original post with the credit to the following advice, since much of the same advice was recommended multiple times, the credit deserves to be shared.
- Create a branch for every new feature, and delete the branch once the feature is merged into main.
- Rebase master often to keep merging pain free.
- Create a branch for proof of concept work.
- Create a branch for incomplete features when you have to switch focus to another project.
- Git Flow was mentioned a few times. Not knowing much about it, I’ll leave you with this tutorial.
- Bug fixes and refactoring should also be done in a branch.
- Having branches for development and production is also a good practice. Production branch will mostly be untouched other than deployments from the development branch.
- Branches can be any size.
- Pull requests allow you to track code changes even after the branch has been deleted.
- Tag releases.
- Use code reviews to ensure quality.
- Branches should have the same test coverage as master / trunk.
Worth noting a few people don’t use the branching feature, but most feedback indicated they were the way to go. Although no elaboration was given, based on my experience alone, if only a few people are working on the project, and they’re all working on different parts with very little overlapping – you can get away without branches with very little pain. However, the larger your team and or codebase grows, the more you can get out of using branching.
Open Source
- Get to know the people working on the code, learn their names, join the slack, get to know them and ask for help when you need it.
- If you’re not sure where to start – even flagging parts of the readme / documentation that is confusing or seems incomplete, is helpful. Collaborate with people across the world and expose yourself to different coding styles.
- Pull Request everything.
Career Development
- Publish what you’re learning
- If you’re giving talks, put the code, slides, notes all on Github
- Public code helps you understand Git workflow even if it’s only you. Also helps keep a conscious effort to create clean code.
- Build something, any size, with clean code, tests, comments, all the stops to show your capabilities.
Other / General
- Don’t blindly accept code reviews, leave a comment about what you verified – even if its as simple as code you like or dislike.
- Don’t EVER post private keys / api keys / certificates.
- Integrate linters and code checkers
- Integrate Continuous Integration (CI) for building software.
- Use descriptive commit messages and pull request messages.
- Tag your commit messages with the ticket number it corresponds with.
Do you have any to add?
Originally posted on KaydaCode
Top comments (18)
I put my project's documentation on GitHub Pages and wrote scripts to assemble up-to-date docs in the
gh-pages
branch whenever I cut a new version. It took some doing to get everything set up, but it's worked wonders for keeping the docs correct and current without being a major time sink.I'd like to know about your setup. Care to share in a dev.to article or an example repo where I can see it?
The repo is here; look in the build/ directory for the scripts themselves, and in the
scripts
section of package.json to see how they're wired up. The docs/ directory contains the "source" for the documentation.I might write up something more detailed soon but no promises -- it's a holiday week here :)
This is a really cool collection of tips :)
There's one thing I'd add, which is probably just an extension on the topic of Branches with respect to this tip: "Integrate Continuous Integration (CI) for building software."
I think it's very common to misunderstand Continuous Integration to mean "run automated tests on every commit to the master/production branch". Which, in a trunk-based-development environment is a partially complete definition - you definitely want to do that, but there's a lot more to it.
However when utilising git branches, it's important to execute your CI pipeline against all branches for every commit they receive. This ensures that your branches that, from the moment of their creation are slowly slipping away from master, are kept in line by being subject to the same, continuous, scrutiny. This commonly includes performing a merge with master in the CI agent to verify everything hangs together nicely.
This goes hand in hand with rebasing against master constantly.
Doing these two things means that merging back into master becomes super boring. You submit a PR, potentially for a code review, and then everyone feels comfortable about hitting merge because they know the branch plays nicely with master.
Waiting until the merge into master to verify that everything works together just kills your feedback loop. It could take you days to discover a regression that could have been identified in the first commit.
I've also found that businesses respond interestingly to this approach too, because when they have to pay for CI agents to run branch builds, they're suddenly really interested in keeping the number and lifetime of branches short. Which is something we should all want anyway ;)
Thank you for putting this together!
I used to use Gitflow. I don’t anymore because it’s a “hold” technology according to ThoughtWorks. Their reasoning is here: thoughtworks.com/radar/techniques/... and thoughtworks.com/radar/techniques/...
I do use branches though and pretty much do everything on a branch for the specific change/feature and then merge.
So, what is the alternative?
I don't use Gitflow, I use GitHub Flow most of the time (master is always deployable, feature/hotfix branches). I try not to let them live long, but you can't always constantly merge either into master because it is always deployable and you could have broken code at this point if you're merging daily.
I'd definitely like to know how ThoughtWorks handles this.
I'm not intending to hi-jack this conversation, but I felt I could provide some insight as a ThoughtWorker. I certainly don't speak for the organisation as a whole, but I can definitely share some thoughts.
I wrote a comment elsewhere in this discussion that partially addresses your question of "what is the alternative (to Gitflow)?". In general I'd say throw away the prescriptive rules about feature/hotfix/whatever branches, and stick to a simple branching strategy that aims to keep the branches as tightly integrated with master as possible (rebase constantly - literally with every commit), and as short lived as possible (think of days as a maximum unit of measurement for branch life. But hours would be better).
I'll preface the rest of this by saying that branching strategies work excellently for projects where there's low developer trust (like an open source project with random contributors). But if you've got a team of folks that you trust working on a product, the following may be useful.
On a more macro level, ThoughtWorks strongly favours Trunk Based Development over any branching strategy in most cases. The ultimate aim of TBD being that every commit made into a repository should be production ready. If a commit causes your CI pipeline to fail, work stops until it starts passing again.
Sounds like a pain in the ass at first. But committing constantly to master and having your code automatically verified in minutes means that if you've introduced a breaking change you know about it straight away - not a few days later when you merge your branch into master. This greatly reduces this risk of entering "merge hell", or just battling odd bugs after a "big-bang" merge.
You raise a very good point about not being able to merge with master frequently because of potentially broken code in your branch/commits. Luckily, we have feature toggles for that. Feature toggles allow us to deploy unfinished work into production, with the work itself being turned off and not available to your end users.
Your tests can still exercise your new code by turning the feature on in the test suite and doing whatever they want. And an added bonus is, that when it comes time to "release" your new feature, all you've got to do is change a boolean flag to true and you're off to the races.
If your new feature breaks stuff. Just turn it back off. No big, scary, patch to write. No panic. Nice and easy. And once your new feature is stable, remove all of the toggles in your codebase - It helps to think of feature toggles like branches in the sense that you should get rid of them as soon as possible after releasing a feature. Stale feature toggles are the worst.
I'd really highly recommend you give TBD a go. Even if it's just in a small side-project to get a feel for what it's like. To get started all you really need is a git repo, a CI tool (like CircleCI or Travis) and a simple, key-value, configuration file for your feature toggles.
Minor niggle, but catching potential merge issues early isn't a function of your branching strategy and is easy to do without adopting TBD. Just build every branch, and merge in the trunk before you do anything else. If you've introduced a conflict or broken a test someone else wrote in the interim, you'll know about it right after you push. If you wait on testing the merge until you're ready to integrate, you could have problems across multiple commits whether your branch has been alive for hours or days.
Absolutely, you're right on the money here. I addressed this in my other comment, but it's good to surface this point in this thread too.
I love this list. Looking forward to seeing any additional wisdom folks might have in these comments.
Nice article :)
My suggestion would be, if your open source project has > 1 people working on it or using it, it's time to start thinking about a code of conduct. It's much easier to lay down some ground rules when you've got five users rather than five thousand, and it sets the tone for the community going forward.
GitHub makes this really easy now!
Thank you so much for sharing this!
I've been wondering how to step up my Git game for a while and this is one hell of a good start 🏋️
Thank you for the great article! :)
I'm glad that you explicitly pointed out not posting secrets! One thing I'd like to add is never even commit private keys/API keys/certificates/secrets, even if it is in a random local branch. If that commit is ever pushed to the remote repository on GitHub (even if the secret was deleted in future commits) a site crawler could find it in your commit log and start utilizing it.
Nice article!
I advise you to put some example of branching model and how to make a code review.
I think that an article about how to make a good code review can be very helpful for many developers and It could be a second article related to your.
I think that sounds like a great post on its own, you should write it 😊
When contributing to open source, look to see if the repo has a
CONTRIBUTING.md
file for more of an in-depth guide to how they handle accepting code.Great summary of tips, Kim! I already follow most of these, but the ones I don't yet follow, I'll be implementing.