46

我想做的事

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

我做了什么?

为了实现这一点,我在文件为空时进行了提交,并将这个空文件推送到服务器(GitHub)。然后用敏感数据填充文件并应用git update-index --skip-worktree path/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

为什么我使用skip-worktree而不是assume-unchanged

我阅读了一些关于这个主题的 SO 问题,并找到了 Borealid 的答案

--assume-unchanged 假定开发人员不应该更改文件。此标志旨在提高 SDK 等不更改文件夹的性能。

--skip-worktree 当您指示 git 不要碰特定文件时很有用,因为开发人员应该更改它。例如,如果上游的主存储库托管了一些生产就绪的配置文件,并且您不想意外提交对这些文件的更改,那么 --skip-worktree 正是您想要的。

在此之后,我找到了Jeff's questionVonC's answer。Jeff 的问题和我的差不多,我遵循了 VonC 的解决方案。但是,这对我不起作用。可能是因为 git 版本不同。因为那个问题来自 2012 年。我们与 VonC 进行了交谈,他说这是一个新问题,因为他不记得答案了。

我尝试将--assume-unchanged--skip-worktree 一起使用,以及软重置工作树。但什么都没有改变。

所以?

你能帮我解决我的问题吗?

谢谢你。

4

7 回答 7

8

我一直无法找到一个简洁的解决方案,所以我正在使用一个.bat文件来运行--no-skip-worktree受影响的文件。然后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 = Read-Host -Prompt 'Skip files? (y/n)'
$skip = $skipText -like "y"
cd $repoPath
foreach ($file in $filesToSkip)
{
    if($skip)
    {
        Write-Host "Skipping" $file
        git update-index --skip-worktree $file
    }
    else
    {
        Write-Host "No-skipping" $file
        git update-index --no-skip-worktree $file
    }
}
于 2016-06-17T11:02:55.563 回答
3

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

git-checkoutsw在你的某处创建一个名为的文件PATH,内容如下:

#!/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

该脚本捕获被忽略文件的列表,取消忽略它们,使用 (for merge) 和指定的任何其他参数签出新分支-m,然后再次忽略它们。

现在你可以git checkoutsw代替git checkout.

于 2018-09-27T22:42:14.307 回答
2

您可以启用稀疏检出并在其中添加文件以及添加跳过工作树标志(如果您单独添加稀疏检出,它可能会被删除)。

要排除文件,您应该将其放入 sparse-checkout 文件(请参阅git-read-tree手册):

/*
!unwanted

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

于 2016-05-06T07:29:28.823 回答
2

我遇到了同样的问题,归结为我想假设的文件上的传入更改 - 未更改。

因此,如果我只是对文件执行 no-assume-unchanged,则将其存储,检出最新版本,弹出我的存储,然后再次假定未更改。

所以现在我可以再次切换分支。

于 2017-06-30T08:56:13.347 回答
1

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

git rm --cached path/to/file
echo 'path/to/file' >> .gitignore
git commit -m'stop tracking path/to/file'

可能会解决您的问题。(对于具有该文件的每个分支都必须重复。或者,如果您不介意历史重写,git filter-branch也可以在以前的提交中使用它来摆脱它。)

于 2015-04-09T21:38:34.467 回答
1

只需找到一行在所有文件上执行 --no-skip-worktree

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

您可以使用该命令轻松创建一个小 alias.unhideall :)

于 2018-11-27T08:39:14.880 回答
0

到目前为止, --assume-unchanged 和 --skip-worktree 不像我发现的那样工作。我的 git 版本是:git version 2.8.4 (Apple Git-73) Stash 是目前唯一可行的方法。

于 2017-01-04T19:51:21.380 回答