Какой самый простой способ получить список конфликтующих файлов?

Мне просто нужен простой список конфликтующих файлов.

Есть ли что-нибудь проще, чем:

git ls-files -u  | cut -f 2 | sort -u

или же

git ls-files -u  | awk '{print $4}' | sort | uniq

?

Я думаю, я мог бы создать удобный псевдоним для этого, однако было интересно, как это делают профессионалы. Я бы использовал его для написания циклов оболочки, например, для автоматического разрешения конфликтов и т. Д. Возможно, замените этот цикл, подключившись к mergetool.cmd?

24 ответа

Решение
git diff --name-only --diff-filter=U

git diff --check покажет список файлов, содержащих маркеры конфликта, например:

> git diff --check
index-localhost.html:85: leftover conflict marker
index-localhost.html:87: leftover conflict marker
index-localhost.html:89: leftover conflict marker
index.html:85: leftover conflict marker
index.html:87: leftover conflict marker
index.html:89: leftover conflict marker

источник: https://ardalis.com/detect-git-conflict-markers

Вот надежный способ:

grep -H -r "<<<<<<< HEAD" /path/to/project/dir

Пытаюсь ответить на мой вопрос:

Нет, кажется, нет более простого способа, чем тот, о котором идет речь, из коробки.

После того, как он набрал это слишком много раз, просто вставил более короткий файл в исполняемый файл с именем 'git-конфликты', сделанный доступным для git, теперь я могу просто:git conflicts чтобы получить список, который я хотел.

Обновление: как предлагает Ричард, вы можете установить псевдоним git, как альтернативу исполняемому файлу

git config --global alias.conflicts '!git ls-files -u | cut -f 2 | sort -u'

Преимущество использования исполняемого файла перед псевдонимом заключается в том, что вы можете поделиться этим сценарием с членами команды (в разделе репозитория bin dir).

git status отображает "оба измененных" рядом с файлами, которые имеют конфликты вместо "измененный" или "новый файл" и т. д.

git status --short | grep "^UU "

Это работает для меня:

git grep '<<<<<<< HEAD'

или же

git grep '<<<<<<< HEAD' | less -N

Ты можешь ударить git ls-files -u в командной строке перечисляет файлы с конфликтами

Я бы также предложил следующую команду, если вы работаете в локальном репозитории git или в каталоге, в котором patch -p1 --merge < ... был применен.

      grep -rnw . -e '^<<<<<<<$'

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

Возможно, это было добавлено в Git, но файлы, которые еще предстоит разрешить, перечислены в сообщении о состоянии (git status), например:

#
# Unmerged paths:
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#   both modified:      syssw/target/libs/makefile
#

Обратите внимание, что это раздел Unmerged paths.

Предполагая, что вы знаете, где находится ваш корневой каталог git, ${GIT_ROOT}, вы можете сделать:

 cat ${GIT_ROOT}/.git/MERGE_MSG | sed '1,/Conflicts/d'

Мои 2 цента здесь (даже когда есть много крутых / рабочих ответов)

Я создал этот псевдоним в моем .gitconfig

[alias]
 ...
 conflicts = !git diff --name-only --diff-filter=U | grep -oE '[^/ ]+$'

который покажет мне только имена файлов с конфликтами... не весь их путь:)

Я всегда просто использовал git status,

могу добавить awk в конце, чтобы получить только имена файлов

git status -s | grep ^U | awk '{print $2}'

Небольшая вариация ответа Чарльза Бейли, который дает больше информации:

git diff --name-only --diff-filter=U | xargs git status

Вот что я использую, чтобы список измененных файлов, подходящих для подстановки командной строки в bash

git diff --numstat -b -w | grep ^[1-9] | cut -f 3

Для редактирования списка используйте $(cmd) замена.

vi $(git diff --numstat -b -w | grep ^[1-9] | cut -f 3)

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

Вы могли бы попробовать

      $ git status | grep both

пример вывода будет:

          both modified:   package.json

Утилита git wizard https://github.com/makelinux/git-wizard подсчитывает отдельно неразрешенные конфликтующие изменения (коллизии) и несвязанные файлы. Конфликты необходимо разрешать вручную или с помощью mergetool. Решенные несоединенные изменения обычно можно добавить и зафиксировать с помощью git rebase --continue.

Ответ на Джонсе Агеманг, вероятно, достаточно для большинства случаев использования и был отличной отправной точкой для моего решения. Для написания сценариев в Git Bent, созданной мной библиотеке-оболочке git, мне нужно было что-то более надежное. Я публикую написанный мной прототип, который еще не полностью совместим со сценариями

Ноты

  • Связанный ответ проверяет наличие <<<<<<< HEAD который не работает для конфликтов слияния от использования git stash apply который имеет <<<<<<< Updated Upstream
  • Мое решение подтверждает наличие ======= & >>>>>>>
  • Связанный ответ, безусловно, более эффективен, так как он не должен делать столько
  • Мое решение НЕ предоставляет номера строк

Печать файлов с конфликтами слияния

Вам нужен str_split_line функция снизу.

# Root git directory
dir="$(git rev-parse --show-toplevel)"
# Put the grep output into an array (see below)
str_split_line "$(grep -r "^<<<<<<< " "${dir})" files
bn="$(basename "${dir}")"
for i in "${files[@]}"; do 
    # Remove the matched string, so we're left with the file name  
    file="$(sed -e "s/:<<<<<<< .*//" <<< "${i}")"

    # Remove the path, keep the project dir's name  
    fileShort="${file#"${dir}"}"
    fileShort="${bn}${fileShort}"

    # Confirm merge divider & closer are present
    c1=$(grep -c "^=======" "${file}")
    c2=$(grep -c "^>>>>>>> " "${file}")
    if [[ c1 -gt 0 && c2 -gt 0 ]]; then
        echo "${fileShort} has a merge conflict"
    fi
done

Вывод

projectdir/file-name
projectdir/subdir/file-name

Разделить строки по линейной функции

Вы можете просто скопировать блок кода, если не хотите, чтобы это была отдельная функция.

function str_split_line(){
# for IFS, see https://stackru.com/questions/16831429/when-setting-ifs-to-split-on-newlines-why-is-it-necessary-to-include-a-backspac
IFS="
"
    declare -n lines=$2
    while read line; do
        lines+=("${line}")
    done <<< "${1}"
}

Для меня принятый ответ не сработал. Чтобы предотвратить захват

предупреждение: LF будет заменен на CRLF в []. Файл будет иметь исходные окончания строки в вашем рабочем каталоге.

Вместо этого в Powershell я использовал это:

      git ls-files -u| ForEach{($_.Split("`t"))|Select-Object -Last 1}| get-unique
      git commit

Если вы попытаетесь зафиксировать слияние и возникнут конфликты, git выдаст вам сообщение об ошибке и список конфликтующих файлов :

      error: Committing is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add/rm <file>'
hint: as appropriate to mark resolution and make a commit.
fatal: Exiting because of an unresolved conflict.
U       foo/bar/buzz.cpp

Git отмечает конфликты в файле с помощью «маркеров конфликтов», которые IDE, такие как VS Code, используют для визуального выделения конфликтов:

      <<<<<<< HEAD 
original code
======= 
merged code
>>>>>>> merged_branch

Вы можете найти все файлы, в которых все еще есть маркеры конфликтов (т. е. все файлы, для которых вам еще предстоит разрешить конфликты), используя:

      git check --diff | grep "conflict" 

Обратите внимание, что это будет работать только до тех пор, пока вы еще не зафиксировали свои файлы (чего вы, вероятно, еще не сделали, если все еще ищете конфликты слияния).

Просто прочитайте справочную страницу для статуса git и отфильтруйте то, что необходимо.

       git status --help

Фрагмент:

             For paths with merge conflicts, X and Y show the modification states of each side of the merge. For paths that do not have merge conflicts, X shows the status of the index, and Y shows the status of the work tree. For untracked
   paths, XY are ??. Other status codes can be interpreted as follows:

   •   ' ' = unmodified

   •   M = modified

   •   A = added

   •   D = deleted

   •   R = renamed

   •   C = copied

   •   U = updated but unmerged

   Ignored files are not listed, unless --ignored option is in effect, in which case XY are !!.

       X          Y     Meaning
       -------------------------------------------------
                [AMD]   not updated
       M        [ MD]   updated in index
       A        [ MD]   added to index
       D                deleted from index
       R        [ MD]   renamed in index
       C        [ MD]   copied in index
       [MARC]           index and work tree matches
       [ MARC]     M    work tree changed since index
       [ MARC]     D    deleted in work tree
       [ D]        R    renamed in work tree
       [ D]        C    copied in work tree
       -------------------------------------------------
       D           D    unmerged, both deleted
       A           U    unmerged, added by us
       U           D    unmerged, deleted by them
       U           A    unmerged, added by them
       D           U    unmerged, deleted by us
       A           A    unmerged, both added
       U           U    unmerged, both modified
       -------------------------------------------------
       ?           ?    untracked
       !           !    ignored
       -------------------------------------------------

Как подчеркивалось в других ответах, мы можем просто использовать команду git status, а затем искать файлы, перечисленные в разделе Unmerged paths:

Другие вопросы по тегам