【问题标题】:"git branch" outputs result even when I'm inside an ".gitignored" folder即使我在“.gitignored”文件夹中,“git 分支”也会输出结果
【发布时间】:2019-01-19 14:11:54
【问题描述】:

我正在尝试将我当前签出的分支解析到我的 bash 提示符中。在您的 PS1 中使用以下 bash 函数非常容易:

parse_git_branch() {
 git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1="\[$(tput setaf 3)\]\u\[$(tput setaf 2)\]@\[$(tput setaf 4)\]\h \[$(tput setaf 5)\]\w\[$(tput setaf 7)\]\[$(tput setaf 3)\]\$(parse_git_branch) \[$(tput setaf 7)\]\\$ \[$(tput sgr0)\]"

当提示仍然显示.gitignore 文件内的文件夹中的“已签出”分支时,我的问题就出现了。 例如: 假设 /home/rbroggi/workspace/project_one 是 git 跟踪的存储库的根目录(例如:找到 .git 文件夹的位置)。在这个存储库中,我有一个 .gitignore 文件/home/rbroggi/workspace/project_one/.gitignore,其中包含以下记录: ignoredfolder/。一旦将目录更改为ignoredfolder,我会假设git branch 的输出/结果为空,但它会继续输出我在父文件夹中签出的分支。这很烦人,也许如果我了解命令 git branch 的工作原理,我可以避免获得被忽略文件夹的输出。

rbroggi@arch ~/workspace/project_one (master) $ pwd
/home/rbroggi/workspace/project_one
rbroggi@arch ~/workspace/project_one (master) $ cat .gitignore
ignoredfolder/
rbroggi@arch ~/workspace/project_one (master) $ cd ignoredfolder/
rbroggi@arch ~/workspace/project_one/ignoredfolder (master) $ git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
 (master)
rbroggi@arch ~/workspace/project_one/ignoredfolder (master) $

感谢您花时间尝试和帮助我。

罗德里戈·布罗吉

【问题讨论】:

  • 我相信这就是 Git 的工作方式。 Git 根目录(.git 文件夹)的任何子文件夹/文件都是 Git 源代码控制的一部分。 .gitignore 用于指示 Git 你对源代码控制该文件中的文件/文件夹引用不感兴趣。这并不意味着您不能通过git add -f ignoredfolder 对其进行源代码控制,这仍然有效。如果您真的希望分支名称在它们的文件夹中消失。您需要考虑一种方式来阅读.gitignore 进行一些路径匹配。所以我想说不要挂断电话。
  • 这只是向用户表明您在该存储库上所做的任何更改都将在该分支下提交。大多数人不记得在完成大部分工作之前检查工作分支。这个功能只是为了让使用 git 变得更容易,所以你不需要仅仅因为你在错误的分支上而隐藏和应用。
  • 顺便说一句:将 git 分支(和其他信息)添加到提示的功能已经可用。我不知道你的环境,但你可以尝试执行__git_ps1(在 git repo 中)。这个功能是 git 自带的。在 Ubuntu 上,它由 /etc/bash_completion.d/git-prompt 加载,git 安装中的文件名为 git-sh-prompt(我认为是 git-core 的一部分)。 __git_ps1 也很可能在被忽略的文件夹中显示分支。
  • Git 在很大程度上并不关心目录,它只关心在“向上”爬升链时是否能找到有效的.git 目录。到达带有.git 的工作树的顶层后,Git 决定,是的,你在 Git 存储库中——在其中 在哪里 并不重要,只要你里面。如果 Git 出于任何原因需要对任何给定目录中的文件进行操作,它将在需要时创建该目录。如果没有,它将单独保留该目录。所以你在一个 Git 不需要接触的目录中,它会不理它,但这就是它的范围。
  • 我认为它是这样工作的(爬升机制)。如果仅当算法找到“.git”目录后,我试图完成的工作就可以检查它来自的目录是否在 .gitignore 文件之外,仅在这种情况下返回选中的出分支。

标签: bash git gitignore prompt


【解决方案1】:

您假设工作树的不同部分可以以不同方式签出。这是不正确的。

(您可以使用git checkout 更新特定的工作树文件以匹配来自不同提交的版本,但这不会更改签出的版本;这只是意味着您对该文件进行了未提交的更改,如果已提交会导致该文件与另一个提交的版本匹配。)

一个给定的分支(或者,在分离的头部状态下,一个给定的提交)被检出整个 repo。 .gitignore 与此无关,无论您在工作树中的哪个位置,它都是一样的。如果你看到cding 似乎改变了你所在的分支,那是因为你改变了你所在的工作树。

【讨论】:

  • 嗨,马克,实际上我的假设是 .gitignore 文件将映射 git 应该考虑的我的工作树。看起来它不像那样工作,但我不知道为什么 git 不能完全真正忽略子文件夹。
  • @RodrigoBroggi - 为什么不能这样?一方面,忽略规则通常适用于文件,而不是文件夹。 (您可以指定一个模式,表示“此文件夹下的所有路径”,并且在您这样做时如何解释其他路径有一个怪癖,但大多数情况下 git 不知道/关心文件夹并忽略 files 匹配该模式)。并且忽略规则仅适用于 untracked 文件,因此,如果该文件夹中的 repo 中已经有某些内容,它仍然会存在并仍然签出该文件夹。即使文件夹现在是空的,你也可以强制添加一些东西
  • 我没有考虑过这种情况(在将文件夹标记为忽略之前添加了文件夹内的文件的情况)。作为解释,这是非常令人满意的。我唯一的挫败感是我希望在我的主目录中有一个 git repo 来跟踪我的dotfiles 上的更改,但我需要忽略我家中的所有其他文件夹。似乎最好的解决方案是将 repo 复制到另一个目录中,而不是将 home 用作 git repo it...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 2020-06-08
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 1970-01-01
相关资源
最近更新 更多