Чи можу я використовувати 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.