All of lore.kernel.org
 help / color / mirror / Atom feed
* interaction between git-diff-index and git-apply
@ 2017-01-22 19:09 Ariel Davis
  2017-01-22 22:06 ` Junio C Hamano
  0 siblings, 1 reply; 2+ messages in thread
From: Ariel Davis @ 2017-01-22 19:09 UTC (permalink / raw)
  To: git

Hello,

I have noticed an interesting interaction between git-diff-index and git-apply.
Essentially, it seems that if we start with a clean working tree, then
git-apply a patch, then git-apply the reverse of that patch, git-diff-index
still thinks files are modified. But then, if we git-status, git-diff-index
seems to "realize" the files are actually not modified.

Below are steps to reproduce, as well as information about my machine, which I
discovered this behavior on.

Reproduction instructions:

$ mkdir -p test/repo
$ cd test/repo
$ git init -q
$ echo 1 > file
$ git add file
$ git commit -qm 1
$ echo 2 >> file
$ git add file
$ git commit -qm 2
$ git diff @~ > ../patch
$ git apply --reverse ../patch
$ git diff-index --name-only @
file
$ git apply ../patch
$ git diff-index --name-only @
file
$ git status
On branch master
nothing to commit, working tree clean
$ git diff-index --name-only @
$ echo hmm
hmm

System information:

$ uname -a
Darwin azdavis-mbp 16.3.0 Darwin Kernel Version 16.3.0: Thu Nov 17 20:23:58 PST
2016; root:xnu-3789.31.2~1/RELEASE_X86_64 x86_64 i386 MacBookPro12,1 Darwin
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.2
BuildVersion:   16C67
$ git --version
git version 2.11.0

Thank you for your time.

Ariel Davis


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: interaction between git-diff-index and git-apply
  2017-01-22 19:09 interaction between git-diff-index and git-apply Ariel Davis
@ 2017-01-22 22:06 ` Junio C Hamano
  0 siblings, 0 replies; 2+ messages in thread
From: Junio C Hamano @ 2017-01-22 22:06 UTC (permalink / raw)
  To: Ariel Davis; +Cc: git

Ariel Davis <ariel.z.davis@icloud.com> writes:

> I have noticed an interesting interaction between git-diff-index and git-apply.
> Essentially, it seems that if we start with a clean working tree, then
> git-apply a patch, then git-apply the reverse of that patch, git-diff-index
> still thinks files are modified. But then, if we git-status, git-diff-index
> seems to "realize" the files are actually not modified.

That is perfectly normal and you are making it too complex.  You do
not need to involve "git apply" at all.

    $ git init
    $ echo hello >file && git add file && git commit -m initial
    $ git diff-index HEAD
    $ echo hello >file
    $ git diff-index HEAD
    :100644 100644 ce013625030ba8dba906f756967f9e9ca394464a 0000000000000000000000000000000000000000 M	file

    $ git update-index --refresh
    $ git diff-index HEAD
    $ exit

A few things about Git that are involved in the above are:

 * There are plumbing commands that are geared more towards
   scripting Git efficiently and there are end-user facing Porcelain
   commands.

 * Git uses cached "(l)stat" information to avoid having to inspect
   the contents of the file all the time.  The idea is that Git
   remembers certain attributes (like size and last modified time)
   of a file when the contents of the file and the blob object in
   the index are the same (e.g. when you did "git add file" in the
   above sequence), and it can tell a file was edited/modified if
   these attributes are different from those recorded in the index
   without comparing the contents of the file with the blob.

 * The plumbing commands trust the cached "(l)stat" information for
   efficiency and whoever uses the plumbing commands are responsible
   for culling the false positives when cached "(l)stat" information
   is used to see which paths are modified.  They (typically these
   are scripted commands) do so with "update-index --refresh".

 * The Porcelain commands sacrifice the efficiency and internally do
   an equivalent of "update-index --refresh" at the beginning to
   hide the false positive.

After your reverse application of the patch with "git apply" (or the
second "echo hello" into the file in the above example), the
contents of the file is equivalent to what is in the index, but the
last modified timestamp (among others) is different because you
wrote into the file.  If you do not do "update-index --refresh"
before running "diff-index" again, "diff-index" will notice and
report the fact that you touched that file.  If you run "git status",
"git diff", etc., they internally do "update-index --refresh" and
then after that until you touch the file on the filesystem, the
cached "(l)stat" information will match and you will stop seeing the
false positive.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-01-22 22:06 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-22 19:09 interaction between git-diff-index and git-apply Ariel Davis
2017-01-22 22:06 ` Junio C Hamano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.