58

I'd like to create a very simple shell script, which will ultimately be called by another application, that updates a local git repository:

#!/bin/bash

cd $1
sudo git pull

When executing this I'm asked for credentials (I'm pulling from a private BitBucket repository).

Can I ( briefly) store credentials in environment variables?

#!/bin/bash

export  GIT_USERNAME=<user>
export  GIT_PASSWORD=<pass>

cd $1
sudo git pull

The above doesn't work. Would anything? I could programmatically modify the origin url but that seems a bit execessive.

Jon Cram
  • 16,609
  • 24
  • 76
  • 107
  • 4
    git doesn't use credentials, it relies on the transport being used. Are you using git over ssh? If so you should look at ssh keys. – CB Bailey Dec 16 '11 at 16:01

4 Answers4

84

I know that it's very old question but if you really need to pass username and password for HTTP basic authentication you can just set helper like this:

git config credential.helper '!f() { sleep 1; echo "username=${GIT_USER}"; echo "password=${GIT_PASSWORD}"; }; f'

UPDATE: I've added sleep 1 to the function. In some environments it may be probably needed due to race condition. I've got 2 virtual machines running Debian Jessie. They had the same architecture but different CPU and different number of cores. On one of these machines the helper was working fine without sleep. On the other one it wasn't. After few hours of debugging I run strace to see what's happening. And it magically started to work. strace just made git a little bit slower.

Patryk Ściborek
  • 1,031
  • 7
  • 8
  • 1
    Thanks a lot! Works fine for HTTP-based pushes! For SSH I would also vote for keys though. – Ben Steinert Apr 21 '17 at 12:27
  • 5
    What does the use of the exclamation mark in `'!f()` do here? It seems this would be a reference to a previous command in history. Using `bash` to execute what is in the helper string as a plain command causes an error with this syntax anyway. I'm curious why it works. – ely Jul 11 '17 at 14:47
  • 3
    N/m -- I see now this is unique to git, but I couldn't find it in the git documentation. The exclamation mark tells git to treat the string config option as executable shell code. For credential helper, for example, if it doesn't treat it as executable, then it tries to append the string to the 'credential' argument and follow it by other options specified in the string. – ely Jul 11 '17 at 15:00
  • 1
    Git documentation to help explain how this works: https://git-scm.com/book/gr/v2/Git-Tools-Credential-Storage – Randy31 Jul 11 '17 at 15:04
  • I had issues with the newline character not being echo'd consistently on different systems. Using `printf` in place of `echo` is supposedly more reliable. – iturgeon Apr 14 '18 at 18:11
  • 1
    `-e` parameter to `echo` is missing to interpret `\n` correctly. Excellent answer otherwise. – Michael Tabolsky Aug 03 '18 at 15:44
  • I tried both and it didn't seem to work for whatever reason. This method seems to work https://alanedwardes.com/blog/posts/git-username-password-environment-variables/. Is there anything I might be overlooking? – Alexander Lallier Sep 05 '18 at 14:54
  • Newline characters in the (`username`, `password`, etc.) keys and values are not allowed by `git-credential`: https://git-scm.com/docs/git-credential#IOFMT – argonym Apr 17 '20 at 12:14
  • Yes, there does seem to be a timing issue. The credential helper only worked intermittently for me until I inserted the sleep 1. – user100464 Feb 15 '22 at 01:58
  • As a side note, even though the example in the documentation creates a function `f` and then calls it. You don't need to do that, you can just write this as: `'!echo "username=${USERNAME}"; echo "password=${PASSWORD}";'` – Peter Frost Feb 13 '23 at 16:08
  • @Randy31: It's Greek to me – mirekphd May 02 '23 at 16:04
24

You can set the username in the git config with:

git config credential.https://github.com.username $GIT_USER

Then you can set the GIT_ASKPASS environment variable to a script that will provide the password:

export GIT_ASKPASS=/path/to/git_env_password.sh

The contents of git_env_password.sh would be:

#!/bin/bash
echo $GIT_PASSWORD

N.B: This will store the username in the git config, so if you are not okay with that use another solution.

For more info consult the gitcredentials man page.

Mike Dotterer
  • 1,198
  • 1
  • 11
  • 19
12

If you're only running one git command in your script you can make the config change extremely localised using the -c argument (scroll right to see the pull command).

git -c credential.helper='!f() { sleep 1; echo "username=${GIT_USER}"; echo "password=${GIT_PASSWORD}"; }; f' pull

(I would have commented on patryk's answer but lack the reputation points at time of writing)

HumbleEngineer
  • 161
  • 1
  • 4
2

Yes you can pass you git Passwort/Username with env, using git-credential-env

GIT_USER=foo
GIT_PASS=bar
npm install -g git-credential-env
git config credential.helper "env --username=GIT_USER --password=GIT_PASS"

The wiki in this project says

You can accomplish the same behavior by using an inline bash function:
GIT_USER=foo
GIT_PASS=bar
git config credential.helper "!f() { echo \"username=${GIT_USER}\\npassword=${GIT_PASS}\"; }; f"
Radon8472
  • 4,285
  • 1
  • 33
  • 41