88

At work we are several developers and don't have a code style guide, and some developers indent with tabs, and some others with 4 spaces (luckily noone of the indent with spaces people uses different than 4 spaces). In general this is no (big) problem because in our editors we set tabwidth=4 and all the indentation seems correct.

But in git diff or git show that's what appears:

diff --git a/mesclatabs.php b/mesclatabs.php
new file mode 100644
index 0000000..1986c91
--- /dev/null
+++ b/mesclatabs.php
@@ -0,0 +1,5 @@
+<?php
+function foo() {
+       echo "line with 1 tab\n";
+    echo "line with 4 spaces\n";
+}

The problem is git diff or git show where each tabs appears as wide as 8 spaces (well, in reality appears as a tab, and the shell (bash in my case) is showing the tab as 8 spaces. I suppose there must be some bash config to change this, but I'd like to know if git has an option to output tabs as 4 spaces in diff / show, as some developers work with zsh instead of bash.

Any ideas?

Carlos Campderrós
  • 22,354
  • 11
  • 51
  • 57
  • 8
    in an ideal world the devs would all use spaces and you won't have silly issues like this. – sashang May 14 '12 at 10:38
  • 5
    I completely disagree. Why would you represent something with 4 characters when you can represent it with 8? – Matthew G May 24 '13 at 14:59
  • Of course I don't know your situation, but I would really push for some super-basic coding guidelines, maybe just about the tabs/spaces. No tabs sounds like a good idea, because then people tend to use tabs to align their comments and such, too, and it becomes a mess... And inserting tabs after spaces... It's confusing when I go to edit and I can't see what's a tab and what's a space (so I always make tabs visible in my editor). I'm a bit neurotic about it, though, so – Neal Gokli Sep 13 '18 at 18:42
  • 1
    Also, I think it's possible to use (only) tabs consistently for indenting code, and spaces for any other alignment, and then people can change the tabstop to whatever they want. I can't imagine people being consistent enough, though! – Neal Gokli Sep 13 '18 at 18:43
  • @MatthewG 8 sounds a lot grander than my 2... Thank you for showing me the light! :D – Neal Gokli Sep 13 '18 at 18:44

3 Answers3

133

I believe git config --global core.pager 'less -x1,5'

References:

kaartic
  • 523
  • 6
  • 24
codemonkee
  • 2,881
  • 1
  • 25
  • 32
  • 5
    The argument to less should be `-x5` because the +/- symbols of the unified diff don't impact the location of the tab-stop, but they *do* push all the spaces one character to the right. A tab-stop of 5 aligns everything properly. – Todd A. Jacobs May 14 '12 at 13:35
  • yes, that works, setting `-x5` as CodeGnome said. Thank you both very much – Carlos Campderrós May 14 '12 at 14:08
  • urgh, it worked on just the first indentation level, at second, third, ... it does not align because of the initial + in the diffs. I'll leave at `-x4` as setting it higher misaligns it one char more for every indentation level (and also on non-added/removed lines is more consistent). – Carlos Campderrós May 14 '12 at 14:15
  • 1
    how to fix space in `git --color=always | less -r` ? `less -x1,5` is invalid – Zheng Kai Jun 12 '12 at 10:17
  • 2
    @ZhengKai: Just as a data point, I have `less` aliased as `less -R`, core.pager defined as above, and I run `git diff --color-words` -- everything works fine and the tab width is correct. Maybe that helps? – Coderer Jul 11 '13 at 12:19
  • Doesn't work for me on Ubuntu 14.04 - If I do this then the colouring escape sequences get shown instead of doing the colouring e.g. ESC[1mdiff --git a/.gitignore b/.gitignoreESC[m ESC[1mindex 6f4a9ba..4dc6e8d 100644ESC[m – Ian Rogers Jun 27 '14 at 14:29
  • 7
    When I do `git add -p` the pager is not used and the tab displayed in wrong way. If you describe how to fix this too. then the answer will be full – Eugen Konkov Dec 23 '15 at 18:51
  • How to use this with `-r`, I want both `-r` and `-x1,5`, but `less -r -x1,5` does not behavior as expected. – chenzhiwei Dec 06 '17 at 14:28
  • @chenzhiwei: I've used `git config --global core.pager 'less -r -x1,4'` (3 space indent) and it works perfectly. (Note that GIT apparently sets the `LESS=-r` environ by default, but that shouldn't cause any issues in this case.) – ntninja Nov 15 '18 at 12:55
  • @chenzhiwei - I haven't looked at this in many years from first answering, so I can't speak to the defaults back then. According to the documentation (edited to reference valid links) if `LESS` is unset Git sets it to FRX, otherwise if `LESS` is set, Git does not change it. – codemonkee Nov 16 '18 at 00:56
  • 2
    @IanRogers - For colour escape sequences you'd want to use `less -R` / `--RAW-CONTROL-CHARS` https://linux.die.net/man/1/less – codemonkee Nov 16 '18 at 01:06
  • 17
    For those wondering, in `-x1,5` the 1 is for the leading column in the diff output (that contains +, - and a space). Subsequent tabs then jump to columns 5, 9, 13, 17, etc - aka 1 + multiples of 4. So, for git diff the right argument is definitely `-x1,5`. People claiming above that `-x5` works for them ... well - that's a tab width of 5 spaces without a leading column, hmm. Unlikely? – Carlo Wood Apr 13 '19 at 16:11
  • `-x5` didn't work for me in the sense that it seems to have broken ANSI escape sequence processing -- `less` output started showing a lot of `ESC[31m-`, `ESC[m` and other similar sequences. Something to do with the `-` in the `-x5` -- `Rx5`, `-x1,5`, `Rx4` do not disrupt the ANSI escape sequence processing (regardless of their correctness). Furthermore, even with `R-x5`, subsequent tab stops are 5 characters apart, which seems to be definitely wrong. – Armen Michaeli Feb 24 '22 at 10:19
  • Is there a way to make `less -x1,5` also work for git [combined diffs](https://git-scm.com/docs/git-show#_combined_diff_format), which have N leading columns, where N is the number of parent commits? – user16785526 Jul 25 '23 at 16:29
5

As the answer https://stackoverflow.com/a/10584237/1850340 did not work for me because of my color settings I came up with following solution:

TAB=$'\t' && git config --global core.pager "sed 's/$TAB/    /g' | less" && unset TAB

This replaces all tab characters with 4 spaces before displaying it with less. (The TAB workaround is needed to circumvent the shells backslash escape)

Community
  • 1
  • 1
adius
  • 13,685
  • 7
  • 45
  • 46
  • I'm not on something I can test with, but would this be where `less -R` would come into play? to allow the ANSI colour escape sequences through, opposed to `less -r`? – codemonkee Nov 16 '18 at 01:00
4

On MacOS you could do

$ git config --global core.pager 'less --tabs 4'

-x/--tabs is the same option I prefer to use full ones. From man less

-xn,... or --tabs=n,...
Sets tab stops. If only one n is specified, tab stops are set at multiples of n. If multiple values separated by commas are speci- fied, tab stops are set at those positions, and then continue with the same spacing as the last two. For example, -x9,17 will set tabs at positions 9, 17, 25, 33, etc. The default for n is 8.

Sardorbek Imomaliev
  • 14,861
  • 2
  • 51
  • 63