Thread (16 messages) flat view 16 messages, 4 authors, 2022-01-04

Re: [PATCH v2 1/1] push: make '-u' have default arguments

From: Eric Sunshine <hidden>
Date: 2021-12-07 22:14:28

On Tue, Dec 7, 2021 at 4:11 PM Abhradeep Chakraborty
[off-list ref] wrote:
[...]
Teach "git push -u" not to require repository and refspec.  When
the user do not give what repository to push to, or which
branch(es) to push, behave as if the default remote repository
and a refspec (depending on the "push.default" configuration)
are given.
[...]
Signed-off-by: Abhradeep Chakraborty <redacted>
This is not a proper review... just some superficial comments from
scanning my eye over the patch...
quoted hunk ↗ jump to hunk
diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh
@@ -60,6 +60,75 @@ test_expect_success 'push -u :topic_2' '
+default_u_setup() {
+       git checkout main
+       remote=$(git config --get branch.main.remote)
+       if [ ! -z "$remote" ]; then
+               git branch --unset-upstream
+       fi
+       git config push.default $1
+       git config remote.pushDefault upstream
+}
A few issues...

* since callers of this function incorporate it into their &&-chains,
the body of the function itself should probably also have an intact
&&-chain

* use `test` rather than `[`

* `then` goes on its own line

* probably want to use test_config() here rather than raw `git config`

* `! -z` can be written more simply as `-n`

Taking the above into account, gives:

    default_u_setup() {
        git checkout main &&
        remote=$(git config --default '' --get branch.main.remote) &&
        if test -n "$remote"
        then
            git branch --unset-upstream
        fi &&
        test_config push.default $1 &&
        test_config remote.pushDefault upstream
    }

The `--default` ensures that `git config` will exit with a success
code which is important now that it's part of the &&-chain.
Alternatively, you could skip the dance of checking for
`branch.main.remote` and just call `git branch --unset-upstream`
unconditionally, but wrap it with test_might_fail() so it can be part
of the &&-chain without worrying about whether that command succeeds
or fails:

    default_u_setup() {
        git checkout main &&
        test_might_fail git branch --unset-upstream &&
        test_config push.default $1 &&
        test_config remote.pushDefault upstream
    }
+test_expect_success 'push -u with push.default=simple' '
+       default_u_setup simple &&
+       git push -u &&
+       check_config main upstream refs/heads/main &&
+       git push -u upstream main:other &&
+       git push -u &&
+       check_config main upstream refs/heads/main
+'
+
+test_expect_success 'push -u with push.default=current' '
+       default_u_setup current &&
+       git push -u &&
+       check_config main upstream refs/heads/main &&
+       git push -u upstream main:other &&
+       git push -u &&
+       check_config main upstream refs/heads/main
+'
+
+test_expect_success 'push -u with push.default=upstream' '
+       default_u_setup upstream &&
+       git push -u &&
+       check_config main upstream refs/heads/main &&
+       git push -u upstream main:other &&
+       git push -u &&
+       check_config main upstream refs/heads/main
+'
When a number of tests have nearly identical bodies like this, it is
sometimes clearer and more convenient to turn them into a for-loop
like this:

    for i in simple current upstream
    do
        test_expect_success "push -u with push.default=$i" '
            default_u_setup $i &&
            git push -u &&
            check_config main upstream refs/heads/main &&
            git push -u upstream main:other &&
            git push -u &&
            check_config main upstream refs/heads/main
        '
    done
+check_empty_config() {
+       test_expect_code 1 git config "branch.$1.remote"
+       test_expect_code 1 git config "branch.$1.merge"
+}
As above, because calls to this function are part of the &&-chain in
test bodies, it is important for the &&-chain to be intact in the
function too. It's especially important in this case since this
function is actually checking for specific conditions. As it's
currently written -- with a broken &&-chain -- if the first
test_expect_code() fails, we'll never know about it since that exit
code gets lost; only the exit code from the second test_expect_code()
has any bearing on the overall result of the test.
+test_expect_success 'progress messagesdo not go to non-tty (default -u)' '
s/messagesdo/messages do/
+       ensure_fresh_upstream &&
+
+       # skip progress messages, since stderr is non-tty
+       git push -u >out 2>err &&
+       test_i18ngrep ! "Writing objects" err
+'
The captured stdout in `out` doesn't seem to be used, so it's probably
better to drop that redirection.
+test_expect_success 'progress messages go to non-tty with default -u (forced)' '
+       ensure_fresh_upstream &&
+
+       # force progress messages to stderr, even though it is non-tty
+       git push -u --progress >out 2>err &&
+       test_i18ngrep "Writing objects" err
+'
Ditto. And repeat for the remaining tests.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help