20

I have successfully installed and configured msysGit Portable on my flash drive, and have used it to pull and push GitHub repos. However, I seem to always have to kludge the SSH support.

Specifically, in order for SSH to find my key files, I have to follow these instructions to start a second instance of ssh-agent and then ssh-add my key every time I run git-bash.bat.

Using the output of ssh -v git@github.com to debug I see that msysGit defaults to my Windows user directory to look for keys. It can't do that; I need it to look in its own directory on the portable drive.

How can I force $HOME to be the program's own folder?

Update for broken Vox link

Instructions from this page are similar to the now-broken link I originally posted. Quoted below. Also here's the webarchive of original Vox article.

However, if you try this and get:

% ssh-add
Could not open a connection to your authentication agent. 

then your session is not running under the ssh-agent. You can get around this by restarting a new shell under the agent by running:

exec ssh-agent bash 

where you can replace bash with the shell of your choice. Once you do this, you should be able to run ssh-add to load your key for that shell.

Community
  • 1
  • 1
dgw
  • 476
  • 1
  • 3
  • 16
  • As a byproduct of a solution to this problem, I'm hoping that all the other files that end up scattered through the user directory of whatever PC I'm using will be properly located as well. .bash_history, .gitk, etc. should travel with me, not be left behind every time I switch machines. – dgw Aug 11 '10 at 01:58
  • http://stackoverflow.com/a/19136789/1233435 has some helpful details on the `Could not open a connection to your authentication agent.` error – bbodenmiller Nov 17 '14 at 07:28

2 Answers2

18

The command used to launch git bash is:

C:\Windows\SysWOW64\cmd.exe /c ""C:\Prog\Git\1.7.1\bin\sh.exe" --login -i"

I just tried the following in a DOS session:

C:\>C:\Windows\SysWOW64\cmd.exe /c ""C:\Prog\Git\1.7.1\bin\sh.exe" --login -i"
VonC@XXX /c/
$ echo $HOME
/c/Users/VonC

By default, $HOME$%HOMEPATH%, but if I force %HOME%:

set HOME=/another/path

and then launch the same bash session:

C:\>C:\Windows\SysWOW64\cmd.exe /c ""C:\Prog\Git\1.7.1\bin\sh.exe" --login -i"
VonC@XXX /c/
$ echo $HOME
/another/path

So if you wrap the bash call by a script setting the HOME to:

  • %~dp0 : the path of the wrapper on your USB key
  • or %~d1\your\path: with %~d1 being the drive letter (of your usb key if your wrapper is on it)

, you should be able to force HOME to whatever value you need.


Note (November 2011): since then, the OP dgw has written his own wrapper:

git-bash-portable.bat:

@echo off
rem Copyright (C): 2010 Voyagerfan5761
rem http://technobabbl.es/

set USERPROFILE=%~dp0
set HOMEDRIVE=%~d0
set HOMEPATH=%~p0
set HOME=%~dp0
set HISTFILE=%USERPROFILE%.bash_history
rem set BASHRC=%USERPROFILE%.bashrc

git-bash.bat

The article "Portable Git for Windows: setting the $HOME environment variable to allow complete portability (including SSL keys and configuration for use with GitHub)" also add useful information.

However, if you install Git on a portable drive, you'll want your settings to travel with the installation—which obviously they won't if it is looking for them in a folder which may not exist on other computers.

So, what we need to do is tell Portable Git to treat a specific location within its own folder as the home folder; that way we can copy the whole Git folder anywhere we like and the settings will travel with it.

Community
  • 1
  • 1
VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
  • Thank you very much. I'll try this out as soon as I can (on the road right now, but I'll have time at some point) and will accept your answer once I verify that it'll work. (I'd accept now, but it seems odd to accept an answer before verifying its correctness.) – dgw Aug 13 '10 at 04:25
  • @Voyager: no problem, take your time ;) I have had answer accepted after a long (very long) time before :) See the comments of http://meta.stackexchange.com/questions/36318/whats-the-longest-interval-between-an-answer-being-posted-and-accepted – VonC Aug 13 '10 at 05:52
  • Great thread. :) I've just tested my wrapper and it totally worked like a charm. Only detail left is whether I can get the value of `%~dp0` without the trailing slashes; any ideas? If not, that's fine; my setup is still working great. – dgw Aug 14 '10 at 01:47
  • @Voyager: if you use a fixed path (always the same) in your USB, you ould use just `%d1` and build your path as you see fit. If not, you need to remove the last char, with DOS-based character substitution. See http://www.dostips.com/DtTipsStringManipulation.php. `set str=%str:-1%` should do it. – VonC Aug 14 '10 at 07:21
  • Any ideas why this isn't the default behavior for the portable installer? It's extremely frustrating to figure this out, and I'm pretty sure I'm going to mess it up and require my user to have to mess with this on every computer he uses (ie, he won't use it as a result of this behavior). – mmr Nov 13 '11 at 06:15
  • I think it's just that the developer of the portable package can't be bothered to implement this. I asked, and was told it wouldn't be added. But [here](http://markashleybell.com/articles/portable-git-windows-setting-home-environment-variable) is another solution (tip: read the comments); try out that and [my BAT file](https://gist.github.com/533267) to see what works best for you. – dgw Nov 23 '11 at 08:20
  • how about for the non-portable version? – Jürgen Paul Aug 09 '12 at 09:53
  • @Severus you can write your own `git-cmd.bat` which will re-define `HOME` and call git. – VonC Aug 09 '12 at 11:21
1

Setting the home dir

The solution with a git-bash-portable.bat wrapper opens another Windows CMD window for me that stays in the background.

Another, more native solution is to adjust /etc/profile and set the HOME var there. Just add the following lines to the end of /etc/profile, myuser beeing your virtual username:

# end of /etc/profile
export HOME="/home/myuser"
cd

This sets the proper HOME directory and cds into it. Then the startup mechanism, like loading all files from /etc/profile.d works correctly and you just start git-bash.exe with a doubleclick.

Of course you have to create your home directory for this to work. Start git-bash and create it:

mkdir -p /home/myuser

Starting or reconnecting to the agent

Regarding the agent, it usually has to be reloaded with every git-bash shell opened. A solution to get an independent agent spanning all git-bash windows is to include the following little script ~/.mgssh in the startup. It stores the agent env vars in a file agent.env in the .ssh directory. Any new shell reads the file, checks if the agent is still running and connects to it. If it is not running it starts the agent and rewrites the agent.env file. Make sure your .ssh dir exists.

# cat ~/.mgssh

agentfile=~/.ssh/agent.env

agent_load_env()
{
  test -f "$agentfile" && . "$agentfile" >| /dev/null;
}

agent_start()
{
  (umask 077; ssh-agent >| "$agentfile")
  . "$agentfile" >| /dev/null;
}

agent_load_env

# agent_run_state: 0=agent running w/ key; 1=agent w/o key; 2= agent not running
agent_run_state=$(ssh-add -l >| /dev/null 2>&1; echo $?)

if [ ! "$SSH_AUTH_SOCK" ] || [ $agent_run_state = 2 ]; then
    agent_start
fi

# uncomment this, if you want to add a key on agent startup
#if [ "$SSH_AUTH_SOCK" ] && [ $agent_run_state = 1 ]; then
#    ssh-add
#fi

unset agentfile

Now source the .mgssh script in your .bashrc:

# cat .bashrc
. ~/.mgssh

# ... more .bashrc content

Found this on GitHub:

https://help.github.com/articles/working-with-ssh-key-passphrases/#platform-windows

Killing the agent before stick removal

Usually, before you remove your usbstick you ask Windows to eject the stick, by right clicking it in the explorer or using the little systray icon. This will not work, if your agent is still up and running. Make sure to kill the agent before closing the last shell upon stick removal:

$ ssh-agent -k

unset SSH_AUTH_SOCK;
unset SSH_AGENT_PID;
echo Agent pid 8472 killed;

Remark: Usually you would use eval $(ssh-agent -k) to unset the env vars as well, but as you do this just before closing the shell it's irrelevant. The above startup script .mgssh takes care of cleaning up the ~/.ssh/agent.env file so that does not have to be done either.

Holger Böhnke
  • 632
  • 8
  • 10
  • Interesting approach. +1 – VonC Apr 10 '18 at 09:25
  • Thanks for the +1. I corrected the $USERNAME to a hardcoded user matching the user dir in the home dir - different windows machines probably have different users so $USERNAME does not work. I also added instructions to kill the agent before stick removal. – Holger Böhnke Apr 10 '18 at 11:58