Reputation: 14042
Before this, I thought the effect of git fetch
and git push
on $GIT_DIR/config
are the same, because both are commands for repository engagements
but when we add a repository as remote repository
for current repository, Git creates a default set of refspec
for git fetch
in config
, for example like this:
fetch = +refs/heads/*:refs/remotes/remote_repository/*
Why does not do the same for default set of refspec for git push in config file?
I guess difference is caused by default
purpose of commands:
fetch
is for downloading all objects and refs from another repository
push
is updating specific remote refs along with associated objects
But I am not sure in about my guess. Is it true?
Upvotes: 3
Views: 1689
Reputation: 1329860
Simply put, a branch can pull from one remote tracking branch and push to another.
Even if you set a default push policy (git config push.default
), that would be overridden by a local branch.<name>.push
config.
Since git 2.5, you can differentiate easily between the refspec used for fetch and push (if there is no push refspec for a branch, it defaults to the fetch one)
For instance, if you are on your master branch and want to see if you are ahead or behind compare to the remote tracking branch you are pushing to (by default, origin/master
, but it could be any other remote one if branch.master.push
is set in the config)
git for-each-ref --format="%(push:track)" refs/heads
The shortcut <branch>@{push}
refers directly to the value set in the config branch.master.push
.
For instance, to see the commits you haven't pushed yet:
git log @{push}..
Note that before Git 2.22 (Q2 2019), the %(push:track)
token used in the --format
option to "git for-each-ref
" and friends was not showing the right branch.
This has been fixed.
See commit c646d09 (16 Apr 2019) by Damien Robert (DamienRobert
).
(Merged by Junio C Hamano -- gitster
-- in commit f560a4d, 08 May 2019)
ref-filter
: use correct branch for%(push:track)
In
ref-filter.c
, when processing the atom%(push:track)
, the ahead/behind values are computed usingstat_tracking_info
which refers to the upstream branch.
Fix that by introducing a new flag
for_push
instat_tracking_info
inremote.c
, which does the same thing but for the push branch.
Update the few callers ofstat_tracking_info
to handle this flag. This ensure that whenever we use this function in the future, we are careful to specify is this should apply to the upstream or the push branch.
Warning: The handling of "%(push)
" formatting element of "for-each-ref
" and friends was broken when the same codepath started handling "%(push:<what>)
", which has been corrected with Git 2.32 (Q2 2021).
See commit 1e1c4c5 (11 May 2021) by ZheNing Hu (adlternative
).
(Merged by Junio C Hamano -- gitster
-- in commit 36a255a, 20 May 2021)
ref-filter
: fix read invalid union member bugSigned-off-by: ZheNing Hu
[jc: further test fixes]
Signed-off-by: Junio C Hamano
used_atom.u
is an union, and it has different members depending on what atom the auxiliary data the union part of the "struct used_atom"
wants to record.
At most only one of the members can be valid at any one time.
Since the code checksu.remote_ref
without even making sure if the atom is "push
" or "push:
" (which are only two cases thatu.remote_ref.push
becomes valid), butu.remote_ref
shares the same storage for other members of the union, the check was reading from an invalid member, which was the bug.Modify the condition here to check whether the atom name equals to "
push
" or starts with "push:
", to avoid reading the value of invalid member of the union.
Upvotes: 2
Reputation: 142662
git push
is working a bit different.
You can set the push.default parameter to control it.
Here is the git v2.0 release notes which explain the change in the way git treat push (simple vs matching). This was updated in git v2.0 to fix the default git push
behaviour.
Prior to git v2.0 when you executed git push
it would have pushed all your changed branches (all and not only the current branch).
Git v2.0 Release Notes
Backward compatibility notes
When
git push [$there]
does not say what to push, we have used the traditionalmatching
semantics so far (all your branches were sent to the remote as long as there already are branches of the same name over there). In Git 2.0, the default is now thesimple
semantics, which pushes:
only the current branch to the branch with the same name, and only when the current branch is set to integrate with that remote branch, if you are pushing to the same remote as you fetch from; or
only the current branch to the branch with the same name, if you are pushing to a remote that is not where you usually fetch from.
You can use the configuration variable
push.default
to change this. If you are an old-timer who wants to keep using thematching
semantics, you can set the variable tomatching
, for example. Read the documentation for other possibilities.
Upvotes: 0