Is it possible to configure the temp file folder in git diff?
Asked Answered
E

5

11

When calling git difftool in a repository, git compares the modified files in the local repository with their match in the remote. To do so, it creates a temporary file for the remote, sets the variables LOCAL and REMOTE and calls whichever tool is specified for diffs in git's config.

By default, the temporary file is created in /tmp/<hash>_filename. Is it possible to change this default location?

Why would you do that?

Long story short, I'm using git via windows subsystem for linux and I want to use a windows tool to do diff and merge. The problem is, /tmp is not accessible from the Windows side, so I'd need to move the default location where git creates temporary files to somewhere accessible by Windows.

What I tried:

So far, all I could find was a suggestion to sudo mount -B /tmp /mnt/c/tmp but this doesn't seem to work (/tmp still points to the same directory as before...)

Evvy answered 9/5, 2018 at 8:33 Comment(5)
Have you tried setting the TMPDIR environment variable?Cicala
No.. Never heard of it before tbh. I'll look it upEvvy
Well, that did it (with some overkilling). I wish this was diable via a git config, instead than a system-wide variable.. now all commands I run in the console will use my new tmp location. @Cicala if you add that as an answer I'll at least upvote it (and mark it as actual answer if no other git-only option exists). I'd throw in also a minimal explanation of what TMPDIR is for linux-ignorants like me ;)Evvy
It's git. Git creates the temporary file, then sets LOCAL and REMOTE to the paths of the temporary file and the matching file in your repository. It finally calls the command specified in .gitconfig with the set environment variablesEvvy
@Liam yes, that's exactly what I'm doing. The custom command, however, takes LOCAL and REMOTE as parameters for the two files to diff. My problem is in where LOCAL is created, not in calling the external toolEvvy
C
8

You can try setting the TMPDIR environment variable.

From the POSIX manual:

TMPDIR This variable shall represent a pathname of a directory made available for programs that need a place to create temporary files.


After a quick look at the git code (git/builtin/difftool.c), I don't think configuring the temp directory is currently supported:

/* Setup temp directories */
tmp = getenv("TMPDIR");
xsnprintf(tmpdir, sizeof(tmpdir), "%s/git-difftool.XXXXXX", tmp ? tmp : "/tmp");

Seems like git is taking the TMPDIR value, or "/tmp", if TMPDIR is not defined.

Cicala answered 9/5, 2018 at 8:45 Comment(4)
Adding here the comment I made also under the question: This works, but it's changing /tmp for all commands run in your console. IMO this is overkilling, so I'd hope there is a way to set this in git's configuration somewhere.Evvy
I've just been digging though the source code trying to find this line. Good work. You could post a feature request to the mailing list if you really, really wanted this feature.Homebrew
Wow, I guess that settles this then.Evvy
If your difftool is tkdiff, make sure your ~/.tkdiffrc file does not define tmpdir as it may override your shell environment's TMPDIR.Pals
C
2

Same Problem, solution not by changing temp directory of git but using the diff script you can define:

  1. Define script for diff in .gitconfig

    [diff]
    external = /home/user/scripts/my_diff.sh
    
  2. Create script /home/user/scripts/my_diff.sh to use the Windows tool:

    #!/bin/bash
    FILE2="C:\\dev\\wsl\\Debian\\rootfs\\${2//\//\\}"
    FILE1=$(wslpath -w $5)
    /c/Program\ Files\ \(x86\)/WinMerge/WinMergeU.exe $FILE1 $FILE2
    

In my example I am using WinMerge.
I know that this solution is against the rule that Windows tools are not allowed to touch Linux files, but I am fine with that since we are talking about a temp file and I don't see the point of changing it in WinMerge anyhow. The manual path substitution is necessary because wslpath does not work on Linux internal path.

Your WSL might be different, normally somewhere

C:\Users\%username%\AppData\Local\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs

This feels a little hacky, but I am using it and am happy up till now.

Chauffeur answered 12/1, 2019 at 21:19 Comment(0)
P
2

By default, the temporary file is created in /tmp/<hash>_filename.
Is it possible to change this default location?

Not exactly, but this default location has been modified with Git 2.37 (Q3 2022): the temporary files fed to external diff command are now generated inside a new temporary directory under the same basename.

See commit 8af7593, commit 2c2db19 (20 Apr 2022) by René Scharfe (rscharfe).
(Merged by Junio C Hamano -- gitster -- in commit 2e96975, 20 May 2022)

diff: use mks_tempfile_dt()

Signed-off-by: René Scharfe

Git uses temporary files to pass the contents of blobs to external diff programs and textconv filters.
It calls mks_tempfile_ts() to create them, which puts them all in the same directory.
This requires adding a random name prefix.

Use mks_tempfile_dt() instead, which allows the files to have arbitrary names, each in their own separate temporary directory.
This way they can have the same basename as the original blob, which looks nicer in graphical diff programs.

And:

tempfile: add mks_tempfile_dt()

Signed-off-by: René Scharfe

Add a function to create a temporary file with a certain name in a temporary directory created using mkdtemp(3).
Its result is more sightly than the paths created by mks_tempfile_ts(), which include a random prefix.
That's useful for files passed to a program that displays their name, e.g. an external diff tool.

Perspicuity answered 22/5, 2022 at 15:54 Comment(0)
C
0

I made a variant of the two approaches here, for my own use. I created a script which I call instead of running git diff (change the "twm" path, if copying - that's my own user directory):

#!/bin/bash                                                                     

export TMPDIR=$( realpath --relative-to=. /mnt/c/Users/twm/tmp )
git difftool -y -t winmerge "$@"

I was specifically targeting WinMerge invoked by Git running in Windows Subsystem for Linux. The problem I hit with using TMPDIR was that while Git wrote to it, WinMerge didn't recognize the temporary path, initially because it started with "/mnt/c" - I did get the paths to match between WSL and Windows, except for the leading "c:" and WinMerge still didn't recognize it. However, I noticed that the other path was correctly recognized, and ps showed it was being passed to WinMerge as a relative path, so I used realpath to make TMPDIR relative too.

Using a script to set TMPDIR locally also solves an issue mentioned in the comments. That is, changing the temporary directory for all other programs for this one use case seems like overkill and might have some unintended side effects.

Like the second approach listed here, I had tinkered with Git aliases too in an attempt to get this to work. However, I wanted to make use of Git's existing WinMerge integration in case the built in integration provides more functionality than a hard coded script, now or in the future.

Cleave answered 20/1, 2019 at 20:8 Comment(0)
B
0

Put this in your .gitconfig in windows/HOME directory. You will need to install cygwin for cygpath (and git) commands and adjust location of WinMerge below

[difftool "winmerge"]
         # Usage: git difftool --tool winmerge
        path = C:/bin/WinMergeU.exe
        cmd =  C:/bin/WinMergeU.exe \"$(cygpath -wam $LOCAL)\" \"$(cygpath -wam $REMOTE)\"
Brosy answered 15/7, 2020 at 13:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.