在 Windows 安装 Git Bash 中更改 ~ 目录的位置

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

我什至不确定我问的问题是否正确。让我解释一下我的情况:

这是关于 Git Windows 7。

我公司将Windows用户目录设置在网络驱动器上,而不是在本地硬盘驱动器上(用于备份和超出本题范围的其他目的)。我无法更改该政策。

我可以在该方案之外拥有本地文件,这就是我的 Apache 服务器的设置方式。完全本地化。

我安装了 Git。它安装 Bash。当我启动 Bash 和 cd ~(切换到根目录)时,我发现它(Bash 根目录)指向我的网络用户目录。我希望它不要那样做。我希望 ~ 位于我硬盘上的其他地方。我想要它,以便当我执行其他操作(例如安装证书、SSH 密钥等)时,它的默认值不会自动使用该网络目录。

我到处都找不着,只能找到涉及别名、重定向、$HOME指向位置的答案。但这根本不是我想要的。

问题是:我可以更改那个目录吗?如果是这样:如何?

更新:所以,$HOME 是我需要修改的。然而,我一直无法找到这个神话般的 $HOME 变量的设置位置,所以我假设它是 PATH 或其他系统版本的 Linux 。 无论如何...

我在 git/etc 下有一个 "profile" 文件。以下是内容(注意没有 $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 ()
  {
    ((  & 0x0002 )) && echo -n "binary" || echo -n "text"
    ((  & 0x0010 )) && echo -n ",exec"
    ((  & 0x0040 )) && echo -n ",cygexec"
    ((  & 0x0100 )) && echo -n ",notexec"
  }

  # Shell dependent settings
  profile_d ()
  {
    local file=
    for file in $(export LC_COLLATE=C; echo /etc/profile.d/*.); 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/*.); 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 '3]0;${PWD}\n3[32m${USER}@${HOSTNAME} 3[33m${PWD/${HOME}/~}3[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

给你: 干得好: 创建系统还原点。 以管理员帐户登录。 删除文件夹 C:\SomeUser。 移动文件夹 c:\Users\SomeUser,使其成为 c:\SomeUser。 打开注册表编辑器。 导航至 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList。 搜索 "ProfileImagePath",直到找到指向 c:\Users\SomeUser 的那个。 修改它,使其指向 c:\SomeUser。 使用系统还原以防出现问题。

我不明白,为什么您不想设置 $HOME 环境变量,因为这正是您所要求的。

cd ~并不是说转到根目录,而是转到用户主目录,也就是由 $HOME 环境变量设置。

Quick'n'dirty 解决方案

编辑 C:\Program Files (x86)\Git\etc\profile 并将 $HOME 变量设置为您想要的任何值(如果不存在则添加)。一个好的位置可以是例如 # Set up USER's home directory 评论的条件之后。必须是 MinGW 格式,例如:

HOME=/c/my/custom/home

保存,打开GitBash执行cd ~。您现在应该位于目录 /c/my/custom/home 中。

访问用户配置文件的所有内容都应该进入此目录,而不是网络驱动器上的 Windows' 配置文件。

注意: C:\Program Files (x86)\Git\etc\profile是所有用户共享的,所以如果机器被多人使用,最好设置$HOME动态:

HOME=/c/Users/$USERNAME

更清洁的解决方案

将Windows中的环境变量HOME设置为你想要的任何目录。在这种情况下,您必须将其设置为 Windows 路径格式(带反斜杠,例如 c:\my\custom\home),Git Bash 将加载它并将其转换为它的格式。

如果您想更改计算机上所有用户的主目录,请将其设置为系统环境变量,您可以在其中可以使用例如 %USERNAME% 变量,这样每个用户都有自己的主目录,例如:

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

如果您想只为自己更改主目录,请将其设置为用户环境变量,这样其他用户就不会了'不受影响。在这种情况下,您可以简单地硬编码整个路径:

HOME=c:\my\custom\home

我会分享我所做的,这不仅适用于 Git,而且适用于 MSYS/MinGW。

通常不会为 Windows 应用程序设置 HOME 环境变量,因此通过 Windows 创建它不会影响任何其他内容。从计算机属性(计算机上的 right-click - 或者它在资源管理器中的任何名称,以及 select 属性,或控制面板 -> 系统和安全 -> 系统),选择 Advanced system settings,然后 Environment Variables... 并创建一个新的 HOME,然后将其分配到任何你喜欢的地方。

如果您不能创建新的环境变量,其他答案仍然有效。 (我仔细研究了如何创建环境变量的细节,因为它很难找到。)

您可以在默认 $HOME 目录(例如 C:\Users\WhateverUser\.bash_profile)中创建具有以下内容的 .bash_profile,而不是修改全局 profile

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

1.Right 点击 Gitbash 快捷方式选择属性
2.Choose "Shortcut" 选项卡
3.Type 您的起始目录到 "Start in" 字段
4.Remove“--cd-to-home”部分来自 "Target" 字段

在我的例子中,我所要做的就是在 Windows 上添加以下 用户变量:

变量名:HOME
变量值:%USERPROFILE%

How to set a Environment Variable(如果您不是系统管理员,您可以使用 用户名的用户变量 部分)

所以,$HOME是我需要修改的。然而,我一直无法找到这个神话般的 $HOME 变量的设置位置,所以我假设它是 PATH 或其他系统版本的 Linux 。 无论如何...**

回答

profile 文件的顶部添加 HOME 成功了。

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 ()
  {
    ((  & 0x0002 )) && echo -n "binary" || echo -n "text"
    ((  & 0x0010 )) && echo -n ",exec"
    ((  & 0x0040 )) && echo -n ",cygexec"
    ((  & 0x0100 )) && echo -n ",notexec"
  }

  # Shell dependent settings
  profile_d ()
  {
    local file=
    for file in $(export LC_COLLATE=C; echo /etc/profile.d/*.); 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/*.); 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 '3]0;${PWD}\n3[32m${USER}@${HOSTNAME} 3[33m${PWD/${HOME}/~}3[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. 没有主驱动器的写入权限
  2. 没有对 Git bash 配置文件的写入权限
  3. 没有从控制面板更改环境变量的管理员权限。

但是下面是从命令行运行的,我能够将 HOME 添加到环境变量。

rundll32 sysdm.cpl,EditEnvironmentVariables

我知道这是一个老问题,但它是 "gitbash homedir windows" 的最高 google 结果,所以我想添加我的发现。

无论我尝试什么,我都无法 git-bash 在我的网络驱动器以外的任何地方启动,(U:) 在我的情况下,每次操作都需要 15-20 秒才能响应。 (VPN 上的远程员工,在该国另一端托管的网络驱动器)

我尝试在 windows 中设置 HOME 和 HOMEDIR 变量。

我尝试在 git 安装的 setc/profile 文件中设置 HOME 和 HOMEDIR 变量。

我尝试将 git-bash 快捷方式上的 "Start in" 编辑为 C:/user/myusername.

"env" 命令在 git-bash shell 中会显示正确的 c:/user/myusername。但是 git-bash 仍会以 U 开头:

最终为我修复的是编辑 git-bash 快捷方式并从目标行中删除“--cd-to-home”。

我正在使用 Windows 10 运行 最新版本 Git-for-windows 2.22.0.

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(2019 年第 3 季度)对于如何设置 HOME 非常明确。

参见 commit e12a955 (04 Jul 2019) by Karsten Blees (kblees)
(由 Junio C Hamano -- gitster -- in commit fc613d2 合并,2019 年 7 月 19 日)

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.

现在,mingw.c 包含以下代码:

/* 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);
}