Deqing
Deqing

Reputation: 14652

Showing the latest changes of each subdirectory in git

In github if you open a repository you will see a page showing the latest commit and time of each subdirectory and file.

Can I do this by command line in git?

Upvotes: 6

Views: 2504

Answers (3)

Deqing
Deqing

Reputation: 14652

Thanks answers from Klas Mellbourn and Nevik Rehnel, finally I combined these two versions into mine:

#!/bin/bash

FILES=`ls -A`
MAXLEN=0
for f in $FILES; do
    if [ ${#f} -gt $MAXLEN ]; then
        MAXLEN=${#f}
    fi
done
for f in $FILES; do
    str=$(git log -1 --format="%cr      [%cn]   %s" $f)
    printf "%-${MAXLEN}s -- %s\n" "$f" "$str"
done

Outputs:

$ bash view.bash
android_webview   -- 4 months ago       [[email protected]]    Disable testCalledForIframeUnsupportedSchemeNavigations
ash               -- 4 months ago       [[email protected]]   Rename _hot_ -> _hover_
cc                -- 4 months ago       [[email protected]]     cc: Let impl-side painting use smaller tiles
chrome            -- 5 weeks ago        [Deqing]     Set the nacl pipe to non-blocking
tools             -- 10 weeks ago       [Haxx Hx]    Add submodule tools/gyp

Upvotes: 8

Klas Mellbourn
Klas Mellbourn

Reputation: 44387

In PowerShell you could create a script like this

git ls-tree --name-only HEAD | ForEach-Object { 
   Write-Host $_ "`t" (git log -1 --format="%cr`t%s" $_)
}

This loops through all files in the current directory, writes out the file name, a tab (the backquoted "t"), and then the output of git log with the relative date, a tab, and the commit message.

Sample output:

subfolder        18 hours ago   folder for miscellaneous stuff included
foo.txt          3 days ago     foo is important
.gitignore       3 months ago   gitignore added

The GitHub result actually contains the committer too, you can get that also by adding [%cn]:

Write-Host $_ "`t" (git log -1 --format="%cr`t%s`t[%cn]" $_)

The script above does not handle long filenames well, since it depends on tabs. Here is a script that creates a nicely formatted table, where each column is exactly as wide as it needs to be:

git ls-tree --name-only HEAD | ForEach-Object { 
  Write-Output ($_ + "|" + (git log -1 --format="%cr|%s" $_)) 
} | ForEach-Object {
  New-Object PSObject -Property @{
    Name = $_.Split('|')[0]
    Time = $_.Split('|')[1]
    Message = $_.Split('|')[2]
  }
} | Format-Table -Auto -Property Name, Time, Message

Upvotes: 3

Nevik Rehnel
Nevik Rehnel

Reputation: 51975

You can't do it in a single Git command for all the entries in the CWD, but with a simple bash script, you can:

Put

#!/bin/bash

FILES=`ls -A`
MAXLEN=0
for f in $FILES; do
    if [ ${#f} -gt $MAXLEN ]; then
        MAXLEN=${#f}
    fi
done
for f in $FILES; do
    printf "%-${MAXLEN}s -- %s\n" "$f" "$(git log --oneline -1 -- $f)"
done

in a file and run it as a script, or use it as an online command by running
FILES=$(ls -A); MAXLEN=0; for f in $FILES; do if [ ${#f} -gt $MAXLEN ]; then MAXLEN=${#f}; fi; done; for f in $FILES; do printf "%-${MAXLEN}s -- %s\n" "$f" "$(git log --oneline -1 -- $f)"; done on a bash prompt directly.

Upvotes: 2

Related Questions