Git 忽略对单行的更改
Git ignore changes to a single line
我知道如何使用 git 属性完全忽略 git 中的特定行(参见 How to tell git to ignore individual lines, i.e. gitignore for specific lines of code),但我将如何忽略 changes 到特定行?
我假设我们可以非常相似地使用过滤器,但我不知道我的 sed 脚本应该做什么来忽略对该行的更改。
举一个实际的例子,我正在编写一个 C# 库,它需要一个特定的构建输出路径,具体取决于它用作子模块的项目。因此,无论在何处使用它都必须手动配置,但不得将更改提交给库本身。
原文Library.csproj:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
...
<OutputPath>bin\Debug\</OutputPath>
...
</PropertyGroup>
子模块 Library.csproj:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
...
<OutputPath>..\Target\</OutputPath>
...
</PropertyGroup>
如何让 git 忽略对此行的更改?
使用git,无法忽略一行代码。一旦文件被跟踪,整个文件就会被索引。
调用您的项目的周围代码不应更改生成位置的输出,而应将生成的输出复制到正确的位置。这样你就不会破坏子模块的完整性。
如果您需要动态更改构建的输出位置,您可以使用在构建之前设置的环境变量。这样,您可以通过更改环境变量的值来更改该位置。
对于这种非常特殊的情况,您可以将清洁过滤器设置为 将 行替换为 标准默认值 行。也就是说,您将读取传入的 XML 数据流,找到一个项目,替换它,然后生成新流(生成为全新的 XML,或者在运行时即时生成).
虽然这整个想法很糟糕。这意味着用户的私人配置存储在他们现有的工作树中,在一个 Git 将 覆盖的文件中。也就是说,在某些情况下,Git会被告知不可挽回地销毁用户的配置,而Git会服从,销毁配置。要将其放回原处,您不仅需要 清洁过滤器,还需要 涂抹过滤器。涂抹过滤器必须从某处获取正确的配置数据——这个不能是正在被销毁并立即重新创建的文件——并将其放入数据流中。
因此,该配置必须也存储在某些其他文件中,Git 不会 覆盖,要么完全在工作树之外,要么从未提交。在这种情况下,您还不如从其他文件中读取值。因此,只需使用该文件即可。有关此替代方案,请参阅 。
另一方面,考虑读取主要 XML 数据:
<OutputPath type="indirect">/etc/oursoftware.d/config.output</OutputPath>
例如,表示此处的输出 "path" 是另一个文件的名称 - 在本例中 /etc/oursofware.d/config.output
- 用户将配置为包含输出路径。或者,如果环境变量可用:
<OutputPath type="envvar">$OURSOFTWARE_OUTPUT_PATH</OutputPath>
表示软件要运行为:
OURSOFTWARE_OUTPUT_PATH=/path/to/file.ext program
例如。 请注意,您必须更改 C# 程序,使其能够理解这些新的 XML 控件。
几个小时后,结合我此时的两个答案和我的解决方案的一些补充研究,这就是我到达的地方:
问题本身的答案:实际上不可能忽略对行的更改
您不能忽略对单行的更改。我在问题中引用的页面仅讨论如何从提交中删除一行,而不是忽略更改。最好的替代方法是挂钩一些东西,当你推动时用其他东西替换线,并且在你拉动时必须放回最初删除的东西,这是可能的但非常乏味。 (参见 Git Attributes Documentation 中的 "clean" 和 "smudge")
至于我选择用于构建问题的解决方案,我决定编写一个小的批处理脚本,运行 as Post Build Event,它将构建的文件复制到目标目录,其路径在文件中定义,从 git 忽略以允许模块化。
Luis Silva 提出的另一个不错的解决方案是使用 .csproj.template 文件并将 .csproj 添加到 gitignore。可以复制和修改模板以适应实施的需要。
我知道如何使用 git 属性完全忽略 git 中的特定行(参见 How to tell git to ignore individual lines, i.e. gitignore for specific lines of code),但我将如何忽略 changes 到特定行?
我假设我们可以非常相似地使用过滤器,但我不知道我的 sed 脚本应该做什么来忽略对该行的更改。
举一个实际的例子,我正在编写一个 C# 库,它需要一个特定的构建输出路径,具体取决于它用作子模块的项目。因此,无论在何处使用它都必须手动配置,但不得将更改提交给库本身。
原文Library.csproj:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
...
<OutputPath>bin\Debug\</OutputPath>
...
</PropertyGroup>
子模块 Library.csproj:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
...
<OutputPath>..\Target\</OutputPath>
...
</PropertyGroup>
如何让 git 忽略对此行的更改?
使用git,无法忽略一行代码。一旦文件被跟踪,整个文件就会被索引。
调用您的项目的周围代码不应更改生成位置的输出,而应将生成的输出复制到正确的位置。这样你就不会破坏子模块的完整性。
如果您需要动态更改构建的输出位置,您可以使用在构建之前设置的环境变量。这样,您可以通过更改环境变量的值来更改该位置。
对于这种非常特殊的情况,您可以将清洁过滤器设置为 将 行替换为 标准默认值 行。也就是说,您将读取传入的 XML 数据流,找到一个项目,替换它,然后生成新流(生成为全新的 XML,或者在运行时即时生成).
虽然这整个想法很糟糕。这意味着用户的私人配置存储在他们现有的工作树中,在一个 Git 将 覆盖的文件中。也就是说,在某些情况下,Git会被告知不可挽回地销毁用户的配置,而Git会服从,销毁配置。要将其放回原处,您不仅需要 清洁过滤器,还需要 涂抹过滤器。涂抹过滤器必须从某处获取正确的配置数据——这个不能是正在被销毁并立即重新创建的文件——并将其放入数据流中。
因此,该配置必须也存储在某些其他文件中,Git 不会 覆盖,要么完全在工作树之外,要么从未提交。在这种情况下,您还不如从其他文件中读取值。因此,只需使用该文件即可。有关此替代方案,请参阅
另一方面,考虑读取主要 XML 数据:
<OutputPath type="indirect">/etc/oursoftware.d/config.output</OutputPath>
例如,表示此处的输出 "path" 是另一个文件的名称 - 在本例中 /etc/oursofware.d/config.output
- 用户将配置为包含输出路径。或者,如果环境变量可用:
<OutputPath type="envvar">$OURSOFTWARE_OUTPUT_PATH</OutputPath>
表示软件要运行为:
OURSOFTWARE_OUTPUT_PATH=/path/to/file.ext program
例如。 请注意,您必须更改 C# 程序,使其能够理解这些新的 XML 控件。
几个小时后,结合我此时的两个答案和我的解决方案的一些补充研究,这就是我到达的地方:
问题本身的答案:实际上不可能忽略对行的更改
您不能忽略对单行的更改。我在问题中引用的页面仅讨论如何从提交中删除一行,而不是忽略更改。最好的替代方法是挂钩一些东西,当你推动时用其他东西替换线,并且在你拉动时必须放回最初删除的东西,这是可能的但非常乏味。 (参见 Git Attributes Documentation 中的 "clean" 和 "smudge")
至于我选择用于构建问题的解决方案,我决定编写一个小的批处理脚本,运行 as Post Build Event,它将构建的文件复制到目标目录,其路径在文件中定义,从 git 忽略以允许模块化。
Luis Silva 提出的另一个不错的解决方案是使用 .csproj.template 文件并将 .csproj 添加到 gitignore。可以复制和修改模板以适应实施的需要。