git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: difftool -d symlinks, under what conditions

From
David Aguilar <davvid@gmail.com>
Date
Nov 27, 2012, 06:20 UTC
Message-ID
<CAJDDKr4mTc8-FX7--pd7j0vUbdk_1+KU0YniKEhRdee6SaS-8Q@mail.gmail.com>
In-Reply-To
<CAJELnLGq_oLBiNHANoaE7iEiA6g4fXX0PtJbqPFi4PQ+5LLvnA@mail.gmail.com>

On Mon, Nov 26, 2012 at 12:23 PM, Matt McClure <matthewlmcclure@gmail.com> wrote:

Show 12 quoted lines
> I'm finding the behavior of `git difftool -d` surprising. It seems that it
> only uses symlinks to the working copy for files that are modified in the
> working copy since the most recent commit. I would have expected it to use
> symlinks for all files whose version under comparison is the working copy
> version, regardless of whether the working copy differs from the HEAD.
>
> I'm using
>
>     $ git --version
>     git version 1.8.0
>
> on a Mac from Homebrew.
cc:ing Tim since he probably remembers this feature.

This is a side-effect of how it's currently implemented, and the general-purpose nature of the "diff" command.

diff can also be used for diffing arbitrary commits. The simplest way to implement that is to create two temporary directories containing "a/" and "b/" and then launch the tool against them. That's what difftool does; it creates a temporary index and uses `git checkout-index` to populate these two dirs.

The worktree handling is a bolt-on that symlinks (or copies (on windows or with --no-symlinks)) modified worktree files into one of these temporary directories.

When symlinks are used (the default) we avoid needing to copy these files back into the worktree; we can blindly remove the temporary directories without checking whether the tool edited any files.

When copies are used we check their content for changes before deciding to copy them back into the worktree.

Files that are not modified are not considered part of the set of files to check when copying back, or when symlinking, mostly because that's just how it's implemented right now.

It seems that there is an edge case here that we are not accounting for: unmodified worktree paths, when checked out into the temporary directory, can be edited by the tool when comparing against older commits. These edits will be lost.

If we had a way to know that either a/ or b/ can be replaced with the worktree itself then we could make it even simpler.

Right now we don't because difftool barely parses the command-line at all; most of it is parsed by git-diff. Originally, difftool was a read-only tool so it was able to avoid needing to know too much about what diff is really doing.

We would need to a way to re-use git's diff command-line parsing logic to answer: "is the worktree involved in this diff invocation?"

When we can do that then we avoid needing to have a temporary directory altogether for any dir-diffs that involve the worktree.

Does anyone know of a good way to answer that question?

The input is the command-line provided to diff/difftool. The output is one of ('a', 'b', 'x'), where 'a' means the left side of the diff is the worktree, 'b' means the right side, and 'x' means neither (e.g. the command-line contains two refs).

Assuming we can do this, it would also make dir-diff faster since we can avoid needing to checkout the entire tree for that side of the diff.

-- 
David
Previous: Matt McClureNext: Matt McClure
Message 2 of 50 in “difftool -d symlinks, under what conditions”
  1. Matt McClureNov 26, 2012
  2. David AguilarNov 27, 2012
  3. Matt McClureNov 27, 2012
  4. Matt McClureMar 12, 2013
  5. John KeepingMar 12, 2013
  6. David AguilarMar 12, 2013
  7. John KeepingMar 12, 2013
  8. Junio C HamanoMar 12, 2013
  9. John KeepingMar 12, 2013
  10. Junio C HamanoMar 12, 2013
  11. Matt McClureMar 12, 2013
  12. Matt McClureMar 12, 2013
  13. Junio C HamanoMar 12, 2013
  14. Matt McClureMar 12, 2013
  15. John KeepingMar 13, 2013
  16. Matt McClureMar 13, 2013
  17. David AguilarMar 13, 2013
  18. Junio C HamanoMar 13, 2013
  19. Junio C HamanoMar 13, 2013
  20. John KeepingMar 13, 2013
  21. Junio C HamanoMar 13, 2013
  22. John KeepingMar 13, 2013
  23. Junio C HamanoMar 13, 2013
  24. 0/2 difftool --dir-diff: symlink all files matching the working treeJohn Keeping, Mar 13, 2013
  25. 1/2 git-difftool(1): fix formatting of --symlink descriptionJohn Keeping, Mar 13, 2013
  26. 2/2 difftool --dir-diff: symlink all files matching the working treeJohn Keeping, Mar 13, 2013
  27. David AguilarMar 14, 2013
  28. John KeepingMar 14, 2013
  29. Junio C HamanoMar 14, 2013
  30. 0/3 difftool --dir-diff: symlink all files matching the working treeJohn Keeping, Mar 14, 2013
  31. 1/3 git-difftool(1): fix formatting of --symlink descriptionJohn Keeping, Mar 14, 2013
  32. 2/3 difftool: avoid double slashes in symlink targetsJohn Keeping, Mar 14, 2013
  33. Junio C HamanoMar 14, 2013
  34. 3/3 difftool --dir-diff: symlink all files matching the working treeJohn Keeping, Mar 14, 2013
  35. Junio C HamanoMar 14, 2013
  36. John KeepingMar 14, 2013
  37. Junio C HamanoMar 14, 2013
  38. John KeepingMar 14, 2013
  39. John KeepingMar 14, 2013
  40. Junio C HamanoMar 14, 2013
  41. 0/2 checkout-index: fix .gitattributes handling with --prefixJohn Keeping, Mar 14, 2013
  42. 1/2 t2003: modernize styleJohn Keeping, Mar 14, 2013
  43. 2/2 entry: fix filter lookupJohn Keeping, Mar 14, 2013
  44. Junio C HamanoMar 14, 2013
  45. Junio C HamanoMar 12, 2013
  46. John KeepingMar 12, 2013
  47. Matt McClureMar 12, 2013
  48. John KeepingMar 12, 2013
  49. Matt McClureMar 13, 2013
  50. John KeepingMar 13, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.