Working with Carbon means I have to fork some open-source projects to submit a pull request with the ad code integration. Here is the list of the tips I’ve collected while learning how to contribute to the public repositories.
By forking a repository, it means that you’ve cloned an identical project that you can edit. Whenever you make a mistake, the worst-case scenario is to delete the forked repository and clone it again.
The main purpose of these tips is to avoid resetting the repository and understand the workflow to contribute back to the upstream project.
I will be referring to the master
branch as main
in this post. They can be used interchangeably, but most new projects prefer to name their default branch as main
.
Always Create a New Branch
Branching is a safe way for you to experiment with a new feature without affecting the main branch. Even if you’re making a minor update to the README
, you’re still going to create a new branch because it will keep the main branch clean.
Whenever you’re done with a feature, you can push the branch you’re working to your forked repository. Then, you can follow up by submitting a pull request to the upstream.
The upstream
remote refers to the original source of your forked repository. You can check the configured remote repository by running git remote -v
in Terminal. Follow this guide by GitHub to configure remote repository.
Never Commit to the Main Branch
You should never commit to the main branch. I mentioned before that we want to keep the main branch clean. What exactly do we want to keep it clean from?
We don’t want our local commits in the main branch.
The local main branch should always match to the upstream origin. Adding commits to the local main branch will create conflicts that trigger Git to asks you merge, rebase, or fast-forward the tree history.
Instead of committing to the main branch, you want the upstream maintainer to accept your pull request, and then you can match the HEAD of your main branch to the upstream main branch. Here’s the command you can run:
git switch main
git pull upstream main --ff
Let’s run through each line. git switch main
lets you switch to the main
branch where you can apply the update from the upstream. Once you’re on the main
branch, you can pull the latest update and pass --ff
option to fast forward the commits. It’s optional to pass --ff
if you keep the main branch clean, however, it’s a good practice to always decide how you want to deal with the conflicts.
Dealing with Conflicts on Main Branch
I often messed up the main branch when I was learning using Git. The most common mistake is to run this command on the main branch.
git pull upstream main
Here is the problem with the command above.
You’re telling git to fetch and update the active branch to match the remote branch without specifying how you want to deal with the conflicts.
Then this happens:
- I panicked because I didn’t know how to deal with the conflicts.
- I gave up, deleted the folder, and recloned the remote repository.
There is no need to panic because you’re still working on your local and remote branch.1 The worst-case scenario is to delete and refork the repository if you’re still unfamiliar with Git.
However, you can easily fix this issue by running this command:
git reflog
git reset HEAD@{index}
Let’s break down the command above.
reflog
shows the history of updates that happened to the tip of branches in the local repository.git reset HEAD@{index}
reset the branch to the number of moves based on the passedindex
value.HEAD@{index}
is one of many ways to specify revision value. I personally prefer to use thesha1
value.
Syncing Local Main Branch to Upstream
You can deal with most conflicts locally before submitting a pull request. The reason is the upstream main branch might have received more commits since the last time you cloned it. Match the tip of your local main branch to the upstream main branch. Here’s what you can run:
git fetch upstream main
git switch main && rebase upstream/main
git push origin main
Pushing –Force to Remote Branch
Sometimes I want to set things right for both local and remote repository. I don’t plan to keep any updates I’ve made and my main goal is to sync local and remote repository to restart everything.
You can only do this if you’re the only one who manage repository. For example, I can do it for my Jekyll site because the repository is private and no one else will be affected if I forcibly push an update to the remote repository.
git reflog
git reset --hard <sha1-value>
git branch -r
git fetch upstream main && git rebase upstream/main
git push --force origin main
- Check for the
sha1
value we’re going to pass into thegit reset
command. - Reset the branch before it’s broken.
- List all remote repositories with their branches. Most of the time, you’re looking at the
upstream/main
branch. - Fetch the
main
branch fromupstream
and rebase localmain
branch to the upstreammain
branch. - Push local
main
branch toorigin/main
remote branch.
This step will ensure you have a clean slate of a local and remote main branch without deleting the forked repository. Next, create and start your work from the new branch.
Unless you’re working in a company that allows you to push your commit to the remote main branch. ↩