text: #!/usr/bin/env bash
  
  . "$(dirname "$0")/testlib.sh"
  
  ensure_git_version_isnt $VERSION_LOWER "2.3.0"
  
  begin_test "credentials with url-specific helper skips askpass"
  (
    set -e
  
    reponame="url-specific-helper"
    setup_remote_repo "$reponame"
  
    clone_repo "$reponame" "$reponame"
    git config credential.useHttpPath false
    git config credential.helper ""
    git config credential.$GITSERVER.helper "lfstest"
  
    git lfs track "*.dat"
    echo "hello" > a.dat
  
    git add .gitattributes a.dat
    git commit -m "initial commit"
  
    # askpass is skipped
    GIT_ASKPASS="lfs-bad-cmd" GIT_TRACE=1 git push origin main 2>&1 | tee push.log
  
    [ "0" -eq "$(grep "filling with GIT_ASKPASS" push.log | wc -l)" ]
  )
  end_test
  
  begin_test "credentials without useHttpPath, with bad path password"
  (
    set -e
  
    reponame="no-httppath-bad-password"
    setup_remote_repo "$reponame"
  
    printf "path:wrong" > "$CREDSDIR/127.0.0.1--$reponame"
  
    clone_repo "$reponame" without-path
    git config credential.useHttpPath false
    git checkout -b without-path
  
    git lfs track "*.dat" 2>&1 | tee track.log
    grep "Tracking \"\*.dat\"" track.log
  
    printf "a" > a.dat
    git add a.dat
    git add .gitattributes
    git commit -m "add a.dat"
  
    GIT_TRACE=1 git push origin without-path 2>&1 | tee push.log
    grep "Uploading LFS objects: 100% (1/1), 1 B" push.log
  
    echo "approvals:"
    [ "1" -eq "$(cat push.log | grep "creds: git credential approve" | wc -l)" ]
    echo "fills:"
    [ "1" -eq "$(cat push.log | grep "creds: git credential fill" | wc -l)" ]
  
    echo "credential calls have no path:"
    credcalls="$(grep "creds: git credential" push.log)"
    [ "0" -eq "$(echo "$credcalls" | grep "no-httppath-bad-password" | wc -l)" ]
    expected="$(echo "$credcalls" | wc -l)"
    [ "$expected" -eq "$(printf "%s" "$credcalls" | grep '", "")' | wc -l)" ]
  )
  end_test
  
  begin_test "credentials with url-specific useHttpPath, with bad path password"
  (
    set -e
  
    reponame="url-specific-httppath-bad-password"
    setup_remote_repo "$reponame"
  
    printf "path:wrong" > "$CREDSDIR/127.0.0.1--$reponame"
  
    clone_repo "$reponame" with-url-specific-path
    git config credential.$GITSERVER.useHttpPath false
    git config lfs.locksverify false
    git checkout -b without-path
  
    git lfs track "*.dat" 2>&1 | tee track.log
    grep "Tracking \"\*.dat\"" track.log
  
    printf "a" > a.dat
    git add a.dat
    git add .gitattributes
    git commit -m "add a.dat"
  
    GIT_TRACE=1 git push origin without-path 2>&1 | tee push.log
    grep "Uploading LFS objects: 100% (1/1), 1 B" push.log
  
    echo "approvals:"
    [ "1" -eq "$(cat push.log | grep "creds: git credential approve" | wc -l)" ]
    echo "fills:"
    [ "1" -eq "$(cat push.log | grep "creds: git credential fill" | wc -l)" ]
  )
  end_test
  
  begin_test "credentials with useHttpPath, with wrong password"
  (
    set -e
  
    reponame="httppath-bad-password"
    setup_remote_repo "$reponame"
  
    printf "path:wrong" > "$CREDSDIR/127.0.0.1--$reponame"
  
    clone_repo "$reponame" with-path-wrong-pass
    git checkout -b with-path-wrong-pass
  
    git lfs track "*.dat" 2>&1 | tee track.log
    grep "Tracking \"\*.dat\"" track.log
  
    contents="a"
    contents_oid=$(calc_oid "$contents")
  
    printf "%s" "$contents" > a.dat
    git add a.dat
    git add .gitattributes
    git commit -m "add a.dat"
  
    GIT_TRACE=1 git push origin with-path-wrong-pass 2>&1 | tee push.log
    [ "0" = "$(grep -c "Uploading LFS objects: 100% (1/1), 0 B" push.log)" ]
    echo "approvals:"
    [ "0" -eq "$(cat push.log | grep "creds: git credential approve" | wc -l)" ]
    echo "fills:"
    [ "2" -eq "$(cat push.log | grep "creds: git credential fill" | wc -l)" ]
  )
  end_test
  
  begin_test "credentials with useHttpPath, with correct password"
  (
    set -e
  
    reponame="$(basename "$0" ".sh")"
    setup_remote_repo "$reponame"
  
    printf "path:$reponame" > "$CREDSDIR/127.0.0.1--$reponame"
  
    clone_repo "$reponame" with-path-correct-pass
    git checkout -b with-path-correct-pass
  
    git lfs track "*.dat" 2>&1 | tee track.log
    grep "Tracking \"\*.dat\"" track.log
  
    # creating new branch does not re-send any objects existing on other
    # remote branches anymore, generate new object, different from prev tests
    contents="b"
    contents_oid=$(calc_oid "$contents")
  
    printf "%s" "$contents" > b.dat
    git add b.dat
    git add .gitattributes
    git commit -m "add b.dat"
  
    GIT_TRACE=1 git push origin with-path-correct-pass 2>&1 | tee push.log
    grep "Uploading LFS objects: 100% (1/1), 1 B" push.log
    echo "approvals:"
    [ "1" -eq "$(cat push.log | grep "creds: git credential approve" | wc -l)" ]
    echo "fills:"
    [ "1" -eq "$(cat push.log | grep "creds: git credential fill" | wc -l)" ]
    echo "credential calls have path:"
    credcalls="$(grep "creds: git credential" push.log)"
    [ "0" -eq "$(echo "$credcalls" | grep '", "")' | wc -l)" ]
    expected="$(echo "$credcalls" | wc -l)"
    [ "$expected" -eq "$(printf "%s" "$credcalls" | grep "t-credentials" | wc -l)" ]
  )
  end_test
  
  begin_test "git credential"
  (
    set -e
  
    printf "git:server" > "$CREDSDIR/credential-test.com"
    printf "git:path" > "$CREDSDIR/credential-test.com--some-path"
  
    mkdir empty
    cd empty
    git init
  
    echo "protocol=http
  host=credential-test.com
  path=some/path" | GIT_TERMINAL_PROMPT=0 git credential fill > cred.log
    cat cred.log
  
    expected="protocol=http
  host=credential-test.com
  path=some/path
  username=git
  password=path"
  
    [ "$expected" = "$(cat cred.log)" ]
  
    git config credential.useHttpPath false
  
    echo "protocol=http
  host=credential-test.com" | GIT_TERMINAL_PROMPT=0 git credential fill > cred.log
    cat cred.log
  
    expected="protocol=http
  host=credential-test.com
  username=git
  password=server"
    [ "$expected" = "$(cat cred.log)" ]
  
    echo "protocol=http
  host=credential-test.com
  path=some/path" | GIT_TERMINAL_PROMPT=0 git credential fill > cred.log
    cat cred.log
  
    expected="protocol=http
  host=credential-test.com
  username=git
  password=server"
  
    [ "$expected" = "$(cat cred.log)" ]
  )
  end_test
  
  
  if [[ $(uname) == *"MINGW"* ]]; then
    NETRCFILE="$HOME/_netrc"
  else
    NETRCFILE="$HOME/.netrc"
  fi
  
  
  begin_test "credentials from netrc"
  (
    set -e
  
    printf "machine localhost\nlogin netrcuser\npassword netrcpass\n" >> "$NETRCFILE"
    echo $HOME
    echo "GITSERVER $GITSERVER"
    cat $NETRCFILE
  
    # prevent prompts on Windows particularly
    export SSH_ASKPASS=
  
    reponame="netrctest"
    setup_remote_repo "$reponame"
  
    clone_repo "$reponame" repo
  
    # Need a remote named "localhost" or 127.0.0.1 in netrc will interfere with the other auth
    git remote add "netrc" "$(echo $GITSERVER | sed s/127.0.0.1/localhost/)/netrctest"
    git lfs env
  
    git lfs track "*.dat"
    echo "push a" > a.dat
    git add .gitattributes a.dat
    git commit -m "add a.dat"
  
    GIT_TRACE=1 git lfs push netrc main 2>&1 | tee push.log
    grep "Uploading LFS objects: 100% (1/1), 7 B" push.log
    echo "any netrc credential calls:"
    [ "4" -eq "$(cat push.log | grep "netrc: git credential" | wc -l)" ]
  
    echo "any netrc credential fills:"
    [ "2" -eq "$(cat push.log | grep "netrc: git credential fill" | wc -l)" ]
  
    echo "any netrc credential approvals:"
    [ "2" -eq "$(cat push.log | grep "netrc: git credential approve" | wc -l)" ]
  )
  end_test
  
  begin_test "credentials from netrc with unknown keyword"
  (
    set -e
  
    printf "machine localhost\nlogin netrcuser\nnot-a-key something\npassword netrcpass\n" >> "$NETRCFILE"
    echo $HOME
    echo "GITSERVER $GITSERVER"
    cat $NETRCFILE
  
    # prevent prompts on Windows particularly
    export SSH_ASKPASS=
  
    reponame="netrctest"
    setup_remote_repo "$reponame"
  
    clone_repo "$reponame" repo2
  
    # Need a remote named "localhost" or 127.0.0.1 in netrc will interfere with the other auth
    git remote add "netrc" "$(echo $GITSERVER | sed s/127.0.0.1/localhost/)/netrctest"
    git lfs env
  
    git lfs track "*.dat"
    echo "push a" > a.dat
    git add .gitattributes a.dat
    git commit -m "add a.dat"
  
    GIT_TRACE=1 git lfs push netrc main 2>&1 | tee push.log
    grep "Uploading LFS objects: 100% (1/1), 7 B" push.log
    echo "any netrc credential calls:"
    [ "4" -eq "$(cat push.log | grep "netrc: git credential" | wc -l)" ]
  
    echo "any netrc credential fills:"
    [ "2" -eq "$(cat push.log | grep "netrc: git credential fill" | wc -l)" ]
  
    echo "any netrc credential approvals:"
    [ "2" -eq "$(cat push.log | grep "netrc: git credential approve" | wc -l)" ]
  )
  end_test
  
  begin_test "credentials from netrc with bad password"
  (
    set -e
  
    printf "machine localhost\nlogin netrcuser\npassword badpass\n" >> "$NETRCFILE"
    echo $HOME
    echo "GITSERVER $GITSERVER"
    cat $NETRCFILE
  
    # prevent prompts on Windows particularly
    export SSH_ASKPASS=
  
    reponame="netrctest"
    setup_remote_repo "$reponame"
  
    clone_repo "$reponame" repo3
  
    # Need a remote named "localhost" or 127.0.0.1 in netrc will interfere with the other auth
    git remote add "netrc" "$(echo $GITSERVER | sed s/127.0.0.1/localhost/)/netrctest"
    git lfs env
  
    git lfs track "*.dat"
    echo "push a" > a.dat
    git add .gitattributes a.dat
    git commit -m "add a.dat"
  
    git push netrc main 2>&1 | tee push.log
    [ "0" = "$(grep -c "Uploading LFS objects: 100% (1/1), 7 B" push.log)" ]
  )
  end_test
  
  begin_test "credentials with bad netrc creds will retry"
  (
    set -e
  
    printf "machine localhost\nlogin netrcuser\npassword badpassretry\n" >> "$NETRCFILE"
    echo $HOME
    echo "GITSERVER $GITSERVER"
    cat $NETRCFILE
  
    # prevent prompts on Windows particularly
    export SSH_ASKPASS=
  
    # ensure we provide the correct creds through ASKPASS so we can fall back
    # when .netrc fails
    export LFS_ASKPASS_USERNAME="netrcuser"
    export LFS_ASKPASS_PASSWORD="netrcpass"
  
    reponame="netrctest"
    setup_remote_repo "$reponame"
  
    clone_repo "$reponame" repo4
  
    # Need a remote named "localhost" or 127.0.0.1 in netrc will interfere with the other auth
    git remote add "netrc" "$(echo $GITSERVER | sed s/127.0.0.1/localhost/)/netrctest"
    git lfs env
  
    git lfs track "*.dat"
    echo "push a" > a.dat
    git add .gitattributes a.dat
    git commit -m "add a.dat"
  
    GIT_TRACE=1 GIT_ASKPASS="lfs-askpass" git push netrc main 2>&1 | tee push.log
    grep -c "Uploading LFS objects: 100% (1/1), 7 B" push.log
  
    # netrc credentials should be attempted then rejected for the lock request
    echo "netrc credentials attempted:"
    [ "1" -eq "$(cat push.log | grep "netrc: git credential fill" | wc -l)" ]
  
    echo "netrc credentials rejected:"
    [ "1" -eq "$(cat push.log | grep "netrc: git credential reject" | wc -l)" ]
  
    # credhelper should then use askpass to find the proper credentials, which
    # should be successful
    echo "askpass credentials attempted:"
    [ "1" -eq "$(cat push.log | grep "creds: git credential fill" | wc -l)" ]
  
    echo "askpass credentials approved:"
    [ "1" -eq "$(cat push.log | grep "creds: git credential approve" | wc -l)" ]
  
    # askpass creds should be cached and used for the batch request
    echo "cached credentials used:"
    [ "1" -eq "$(cat push.log | grep "creds: git credential cache" | wc -l)" ]
  )
  end_test
  
  begin_test "credentials from lfs.url"
  (
    set -e
  
    reponame="requirecreds-lfsurl"
    setup_remote_repo "$reponame"
    clone_repo "$reponame" "$reponame"
  
    git lfs track "*.dat"
    echo "push a" > a.dat
    git add .gitattributes a.dat
    git commit -m "add a.dat"
  
    echo "bad push"
    git lfs env
    git lfs push origin main 2>&1 | tee push.log
    grep "Uploading LFS objects:   0% (0/1), 0 B" push.log
  
    echo "good push"
    gitserverhost=$(echo "$GITSERVER" | cut -d'/' -f3)
    git config lfs.url http://requirecreds:pass@$gitserverhost/$reponame.git/info/lfs
    git lfs env
    GIT_TRACE=1 git lfs push origin main 2>&1 | tee push.log
    # A 401 indicates URL access mode for the /storage endpoint
    # was used instead of for the lfsapi endpoint
    grep "HTTP: 401" push.log
    # Ensure we didn't make a second batch request, which means the request
    # was successfully retried internally
    [ ! "$(grep "tq: retrying object" push.log)" ]
    grep "Uploading LFS objects:   0% (0/1), 0 B" push.log
  
    echo "bad fetch"
    rm -rf .git/lfs/objects
    git config lfs.url http://$gitserverhost/$reponame.git/info/lfs
    git lfs env
    git lfs fetch --all 2>&1 | tee fetch.log
    grep "Downloading LFS objects:   0% (0/1), 0 B" fetch.log
  
    echo "good fetch"
    rm -rf .git/lfs/objects
    git config lfs.url http://requirecreds:pass@$gitserverhost/$reponame.git/info/lfs
    git lfs env
    GIT_TRACE=1 git lfs fetch --all 2>&1 | tee fetch.log
    # No 401 should occur as we've already set an access mode for the
    # storage endpoint during the push
    [ ! "$(grep "HTTP: 401" fetch.log)" ]
    git lfs fsck
  
    echo "good fetch, setting access mode"
    rm -rf .git/lfs/objects
    git config lfs.url http://requirecreds:pass@$gitserverhost/$reponame.git/info/lfs
    git config lfs.http://$gitserverhost/storage/.access "None"
    git lfs env
    GIT_TRACE=1 git lfs fetch --all 2>&1 | tee fetch.log
    # A 401 indicates URL access mode for the /storage endpoint
    # was used instead of for the lfsapi endpoint
    grep "HTTP: 401" fetch.log
    # Ensure we didn't make a second batch request, which means the request
    # was successfully retried internally
    [ ! "$(grep "tq: retrying object" fetch.log)" ]
  
    git lfs fsck
  )
  end_test
  
  begin_test "credentials from remote.origin.url"
  (
    set -e
  
    reponame="requirecreds-remoteurl"
    setup_remote_repo "$reponame"
    clone_repo "$reponame" "$reponame"
  
    git lfs track "*.dat"
    echo "push b" > b.dat
    git add .gitattributes b.dat
    git commit -m "add b.dat"
  
    echo "bad push"
    git lfs env
    git lfs push origin main 2>&1 | tee push.log
    grep "Uploading LFS objects:   0% (0/1), 0 B" push.log
  
    echo "good push"
    gitserverhost=$(echo "$GITSERVER" | cut -d'/' -f3)
    git config remote.origin.url http://requirecreds:pass@$gitserverhost/$reponame.git
    git lfs env
    GIT_TRACE=1 git lfs push origin main 2>&1 | tee push.log
    # A 401 indicates URL access mode for the /storage endpoint
    # was used instead of for the lfsapi endpoint
    grep "HTTP: 401" push.log
    # Ensure we didn't make a second batch request, which means the request
    # was successfully retried internally
    [ ! "$(grep "tq: retrying object" push.log)" ]
    grep "Uploading LFS objects: 100% (1/1), 7 B" push.log
  
    echo "bad fetch"
    rm -rf .git/lfs/objects
    git config remote.origin.url http://$gitserverhost/$reponame.git
    git lfs env
    git lfs fetch --all 2>&1 | tee fetch.log
    # Missing authentication causes `git lfs fetch` to fail before the progress
    # meter is printed to the TTY.
  
    echo "good fetch"
    rm -rf .git/lfs/objects
    git config remote.origin.url http://requirecreds:pass@$gitserverhost/$reponame.git
    git lfs env
    GIT_TRACE=1 git lfs fetch --all 2>&1 | tee fetch.log
    # No 401 should occur as we've already set an access mode for the
    # storage endpoint during the push
    [ ! "$(grep "HTTP: 401" fetch.log)" ]
    git lfs fsck
  
    echo "good fetch, setting access mode"
    rm -rf .git/lfs/objects
    git config remote.origin.url http://requirecreds:pass@$gitserverhost/$reponame.git
    git config lfs.http://$gitserverhost/storage/.access "None"
    git lfs env
    GIT_TRACE=1 git lfs fetch --all 2>&1 | tee fetch.log
    # A 401 indicates URL access mode for the /storage endpoint
    # was used instead of for the lfsapi endpoint
    grep "HTTP: 401" fetch.log
    # Ensure we didn't make a second batch request, which means the request
    # was successfully retried internally
    [ ! "$(grep "tq: retrying object" fetch.log)" ]
  
    git lfs fsck
  )
  end_test
  