Git игнорирует изменения в одной строке

Я знаю, как полностью игнорировать определенные строки в git, используя gitattributes (см. -for-specific-lines-of">Как указать git игнорировать отдельные строки, т. е. gitignore для определенных строк кода), но как мне игнорировать изменения для определенного линия?

Я предполагаю, что мы можем использовать фильтр очень похожим образом, но я не знаю, что должен делать мой скрипт sed, чтобы игнорировать изменения в строке.

В качестве практического примера я пишу библиотеку C#, которой требуется определенный путь вывода сборки в зависимости от проекта, в котором она используется в качестве подмодуля. Таким образом, его необходимо настроить вручную, где бы он ни использовался, но это изменение не должно быть зафиксировано в самой библиотеке.

Исходная библиотека.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 игнорировать изменение этой строки?


person Sushi Yeti Dev    schedule 07.04.2020    source источник
comment
что люди делают, так это фиксируют файл шаблона, например Library.csproj.template, и добавляют файл Library.csproj в .gitignore, и таким образом каждый создает свои собственные файлы Library.csproj, которые игнорируются git   -  person Luis Silva    schedule 08.04.2020


Ответы (3)


С git невозможно игнорировать ни одну строку кода. Как только файл отслеживается, весь файл индексируется.

Вместо изменения выходных данных расположения сборки окружающий код, вызывающий ваш проект, должен копировать выходные данные сборки в нужное место. Таким образом, вы не нарушаете целостность подмодуля.

Если вам нужно динамически изменить выходное местоположение сборки, вы можете использовать переменную среды, которая устанавливается до сборки. Таким образом, вы можете изменить это местоположение, изменив значение переменной среды.

person Ben W    schedule 08.04.2020

В этом особом случае вы можете настроить чистый фильтр так, чтобы он заменял строку на стандартную строку по умолчанию. То есть вы читаете входящий поток XML-данных, находите один элемент, заменяете его и генерируете новый поток (либо сгенерированный как совершенно новый XML, либо «на лету» по ходу работы).

Хотя вся эта идея плоха. Это означает, что личная конфигурация пользователя хранится в его существующем рабочем дереве, в файле, который Git перезапишет. Другими словами, бывают ситуации, когда Git будет приказано уничтожить конфигурацию пользователя безвозвратно, и Git подчинится, и конфигурация будет уничтожена. Чтобы вернуть его, вам понадобится не только чистый фильтр, но и грязевой фильтр. Фильтр пятен должен откуда-то получить правильные данные конфигурации — это не может быть файлом, который сейчас уничтожается и создается заново, — и помещать их в поток данных.

Поэтому эта конфигурация должна также храниться в каком-то другом файле, который Git не будет перезаписывать, либо полностью вне рабочего дерева, либо никогда не будет зафиксирован. . В этом случае вы можете просто прочитать значение из другого файла. Так что просто используйте этот файл. См. ответ Бена В. для этой альтернативы.

Во-вторых, рассмотрите возможность чтения основных данных XML:

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

например, чтобы указать, что выходной «путь» здесь является именем другого файла — в данном случае /etc/oursofware.d/config.output — который пользователь настроит так, чтобы он содержал выходной путь. Или, если доступны переменные среды:

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

указывающее, что программное обеспечение должно запускаться как:

OURSOFTWARE_OUTPUT_PATH=/path/to/file.ext program

например. Обратите внимание, что вы должны изменить свою программу C#, чтобы она понимала эти новые элементы управления XML.

person torek    schedule 08.04.2020
comment
Решение с косвенным отображением кажется лучшим в моем сценарии, но я не могу заставить его работать. Как только я добавляю 'type=indirect', я получаю: Тип атрибута в элементе ‹OutputPath› не распознан. - person Sushi Yeti Dev; 08.04.2020
comment
Я предполагаю, что вы написали средство чтения XML, и поэтому вы можете изменить код для обработки атрибута здесь. Вы сказали в конце концов, я пишу библиотеку C#. - person torek; 08.04.2020
comment
Если это то, что вы предлагаете, мне кажется немного чрезмерным изменить средство чтения xml Visual Studio для файлов .csporoj. - person Sushi Yeti Dev; 08.04.2020
comment
Вы не сказали, что используете чужую библиотеку. Вы сказали, что пишете свою собственную библиотеку. - person torek; 08.04.2020
comment
Это моя собственная библиотека, но ‹OutputPath› находится не в .xml, который я читаю с кодом, а в .csproj и связан со сборкой проекта. У меня нет контроля над тем, как читатель обрабатывает это без каких-либо серьезных изменений, потому что это часть самой Visual Studio, а не мой код или чей-либо еще (кроме Microsoft). - person Sushi Yeti Dev; 08.04.2020
comment
Ну, в таком случае вам понадобится другой подход. Общий смысл таков: там, где у вас есть контроль (ваш код), заставьте его работать таким образом, чтобы выполнить вашу задачу. - person torek; 08.04.2020
comment
Я понимаю. К сожалению, ничего из этого не имеет отношения к моему коду. Это связано либо с конфигурациями сборки, либо с конфигурацией git. Я близок к решению, хотя и комбинирую оба ваших ответа. - person Sushi Yeti Dev; 08.04.2020

После нескольких часов на это, вот куда я пришел, объединив два ответа, которые у меня есть на данный момент, и некоторые дополнительные исследования для моего решения:

Ответ на сам вопрос: Невозможно игнорировать изменения в строке

Вы не можете игнорировать изменения в одной строке. На странице, на которую я ссылался в своем вопросе, обсуждается только то, как УДАЛИТЬ одну строку из коммита, а не ИГНОРИРОВАТЬ ИЗМЕНЕНИЯ. Лучшей альтернативой было бы зацепить что-то, что ЗАМЕНИТ леску чем-то другим, когда вы нажимаете, и вам придется возвращать то, что было изначально удалено, когда вы тянете, что возможно, но очень утомительно. (См. «очистить» и «размазать» в документации по атрибутам Git. )


Что касается решения, которое я решил использовать для своих проблем со сборкой, я решил написать небольшой пакетный скрипт, запускаемый как Событие после сборки, которое копирует созданные файлы в целевой каталог, путь которого указан в файле, который игнорируется из git, чтобы обеспечить модульность.


Еще одно хорошее решение, предложенное Луисом Сильвой, — использовать файл .csproj.template и добавить .csproj в gitignore. Шаблон можно скопировать и изменить в соответствии с потребностями реализации.

person Sushi Yeti Dev    schedule 08.04.2020