Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a filename argument gitconfig diff textconv?

The documentation on textconv at https://git.wiki.kernel.org/index.php/Textconv has the succinct wording:

~/.gitconfig must indicate the command to execute for the the textconv driver:

[diff "<driver_name>"]
    textconv=<command>

I cannot find any documentation on how to format a command which requires the filename passed as a positional argument. For example, I'd like to use the following pdf formatter command, which requires a dash as last argument to write to stdout:

[diff "pdf"]
    textconv = pdftotext -layout "$1" -

For now I've had to write custom one-liner shell-scripts as a workaround, but they start to accumulate, and it becomes a bit annoying.

Is there a way to do without those scripts? The "$1" or xargs' '{}' convention for arguments don't seem to work.

like image 457
nyov Avatar asked Apr 09 '19 21:04

nyov


People also ask

How do you tell the difference in files in git?

You can run the git diff HEAD command to compare the both staged and unstaged changes with your last commit. You can also run the git diff <branch_name1> <branch_name2> command to compare the changes from the first branch with changes from the second branch.

How does git diff change if you add the -- color words option to the command?

git diff --color-words git diff also has a special mode for highlighting changes with much better granularity: ‐‐color-words . This mode tokenizes added and removed lines by whitespace and then diffs those. Now the output displays only the color-coded words that have changed.

What is the difference between the git diff and git status?

The main difference between the commands is that git diff is specially aimed at comparisons, and it's very powerful at that: It can compare commits, branches, a single file across revisions or branches, etc. On the other hand, git status is specifically for the status of the working tree.

How git diff works internally?

The super-short version is that git status runs git diff . In fact, it runs it twice, or more precisely, it runs two different internal variations on git diff : one to compare HEAD to the index/staging-area, and one to compare the staging-area to the work-tree.


2 Answers

As a workaround for gitconfig lacking parameter substitution functionality, you can wrap the command into a shell call, as in

[diff "pdf"]
    textconv = sh -c 'pdftotext -layout -enc UTF-8 "$0" -'

(found here: https://gist.github.com/t-yuki/9348e5d4aa4a75a6acf9)

like image 114
eMPee584 Avatar answered Sep 21 '22 07:09

eMPee584


Unfortunately, that information is just plain not available. Here is the code that actually achieves the text conversion:

temp = prepare_temp_file(r, spec->path, spec);
*arg++ = pgm;
*arg++ = temp->name;
*arg = NULL;


child.use_shell = 1;
child.argv = argv;
child.out = -1;
if (start_command(&child)) {
    remove_tempfile();
    return NULL;
}

The two arguments are the name of the program itself (argv[0] as usual) and the name of the temporary file containing the bits extracted from wherever they reside (based on the spec parameter; follow the link above for additional detail).

The spec probably does carry the original path name in most or all cases (and if not, look at the function just below this one), it's just not copied through to the program arguments. The textconv filter code could, but doesn't, employ the %-expansion technique used by Git merge drivers, and if it did (but it doesn't) it could has a %-escape that passed the original file name. But of course it doesn't.

(You can make your own clone of Git and work on it, and perhaps try to convince the Git folks to take your change as a contribution to public Git...)

like image 34
torek Avatar answered Sep 21 '22 07:09

torek