Git GitHub and GitLab Workflow
The GitHub and GitLab workflow is how most teams use Git together. Nobody pushes directly to main. Instead, each change lives on a feature branch and is merged through a pull request (GitHub) or merge request (GitLab), where teammates review it and automated checks run.
The Feature Branch Workflow
- Update main: git switch main && git pull.
- Create a branch: git switch -c feature/dark-mode.
- Commit your work in small, clear commits.
- Push the branch: git push -u origin feature/dark-mode.
- Open a pull request / merge request on the website.
- Address review comments by pushing more commits to the same branch.
- Merge when approved and checks pass, then delete the branch.
Opening a Pull Request
After pushing, GitHub and GitLab show a link to open a PR/MR. You can also use the command-line tools gh (GitHub) and glab (GitLab).
git push -u origin feature/dark-mode
gh pr create --title "Add dark mode" --body "Adds a theme toggle and saves the choice."remote: Create a pull request for 'feature/dark-mode' on GitHub by visiting: remote: https://github.com/you/portfolio/pull/new/feature/dark-mode https://github.com/you/portfolio/pull/12
Writing a Good Pull Request
- A clear title that says what changes, not "updates".
- Explain why the change is needed and how you tested it.
- Add screenshots for UI changes.
- Keep it small — a few hundred lines is far easier to review than thousands.
- Link related issues, e.g. "Closes #34" closes the issue automatically on merge.
Merge Options
GitHub and GitLab offer several ways to merge: a merge commit (keeps every commit plus a merge commit), squash and merge (combines the PR into one commit on main), and rebase and merge (replays commits without a merge commit). Many teams choose squash to keep main readable.
Contributing to Open Source with Forks
You cannot push to other people's repositories, so you fork them: a fork is your own copy on GitHub. You push to your fork and open a pull request back to the original (called upstream).
git clone git@github.com:you/awesome-lib.git
cd awesome-lib
git remote add upstream https://github.com/original/awesome-lib.git
# keep your fork in sync
git fetch upstream
git switch main
git merge upstream/main
git push origin mainFrom https://github.com/original/awesome-lib * [new branch] main -> upstream/main Updating 1a2b3c4..5d6e7f8 Fast-forward
Protecting main and CI
Repository settings let you protect main: require pull requests, approvals and passing checks before merging. GitHub Actions and GitLab CI run tests, linters and deployments automatically on every push, defined in .github/workflows/*.yml or .gitlab-ci.yml.
Frequently asked questions
What is the difference between a pull request and a merge request?
They are the same idea with different names. GitHub, Bitbucket and Azure DevOps call it a pull request; GitLab calls it a merge request.
How do I update a pull request after review?
Make the changes on the same branch, commit and push. The pull request updates automatically with the new commits.
How do I sync my fork with the original repository?
Add the original as a remote called upstream, run git fetch upstream, merge upstream/main into your main, and push to your fork. GitHub also has a "Sync fork" button.