Okay so the title is a clickbait. This is not a hack, it’s just about setting git configuration differently. However, a surprisingly small number of people knows about it, even within ones who consider themselves git experts. If you already know about this setup congratulations, you rock! If not, this is your chance to become one of the lucky ten thousand and make your workflow less painful.
What’s the problem?
So you decided to contribute to a project that lives on GitHub or GitLab. The
typical setup here is to have the parent repo (to which you want to contribute)
and your fork of the repo where your changes live before they are merged. You
clone your fork to do all the work in and add the parent as a remote to be able
to keep them in sync. Easy, right? The elephant in the repo is that it’s really
easy to forget to update your fork with this flow. Get into the right directory,
run git pull
, create a new branch, do the work, submit the pull request… oops
you forgot to push into your fork when updating and now there are conflicts or
you have to at least rebase!
This happened to me way more often than I’d like even when I was already used to the flow. There had to be a better way.
Harness the powers of .git/config
Having to keep your fork in sync is a lie. The only case when you need it is when you have other people working from your fork instead of the parent repo, which is a very specific use case irrelevant 99% of the time. Instead, you can work directly from the main branch of the parent repo, ignoring your fork’s main branch completely because you don’t need it at all.
How do you do it? Let’s showcase what I’m talking about by an example of my own
.git/config
:
[remote "origin"]
url = https://gitlab.com/veruu/reporter
fetch = +refs/heads/*:refs/remotes/origin/*
[remote "upstream"]
url = https://gitlab.com/cki-project/reporter
fetch = +refs/heads/*:refs/remotes/upstream/*
[branch "main"]
remote = upstream
merge = refs/heads/main
The origin
remote points to my fork and the upstream
one to the parent repo.
This is nothing special. What is worth noticing is the configuration of the
main branch (in this case the [branch "main"]
section), which doesn’t point to
my fork but instead to the upstream
remote! That’s literally all that’s needed,
switching the remote the branch is pointing to!
After switching the config you can happily work the same way you’d with a single
repo without a fork. Your local main branch will follow the parent repo so all
you have to do to keep it in sync is running git pull
as you’d before. Then you
can go on with creating a new branch and development, and by running
git push origin <branch>
you update your fork with the changes.