Discussion:
Feature request: svn log constrained by line range
Joel Polowin
2017-04-07 02:50:49 UTC
Permalink
Hi, all.  This is my first post to this list, but I've been a member
on many others.

I'd like to make a feature/enhancement suggestion for svn. Would you
please let me know how I might do that? Or of course I'd be happy if
someone can tell me how to do what I want with the existing features,
though a couple of people in my group who are more experienced than
I am with svn haven't been able to figure out how it might be done.

In case posting to this list is sufficient... I'd like to be able
to specify a line range for a file so that _svn log filename_ would
show the change log for only those lines, allowing for the movements
of the first and last lines through the file's history. So if my file
'blargh' has a function which currently begins at line 1500 and ends at
line 1800, the command "svn log blargh --lines 1500:1800" would give
me the commit messages for that function even if that block of lines
was originally added to occupy, say, lines 2700 to 3500. And wouldn't
report the messages for commits that didn't touch that block of lines.

This would help to resolve a conflict in my work group regarding good
practises for code documentation. :-(

Thanks,
Joel
Johan Corveleyn
2017-04-07 12:16:38 UTC
Permalink
Hi, all. This is my first post to this list, but I've been a member
on many others.
I'd like to make a feature/enhancement suggestion for svn. Would you
please let me know how I might do that? Or of course I'd be happy if
someone can tell me how to do what I want with the existing features,
though a couple of people in my group who are more experienced than
I am with svn haven't been able to figure out how it might be done.
In case posting to this list is sufficient... I'd like to be able
to specify a line range for a file so that _svn log filename_ would
show the change log for only those lines, allowing for the movements
of the first and last lines through the file's history. So if my file
'blargh' has a function which currently begins at line 1500 and ends at
line 1800, the command "svn log blargh --lines 1500:1800" would give
me the commit messages for that function even if that block of lines
was originally added to occupy, say, lines 2700 to 3500. And wouldn't
report the messages for commits that didn't touch that block of lines.
This would help to resolve a conflict in my work group regarding good
practises for code documentation. :-(
Interesting question. In theory svn could do this ... it's sort of a
combination of 'blame' and 'log'. The information is there. But at
present there is no functionality exposed for this in the client.

* 'svn blame' works by invoking 'get_file_revs2' on the repository,
retrieving all revisions, and processing the diffs between them,
sequentially. It keeps track of which rev / author last touched each
line (in the end it outputs the final result: each line with its
corresponding "last rev / author"). See the source of
libsvn_client/blame.c [1] for a starting point.

* Your 'svn log Filename --lines 1500:1800' could similarly walk the
history of the file with get_file_revs2. It would need to keep a list,
per line, of all revisions that touched the line. And at the end
output the log of all revisions that are applicable to the range of
lines given.

You might be able to write this, purely client-side, in C, or using
one of the language bindings (python bindings or JavaHL), invoking the
get_file_rev2 API.


[1] http://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_client/blame.c,
see lines 809 and following, where it calls svn_ra_get_file_revs2,
passing file_rev_handler as callback function.
--
Johan
Joel Polowin
2017-04-07 22:56:25 UTC
Permalink
Post by Johan Corveleyn
Post by Joel Polowin
In case posting to this list is sufficient... I'd like to be able
to specify a line range for a file so that _svn log filename_ would
show the change log for only those lines, allowing for the movements
of the first and last lines through the file's history. So if my file
'blargh' has a function which currently begins at line 1500 and ends at
line 1800, the command "svn log blargh --lines 1500:1800" would give
me the commit messages for that function even if that block of lines
was originally added to occupy, say, lines 2700 to 3500. And wouldn't
report the messages for commits that didn't touch that block of lines.
Interesting question. In theory svn could do this ... it's sort of a
combination of 'blame' and 'log'. The information is there. But at
present there is no functionality exposed for this in the client.
* 'svn blame' works by invoking 'get_file_revs2' on the repository,
retrieving all revisions, and processing the diffs between them,
sequentially. It keeps track of which rev / author last touched each
line (in the end it outputs the final result: each line with its
corresponding "last rev / author"). See the source of
libsvn_client/blame.c [1] for a starting point.
* Your 'svn log Filename --lines 1500:1800' could similarly walk the
history of the file with get_file_revs2. It would need to keep a list,
per line, of all revisions that touched the line. And at the end
output the log of all revisions that are applicable to the range of
lines given.
You might be able to write this, purely client-side, in C, or using
one of the language bindings (python bindings or JavaHL), invoking the
get_file_rev2 API.
Hm. Would that cover lines that were deleted, rather than added or
merely altered? That's one of my objections to a colleague's "just
use 'svn blame'!"

I was, of course, hoping to get away without undertaking a big
programming task in a language I'm comfortable with (C), much less
ones I'm essentially unfamiliar with (python, any flavour of Java).
Ah, well.

Joel
Johan Corveleyn
2017-04-08 18:38:13 UTC
Permalink
Post by Joel Polowin
Post by Johan Corveleyn
Post by Joel Polowin
In case posting to this list is sufficient... I'd like to be able
to specify a line range for a file so that _svn log filename_ would
show the change log for only those lines, allowing for the movements
of the first and last lines through the file's history. So if my file
'blargh' has a function which currently begins at line 1500 and ends at
line 1800, the command "svn log blargh --lines 1500:1800" would give
me the commit messages for that function even if that block of lines
was originally added to occupy, say, lines 2700 to 3500. And wouldn't
report the messages for commits that didn't touch that block of lines.
Interesting question. In theory svn could do this ... it's sort of a
combination of 'blame' and 'log'. The information is there. But at
present there is no functionality exposed for this in the client.
* 'svn blame' works by invoking 'get_file_revs2' on the repository,
retrieving all revisions, and processing the diffs between them,
sequentially. It keeps track of which rev / author last touched each
line (in the end it outputs the final result: each line with its
corresponding "last rev / author"). See the source of
libsvn_client/blame.c [1] for a starting point.
* Your 'svn log Filename --lines 1500:1800' could similarly walk the
history of the file with get_file_revs2. It would need to keep a list,
per line, of all revisions that touched the line. And at the end
output the log of all revisions that are applicable to the range of
lines given.
You might be able to write this, purely client-side, in C, or using
one of the language bindings (python bindings or JavaHL), invoking the
get_file_rev2 API.
Hm. Would that cover lines that were deleted, rather than added or
merely altered? That's one of my objections to a colleague's "just
use 'svn blame'!"
I think in general it's hard to say whether you're interested in the
deletion of line 100 in rev 10, when you're running 'svn log --lines
1500:1800' with HEAD being rev 10000. After the line is deleted, how
would svn know that it's a deletion you're interested in, i.e. that it
ends up being interesting to your line range? Subversion (currently)
doesn't have functionality for tracking larger contextual blocks of
text, so saying "but this line was part of a large block of text that
got moved and ended up at lines 1500:1800" doesn't help.

Thinking more about this, I guess my initial suggestion was a bit
naive. The diffs used by 'blame' are just "minimal diffs". This means
it's the smallest set of deletions and additions of lines that
transforms X into Y. There is really no notion of a modification of a
line. Some lines are deleted, some new ones are added. Maybe for you
they're semantically related (so you see them as modifications), but
they might just as well be totally unrelated (for instance: a function
got deleted, and at that same spot a block of comments is introduced
for the function below).

So 'blame' can show you the author / rev that added a particular line.
But it would require quite a bit more logic to build a list of all
revs that modified a line ... since there is no concept of modifying a
line.
Post by Joel Polowin
I was, of course, hoping to get away without undertaking a big
programming task in a language I'm comfortable with (C), much less
ones I'm essentially unfamiliar with (python, any flavour of Java).
Ah, well.
Yes, I'm sorry Subversion can't help you out of the box with this. But
if you want to experiment a bit with the code, or feel inclined to
discuss a design idea (on the dev@ list), you're certainly welcome to
share your ideas. Subversion is largely a volunteer-driven project
nowadays, so we're always looking for extra hands :-). In case you're
interested, please take a look at our Community Guide:
http://subversion.apache.org/docs/community-guide/.
--
Johan
Joel Polowin
2017-04-09 23:15:32 UTC
Permalink
Post by Johan Corveleyn
Post by Joel Polowin
Hm. Would that cover lines that were deleted, rather than added or
merely altered? That's one of my objections to a colleague's "just
use 'svn blame'!"
I think in general it's hard to say whether you're interested in the
deletion of line 100 in rev 10, when you're running 'svn log --lines
1500:1800' with HEAD being rev 10000. After the line is deleted, how
would svn know that it's a deletion you're interested in, i.e. that it
ends up being interesting to your line range? Subversion (currently)
doesn't have functionality for tracking larger contextual blocks of
text, so saying "but this line was part of a large block of text that
got moved and ended up at lines 1500:1800" doesn't help.
Thinking more about this, I guess my initial suggestion was a bit
naive. The diffs used by 'blame' are just "minimal diffs". This means
it's the smallest set of deletions and additions of lines that
transforms X into Y. There is really no notion of a modification of a
line. Some lines are deleted, some new ones are added. Maybe for you
they're semantically related (so you see them as modifications), but
they might just as well be totally unrelated (for instance: a function
got deleted, and at that same spot a block of comments is introduced
for the function below).
"svn diff" (and "diff", for that matter) seem to be able to keep pretty
good track of changes in the positions of lines that *aren't* changed
-- the context lines. A patch file notes that an altered block,
with its context lines, has been shifted up or down to a different
position, as long as the alterations aren't too severe; it generally
fails to recognize a block of text that has been moved with respect
to the rest of a file. If we accept that limitation, i.e. that we
can only get the limited history for a block of lines so far back as
the delimiting lines are invariant enough to serve as context lines
for diffs, does that simplify the problem enough to make it tractable?

Joel

Loading...