I was recently working on an open source project (tryfi/hass-tryfi - A Home Assistant integration for pulling data from my dog’s collar using the TryFi API and I found out that Git pushes can behave in a surprising way after I accidentally pushed a bunch of testing commits to the wrong branch.
Background
In my workspace, I had two different remotes. One that tracked my own testing repo and one that was the official repo:
|
|
I had two branches: master
(upstream to origin/master) and official-master
(upstream to officialf/master). This enabled me to do testing work on my own repo and push it and when I thought it was ready, merge into the official repo. Yes these names are confusing. I’ll fix it later.
What was the surprise?
All hell broke loose when I was on my main-master
branch and wanted to push some small commits to the tryfi/hass-tryfi
repo:
|
|
What I assumed would happen is that it would take my main-master
branch commits and push them to main/master
. That would make sense wouldn’t it? Turns out, that’s not what happened. It took all the juicy, barely tested commits on my master
branch of the same name and pushed them to main/master
.
Git Config
After cleaning up my mess, I then tried to figure out what I did wrong. Looking at the Git docs shows an interesting git config option: push.default
that “Defines the action git
push
should take if no refspec is given (whether from the command-line, config, or elsewhere).” It defines the following options:
nothing
- do not push anything (error out) unless a refspec is given. This is primarily meant for people who want to avoid mistakes by always being explicit.current
- push the current branch to update a branch with the same name on the receiving end. Works in both central and non-central workflows.upstream
- push the current branch back to the branch whose changes are usually integrated into the current branch (which is called@{upstream}
). This mode only makes sense if you are pushing to the same repository you would normally pull from (i.e. central workflow).tracking
- This is a deprecated synonym forupstream
.simple
- DEFAULT - push the current branch with the same name on the remote.matching
- push all branches having the same name on both ends. This makes the repository you are pushing to remember the set of branches that will be pushed out (e.g. if you always push maint and master there and no other branches, the repository you push to will have these two branches, and your local maint and master will be pushed there).
So I was using the default of simple
meaning that it pushes the branch with the same name as the remote. Since I pushed to master, it pushed from my master to official/master
.
In a way, I could see how some people might expect this behavior. In this situation, it was unexpected.
Instead, I want to change to use upstream
to always push to the upstream branch. This can be changed with:
|
|