How can I find the svn diff between working copy and arbitrary rev? - linux

I'm trying to write a multi-file patch for an open-source project, but the master copy has changed since I started working. I need to get the SVN difference (just the files under version control) between my uncommitted version and the revision from which it was checked. Which SVN command can I use to find the difference?
Edit: I'm sorry, I must have been using the term "working copy" improperly. I need to compare my uncommitted changes to the revision off which they are based. In other words, I checked out revision 1000 and changed files foo and bar. The rev number is now up to 1015, but I need to compare my version of foo and bar to the version of revision 1000. Is there an easy command to do this (compare my altered copy of a program with a past revision)?

You can use -rN:M parameter with diff command which specifies the revisions you want to compare. Just provide revision from which your working copy was checked out (you can omit M as it defaults to working copy) and you should get what you need.
If you don't remember the original revision number try to run svn status -v and first column should show it.
More info svn help diff...

svn diff takes a -rN:M argument which defaults to N == BASE and M == working copy. Will svn diff -r REV where REV is the revision you want not work?
To answer your edit, suppose you have the following:
$ ls
foo bar baz
$ svn st -u
Status against revision: 1071
$ echo "more stuff" >> foo
$ svn diff -r 1000 foo
Index: foo
===================================================================
--- foo (revision 1000)
+++ foo (working copy)
...
I believe this is what you are after, yes?

If your goal was to get a report of just the filenames where the contents has changed, this should do the trick:
svn diff | grep 'Index: ' .

Related

How to visually compare two revisions of a folder versioned by SVN on Linux?

I can compare a current folder state to its latest revision using the following command:
meld .
meld shows a list of changed files. One can click on each file and see a diff.
Is it possible to compare a current folder state to its specific revision (not the latest one)?
TortoiseSVN allows to compare arbitrary revisions, however it works on Windows only. SmartSVN is proprietary. SVN CLI is unusable for big changesets (CLI diff is fine for small commits, but it's very hard to use it for branch comparision with a lot of changes).
Maybe I could checkout the revision to compare into a separate folder and compare two folders using meld. But I guess there should be a simpler approach.
Preface
Question is offtopic here: as already mentioned in comment, it's question for Software Recommendations site
Face
Every versioned object with history in SVN can be referenced using PEG-revision for its history state
Folder in SVN-repo is object of versioning
In order to compare two folders, you have to have folder-diff tool (for your OS) and know (command-line) options for calling it
According to Slant's comparison:
Meld can be used on Linux for folder-diffing
Best folder-diff tool is Beyond Compare
From points 1-3 above it follows that Meld can be used for your task in form
meld folder#REV1 folder#REV2
Folder comparision is usually required for code review or branch merging. It seems that the simplest approach is as follows:
Find last trunk revision merged to a current brach
If the current branch was not merged from trunk, then find the branch creation revision
Checkout trunk with a specified revision to some folder
Compare the trunk folder and the brach folder
I didn't found any existing tools supporting it. Here is a bash script I use, maybe it will be useful for someone:
TRUNK_BASE_PATH=~/tmp
BRANCH_RELATIVE_URL=$(svn info --no-newline --show-item relative-url)
if [[ "$BRANCH_RELATIVE_URL" != *"/branches/"* ]]; then
echo "Run it in a branch. Relative URL should contain /branches/. Given: $BRANCH_RELATIVE_URL"
exit 1
fi
TRUNK_RELATIVE_URL=${BRANCH_RELATIVE_URL%%/branches/*}/trunk
echo "Trunk relative URL: $TRUNK_RELATIVE_URL"
ROOT_URL=$(svn info --no-newline --show-item repos-root-url)
TRUNK_URL=${ROOT_URL}${TRUNK_RELATIVE_URL:1}
echo "Trunk URL: $TRUNK_URL"
TRUNK_PATH=${TRUNK_BASE_PATH}/${TRUNK_URL#*://}
echo "Trunk local copy path: $TRUNK_PATH"
BRANCH_PATH=$(svn info --no-newline --show-item wc-root)
echo "Branch local copy path: $BRANCH_PATH"
SUBFOLDER=$(realpath --relative-to="$BRANCH_PATH" .)
echo "Comparing subfolders: $SUBFOLDER"
TRUNK_REVISION=$(svn mergeinfo --show-revs merged -R "$TRUNK_RELATIVE_URL" "$BRANCH_PATH" | tail -n 1)
if [[ -z "$TRUNK_REVISION" ]]; then
TRUNK_REVISION=$(svn log -r 1:HEAD --limit 1 --stop-on-copy -q | grep -oP "^r\K[0-9]+")
echo "Comparison with trunk#$TRUNK_REVISION from which the current branch was copied"
else
echo "Comparison with trunk#$TRUNK_REVISION with which the current branch was last merged"
fi
if [[ -d "$TRUNK_PATH/.svn" ]]; then
echo "Found .svn subfolder in the local trunk copy, updating it"
svn update -r $TRUNK_REVISION "$TRUNK_PATH"
else
echo "Not found .svn subfolder in the local trunk copy, checking out it"
svn checkout "$TRUNK_URL" -r $TRUNK_REVISION "$TRUNK_PATH"
fi
meld "$TRUNK_PATH/$SUBFOLDER" . &!

How should be paths to p4 sync -L formatted

I'm trying to figure out what is correct syntax for p4 sync -L. When I try p4 sync -L //one/of/my/files it complains that revision is not specified while if I try p4 sync -L //one/of/my/files#1234 it complains that # and # are illegal.
Well, the documentation says:
a list of valid file arguments in full depot syntax with a valid revision number
Revision numbers are #1, #17, etc. The # syntax is used to reference a label name, client name, or changelist number, which are not revision numbers.
For more details on this, check [p4 help revisions][2]; as it says, you want:
`file#n Revision specifier: The nth revision of file.`
So, specify //one/of/my/files#17, assuming that revision 17 is the revision of that file that you want to sync.
To see the revisions of your files, use p4 filelog //one/of/my/files.

How to get proper diff of merge commit in tig

if i got into tig main view, i get a nice graph of commits and merges. i'd prefer to just look at the merge commits to trunk but unlike with normal commits tig where tig shows the full diff with file contents, on merge commits it just shows a list of changed files in the diff view. How do i get tig to display the file contents diff on merge commits?
commit fb56223ec50cf659a308b3c9979c912881147689
Refs: [master], {origin/master}, {origin/HEAD}, juju-1.21-alpha1-229-gfb56223
Merge: 7e7c95d a017b5a
Author: Juju bot
AuthorDate: Mon Sep 22 01:22:03 2014 +0100
Commit: Juju bot
CommitDate: Mon Sep 22 01:22:03 2014 +0100
Merge pull request #803 from mjs/check-ssh-api-methods-are-allowed-during-upgrade
cmd/juju: ensure that API calls used by "juju ssh" are allowed during upgrades
We recently had a regression where an API call required by "juju ssh" wasn't being allowed by the API server while upgrades are in progress. "juju ssh" is one of the few commands that is supposed to work during upgrades.
The Client used by "juju ssh" is now forced into an interface and this is checked using reflection against what the API server will allow during upgrades. Effectively, the compiler helps to check that the required API methods will be allowed.
http://reviews.vapour.ws/r/64/diff/
apiserver/upgrading_root.go | 20 +++++++++++---------
cmd/juju/ssh.go | 15 +++++++++++----
cmd/juju/ssh_test.go | 24 ++++++++++++++++++++++++
3 files changed, 46 insertions(+), 13 deletions(-)
navigating to the individual files (j/k) in the view, says press 'Enter' to view file diff, but hitting enter gets "Failed to find file diff" err message. ideally i'd just be looking at the combined diff for the merge commit.
[update] i traced through tig with sysdig and it looks like its doing the following which on merge commits won't show the actual diff.
git show --encoding=UTF-8 --pretty=fuller --root --patch-with-stat --show-notes --no-color fb56223ec50cf659a308b3c9979c912881147689 --
i guess what i'm looking for on merge commits then is to parse the parents commits and then do something like the following
git diff 7e7c95d a017b5a
[update] so the diff actually isn't correct here as that diff would be between the two parents, and be more inclusive of changes then the merge itself, the best content rendering of the diff seems to be
git diff fb56223^ fb56223
Turns out this is pretty straightforward via external command integration.
I dropped this into ~/.tigrc:
bind diff 7 !git diff %(commit)^ %(commit)
and now just press 7 for the diff output i'm looking.
You have several options:
put this into your .tigrc
set diff-options = -m
you can set many options in ~/.tigrc, see also the manpage:
man tigrc
or start tig with the option -m
tig -m
Options to tig are passed to the underlying git command. More Info about this also in the manpage:
man tig

Perforce: How to find the original number of a change list

In perforce changelists get renumbered on submission. So for e.g. when the changelist was created it would be numbered 777 , but on submission of changelist it would get renumbered to say 790.
My question is how do I get the new CL number (790) , if I know the old CL number 777 , or vice versa ?
If you really want the original changelist number, that can be retrieved from Perforce without having to embed the original changelist number in the description. You can use the -ztag command line option to get at it. And you can only get at it through the 'changes' command (as far as I know):
d:\sandbox>p4 submit -c 24510
Submitting change 24510.
Locking 1 files ...
edit //depot/testfile.txt#2
Change 24510 renamed change 24512 and submitted.
d:\sandbox>p4 -ztag changes -m1 //depot/testfile.txt
... change 24512
... time 1294249178
... user test.user
... client client-test.user
... status submitted
... oldChange 24510
... desc <enter description here>
<saved
As pointed out, it's probably not that useful. However, I did want to note that it's possible to get at it.
The only way I can think of is adding the original changelist number as part of the changelist description field. First, you'll need a script to store the original changelist number:
#!/bin/env perl
$id = $ARGV[0];
open (CHANGE_IN, "p4 change -o $id|");
open (CHANGE_OUT, "|p4 change -i $id");
while (<CHANGE_IN>)
{
if (/^Description:/ and not /ORIGID/)
{
s/(^Description:)(.*)$/$1 ORIGID $id. $2/;
}
print CHANGE_OUT $_;
}
close (CHANGE_IN);
close (CHANGE_OUT);
Save this as origid.pl on the Perforce server with the executable bit set. Then setup a trigger with p4 triggers.
Triggers:
add_origid change-submit //depot/... /usr/bin/origid.pl %change%
Version 2012.1 of Perforce introduced the -O (capital oh) argument to p4 describe, which allows you to query a changelist by its original number (before being renumbered by p4 submit).
I find this very helpful, since I often find myself keeping notes about a changeset before it is submitted, then forgetting to note what it was renumbered to on submission.
So if I have a note talking about change 12300, I can now see what it refers to by typing:
p4 describe -s -O 12300
and having Perforce tell me:
Change 12345 by me#myhost on 2013/10/31 00:00:00
Fix that thing I wrote that note about
Affected files ...
... //Proj/MAIN/foo.c
The ztag method mentioned earlier can be used to find the old changelist number of a submitted change:
> p4 -ztag describe -s 12345 | grep oldChange
... oldChange 12300
Adding to Eric Miller's reply, because I can't comment (not enough points):
to just emit the 1 number
p4 -ztag describe $ORIG | sed -e 's/^\.\.\. oldChange //;t-ok;d;:-ok'
e.g.
OLD=$(p4 -ztag describe $ORIG | sed -e 's/^\.\.\. oldChange //;t-ok;d;:-ok')
or if you want to look up many numbers, this will output a map of new old on each line (may be useful with the "join" command). If there is no old commit, then it re-emits the new commit.
p4 -ztag describe 782546 782547 ... | sed -e '${x;p};s/^\.\.\. change //;t-keep;b-next;:-keep;x;/./p;g;G;s/\n/ /;x;d;:-next;s/^\.\.\. oldChange //;t-ok;d;:-ok;H;x;s/ .*\n/ /;x;d;'
I tried to avoid using GNU extensions to sed.
Unless you do something like Tim suggests the old change list number will be lost on submission.
Change list numbers are only temporary until you actually submit. So if you create a new change list (777 say) and then decide to delete it, the next change list you create will be 778.
It can be a bit more elegant if you use the P4 Python module.
i.e.
import P4
p4 = P4.P4()
p4.connect() # having a valid p4 workspace/connection is on you :)
c = p4.run_describe('969696') # describe a Submitted, renumbered changelist, i.e. 969696
old_pending_cl_number = c['oldChange'] # print out prior/pending CL# if this exists.
Cheers

Merging fails in mercurial with "Operation not supported"

I've set up my ~/.hgrc as per https://www.mercurial-scm.org/wiki/MergingWithVim to use vimdiff.
[ui]
merge = vimdiff
[merge-tools]
vimdiff.executable = vim
vimdiff.args = -d $base $local $output $other +close +close
However, when I try to run the actual merge, it just fails out not very helpfully with the following:
bash-3.2$ hg --debug merge
searching for copies back to rev 7
resolving manifests
overwrite None partial False
ancestor 88aaf3a2e10f local 311bb03b96cd+ remote 29bec6ac5dd3
junk: versions differ -> m
preserving junk for resolve of junk
updating: junk 1/1 files (100.00%)
picked tool 'vimdiff' for junk (binary False symlink False)
abort: Operation not supported: /Accounts/rainest/mtest/junk.orig
Any idea why it's doing this?
I've figured it out.
It turns out there's a very specific bug in Python2.6's shutil library that occurs if you're working with NFS mounts on a BSD-like system. More information, and the fix, can be found at http://bugs.python.org/issue7512.
Depending on how you installed it Mercurial usually comes with vimdiff pre-configured for merging. On my machine that's in /etc/mercurial/hgrc.d/mergetools.rc but I imagine it's different in your OSX box.
You might want to check to see if it doesn't already use vimdiff for merging if you remove all of that from your .hgrc.
You can use the command hg showconfig --debug to see all the per-user, per-repo, and system-wide configuration items that are in effect. If you see vimdiff in there after the lines you've added are removed then you might be good to go.

Resources