Git 无法在--跳过工作树之后切换分支 我想做什么

Git 无法在--跳过工作树之后切换分支 我想做什么,git,git-branch,git-assume-unchanged,git-skip-worktree,Git,Git Branch,Git Assume Unchanged,Git Skip Worktree,我有一个包含敏感数据的文件,所以我不想将此文件的内容推送到远程服务器 我做了什么? 为了实现这一点,我在文件为空时进行了提交,并将此空文件推送到服务器(GitHub)。然后用敏感数据填充文件并应用git更新索引--跳过工作树路径/to/file。但我没有做出任何承诺 现在我正在尝试切换我的分支,但出现以下错误: error: Your local changes to the following files would be overwritten by checkout: pa

我有一个包含敏感数据的文件,所以我不想将此文件的内容推送到远程服务器

我做了什么? 为了实现这一点,我在文件为空时进行了提交,并将此空文件推送到服务器(GitHub)。然后用敏感数据填充文件并应用
git更新索引--跳过工作树路径/to/file
。但我没有做出任何承诺

现在我正在尝试切换我的分支,但出现以下错误:

    error: Your local changes to the following files would be overwritten by checkout:
    path/to/file
    Please, commit your changes or stash them before you can switch branches.
    Aborting
为什么我使用
跳过工作树
而不是
假定未更改
? 我读了一些关于这个主题的问题,发现

--假定未更改假定开发人员不应更改文件。此标志用于提高不更改SDK等文件夹的性能

--当您指示git不要触摸特定文件,因为开发人员应该更改它时,skip worktree非常有用。例如,如果主存储库上游承载一些生产就绪配置文件,并且您不想意外地提交对这些文件的更改,那么跳过工作树正是您想要的

在这之后,我找到了。杰夫的问题和我的几乎一样,我遵循了VonC的解决方案。然而,这对我来说不起作用。可能是因为git版本的不同。因为这个问题来自2012年。我们和VonC谈过,他说要问这个新问题,因为他记不起答案了

我试图同时使用
--假定未更改
--跳过工作树
,并软重置工作树。但一切都没有改变

所以 你能帮我解决我的问题吗


谢谢。

是否有理由签入该文件的空变体?如果不是

git rm --cached path/to/file
echo 'path/to/file' >> .gitignore
git commit -m'stop tracking path/to/file'
也许能解决你的问题。(必须对包含该文件的每个分支重复。或者,如果您不介意重写历史记录,也可以使用
git filter branch
在以前的提交中删除它。)

您可以同时添加skip worktree标志(如果您单独添加稀疏签出,它可能会被删除)

要排除文件,应将其放入稀疏签出文件(请参阅手册):


然后它在更新时不会被触摸(所以您不会在那个里获得另一个分支的内容,而是保留您的编辑)。这可能不是您想要的。

我还没有找到一个简单的解决方案,所以我正在使用
.bat
文件对受影响的文件运行
--无跳过工作树。然后,我将
stash
,切换分支,
stash apply
,然后使用另一个
.bat
文件在相同的文件上运行
--skip worktree

这并不好,但这是迄今为止我找到的最简单、最快捷的方法

更新: 我又遇到了这个问题,所以我创建了一个PowerShell脚本,而不是上面提到的
.bat
文件。它将提示用户是否要跳过文件。更新这两个参数,就可以开始了:

[string]$repoPath=“C:\Fully\Qualified\Path”
[string[]$filesToSkip=@(
“Local/Path/To/File.txt”,
“Local/Path/To/OtherFile.txt”
)
$skipText=读取主机-提示“跳过文件?”?(是/否)"
$skip=$skipText-类似于“y”
cd$repoPath
foreach($filesToSkip中的文件)
{
如果($skip)
{
写入主机“跳过”$文件
git更新索引--跳过工作树$file
}
其他的
{
写入主机“不跳过”$文件
git更新索引--不跳过worktree$文件
}
}

到目前为止,-假设未更改,-跳过worktree不象我发现的那样工作。我的git版本是:到目前为止,git版本2.8.4(Apple git-73)隐藏是唯一有效的方法。

我也遇到了同样的问题,归结起来是由于我想假设的文件发生了更改

因此,如果我只是在文件上不假设未更改,则将其隐藏,签出最新版本,弹出我的隐藏,然后再次假设未更改


因此,现在我可以再次切换分支了。

这是一个粗糙的解决方案,但似乎工作得相当好(尽管它只是经过少量测试):

路径
的某处创建一个名为
git checkoutsw
的文件,包含以下内容:

#!/bin/bash
ignored=( $(git ls-files -v | grep "^S " | cut -c3-) )
for x in "${ignored[@]}"; do
  git update-index --no-skip-worktree -- "$x"
done
git checkout -m $@
for x in "${ignored[@]}"; do
  git update-index --skip-worktree -- "$x"
done
该脚本捕获被忽略文件的列表,取消忽略它们,使用
-m
(用于合并)和指定的任何其他参数签出新分支,然后再次忽略它们

现在,您可以执行
git checkoutsw
而不是
git checkout

只需找到一行即可--不跳过所有文件上的工作树

git ls-files -v | grep "^S" | cut -c 3- | xargs -L1 git update-index --no-skip-worktree

您可以很容易地使用该命令创建一个小别名。unhideall:)

我推送了文件的空变体,否则其他文件(包括此
sensitivefile.php
和这些文件)将产生文件未找到错误。因此必须有一个
sensitivedata.php
文件,不管它是否为空。您是否考虑过将创建该文件作为构建过程的一部分?一种常见的模式是,在某些IDE中使用项目之前和完整构建之前,都要运行一个
/configure
脚本。只要它和触摸一个文件一样无害且(计算上)便宜,那么从a调用该脚本可能是值得的。我试图重现这个问题,但它对我有效。我复制它的唯一方法是如果我的私有文件在我的分支之间是不同的。您是否仔细检查了分支之间的
path/to/file
是否完全相同?Do
git diff branch1..branch2--path/to/file
@Eray Justin是对的。您必须确保有问题的文件(之前--skip worktree)在您的分支中是相同的。您可以共享您的.bat文件吗?@Woland我恐怕再也没有这个文件的副本了,但如果我没记错的话,有一个只包含
——每个文件都没有跳过工作树
,还有一个只包含
——跳过工作树
git ls-files -v | grep "^S" | cut -c 3- | xargs -L1 git update-index --no-skip-worktree