Git does not track directories as such. It only tracks files that live in some directory. (See How can I add an empty directory to a Git repository?)
However, if I have certain history of commits I implicitly also have history of changes to the directory tree.
So how do I answer questions like:
- when was directory foo/bar created (in git terminology: when was the first file created in that directory). There could be more than one qualifying commit if foo/bar has been deleted some time in history and recreated later.
- when was directory foo/bar removed (in git terminology: when was the last file removed from that directory). As above there could be more than one qualifying commit.
- what are the subdirectories of foo/bar that existed in any point of time in history
The closest I could come up with is in pseudo code:
loop over all commits (git rev-list --all)
start from repo root directory
do recursively on the directory tree rebuilt so far
call git ls-tree and grep the tree lines
rebuild next level of directory tree
end
end
Obviously this could be written in your favorite scripting language.
Then I have all directory trees and I still need to search them in a smart way in order to be to answer questions of type 1 - 3. Again, doable but probably not in a couple of minutes.
The questions are:
- Is there an easier way?
- If not: are suitable the scripts already on the net? (my googling didn't reveal any, but I did not come up the perfect search words either)
For questions 1 and 2, it's quite easy:
when was directory foo/bar created?
git log --oneline -- foo/bar | tail -n 1
when was directory foo/bar deleted?
git log --oneline -- foo/bar | head -n 1
However, the third part is a bit tricky and I cannot answer it completely.
The two commands above give you
$FIRST_REV
(created) and$LAST_REV
(deleted).The following snippet gives you all commits where the tree was modified:
Then, you have a list of directories that were present. But there are still duplicates. Pass that list to a
sort -u
and you're done:However, you lose the information of the commits where these directories were affected. That's the drawback.
And, this assumes that
foo/bar
was created only once and is no longer present.gitk foo/bar
gives you a user interface for browsing the git history limited to commits that touchedfoo/bar
.