Before Your First Commit: Reconnaissance in a New Codebase
Git is a tool for recording changes. It has no opinion about branches, releases, or reviews.
Everything you think of as "the Git workflow" is a team agreement layered on top: which branches exist, what they mean, how work gets onto them, and what has to happen before it does. Two teams using identical software can work in completely incompatible ways, and both can be right.
This is why guessing costs you.
I once opened my first pull request at a new job against the wrong branch. I branched from main out of habit, but they integrated on develop. Writing the three-line change had taken minutes, but fixing it cleanly meant wrestling with git rebase --onto or cherry-picking to a new branch, which needless to say took longer than writing the code. Awkward.
Your first pull request is not judged on the code. It is judged on whether it looks like everyone else's. The conventions that decide that are almost never written down in full.
That's why I say before you write a line of code in a new repository, do your reconnaissance.
1. Work out which model you have joined
Before anything else, look at the branch list and the recent history. It tells you most of what you need.
git branch -a
git log --oneline --graph --decorate -30
If you see long-lived branches called develop or release/1.4, you are probably in something like Git flow. If you see only main and a handful of short-lived branches merged within a day or two, you are probably in trunk-based development or GitHub flow. If the history is a straight line with no merge commits, the team rebases and probably requires it.
Git flow, properly explained
Git flow is a specific, named model. People often use the term loosely for anything with a develop branch, but here is the actual shape:
mainholds what is in production. Every commit on it is a release, usually tagged.developholds work that is finished but not yet released. It is the integration branch.- Feature branches come off
developand merge back into it. One per piece of work. - Release branches are cut from
developto stabilise the next release (bug fixes only, no new features). When the release goes out, the branch merges intomainand back intodevelop. Forgetting that second merge is how a bug gets fixed in one release and reappears in the next.
Git flow optimises for scheduled releases and supported versions.
The alternatives
- Trunk-based development keeps one long-lived branch. Work happens on branches that live for hours or a day, merging back quickly. Unfinished work is hidden behind feature flags that can live in a database. It optimises for continuous delivery.
- GitHub flow sits in between. One
mainbranch, a branch per change, a pull request, review, merge, deploy. Nodevelop, no release branches.
Which model a team uses is decided by its release constraints. Frequent releases and a single live version point to trunk-based or GitHub flow. Scheduled releases, or older versions still receiving fixes, require release branches.
2. Check for hidden checklists
Before you create a branch, look for a .github/PULL_REQUEST_TEMPLATE.md or a CONTRIBUTING.md file hidden in the repository root.
Teams often bury their most rigid conventions here. You might find that all PR titles must include a Jira ticket number, that UI changes require before-and-after screenshots, or that database migrations must be in a separate PR. Finding this out before you open the PR saves you from having to immediately rewrite your description.
3. Branch naming and history policy
Most teams have a branch naming convention, usually including the ticket key:
feature/CC-1234-add-payment-retry
bugfix/CC-1290-null-reference-on-checkout
This is not decoration. The ticket key in the branch name is what lets the issue tracker and the repository stay connected. Auto-linking is what lets somebody in a year's time work out why a change was made.
Teams also differ on what the Git history should look like:
- Merge commits preserve exactly what happened, including your intermediate commits.
- Squash and merge collapses your branch into a single commit on the target branch. This is the most common modern default.
- Rebase and merge replays your commits onto the target branch, producing a linear history.
Commit messages have conventions too. If a team uses Conventional Commits (prefixing messages with feat: or fix:), getting the prefix wrong is not a style preference, it breaks the automated release notes.
4. Prepare for the robots
The workflow isn't just human reviews; it is the automated checks that attack your branch. Two things will catch you off guard if you don't look for them:
Pre-commit hooks: You try to make your first commit, and your terminal explodes with errors. Many teams use tools like Husky, Prettier, or Black to force linting and formatting before a commit is allowed. Check the package.json or equivalent to see if you need to run an install script to set these up locally.
The CI/CD Gauntlet: Check the Actions or Pipelines tab to see how the automation behaves. Does the build take 3 minutes or 45? Does a linter auto-fail the PR for a missing trailing comma? Knowing how aggressive the automation is changes how you commit.
5. Read the last twenty merged pull requests
I wish somebody had told me this on day one, rather than working it out in month three.
Before you open your first PR, spend twenty minutes reading the last twenty PRs that were successfully merged.
This is the single most useful piece of advice in this article. It shows you the expected branch sizes, the description style, the review tone, how much discussion is normal, and who reviews what. You will learn more about the team's engineering culture from reading 20 merged PRs and their comments than from any onboarding document.
When you do open yours:
If possible, make it small so you get feedback quickly, and because it shows momentum to have something merged early.
Leave comments to point out what you are unsure about, like "I wasn't sure if this was the best place to put the retry logic," because it invites the guidance you actually want and reviewers respond well to it.
6. The parts nobody explains until it is urgent
Branch protection. Most repositories block direct pushes to the main branch. The rules live in GitHub or GitLab rather than in Git, so the rejection comes from the remote server, and it will hold until the required checks pass and the required reviewers approve.
Code owners. Many repositories name specific people or teams who must review changes to particular directories. If your pull request sits untouched for two days, check whether it is waiting on somebody who was never notified.