Change the location of the ~ directory in a Windows install of Git Bash

本秂侑毒 提交于 2019-11-26 17:30:24

问题


I am not even sure I am asking the right question. Let me explain my situation:

This is about Git on Windows 7.

My company sets up the Windows user directory on a network drive, not on the local hard drive (for backup and other purposes beyond the scope of this question). I cannot change that policy.

I CAN have local files outside of that scheme however and that is how my Apache server is set up. Entirely local.

I installed Git. It installs Bash. When I fire up Bash and cd ~ (change to the root directory) I find that it (the Bash root) points to my network user directory. I want it not to do that. I want ~ to be elsewhere on my hard drive. I want it so that when I perform other operations such as installing a certificate, an SSH key, etc. its defaults will not automatically use that network directory.

I have searched in vain everywhere, and all I can find refers to answers that involve aliases, redirection, and the location $HOME points to. But that is not what I want at all.

The question is: Can I change that directory? And if so: How?

UPDATE: So, $HOME is what I need to modify. However I have been unable to find where this mythical $HOME variable is set so I assumed it was a Linux system version of PATH or something. Anyway...

I do have a "profile" file under git/etc. Here are the contents (notice no $HOME):

  # To the extent possible under law, the author(s) have dedicated all
  # copyright and related and neighboring rights to this software to the
  # public domain worldwide. This software is distributed without any warranty.
  # You should have received a copy of the CC0 Public Domain Dedication along
  # with this software.
  # If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.


  # System-wide profile file

  # Some resources...
  # Customizing Your Shell: http://www.dsl.org/cookbook/cookbook_5.html#SEC69
  # Consistent BackSpace and Delete Configuration:
  #   http://www.ibb.net/~anne/keyboard.html
  # The Linux Documentation Project: http://www.tldp.org/
  # The Linux Cookbook: http://www.tldp.org/LDP/linuxcookbook/html/
  # Greg's Wiki http://mywiki.wooledge.org/

  # Setup some default paths. Note that this order will allow user installed
  # software to override 'system' software.
  # Modifying these default path settings can be done in different ways.
  # To learn more about startup files, refer to your shell's man page.

  MSYS2_PATH="/usr/local/bin:/usr/bin:/bin"
  MANPATH="/usr/local/man:/usr/share/man:/usr/man:/share/man:${MANPATH}"
  INFOPATH="/usr/local/info:/usr/share/info:/usr/info:/share/info:${INFOPATH}"
  MINGW_MOUNT_POINT=
  if [ -n "$MSYSTEM" ]
  then
    case "$MSYSTEM" in
      MINGW32)
        MINGW_MOUNT_POINT=/mingw32
        PATH="${MINGW_MOUNT_POINT}/bin:${MSYS2_PATH}:${PATH}"
        PKG_CONFIG_PATH="${MINGW_MOUNT_POINT}/lib/pkgconfig:${MINGW_MOUNT_POINT}/share/pkgconfig"
        ACLOCAL_PATH="${MINGW_MOUNT_POINT}/share/aclocal:/usr/share/aclocal"
        MANPATH="${MINGW_MOUNT_POINT}/share/man:${MANPATH}"
      ;;
      MINGW64)
        MINGW_MOUNT_POINT=/mingw64
        PATH="${MINGW_MOUNT_POINT}/bin:${MSYS2_PATH}:${PATH}"
        PKG_CONFIG_PATH="${MINGW_MOUNT_POINT}/lib/pkgconfig:${MINGW_MOUNT_POINT}/share/pkgconfig"
        ACLOCAL_PATH="${MINGW_MOUNT_POINT}/share/aclocal:/usr/share/aclocal"
        MANPATH="${MINGW_MOUNT_POINT}/share/man:${MANPATH}"
      ;;
      MSYS)
        PATH="${MSYS2_PATH}:/opt/bin:${PATH}"
        PKG_CONFIG_PATH="/usr/lib/pkgconfig:/usr/share/pkgconfig:/lib/pkgconfig"
      ;;
      *)
        PATH="${MSYS2_PATH}:${PATH}"
      ;;
    esac
  else
    PATH="${MSYS2_PATH}:${PATH}"
  fi

  MAYBE_FIRST_START=false
  SYSCONFDIR="${SYSCONFDIR:=/etc}"

  # TMP and TEMP as defined in the Windows environment must be kept
  # for windows apps, even if started from msys2. However, leaving
  # them set to the default Windows temporary directory or unset
  # can have unexpected consequences for msys2 apps, so we define
  # our own to match GNU/Linux behaviour.
  ORIGINAL_TMP=$TMP
  ORIGINAL_TEMP=$TEMP
  #unset TMP TEMP
  #tmp=$(cygpath -w "$ORIGINAL_TMP" 2> /dev/null)
  #temp=$(cygpath -w "$ORIGINAL_TEMP" 2> /dev/null)
  #TMP="/tmp"
  #TEMP="/tmp"
  case "$TMP" in *\\*) TMP="$(cygpath -m "$TMP")";; esac
  case "$TEMP" in *\\*) TEMP="$(cygpath -m "$TEMP")";; esac
  test -d "$TMPDIR" || test ! -d "$TMP" || {
    TMPDIR="$TMP"
    export TMPDIR
  }


  # Define default printer
  p='/proc/registry/HKEY_CURRENT_USER/Software/Microsoft/Windows NT/CurrentVersion/Windows/Device'
  if [ -e "${p}" ] ; then
    read -r PRINTER < "${p}"
    PRINTER=${PRINTER%%,*}
  fi
  unset p

  print_flags ()
  {
    (( $1 & 0x0002 )) && echo -n "binary" || echo -n "text"
    (( $1 & 0x0010 )) && echo -n ",exec"
    (( $1 & 0x0040 )) && echo -n ",cygexec"
    (( $1 & 0x0100 )) && echo -n ",notexec"
  }

  # Shell dependent settings
  profile_d ()
  {
    local file=
    for file in $(export LC_COLLATE=C; echo /etc/profile.d/*.$1); do
      [ -e "${file}" ] && . "${file}"
    done

    if [ -n ${MINGW_MOUNT_POINT} ]; then
      for file in $(export LC_COLLATE=C; echo ${MINGW_MOUNT_POINT}/etc/profile.d/*.$1); do
        [ -e "${file}" ] && . "${file}"
      done
    fi
  }

  for postinst in $(export LC_COLLATE=C; echo /etc/post-install/*.post); do
    [ -e "${postinst}" ] && . "${postinst}"
  done

  if [ ! "x${BASH_VERSION}" = "x" ]; then
    HOSTNAME="$(/usr/bin/hostname)"
    profile_d sh
    [ -f "/etc/bash.bashrc" ] && . "/etc/bash.bashrc"
  elif [ ! "x${KSH_VERSION}" = "x" ]; then
    typeset -l HOSTNAME="$(/usr/bin/hostname)"
    profile_d sh
    PS1=$(print '\033]0;${PWD}\n\033[32m${USER}@${HOSTNAME} \033[33m${PWD/${HOME}/~}\033[0m\n$ ')
  elif [ ! "x${ZSH_VERSION}" = "x" ]; then
    HOSTNAME="$(/usr/bin/hostname)"
    profile_d zsh
    PS1='(%n@%m)[%h] %~ %% '
  elif [ ! "x${POSH_VERSION}" = "x" ]; then
    HOSTNAME="$(/usr/bin/hostname)"
    PS1="$ "
  else
    HOSTNAME="$(/usr/bin/hostname)"
    profile_d sh
    PS1="$ "
  fi

  if [ -n "$ACLOCAL_PATH" ]
  then
    export ACLOCAL_PATH
  fi

  export PATH MANPATH INFOPATH PKG_CONFIG_PATH USER TMP TEMP PRINTER HOSTNAME PS1 SHELL tmp temp
  test -n "$TERM" || export TERM=xterm-256color

  if [ "$MAYBE_FIRST_START" = "true" ]; then
    sh /usr/bin/regen-info.sh

    if [ -f "/usr/bin/update-ca-trust" ]
    then
      sh /usr/bin/update-ca-trust
    fi

    clear
    echo
    echo
    echo "###################################################################"
    echo "#                                                                 #"
    echo "#                                                                 #"
    echo "#                   C   A   U   T   I   O   N                     #"
    echo "#                                                                 #"
    echo "#                  This is first start of MSYS2.                  #"
    echo "#       You MUST restart shell to apply necessary actions.        #"
    echo "#                                                                 #"
    echo "#                                                                 #"
    echo "###################################################################"
    echo
    echo
  fi
  unset MAYBE_FIRST_START

回答1:


I don't understand, why you don't want to set the $HOME environment variable since that solves exactly what you're asking for.

cd ~ doesn't mean change to the root directory, but change to the user's home directory, which is set by the $HOME environment variable.

Quick'n'dirty solution

Edit C:\Program Files (x86)\Git\etc\profile and set $HOME variable to whatever you want (add it if it's not there). A good place could be for example right after a condition commented by # Set up USER's home directory. It must be in the MinGW format, for example:

HOME=/c/my/custom/home

Save it, open Git Bash and execute cd ~. You should be in a directory /c/my/custom/home now.

Everything that accesses the user's profile should go into this directory instead of your Windows' profile on a network drive.

Note: C:\Program Files (x86)\Git\etc\profile is shared by all users, so if the machine is used by multiple users, it's a good idea to set the $HOME dynamically:

HOME=/c/Users/$USERNAME

Cleaner solution

Set an environment variable HOME in Windows to whatever you want. In this case, you have to set it in Windows path format (e.g. c:\my\custom\home), Git Bash will load it and convert it to its format.

If you want to change the home directory for all users on your machine, set it as a system environment variable, where you can use for example %USERNAME% variable so every user has his own home directory, for example:

HOME=c:\custom\home\%USERNAME%

If you want to change the home directory just for yourself, set it as a user environment variable, so other users won't be affected. In this case, you can simply hard-code the whole path:

HOME=c:\my\custom\home



回答2:


I'd share what I did, which works not only for Git, but MSYS/MinGW as well.

The HOME environment variable is not normally set for Windows applications, so creating it through Windows did not affect anything else. From the Computer Properties (right-click on Computer - or whatever it is named - in Explorer, and select Properties, or Control Panel -> System and Security -> System), choose Advanced system settings, then Evironment Variables... and create a new one, HOME, and assign it wherever you like.

If you can't create new environment variables, the other answer will still work. (I went through the details of how to create environment variables precisely because it's so dificult to find.)




回答3:


In my case, all I had to do was add the following User variable on Windows:

Variable name: HOME
Variable value: %USERPROFILE%

How to set a Environment Variable (You can use the User variables for username section if you are not a system administrator)




回答4:


Instead of modifying the global profile you could create the .bash_profile in your default $HOME directory (e.g. C:\Users\WhateverUser\.bash_profile) with the following contents:

export HOME="C:\my\projects\dir"
cd "$HOME" # if you'd like it to be the starting dir of the git shell



回答5:


1.Right click to Gitbash shortcut choose Properties
2.Choose "Shortcut" tab
3.Type your starting directory to "Start in" field
4.Remove "--cd-to-home" part from "Target" field




回答6:


So, $HOME is what I need to modify. However I have been unable to find where this mythical $HOME variable is set so I assumed it was a Linux system version of PATH or something. Anyway...**

Answer

Adding HOME at the top of the profile file worked.

HOME="c://path/to/custom/root/".

  #THE FIX WAS ADDING THE FOLLOWING LINE TO THE TOP OF THE PROFILE FILE

  HOME="c://path/to/custom/root/"

  # below are the original contents ===========
  # To the extent possible under law, ..blah blah

  # Some resources...
  # Customizing Your Shell: http://www.dsl.org/cookbook/cookbook_5.html#SEC69
  # Consistent BackSpace and Delete Configuration:
  #   http://www.ibb.net/~anne/keyboard.html
  # The Linux Documentation Project: http://www.tldp.org/
  # The Linux Cookbook: http://www.tldp.org/LDP/linuxcookbook/html/
  # Greg's Wiki http://mywiki.wooledge.org/

  # Setup some default paths. Note that this order will allow user installed
  # software to override 'system' software.
  # Modifying these default path settings can be done in different ways.
  # To learn more about startup files, refer to your shell's man page.

  MSYS2_PATH="/usr/local/bin:/usr/bin:/bin"
  MANPATH="/usr/local/man:/usr/share/man:/usr/man:/share/man:${MANPATH}"
  INFOPATH="/usr/local/info:/usr/share/info:/usr/info:/share/info:${INFOPATH}"
  MINGW_MOUNT_POINT=
  if [ -n "$MSYSTEM" ]
  then
    case "$MSYSTEM" in
      MINGW32)
        MINGW_MOUNT_POINT=/mingw32
        PATH="${MINGW_MOUNT_POINT}/bin:${MSYS2_PATH}:${PATH}"
        PKG_CONFIG_PATH="${MINGW_MOUNT_POINT}/lib/pkgconfig:${MINGW_MOUNT_POINT}/share/pkgconfig"
        ACLOCAL_PATH="${MINGW_MOUNT_POINT}/share/aclocal:/usr/share/aclocal"
        MANPATH="${MINGW_MOUNT_POINT}/share/man:${MANPATH}"
      ;;
      MINGW64)
        MINGW_MOUNT_POINT=/mingw64
        PATH="${MINGW_MOUNT_POINT}/bin:${MSYS2_PATH}:${PATH}"
        PKG_CONFIG_PATH="${MINGW_MOUNT_POINT}/lib/pkgconfig:${MINGW_MOUNT_POINT}/share/pkgconfig"
        ACLOCAL_PATH="${MINGW_MOUNT_POINT}/share/aclocal:/usr/share/aclocal"
        MANPATH="${MINGW_MOUNT_POINT}/share/man:${MANPATH}"
      ;;
      MSYS)
        PATH="${MSYS2_PATH}:/opt/bin:${PATH}"
        PKG_CONFIG_PATH="/usr/lib/pkgconfig:/usr/share/pkgconfig:/lib/pkgconfig"
      ;;
      *)
        PATH="${MSYS2_PATH}:${PATH}"
      ;;
    esac
  else
    PATH="${MSYS2_PATH}:${PATH}"
  fi

  MAYBE_FIRST_START=false
  SYSCONFDIR="${SYSCONFDIR:=/etc}"

  # TMP and TEMP as defined in the Windows environment must be kept
  # for windows apps, even if started from msys2. However, leaving
  # them set to the default Windows temporary directory or unset
  # can have unexpected consequences for msys2 apps, so we define
  # our own to match GNU/Linux behaviour.
  ORIGINAL_TMP=$TMP
  ORIGINAL_TEMP=$TEMP
  #unset TMP TEMP
  #tmp=$(cygpath -w "$ORIGINAL_TMP" 2> /dev/null)
  #temp=$(cygpath -w "$ORIGINAL_TEMP" 2> /dev/null)
  #TMP="/tmp"
  #TEMP="/tmp"
  case "$TMP" in *\\*) TMP="$(cygpath -m "$TMP")";; esac
  case "$TEMP" in *\\*) TEMP="$(cygpath -m "$TEMP")";; esac
  test -d "$TMPDIR" || test ! -d "$TMP" || {
    TMPDIR="$TMP"
    export TMPDIR
  }


  # Define default printer
  p='/proc/registry/HKEY_CURRENT_USER/Software/Microsoft/Windows NT/CurrentVersion/Windows/Device'
  if [ -e "${p}" ] ; then
    read -r PRINTER < "${p}"
    PRINTER=${PRINTER%%,*}
  fi
  unset p

  print_flags ()
  {
    (( $1 & 0x0002 )) && echo -n "binary" || echo -n "text"
    (( $1 & 0x0010 )) && echo -n ",exec"
    (( $1 & 0x0040 )) && echo -n ",cygexec"
    (( $1 & 0x0100 )) && echo -n ",notexec"
  }

  # Shell dependent settings
  profile_d ()
  {
    local file=
    for file in $(export LC_COLLATE=C; echo /etc/profile.d/*.$1); do
      [ -e "${file}" ] && . "${file}"
    done

    if [ -n ${MINGW_MOUNT_POINT} ]; then
      for file in $(export LC_COLLATE=C; echo ${MINGW_MOUNT_POINT}/etc/profile.d/*.$1); do
        [ -e "${file}" ] && . "${file}"
      done
    fi
  }

  for postinst in $(export LC_COLLATE=C; echo /etc/post-install/*.post); do
    [ -e "${postinst}" ] && . "${postinst}"
  done

  if [ ! "x${BASH_VERSION}" = "x" ]; then
    HOSTNAME="$(/usr/bin/hostname)"
    profile_d sh
    [ -f "/etc/bash.bashrc" ] && . "/etc/bash.bashrc"
  elif [ ! "x${KSH_VERSION}" = "x" ]; then
    typeset -l HOSTNAME="$(/usr/bin/hostname)"
    profile_d sh
    PS1=$(print '\033]0;${PWD}\n\033[32m${USER}@${HOSTNAME} \033[33m${PWD/${HOME}/~}\033[0m\n$ ')
  elif [ ! "x${ZSH_VERSION}" = "x" ]; then
    HOSTNAME="$(/usr/bin/hostname)"
    profile_d zsh
    PS1='(%n@%m)[%h] %~ %% '
  elif [ ! "x${POSH_VERSION}" = "x" ]; then
    HOSTNAME="$(/usr/bin/hostname)"
    PS1="$ "
  else
    HOSTNAME="$(/usr/bin/hostname)"
    profile_d sh
    PS1="$ "
  fi

  if [ -n "$ACLOCAL_PATH" ]
  then
    export ACLOCAL_PATH
  fi

  export PATH MANPATH INFOPATH PKG_CONFIG_PATH USER TMP TEMP PRINTER HOSTNAME PS1 SHELL tmp temp
  test -n "$TERM" || export TERM=xterm-256color

  if [ "$MAYBE_FIRST_START" = "true" ]; then
    sh /usr/bin/regen-info.sh

    if [ -f "/usr/bin/update-ca-trust" ]
    then
      sh /usr/bin/update-ca-trust
    fi

    clear
    echo
    echo
    echo "###################################################################"
    echo "#                                                                 #"
    echo "#                                                                 #"
    echo "#                   C   A   U   T   I   O   N                     #"
    echo "#                                                                 #"
    echo "#                  This is first start of MSYS2.                  #"
    echo "#       You MUST restart shell to apply necessary actions.        #"
    echo "#                                                                 #"
    echo "#                                                                 #"
    echo "###################################################################"
    echo
    echo
  fi
  unset MAYBE_FIRST_START



回答7:


So, $HOME is what I need to modify.

However I have been unable to find where this mythical $HOME variable is set so I assumed it was a Linux system version of PATH or something.

Git 2.23 (Q3 2019) is quite explicit on how HOME is set.

See commit e12a955 (04 Jul 2019) by Karsten Blees (kblees).
(Merged by Junio C Hamano -- gitster -- in commit fc613d2, 19 Jul 2019)

mingw: initialize HOME on startup

HOME initialization was historically duplicated in many different places, including /etc/profile, launch scripts such as git-bash.vbs and gitk.cmd, and (although slightly broken) in the git-wrapper.

Even unrelated projects such as GitExtensions and TortoiseGit need to implement the same logic to be able to call git directly.

Initialize HOME in Git's own startup code so that we can eventually retire all the duplicate initialization code.

Now, mingw.c includes the following code:

/* calculate HOME if not set */
if (!getenv("HOME")) {
    /*
     * try $HOMEDRIVE$HOMEPATH - the home share may be a network
     * location, thus also check if the path exists (i.e. is not
     * disconnected)
     */
    if ((tmp = getenv("HOMEDRIVE"))) {
        struct strbuf buf = STRBUF_INIT;
        strbuf_addstr(&buf, tmp);
        if ((tmp = getenv("HOMEPATH"))) {
            strbuf_addstr(&buf, tmp);
            if (is_directory(buf.buf))
                setenv("HOME", buf.buf, 1);
            else
                tmp = NULL; /* use $USERPROFILE */
        }
        strbuf_release(&buf);
    }
    /* use $USERPROFILE if the home share is not available */
    if (!tmp && (tmp = getenv("USERPROFILE")))
        setenv("HOME", tmp, 1);
}



回答8:


I faced exactly the same issue. My home drive mapped to a network drive. Also

  1. No Write access to home drive
  2. No write access to Git bash profile
  3. No admin rights to change environment variables from control panel.

However below worked from command line and I was able to add HOME to environment variables.

rundll32 sysdm.cpl,EditEnvironmentVariables




回答9:


I know this is an old question, but it is the top google result for "gitbash homedir windows" so figured I'd add my findings.

No matter what I tried I couldn't get git-bash to start in anywhere but my network drive,(U:) in my case making every operation take 15-20 seconds to respond. (Remote employee on VPN, network drive hosted on the other side of the country)

I tried setting HOME and HOMEDIR variables in windows.

I tried setting HOME and HOMEDIR variables in the git installation'setc/profile file.

I tried editing the "Start in" on the git-bash shortcut to be C:/user/myusername.

"env" command inside the git-bash shell would show correct c:/user/myusername. But git-bash would still start in U:

What ultimately fixed it for me was editing the git-bash shortcut and removing the "--cd-to-home" from the Target line.

I'm on Windows 10 running latest version of Git-for-windows 2.22.0.




回答10:


Here you go: Here you go: Create a System Restore Point. Log on under an admin account. Delete the folder C:\SomeUser. Move the folder c:\Users\SomeUser so that it becomes c:\SomeUser. Open the registry editor. Navigate to HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList. Search for "ProfileImagePath" until you find the one that points at c:\Users\SomeUser. Modify it so that it points at c:\SomeUser. Use System Restore in case things go wrong.



来源:https://stackoverflow.com/questions/32232978/change-the-location-of-the-directory-in-a-windows-install-of-git-bash

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!