Как использовать слияние git, чтобы игнорировать конечные пробелы? - PullRequest
1 голос
/ 26 февраля 2020

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

git merge -Xignore-space-at-eol --no-commit --no-ff branch1

Но следующий скрипт, когда он выполняется, демонстрирует, что строки, которые имеют изменения в конце пробела, по-прежнему добавляются.

#!/bin/bash

# Transcribe all commands:
set -x

# Show the version I'm using:
git --version

# Create the repo and add a initial file:
cd /tmp
rm -rf scrap
mkdir scrap
cd scrap
git init
echo "// line 1 " > sample.C
echo "// line 2" >> sample.C
git add sample.C
git diff --cached | sed 's% $%EOLWS%g'
git commit -m "change 1"

# Create a new branch and add changes to it:
git checkout -b branch1
# Change an existing line by changing the whitespace at the end of one line:
sed -i 's%// line 1 %// line 1%g' sample.C
git add sample.C
# Check the whitespace was changed prior to committing:
git diff --cached | sed 's% $%EOLWS%g'
git commit -m "Add trailing whitespace"

# Check out master and merge into it, expecting no lines containing only trailing whitespace to be included:
git checkout master
git merge -Xignore-space-at-eol --no-commit --no-ff branch1
git diff --cached | sed 's% $%EOLWS%g'

Приведенный выше результат приводит к следующему выводу. Позже я добавил номера строк для ссылок:

     1  + git --version
     2  git version 2.20.1
     3  + cd /tmp
     4  + rm -rf scrap
     5  + mkdir scrap
     6  + cd scrap
     7  + git init
     8  Initialized empty Git repository in /tmp/scrap/.git/
     9  + echo '// line 1 '
    10  + echo '// line 2'
    11  + git add sample.C
    12  + git diff --cached
    13  + sed 's% $%EOLWS%g'
    14  diff --git a/sample.C b/sample.C
    15  new file mode 100644
    16  index 0000000..42b5bc0
    17  --- /dev/null
    18  +++ b/sample.C
    19  @@ -0,0 +1,2 @@
    20  +// line 1EOLWS
    21  +// line 2
    22  + git commit -m 'change 1'
    23  [master (root-commit) 07cd37f] change 1
    24   1 file changed, 2 insertions(+)
    25   create mode 100644 sample.C
    26  + git checkout -b branch1
    27  Switched to a new branch 'branch1'
    28  + sed -i 's%// line 1 %// line 1%g' sample.C
    29  + git add sample.C
    30  + git diff --cached
    31  + sed 's% $%EOLWS%g'
    32  diff --git a/sample.C b/sample.C
    33  index 42b5bc0..4b9e635 100644
    34  --- a/sample.C
    35  +++ b/sample.C
    36  @@ -1,2 +1,2 @@
    37  -// line 1EOLWS
    38  +// line 1
    39   // line 2
    40  + git commit -m 'Add trailing whitespace'
    41  [branch1 6144b0c] Add trailing whitespace
    42   1 file changed, 1 insertion(+), 1 deletion(-)
    43  + git checkout master
    44  Switched to branch 'master'
    45  + git merge -Xignore-space-at-eol --no-commit --no-ff branch1
    46  Automatic merge went well; stopped before committing as requested
    47  + git diff --cached
    48  + sed 's% $%EOLWS%g'
    49  diff --git a/sample.C b/sample.C
    50  index 42b5bc0..4b9e635 100644
    51  --- a/sample.C
    52  +++ b/sample.C
    53  @@ -1,2 +1,2 @@
    54  -// line 1EOLWS
    55  +// line 1
    56   // line 2

Слово "EOLWS" ожидается в строках 20 и 37, но не в 54.

Что я здесь делаю неправильно?

1 Ответ

3 голосов
/ 26 февраля 2020

Я думаю, вы не понимаете, что такое идея "ignore-space-at-eol" (конечно, иначе вы бы не спрашивали:)).

ignore-space-at-eol - это опция стратегии слияния для recursive стратегии слияния . Эти параметры применимы только к конфликтам (это важный бит!)

Предоставленный вами MWE создает ветку с дополнительными коммитами не на мастере, но мастер не имеет других коммитов ( так что в теории это можно было бы быстро переадресовать, но поскольку --no-ff пройдено, этого не происходит).

Итак, в этом случае выполняется нормальное слияние. Все изменения не в master, а только в ветке объединяются в master. Поскольку нет никаких конфликтов, -Xignore-space-at-eol не вступает в силу.

Это вступит в силу, если вы имели eol-whitespace-only-changes в обеих ветвях к одной и той же строке, а затем попытаетесь объединить ее, то есть:

$ git init
$ >file echo 'a'
$ git add file
$ git commit -m 'initial'
$ git branch feature # create a branch, but do not switch to it
$ >file echo 'a ' # add one blank
$ git add file ; git commit -m 'add one blank on master'
$ git checkout feature
$ >file echo 'a  ' # add two blank
$ git add file ; git commit -m 'add two blanks branch'
$ git checkout master ; git merge feature # you will get conflicts
$ git merge --abort # let's try that again:
$ git merge -Xignore-space-at-eol feature # no conflicts, hooray!

Видите ли, ignore-space-at-eol - это вариант стратегии, как обрабатывать конфликты. Это не означает, что такие изменения будут полностью проигнорированы.

Вариант использования: вы хотите объединить ветвь, которая не совпадает с окончанием строки или пробелом вашей ветки (представьте, что CRLF vs LF). С помощью этой опции стратегии вы можете автоматически разрешать такие конфликты и корректно объединять изменения.

...