hasanghaforian
hasanghaforian

Reputation: 14042

default set of "refspec" for "git push"

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:

But I am not sure in about my guess. Is it true?

Upvotes: 3

Views: 1689

Answers (2)

VonC
VonC

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 using stat_tracking_info which refers to the upstream branch.

Fix that by introducing a new flag for_push in stat_tracking_info in remote.c, which does the same thing but for the push branch.
Update the few callers of stat_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 bug

Signed-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 checks u.remote_ref without even making sure if the atom is "push" or "push:" (which are only two cases that u.remote_ref.push becomes valid), but u.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

CodeWizard
CodeWizard

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 traditional matching 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 the simple 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 the matching semantics, you can set the variable to matching, for example. Read the documentation for other possibilities.

Upvotes: 0

Related Questions