From: Yuri Kanivetsky Date: Tue, 17 Dec 2024 08:12:27 GMT Subject: Re: remote..push without dst doesn't behave as documented Message-ID: In-Reply-To: So it was your doing :) (no offense meant) https://github.com/git/git/commit/ca02465b41311fe7634acb9bb5b5c61975ef5f38 > If git push [] without any argument is set to update some ref at the destination with with remote..push configuration variable, : part can be omitted—such a push will update a ref that normally updates without any on the command line. Otherwise, missing : means to update the same ref as the . My understanding of this was (the only phrasing that made some sense to me): > If git push [] without any argument __is invoked__ to update some ref at the destination with __and remote..push is set__, : part can be omitted __in remote..push__ -- such a push will update a ref that normally updates without any on the command line. Otherwise, missing : means to update the same ref as the . As such I chose `push.default = upstream` because that's the only mode which allows non-matching refs. I expected it to allow me to discriminate between having and not having :dst in remote..push. But without :dst in remote..push it updated the matching ref (the second test failed). Now I understand that what was really meant: > If remote..push is set and the refspec on the command line doesn't have the :dst part, then the former (remote..push) is used as a refmap. Otherwise (if remote..push is not set), then missing :dst makes it push to the matching branch. I believe the phrasing in the documentation calls for being changed. But also I can't confirm the "otherwise" part. Below the last test fails. Either you have to (unless I'm missing something) say: > If remote..push is not set, then it falls back to the `push.default` behavior. Or make it really push to the matching branch even if `push.default = upstream` and the upstream is a non-matching branch. Regards, Yuri -- The whole file is in a gist: https://gist.github.com/x-yuri/943fd13704b38551da36c8363d7852e1#file-b-md # the state of the cloned repository (1 commit, 1 local branch ba) # a (HEAD -> ba, origin/ba) @test "normally it acts according to push.default" { start_cloned_repo git commit --allow-empty -m b git push assert_equal_refs origin/ba ba } @test "but remote..push changes the destination when the refspec on the command line doesn't have :dst" { start_cloned_repo git config remote.origin.push 'refs/heads/ba:refs/heads/bb' git commit --allow-empty -m b git push origin ba assert_equal_refs origin/bb ba } @test "specifying :dst overrides remote..push" { start_cloned_repo git config remote.origin.push 'refs/heads/*:refs/heads/*' git commit --allow-empty -m b git push origin ba:bb assert_equal_refs origin/bb ba } @test "if remote..push is not set, it pushes to the matching branch" { start_cloned_repo git config push.default upstream git push origin ba:bb git branch -u origin/bb git commit --allow-empty -m b git push origin ba assert_equal_refs origin/ba ba } start_cloned_repo() { (mkrepo) cd "$BATS_TEST_TMPDIR" git clone --bare a a.git git clone a.git b cd b git config user.email you@example.com git config user.name "Your Name" } mkrepo() { cd "$BATS_TEST_TMPDIR" mkdir a (cd a git init git branch -m ba git config user.email you@example.com git config user.name "Your Name" git commit --allow-empty -m a) }