Могу ли я использовать git diff для неотслеживаемых файлов?

Можно ли попросить git diff включить неотслеживаемые файлы в свой вывод diff? Или мой лучший выбор - добавить новые файлы, которые я создал, и существующие файлы, которые я отредактировал, и использовать

git diff --cached

?

12 ответов

Решение

С последними версиями Git вы можете git add -N файл (или --intent-to-add), который добавляет блоб нулевой длины к индексу в этом месте. В результате ваш "неотслеживаемый" файл теперь становится модификацией для добавления всего содержимого в этот файл нулевой длины, и это отображается в выводе "git diff".

git diff

echo "this is a new file" > new.txt
git diff

git add -N new.txt
git diff
diff --git a/new.txt b/new.txt
index e69de29..3b2aed8 100644
--- a/new.txt
+++ b/new.txt
@@ -0,0 +1 @@
+this is a new file

К сожалению, как указано, вы не можете git stash пока у вас есть --intent-to-add файл в ожидании, как это. Хотя, если вам нужно спрятать, просто добавьте новые файлы, а затем спрячьте их. Или вы можете использовать обходной путь эмуляции:

git update-index --add --cacheinfo \
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt

(настройка псевдонима - ваш друг здесь).

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

git diff --no-index tracked_file untracked_file

Не на 100%, но поскольку нет действительно удовлетворительного ответа, вот еще один ответ такого рода;) Если файлы не отслеживаются, очевидно, что diff - это весь файл, так что вы можете просто просмотреть их с меньшими затратами:

less $(git ls-files --others --exclude-standard)

Перейдите между ними с помощью:n и:p для следующего и предыдущего.

Для моей интерактивной повседневной работы (где я постоянно разрабатываю рабочее дерево по отношению к HEAD и хотел бы, чтобы неотслеживаемые файлы были включены в diff), add -N/--intent-to-add непригоден, потому что он ломается git stash,

Так вот мой git diff замена. Это не особо чистое решение, но, поскольку я действительно использую его только в интерактивном режиме, у меня все в порядке с хаком:

d() {
    if test "$#" = 0; then
        (
            git diff --color
            git ls-files --others --exclude-standard |
                while read -r i; do git diff --color -- /dev/null "$i"; done
        ) | `git config --get core.pager`
    else
        git diff "$@"
    fi
}

Печатать просто d будет включать неотслеживаемые файлы в diff (это то, что мне важно в моем рабочем процессе), и d args... будет вести себя как обычный git diff,

Заметки:

  • Мы используем тот факт, что здесь git diff на самом деле это просто отдельные различия, поэтому невозможно сказать, d вывод "real diff" - за исключением того факта, что все неотслеживаемые файлы сортируются последними.
  • Единственная проблема с этой функцией заключается в том, что выходные данные окрашены, даже если они перенаправлены; но я не могу потрудиться добавить логику для этого.
  • Я не мог найти способ включить неотслеживаемые файлы, просто собирая список аргументов для git diff, Если кто-то выяснит, как это сделать, или, возможно, функция будет добавлена ​​в git в какой-то момент в будущем, пожалуйста, оставьте записку здесь!
git add -A
git diff HEAD

При необходимости сгенерируйте патч, а затем:

git reset HEAD

Для одного файла:

git diff --no-index /dev/null new_file

Для всех новых файлов:

for next in $( git ls-files --others --exclude-standard ) ; do git --no-pager diff --no-index /dev/null $next; done;

Как псевдоним:

alias gdnew="for next in \$( git ls-files --others --exclude-standard ) ; do git --no-pager diff --no-index /dev/null \$next; done;"

Для всех измененных и новых файлов, объединенных в одну команду:

{ git --no-pager diff; gdnew }

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

git add my_file.txt
git diff --cached my_file.txt
git reset my_file.txt

Последний шаг не является обязательным, он оставит файл в предыдущем состоянии (без отслеживания)

полезно, если вы тоже создаете патч:

  git diff --cached my_file.txt > my_file-patch.patch

Изменения работают, когда ставятся и не ставятся с помощью этой команды. Новые файлы работают при постановке:

$ git diff HEAD

Если они не организованы, вы увидите только различия файлов.

Используя тот факт, что вы можете подготовить не отслеживаемый / новый файл и вы можете различать подготовленные файлы, вы можете объединить эти два файла, чтобы увидеть разницу. Я считаю его простым в использовании.

  1. Добавьте файлы, которые вы хотите увидеть, или добавьте все файлы, включая новые.

    git add .

  2. Различайте поэтапные файлы

    git diff --staged

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

    git reset или же git reset filePath для сброса определенного файла.

Обычно, когда я работаю с командами удаленного определения местоположения, для меня важно, чтобы у меня были предварительные знания о том, какие изменения были сделаны другими командами в том же файле, прежде чем я буду следовать этапам git untrack-> staged -> commit для этого, я написал скрипт bash, который помогите мне избежать ненужного разрешения конфликта слияния с удаленной командой или создания новой локальной ветки и сравнения и слияния в основной ветке

#set -x 
branchname=`git branch | grep -F '*' |  awk '{print $2}'`
echo $branchname
git fetch origin ${branchname}
for file in `git status | grep "modified" | awk "{print $2}" `
do
echo "PLEASE CHECK OUT GIT DIFF FOR "$file 
git difftool FETCH_HEAD $file ;
done

В приведенном выше сценарии я выбираю удаленную основную ветвь (не обязательно ее основную ветвь), чтобы FETCH_HEAD создал список только моего измененного файла и сравнил измененные файлы с git difftool

здесь много difftool, поддерживаемых git, я настраиваю 'Meld Diff Viewer' для хорошего сравнения GUI.

Если вам это понадобится в контексте скриптов, использующих git stash(т.е. хук git перед фиксацией) это хорошо работает для меня с git v2.34.1 на macOS Big Sur:

      # Stash unstaged changes
# NOTE: we always create a stash - possibly even a totally empty one.
git stash --keep-index --include-untracked --message="pre-commit auto-stash"
diffTracked=$(git diff --stat --staged stash@{0})
diffUntracked=$(git stash show --only-untracked stash@{0})
[[ $diffTracked || $diffUntracked ]] && {
  echo "Stashed diff:"
  # Ensure diffs have standard coloring:
  git diff --stat --staged stash@{0}
  git stash show --only-untracked stash@{0}
}

Предполагая, что у вас нет локальных коммитов,

git diff origin/master
Другие вопросы по тегам