简体   繁体   中英

Git ignore changes to a single line

I know how to ignore specific lines completely in git using gitattributes (see How to tell git to ignore individual lines, ie gitignore for specific lines of code ), but how would I go about ignore changes to a specific line?

I assume we can use a filter very similarly, but I don't know what my sed script should do to ignore the changes to the line.

For a practical example, I am writing up a C# library that needs a specific build output path depending on the project it's used in as a submodule. Thus, it has to be configured manually wherever it's being used, but that change must not be commited to the library itself.

Original Library.csproj:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    ...
    <OutputPath>bin\Debug\</OutputPath>
    ...
</PropertyGroup>

Submodule Library.csproj:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    ...
    <OutputPath>..\Target\</OutputPath>
    ...
</PropertyGroup>

How do I get git to ignore the change to this line?

With git, there is no way to ignore a single line of code. Once a file is tracked, the whole file is indexed.

Instead of changing the output of the build location, the surrounding code that calls your project should copy the outputs of the build to the proper location. This way you don't mess with the integrity of the submodule.

If you need to dynamically change the output location of the build, you could use an environment variable that is set prior to the build. This way, you could have that location change by changing the value of the environment variable.

For this very specific case, you could set up your clean filter to replace the line with a standard default line. That is, you'd read the incoming XML data stream, find the one item, replace it, and generate the new stream (either generated as all-new XML, or on the fly as you go).

This whole idea is a bad one though. It means that the user's private configuration is stored in their existing work-tree, in a file that Git will overwrite. In other words, there are situations under which Git will be told destroy the user's configuration irretrievably , and Git will obey, and the configuration will be destroyed. To put it back, you will need not only a clean filter but also a smudge filter . The smudge filter must obtain the correct configuration data from somewhere—this cannot be the file that is being destroyed and re-created right now—and put it into the data-stream.

That configuration must therefore also be stored in some other file that Git won't overwrite, either entirely outside the work-tree, or never committed. In this case, you might as well just read the value from the other file. So just use that file. See Ben W's answer for this alternative.

For another, consider having the main XML data read:

<OutputPath type="indirect">/etc/oursoftware.d/config.output</OutputPath>

for instance, to indicate that the output "path" here is the name of another file—in this case /etc/oursofware.d/config.output —that the user will configure to contain the output path. Or, if environment variables are available:

<OutputPath type="envvar">$OURSOFTWARE_OUTPUT_PATH</OutputPath>

indicating that the software is to be run as:

OURSOFTWARE_OUTPUT_PATH=/path/to/file.ext program

for instance. Note that you must change your C# program so that it understands these new XML controls.

After a few hours on this, here is where I have arrived, combining the two answers I have at this time and some supplementary research for my solution:

Answer to the question itself: Not really possible to ignore changes to a line

You can't ignore changes to a single line. The page I referenced in my question only discusses how to DELETE a single line from a commit, not IGNORE CHANGES. The best alternative would be to hook something that would REPLACE the line with something else when you push, and having to put back what was initially removed when you pull, which is possible but very tedious. (See "clean" and "smudge" in the Git Attributes Documentation )


As for the solution I opted to use for my build issues, I decided to write a small batch script, run as Post Build Event , that copies the files built to a target directory, whose path is defined in a file ignored from git to allow modularity.


Another nice solution, proposed by Luis Silva, is to use a.csproj.template file and add.csproj to the gitignore. The template can be copied and modified to fit the needs of the implementation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM