Чи можу я використовувати git diff для файлів, що не відстежуються?


270

Чи можна попросити git diff включити неперевірені файли у свій різний вихід? Або я найкраще ставлю Git додати нові файли, які я створив, і існуючі файли, які я редагував, і використовую

git diff --cached

?

Відповіді:


267

З останніми версіями 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 недостатньо недавня, щоб мати додаток -N, але це відповідає на моє запитання.
— Ендрю Грімм

1
Ви можете імітувати "git add -N new.txt" за допомогою "git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt" (як мені вдалося поставити це на неправильну відповідь?)
— araqnid


1
що робити, якщо у вас багато нових файлів, чи є простий спосіб додати їх усі, а потім відрізнятись?
— Вік

1
@Vicgit add -N .
— Натан

92

Я вважаю, що ви можете відрізнятись від файлів у вашому індексі та відірваних файлів, просто надавши шлях до обох файлів.

git diff --no-index tracked_file untracked_file

3
Чи спрацьовує це, якщо у вас є більше одного непотрібного файлу, який ви створили з останнього комітету?
— Ендрю Грімм

12
Так, ідеальна відповідь! Тоді я можу використовувати git diff --no-index untracked_file_1 untracked_file_2для отримання git diffсинтаксичного забарвлення і т. Д. На різний ... прекрасний.
— Колін Д Беннетт

40
Я не розумію, чому ви порівнюєте відсліджений файл із непов’язаним файлом без відстеження. Якщо ви просто хотіли , щоб отримати діфф вихід для неотслежіваемих файлу, ви можете просто використовувати /dev/nullзамість: git diff --no-index -- /dev/null <untracked_file>.

4
Або просто cat untracked_file_1, або, можливо, printf '\e[1;32m%s\e[0m\n' "$(cat untracked_file_1)"вам дійсно потрібен зелений вихід. :) (Хоча на більш серйозну увагу, зауважте, що заміна команд видалить з вашого файлу проміжні нові рядки.)
— Wildcard

8
Це має бути прийнятою відповіддю - це не вимагає зміни індексу git; що, як каже оригінальний автор, має і свою сторону
— DIMMSum

38

Для мого інтерактивного з день в день gitting (де я дифф робочого дерева проти ГОЛОВІ всього час, і хотів би мати неотслежіваемих файли , що входять до диффе), 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буде включати в розрізнені файли, що не відслідковуються (про що я хвилююсь у своєму робочому процесі), і d args...буде вести себе як звичайне git diff.

Примітки:

  • Тут ми використовуємо той факт, що git diffнасправді просто окремі розрізнені, тому неможливо сказати dвихід із "справжнього розрізника" - за винятком того, що всі не відстежені файли відсортовані останніми.
  • Єдина проблема з цією функцією полягає в тому, що висновок забарвлюється навіть під час перенаправлення; але мені не завадить додавати логіку для цього.
  • Я не міг знайти жодного способу включити незавершені файли, просто склавши список гладких аргументів git diff. Якщо хтось з'ясував, як це зробити, або, можливо, якусь функцію додасть gitу якийсь момент у майбутньому, будь ласка, залиште тут записку!

4
За іронією долі, моє git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txtвирішення, яке я запропонував для старших гейтів , спрацьовує git stash, припускаючи, що ви вже отримали e69de29bb у своєму db, наприклад, намагаючись використовувати add -Nраніше. Тож мабуть це не зовсім рівнозначно git add -Nчомусь: tbh Я не впевнений як.
— araqnid

2
Ви test, до речі, виконуєте порівняння рядків, а не числову рівність . Не повинен нічого впливати, але test "$#" -eq 0точніше, що призначено.
— Wildcard

1
Так, все одно виглядає, що вам потрібно зробити це попарно ... але ви можете підробити його в один, lessтак що вам не потрібно натискати qна кожен файл, і він виглядає точно так git diff, видаляючи пагін файлу ( -P), додаючи його назад ( | less), зберігаючи колір ( --color=always) та інтерпретуючи його як колір ( less -rабо less -R). Отже, це:do git -P diff --color=always -- /dev/null "$i"; done | less -r
— гіперпалій

Якщо ви хочете, щоб вас турбували в майбутньому, test -t 1(наприклад, if [ -t 1 ]; then color_arg=--color; fiчи щось таке), оболонка - це спосіб перевірити, чи є її вихід терміналом, що є корисним способом прийняти рішення про забарвлення. І xargsможе дати спосіб позбутися циклу while. Вам все одно знадобиться -n 1на цьому, тож він все одно запустить git ще чимало разів, і все одно потрібно парним шляхом, але ... це позбудеться, whileі read, може, це краще?!? Я залишаю це читачеві.
— лінди

28

Не на 100% до речі, але якщо ви чомусь не хочете додавати свої файли до індексу, як це запропоновано прийнятою відповіддю, ось ще один варіант:

Якщо файли не відслідковуються, очевидно, різниця - це весь файл, тож ви можете просто переглянути їх менше:

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

Переміщення між ними :nі :pна наступний і попередній ..

Оновлення з коментарів: Якщо вам потрібен формат патча, ви також можете комбінувати його з git diff:

git ls-files --others --exclude-standard | xargs -n 1 git --no-pager diff /dev/null | less

Ви також можете перенаправити висновок на файл або використовувати іншу команду diff у цьому випадку.


6
ви також можете запустити git diff /dev/null <untracked_tile>та отримати патч у форматі патча, а не "просто" файл
— SimSimY

2
ця відповідь у поєднанні з git diff є ідеальним рішенням.
— вперед

22
git add -A
git diff HEAD

Створіть виправлення, якщо потрібно, а потім:

git reset HEAD

Це може втратити попередню (перед) роботу, додавши все. Особливо випадок, якщо хтось користується git add -pдуже часто (що я, до речі, рекомендую, до речі) ... Це дійсно дає спосіб робити основне, це просто ... слід зазначити, що він має потенціал для небажаної сторони ефекти.
— лінди

13

це працює для мене:

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

Специфіка цієї пари додавання / скидання є приємним контрастом до підходу рушниці stackoverflow.com/a/50486906/313756 ... дякую за це.
— lindes

9

Зміни працюють при поетапному та нестадійному виконанні цієї команди. Нові файли працюють під час постановки:

$ git diff HEAD

Якщо вони не ставлять поетапно, ви побачите лише відмінності файлів.


26
HEADє типовим значенням , тому це те саме, git diffщо не вирішує проблему.
— Юліан Онофрей

4
Це вимагає git addвід кожного не відстежуваного файлу
— SilvioQ

Якщо ви редагуєте цю відповідь, щоб включити git addїї, це найпростіше, якщо ваш випадок використання - перевірити, що ви тільки що додали / хочете додати
— KCD

8

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

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 }

2

Зазвичай, коли я працюю з командами віддаленого розташування, для мене важливо, щоб я мав попередні знання про те, що зміни зроблені іншими командами в тому ж файлі, перш ніж я слідкувати за етапами git unntrack -> staged -> виконувати для цього я написав скрипт 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" для гарного порівняння графічного інтерфейсу.


-9

Припустимо, що у вас немає місцевих комітетів,

git diff origin/master

8
Питання задає git diffкоманду, яка включає непозахищені файли. Ця команда не включає їх. Крім того, існують чи ні місцеві комітети, абсолютно нічого спільного з цим питанням немає.
— toon81

JFTR, я git merge --squash mybranch, і git diff masterпоказав мені зміни у відслідковуваних файлах.
— муаммар

2
Це неможливо. Ви, здається, плутаєтеся про те, що означає "без нагляду". Без відстеження не означає, що файл відслідковується в одній гілці, а не в іншій, це означає, що він ні в якому разі не знаходиться "в Git". Будь ти сквош чи ні, не має значення. git diffне показує відмінності у відслідковуваних файлах: оскільки вони не відслідковуються, за визначенням ніколи не відображаються різниці. Це просто так, як працює Git. :)
— toon81
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.