Подтвердить что ты не робот

Есть ли способ сравнить два различия или патчи?

Есть ли способ проверить, являются ли два diff или patches эквивалентными?

Предположим, что у вас есть следующая история событий git, где функции F и G являются чисто перемасштабируемыми для E:

     G
    /
A--B--C--D--E
 \
  F

Из-за ограничений в нашем текущем процессе развертывания мы имеем следующий, несколько связанный граф (он не контролируется версией)

              G'
             /
------------E'
             \
              F'

F 'и G' в конечном итоге будут применены к голове E ', в некоторых из которых будет определен порядок, так что это закончится как

------------E'--G'--F'

Есть ли способ проверить, что diff от E 'до G' совпадает с патчем, созданным фиксацией git G из B?

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

Вы могли бы по-разному играть в оба патча на отдельных кассах и сравнивать выходы, но это кажется довольно неуклюжим. И сравнение самих различий, я предполагаю, не будет работать, потому что номера строк могут измениться. Даже если G 'и F' были переустановлены на E ', патч для F' в конечном итоге будет применен к G ', что делает diff-контекст патча другим.

4b9b3361

Ответ 1

diff <(git show COMMIT1SHA) <(git show COMMIT2SHA)

Ответ 2

Я просто хотел бы git попробовать и посмотреть:

git checkout E -b FG
git cherry-pick F' G'
git checkout E -b GF
git cherry-pick G' F'
git diff FG GF
git branch -D FG GF

Ответ 3

В интересах читателя, здесь обновляется ответ @mrbrdo с небольшой настройкой:

  • Добавляет псевдоним git sdiff для легкого доступа к этому. sdiff означает show diff.
  • Игнорировать аннотированные заголовки тегов, используя суффикс ^{}.
  • Разрешить diff параметры, которые будут использоваться как -u и т.д.

Запустите это один раз в каждой из ваших учетных записей, в которых вы используете git:

git config --global alias.sdiff '!'"bash -c 'O=(); A=(); while x=\"\$1\"; shift; do case \$x in -*) O+=(\"\$x\");; *) A+=(\"\$x^{}\");; esac; done; g(){ git show \"\${A[\$1]}\" && return; echo FAIL \${A[\$1]}; git show \"\${A[\$2]}\"; }; diff \"\${O[@]}\" <(g 0 1) <(g 1 0)' --"

Впоследствии вы можете использовать это:

git sdiff F G

Обратите внимание, что для этого требуется bash версия 3 или выше.

Разъяснения:

  • git config --global alias.sdiff добавляет псевдоним с именем git sdiff в глобальный ~/.gitconfig.

  • ! запускает псевдоним в виде команды оболочки

  • bash -c нам нужно bash (или ksh), поскольку <(..) не работает в dash (aka. /bin/sh).

  • O=(); A=(); while x="$1"; shift; do case $x in -*) O+=("$x");; *) A+=("$x^{}");; esac; done; разделяет параметры (-something) и аргументы (все остальное). Параметры находятся в массиве O, а аргументы - в массиве A. Обратите внимание, что все аргументы также присоединяются к ^{}, которые пропускают аннотации (например, вы можете использовать аннотированные теги).

  • g(){ git show "${A[$1]}" && return; echo FAIL ${A[$1]}; git show "${A[$2]}"; }; создает вспомогательную функцию, которая делает git show для первого аргумента. Если это не удается, он выводит "FAIL first-argument", а затем выводит второй аргумент. Это трюк, чтобы уменьшить накладные расходы, если что-то не получится. (Правильное управление ошибками было бы слишком.)

  • diff "${O[@]}" <(g 0 1) <(g 1 0) запускает diff с заданными параметрами в отношении первого аргумента и второго аргумента (при этом FAIL-ошибка возвращается к другому аргументу, чтобы уменьшить diff).

  • -- позволяет передать diff -options (-something) в этот псевдоним /script.

Ошибка:

  • Число аргументов не проверяется. Все, что находится за вторым аргументом, игнорируется, и если вы даете ему слишком мало, вы просто видите FAIL или ничего вообще.

  • Ошибки действуют немного странно и загромождают выход. Если вам это не нравится, запустите его с помощью 2>/dev/null (или соответствующим образом измените script).

  • Он не возвращает ошибку, если что-то ломается.

  • По всей видимости, вы хотите передать это в пейджер по умолчанию.

Обратите внимание, что легко определить еще несколько псевдонимов, например:

git config --global alias.udiff '!git sdiff -u'
git config --global alias.bdiff '!git sdiff -b'

git config --global alias.pager '!pager() { cd "$GIT_PREFIX" && git -c color.status=always -c color.ui=always "[email protected]" 2>&1 | less -XFR; }; pager'
git config --global alias.ddiff '!git pager udiff'

Надеюсь, это не нужно объяснять дальше.

Для получения дополнительных псевдонимов, возможно, посмотрите мой репозиторий GitHub