Изменения, которые явно не связаны с человеком (который может понимать код), регулярно путаются алгоритмом diff в Git. Например
def method_that_already_existed(blah)
a line that did not change
a line that was deleted ######## the changed area starts here (per Git)
a new line
end
def a newly_added_method_that_belongs_in_its_own_commit
blah blah blah
blah blah blah
etc. ######## the changed area ends here (per Git)
end
Для человека очевидно, что изменения в первом методе и совершенно новом методе - это совершенно разные изменения. Но Git относится к ним как к одному и НЕ ПОЗВОЛЯЕТ МНЕ РАЗДЕЛИТЬ ИХ ПОД ЛЮБЫМИ ОБСТОЯТЕЛЬСТВАМИ.
Хуже того, изменение (согласно Git) происходит от середины первого метода до непосредственно перед окончанием второго метода. Это делает невозможным выделение только определенных строк и принятие одного из методов. Те строки, которые git видит как «контекст», невозможно выделить.
Если я использую git add -p ./path/to/file
, он больше не имеет опции s
для разделения в моей версии Git (которая никогда не работала в любом случае), но имеет e
для редактирования, но это не позволит добавить финал end
второго метода. Так что в основном Git предлагает мне абсолютно никакой способ разумного выбора изменений и добавления их отдельно в отдельных коммитах.
Аналогично в VS Code, я могу выбирать построчно из существующих строк, но я не могу выбрать строки, которые Git не считает частью измененной области. (И также я не могу различить добавленные строки и удаленные строки - изменение включает в себя удаленные строки незаметно, поэтому, если они на самом деле являются частью другого изменения, мне снова не повезло.)
Так что я не могу найти способ контролировать это, , если я не изменю свой код , просто чтобы заставить Git сделать правильную вещь . Если я покопаюсь в истории, чтобы получить строку, которая была удалена в первом методе, и добавлю ее обратно, а затем удалю (временно) добавленную строку и сохраню файл, тогда он будет правильно распознавать то, что изменилось. Конечно, я должен помнить, чтобы отменить это грязное решение и убедиться, что я отменил его правильно, или я сломал свой код. И это утомительный и действительно ужасный обходной путь.
Мне бы понравилось, если бы был способ заставить Git распознавать изменения "должным образом", как это сделал бы человек. Пока у нас нет разностных алгоритмов на основе AST, я не ожидаю, что это будет доступно в ближайшее время. Таким образом, следующая лучшая вещь будет иметь способ указать что изменилось и не оставлять это на усмотрение Git. Есть ли способ сделать это?
Например (это был бы только один из способов частично решить проблему), если бы я мог сказать Git НИКОГДА, НИКОГДА, НИКОГДА не позволять блоку diff занимать пустую строку, я бы решил этот конкретный пример. Если у меня есть чанк, который я хочу охватить пустой строкой, я с удовольствием добавлю оба чанка отдельно. Git должен всегда рассматривать их как отчетливые изменения. Но это только один пример, а не основной вопрос.
Основной вопрос:
Если Git не может правильно распознать, что изменилось, как я могу заставить его принять мою версию того, что изменилось? (Не прибегая к утомительным и подверженным ошибкам ошибкам, таким как ручное удаление некоторых изменений, копаясь в истории git, чтобы отменить одно из изменений, чтобы не было ошибочной группировки двух отдельных вещей!)