12

It would be very handy for me to see the file size of untracked files. And maybe the old/new size of changed files.

Is it possible to configure git in a way to show it?

Martin Thoma
  • 124,992
  • 159
  • 614
  • 958

6 Answers6

11
git status --porcelain | awk '{print $2}' | xargs ls -hs | sort -h
  1. The git status --porcelain will show the file changed.
$ git status
?? IMG_20160813_205506_AO_HDR.jpg
?? IMG_20160813_205539_AO_HDR.jpg
?? IMG_20160813_211139_HDR.jpg
?? IMG_20160814_143649_HDR.jpg
  1. awk '{print $2}' will extract the content after ??
  2. Finally, the ls -hs will show the size of each file in a human readable format. and the sort -h will sort them by size.

Sample Output:

$ git status --porcelain | awk '{print $2}' | xargs ls -hs | sort -h
136 IMG_20160813_205506_AO_HDR.jpg
384 IMG_20160813_205539_AO_HDR.jpg
784 IMG_20160813_211139_HDR.jpg
5667898 IMG_20160814_143649_HDR.jpg
Rian Rizvi
  • 9,989
  • 2
  • 37
  • 33
ramwin
  • 5,803
  • 3
  • 27
  • 29
  • I got this error "xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option". The output after command "awk '{print $2}' gave me text that include: "Assets/Editor (line break) "Assets/Editor – Trong Nguyen Jul 03 '23 at 07:41
  • @TrongNguyen Maybe that occurs because there is space or double quote in your file name. You need to modify the command to adjustify it. Here the command meets the majority requirements. – ramwin Jul 04 '23 at 01:51
6

Try to add the following codes into your .bashrc or .zshrc. And then use gst to get a pretty format output with file size information

alias gst="git_status_size"
git_status_size(){
    git status --porcelain | awk '{print $2}' | xargs ls -hl | sort -r -h | awk '{print $5 "\t" $9}'
}

Output:

$ gst
287MB   video.mp4
53B     README.md
33B     222.txt
18B     333.txt
6B      111.txt
Patrick J. Holt
  • 516
  • 4
  • 7
  • This script is not optimized if you have deleted files or if you are not running the command form the root of your repository. I have edited this to solve both the problems : https://stackoverflow.com/a/70792144/6224662 – fireball.1 Jan 20 '22 at 19:13
5

No, you cannot make git status do that.

You may not need to make git status do that, because you can write your own command that does that instead. Use:

git -C "$(git rev-parse --show-cdup)" ls-files --other --exclude-standard

to obtain the file list. You can then use whatever command you like to view statistics about those files. You may want to run this command immediately after git status and have git status suppress its own listing with --untracked-files=no. For instance:

alias st='git status -uno;
  git -C "$(git rev-parse --show-cdup)" ls-files --others --exclude-standard -z | 
  xargs -0 ls -lR'

Here I've used -z as well since the command I am using, xargs -0 ls -l, can handle that, and expressed this as a shell alias rather than a Git alias.

There is a flaw here. While git status with -uall will enumerate all the untracked files within a directory, git ls-files --others won't: it behaves like a default git status, summarizing such files by printing only the containing directory name. The ls -l here will show the files within the directory; to stop that, use ls -ld instead, but of course you won't see any file sizes.

(To get modified files, use git ls-files -m rather than --others.)

torek
  • 448,244
  • 59
  • 642
  • 775
0

All the above answers use git status --porcelain, which returns file paths from the root of the repository.

Using git status -s would be preferred if we want relative file paths. I have written the below command to show only files that exist (deleted file can't exist) and can be used anywhere.

git status -s | grep -v D.* | awk '{print $2}' | xargs ls -hl | sort -r -h | awk '{print $5 "\t" $9}'

You can also add the following to your .bashrc file to use as an alias.

alias gst="git_status_size"
git_status_size(){
        git status -s | grep -v D.* | awk '{print $2}' | xargs ls -hl | sort -r -h | awk '{print $5 "\t" $9}'
}

Sample Output

7.8K    nnp_replication_attempt_1/scaling.data
7.8K    enhanced_sampling_1/scaling.data
5.3K    nvt_transfer_H_template.lmp
5.3K    ../replication_attempt_1/nvt_stretch_bond.lmp
719     enhanced_sampling_1/z1-ada.sh
fireball.1
  • 1,413
  • 2
  • 17
  • 42
0

This one works for me: git status -s . | awk '{print $2}' | xargs ls -s M -S

Explanation

git

  • -s: list size using current directory as reference rather than repo root (which is what --porcelain` asks for).
  • . restricts output to only files in current directory or below.

ls

  • -s M: print sizes in MB.
  • -S argument for ls sorts the output by size and avoids the need for sort.
mikemtnbikes
  • 393
  • 2
  • 11
0

This command will work with filenames that contain whitespace.

git status --porcelain | awk '{print substr($0,4)}' | xargs ls -hs | sort -h

Based on @ramwin's answer.

If your files have whitespace in them, running ramwin's command will give you error "xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option"

I modified the awk part to awk '{print substr($0,4)}', substr($0,4) takes the output from git status and get the texts from the 4th character to the end of each line. Example:

If git status --porcelain give you: ?? "folder/Folder with whitespace/fileA.ext"

awk '{print substr($0,4)} will output "folder/Folder with whitespace/fileA.ext"

Trong Nguyen
  • 368
  • 2
  • 12