Могу ли я использовать 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
Если они не организованы, вы увидите только различия файлов.
Используя тот факт, что вы можете подготовить не отслеживаемый / новый файл и вы можете различать подготовленные файлы, вы можете объединить эти два файла, чтобы увидеть разницу. Я считаю его простым в использовании.
Добавьте файлы, которые вы хотите увидеть, или добавьте все файлы, включая новые.
git add .
Различайте поэтапные файлы
git diff --staged
При необходимости вы можете отключить файлы, используя
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