All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Mason <mason@suse.com>
To: git@vger.kernel.org
Subject: Finding file revisions
Date: Wed, 27 Apr 2005 12:50:59 -0400	[thread overview]
Message-ID: <200504271251.00635.mason@suse.com> (raw)

Hello everyone,

I haven't seen a tool yet to find which changeset modified a given file, so 
I whipped up something.  The basic idea is to:

for each changeset in rev-list
	for each file in diff-tree -r parent changeset
		match against desired files

Is there a faster way?  This will scale pretty badly as the tree grows, but 
I usually only want to search back a few months in the history.  So, it 
might make sense to limit the results by date or commit/tag.

Usage:
file-changes [-c commit id] file1 ...

The file names can be perl regular expressions, and it will match any file 
starting with the expression listed.  So "file-changes fs/ext" will show 
everything in ext2 and ext3.

Example output:

diff-tree -r 56022b4d00cae3ff816d3ff05d9f8a80e1517c60 9bd104d712d710d53c35166e40bd5fe24caf893e
8a796b48e757e56b50802c28abf28e0199c45ad9->2db368df614de4799be2d1baffb6563dbe1b8926 fs/ext2/inode.c
dbc8fd9bab639b84b8cc94fdbbf850b1e4bf1b2b->a4cd819734ba2eea9d5d21039deca62057f72d44 fs/ext3/inode.c
cat-file commit 9bd104d712d710d53c35166e40bd5fe24caf893e
    tree cd4e40eae003e29c0d3be2aa769c3b572ab1b488
    parent 56022b4d00cae3ff816d3ff05d9f8a80e1517c60
    author mason <mason@coffee> 1114617717 -0400
    committer mason <mason@coffee> 1114617717 -0400

    comments go here

This is meant for cut n' paste.  If you find a changeset comment you like, 
run the diff-tree -r command on the first line to see a diff of the 
changeset (maybe I should add | diff-tree-helper here?)

-chris


#!/usr/bin/perl

use strict;

my $last;
my $ret;
my $i;
my @wanted = ();
my $matched;
my $argc = scalar(@ARGV);
my $commit;

sub print_usage() {
    print STDERR "usage: file-changes [-c commit] file_list\n";
    exit(1);
}

if ($argc < 1) {
    print_usage();
}

for ($i = 0 ; $i < $argc ; $i++)  {
    if ($ARGV[$i] eq "-c") {
    	if ($i == $argc - 1) {
	    print_usage();
	}
	$commit = $ARGV[++$i];
    } else {
	push @wanted, $ARGV[$i];
    }
}

if (!defined($commit)) {
    $commit = `commit-id`;
    if ($?) {
    	print STDERR "commit-id failed, try using -c to specify a commit\n";
	exit(1);
    }
    chomp $commit;
}

$last = $commit;

open(RL, "rev-list $commit|") || die "rev-list failed";
while(<RL>) {
    chomp;
    my $cur = $_;
    $matched = 0;
    if ($cur eq $last) {
        next;
    }
    # rev-list gives us the commits from newest to oldest
    open(DT, "diff-tree -r $cur $last|") || die "diff-tree failed";
    while(<DT>) {
        chomp;
	my @words = split;
	my $file = $words[3];
	# if the filename has whitespace, suck it in
	if (scalar(@words) > 4) {
	    if (m/$file(.*)/) {
	        $file .= $1;
	    }
	}
	foreach my $m (@wanted) {
	    if ($file =~ m/^$m/) {
		if (!$matched) {
		    print "diff-tree -r $cur $last\n";
		}
		print "$words[2] $file\n";
		$matched = 1;
	    }
	}
    }
    close(DT);
    if ($?) {
	$ret = $? >> 8;
	die "diff-tree failed with $ret";
    }
    if ($matched) {
	print "cat-file commit $last\n";
	open(COMMIT, "cat-file commit $last|") || die "cat-file $last failed";
	while(<COMMIT>) {
	    print "    $_";
	}
	close(COMMIT);
	if ($?) {
	    $ret = $? >> 8;
	    die "cat-file failed with $ret";
	}
	print "\n";
    }
    $last = $cur;
}

close(RL);
if ($?) {
    $ret = $? >> 8;
    die "rev-list failed with $ret";
}

             reply	other threads:[~2005-04-27 16:46 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-04-27 16:50 Chris Mason [this message]
2005-04-27 17:34 ` Finding file revisions Linus Torvalds
2005-04-27 18:23   ` Chris Mason
2005-04-27 22:19     ` Linus Torvalds
2005-04-27 22:31       ` Chris Mason
2005-04-28  8:41         ` Simon Fowler
2005-04-28 11:56           ` Chris Mason
2005-04-28 13:13             ` Simon Fowler
2005-04-28 11:45       ` Chris Mason
2005-04-28 16:34         ` Kay Sievers
2005-04-28 17:10           ` Tony Luck
2005-04-28 17:22             ` Thomas Glanzmann
2005-04-28 19:11         ` Kay Sievers
2005-04-28 20:58           ` Chris Mason
2005-04-28 21:32             ` Linus Torvalds
2005-04-28 21:33             ` Kay Sievers
2005-04-28 21:50               ` Linus Torvalds
2005-04-28 22:27               ` Chris Mason
2005-04-28 13:09       ` David Woodhouse
2005-04-28 13:01     ` David Woodhouse
2005-04-27 18:41   ` Thomas Gleixner
2005-04-28 15:24     ` Linus Torvalds
2005-04-28 16:47       ` Thomas Gleixner
2005-04-28 16:08 ` Daniel Barkalow
2005-04-28 17:05   ` Chris Mason

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200504271251.00635.mason@suse.com \
    --to=mason@suse.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.