追跡されていないファイルでgit diffを使用できますか?


270

git diffに、追跡されていないファイルをdiff出力に含めるように依頼することはできますか?または、私が作成した新しいファイルと編集した既存のファイルをgit追加して使用するのが最善の策です。

git diff --cached

回答:


267

最近のgitバージョンではgit add -N、ファイル(または--intent-to-add)を使用できます。これにより、その場所のインデックスに長さゼロのblobが追加されます。その結果、「追跡されていない」ファイルがすべてのコンテンツをこの長さゼロのファイルに追加する変更になり、「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のコピーはadd -Nを実行するのに十分最近ではないことがわかりましたが、これは私の質問に答えます。
Andrew Grimm、

1
「git add -N new.txt」は「git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt」でエミュレートできます(これをどのようにして間違った答えにしたのですか?)
araqnid


1
新しいファイルがたくさんある場合、それらをすべて追加してからdiffする簡単な方法はありますか?
2016

1
@Vicgit add -N .
Nathan、

92

両方のファイルへのパスを指定するだけで、インデックス内のファイルと追跡されていないファイルを比較できると思います。

git diff --no-index tracked_file untracked_file

3
前回のコミット以降に作成した追跡されていないファイルが複数ある場合、それは機能しますか?
Andrew Grimm、

12
はい、完璧な答えです!次に、diffの構文の色付けなどgit diff --no-index untracked_file_1 untracked_file_2を取得するために使用できgit diffます...美しい。
コリンDベネット

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)"本当にグリーン出力が本当に必要な場合。:)(より深刻な注意事項ですが、コマンドの置換により、ファイルの末尾の改行が削除されることに注意してください。)
ワイルドカード

8
これは受け入れられる答えです。gitのインデックスを変更する必要はありません。元の作者が言うように、欠点があります
DIMMSum

38

インタラクティブな日常のギッティング(作業ツリーを常に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と、追跡されていないファイルが差分に含まれ(ワークフローで気になっていること)、d args...通常のように動作しますgit diff

ノート:

  • ここでgit diffは、実際には個々のdiffが連結されているという事実を使用しているためd、「実際のdiff」からの出力を区別することはできません。ただし、追跡されていないすべてのファイルが最後にソートされるという事実は除きます。
  • この関数の唯一の問題は、リダイレクトされた場合でも出力が色分けされることです。しかし、そのためのロジックを追加することに煩わされることはありません。
  • の滑らかな引数リストを作成するだけでは、追跡されていないファイルを取得する方法が見つかりませんでしたgit diff。誰かがこれを行う方法を見つけた場合、またはgit将来的に機能が追加される可能性がある場合は、ここにメモを残してください!

4
皮肉なことに、私のgit update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt私は古いGITSのために提案回避策はありませんでの作業をgit stash既に使用しようとしてデシベルでe69de29bb、例えばを持っていると仮定すると、add -N以前に。明らかに、これgit add -Nはある意味では完全に同等ではありません。tbh方法がわかりません。
araqnid

2
testちなみに、コマンドで数値の等価チェックではなく文字列比較を実行しています。何にも影響を与えるべきではありませんが、test "$#" -eq 0意図したとおりです。
ワイルドカード2016年

1
ええ、それでもペアで行う必要があるように見えます...しかし、それを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の、まだ道というペアワイズする必要がありますので、その上で、しかし...それはを取り除くwhileread、ので、多分良いでしょうそれ?!?読者にお任せします。
lindes

28

100%ではありませんが、何らかの理由で、承認された回答で提案されているようにファイルをインデックスに追加したくない場合は、別のオプションを次に示します。

ファイルが追跡されていない場合、明らかにdiffはファイル全体なので、少ないファイルで表示できます。

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を組み合わせると、完璧なソリューションになります。
iwind

22
git add -A
git diff HEAD

必要に応じてパッチを生成し、次に:

git reset HEAD

これは、すべてを追加することにより、以前の(事前)作業を失う可能性があります。特に、git add -p私が頻繁に使用する場合(私は一般的に、これをお勧めします)...これは、基本的なことを行う方法を提供します。効果。
lindes

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のショットガンアプローチとの対比です。
リンデス

9

変更は、このコマンドを使用してステージングされている場合とされていない場合に機能します。新しいファイルはステージング時に機能します:

$ git diff HEAD

ステージングされていない場合は、ファイルの違いのみが表示されます。


26
HEADデフォルト値なので、これはgit diff問題を解決しない場合と同じです。
Iulian Onofrei 2017

4
これにはgit add、追跡されていないすべてのファイルが必要です
SilvioQ

この回答を編集して含める場合、追加したい/追加したいものを確認するのがユースケースである場合がgit add最も簡単です
KCD

8

1つのファイルの場合:

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;"

1つのコマンドとして結合されたすべての変更されたファイルと新しいファイル:

{ git --no-pager diff; gdnew }

2

通常、リモートロケーションチームで作業するときは、同じファイルで他のチームが行った変更について事前に知っていることが重要です。前に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と比較します

ここでは、gitでサポートされている多くのdifftoolを使用して、適切なGUI比較のために「Meld Diff Viewer」を構成しています。


-9

ローカルコミットがないと仮定すると、

git diff origin/master

8
質問は、git diff追跡されていないファイルを含むコマンドを要求します。このコマンドには含まれていません。また、ローカルコミットが存在するかどうかは、質問とはまったく関係ありません。
toon81

JFTR、私git merge --squash mybranch、そしてgit diff master追跡されていないファイルの変更を見せてくれました。
muammar 2016年

2
それ無理。「追跡されていない」の意味について混乱しているようです。追跡されていないということは、ファイルが1つのブランチで追跡され、別のブランチでは追跡されないという意味ではありません。スカッシュするかどうかは関係ありません。git diff追跡されていないファイルの違いは表示されません。追跡されていないため、定義上、表示する必要のある違いはありません。これはGitが機能する方法に過ぎません。:)
toon81 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.