Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git: list all files with owner/identity at first commit (or rather, the first user to commit the file)

Tags:

git

How do I, using git, list all files in a particular directory together with the owner/identity of those files at first commit?

Is getting slices of information like this across many files usually difficult?

Edit: Okay, git doesn't provide a direct way to do this, but it does store who commits various files, right? I need this list in a particular directory so I can get a sense of which files I'm 'responsible' for.

like image 299
Rex Butler Avatar asked Sep 27 '11 22:09

Rex Butler


People also ask

What is the git command to view all the commits made by a specific person?

The git log command displays all of the commits in a repository's history.

How do I filter a commit?

To filter commits by their commit message, use the --grep flag. This works just like the --author flag discussed above, but it matches against the commit message instead of the author. You can also pass in the -i parameter to git log to make it ignore case differences while pattern matching.


4 Answers

Give this a try:

$ cd thatdirectory
$ git ls-files |
  while read fname; do
    echo "`git log --reverse --format="%cn" "$fname" | head -1` first added $fname"
  done

The "first added" can be misleading in case of renames.

Refs:

  • https://git-scm.com/docs/git-ls-files
  • https://git-scm.com/docs/git-log#_pretty_formats (see placeholders under format:<string>)
like image 150
holygeek Avatar answered Oct 25 '22 19:10

holygeek


I happened to run into a similar situation. The accepted answer is working, but why don't you guys use find with working copy?

find . -type f -exec git log --reverse --format="{} %cn" -1 {} \;
like image 30
pinxue Avatar answered Oct 25 '22 19:10

pinxue


A very straightforward approach would be

git rev-list --objects --all |
    cut -d' ' -f2- |
    sort -u |
    while read name; do 
         git --work-tree=. log --reverse --format="%cn%x09$name" -- "$name" | head -n1
    done

Caveats:

  • This shows the first author name (%an) of each path that exists in the object database (not just in (any) current revision). You may also want the committer name (%cn), though be aware that if person B rebased a commit from person A that created the file, B will be the committer and A will be the author.
  • The --all flag signifies that you want all objects on all branches. To limit scope, replace it by the name of the branch/tag or just by HEAD

  • n2 performance (doesn't scale well for very large repo's)

  • improper output if the pathname contains formatting sequences (e.g. %H etc.)

It will start out with the empty name, which is the root tree object.

like image 20
sehe Avatar answered Oct 25 '22 21:10

sehe


To do this efficiently,

git log --raw --date-order --reverse --diff-filter=A --format=%H%x09%an \
| awk -F$'\t' '
       /^[^:]/   {thisauthor=$2}
       $1~/A$/   {print thisauthor "\t" $2}
'

with maybe a |sort -t$'\t' -k1,1 or something to make it a bit prettier

like image 22
jthill Avatar answered Oct 25 '22 21:10

jthill