What other repository systems have cvs's -D (date) option? - version-control

I recently stumbled upon a cool feature in CVS where you can name revisions by date, e.g.:
# List changes made between the latest revision 24 hours ago and now
cvs diff -D "1 day ago"
Do any other repository systems (e.g. Git, SVN, Bazaar, Mercurial, etc.) have an option like this?

Subversion has a similar feature. For example:
svn diff -r {2010-07-31}
The syntax is explained in http://svnbook.red-bean.com/en/1.5/svn.tour.revs.specifiers.html#svn.tour.revs.dates

Mercurial has a wide range of date formats: http://www.selenic.com/mercurial/hg.1.html#date-formats, though maybe not "1 day ago".
This subversion bug report indicates that Subversion can't do it natively, but does offer a tip on using date to do it:
(2) Whilst Subversion doesn't understand -r "{3 days ago}", date can
help out there too: -r "{date -Is -d '3 days ago'}".

(answering my own question)
git log supports dates for filtering before or after given times. Example:
git log --after='july 17 2010' --before='july 31 2010'
Here's a shell script that makes it a little easier to list ranges of commits, but it also uses a terser format than git log's default:
#!/bin/sh
# git-changes
FORMAT='%cd%x09%h%n%x09%s%n'
CMD="git log --format=format:$FORMAT"
case $# in
0 )
$CMD ;;
1 )
$CMD "--after=`date -d "$1"`" ;;
2 )
$CMD "--after=`date -d "$1"`" --before="`date -d "$2"`";;
esac
Note: I wrapped the date arguments with the date command, since git treats 'July 17' as a few hours off from 'July 17 2010' for some reason.
Usage:
git-changes # Same as git log, but more terse
git-changes 'yesterday' # List all commits from 24 hours ago to now
git-changes 'jul 17' 'aug 1' # List all commits after July 17 at midnight
# and before August 1 at midnight.
Sample output of git-changes 'jul 17' 'aug 1':
Sat Jul 31 23:43:47 2010 -0400 86a6727
* Moved libcurl into project directory as static lib.
Sat Jul 31 20:04:24 2010 -0400 3a4eb10
* Added configuration file support.
Sat Jul 31 17:44:53 2010 -0400 aa2046b
* Fixed truncation bug in bit parser.
Sat Jul 17 00:10:57 2010 -0400 99e8124
* Added support for more bits.
Now, to see all changes introduced by commit 99e8124, type git show 99e8124. To see all changes since revision 99e8124 (not including that commit itself), type git diff 99e8124.

Related

Perl created files with future timestamps on FreeBSD 9.3

I just encountered some strange behavior with Perl 5.16.3 on FreeBSD 9.3-RELEASE-p3. We've got a cron job which runs every five minutes and generates some text status files. I just happened to list the contents of the output directory and saw that the timestamps for some of the files were in the future! The files are created like this:
if (open(OUT, "> $status_file_path")) {
print OUT "$status_info\n";
close OUT;
}
Now, the file handle OUT is used in several places, however it is opened and closed within the same block as shown above. And like I said, out of ten files, only a few had future dates when displayed using ls.
For example, files with the current date had timestamps like 04/02/2015 20:29:46, files with future timestamps were out in November, e.g. 11/10/2015 09:38:41.
What might be going on here?
EDIT
I've got two tests running:
1) a perl script running a loop of 1000 iterations, sleeping a random time up to 10 seconds between iterations, using the open/print/close logic to create an output file and abort the script if the file's modification time is in the future.
2) a cron entry to touch a test file every minute, e.g. touch /home/test/test_file_date_with_cron.txt
TEST RESULTS
Neither of the tests generated output files with a timestamp in the future.
This is scary.
EDIT 2
Here is the filesystem info, the files are written in the /usr directory.
# df -h
Filesystem Size Used Avail Capacity Mounted on
/dev/gpt/gprootfs 2G 133M 1.7G 7% /
devfs 1.0k 1.0k 0B 100% /dev
/dev/gpt/gpusrfs 431G 3.8G 392G 1% /usr
procfs 4.0k 4.0k 0B 100% /proc
EDIT 3
Running the script outside of cron for several hundred iterations didn't duplicate the problem. HOWEVER, I just found some other files, which are created by a CGI script which have the future dates:
-rw-r--r-- 1 test test 5783 Nov 10 2015 Config.xml_20150210_104151
-rw-r--r-- 1 test test 34548 Nov 10 2015 Config2.xml_20150210_104151
-rw-r--r-- 1 test test 6105 Nov 10 2015 Config.xml_20151109_232210
-rw-r--r-- 1 test test 34554 Nov 10 2015 Config2.xml_20151109_232210
-rw-rw-r-- 1 root test 2075 Nov 9 2015 Config.xml_20151109_231055
-rw-rw-r-- 1 root test 1232 Nov 9 2015 Config2.xml_20151109_231055
These are archive files, which get moved and renamed with the file's mtime timestamp. Note that BOTH ls and Perl's stat() function report the future date -- stat() is used to generate the file's timestamp portion of the name.
Looking at the first entry, ls reports "Nov 10 2015", whereas when the CGI script processed it, Perl's stat() reported "20150210_104151", i.e. "Feb 02 2015" which is most likely correct.
Further down, we see ls showing "Nov 10 2015" and stat() reported "20151109_232210", i.e. "Nov 09 2015".
Finding those additional archived config files helped me track down the cause, which was as others have suggested, that the system date and timezone changed.
From: 1447147328 and America/Adak
To: 1426637771 and America/New_York
What was throwing me off, was that I thought the cron script wrote ALL of the output files each time it executes, but that's not the case. The files have different "refresh intervals".

Recovering history in hg when move not done properly

So somebody on our team moved an entire folder into a subdirectory without using hg's rename feature. The directory structure is like we need it, but the history is now gone prior to the move. It shows it as a new file when the move occurred. Numerous large merges have happened since then, and so it is not really practical to go back in time and do it right.
I have tried hg log --follow and it does not help, since hg does not know about the rename. Is there any way to manually link the files to the old removed versions after the fact, or is there some facility like the way git can infer moves and renames based on hueristics? It would be nice if there was some way to explicitly say, "this file is a continuation of this old deleted file.", even though that would still take some time to fix it all up right.
We have all but given up on ever getting that history back, but it would be really nice to have it.
You need to redo the move correctly by explicitly telling Mercurial what files were moved, then merge the broken changesets. This way you will restore the history path to the original files.
Steps, assuming <x> is the move revision, and <y> is the current head revision.
Update to the revision before the move: hg update <x-1>
Redo the move, but now correctly using hg rename or hg rename --after
Commit
Merge with the original move revision (hg merge <x>), this should have no conflicts but if there are discard all changes.
Commit
Merge with the remaining changesets after the move (if any) (hg merge <y>)
Commit
Here is the basic process shown on the command line:
$ mkdir move-merge-test
$ cd move-merge-test
$ hg init
$ echo "x" > a
$ hg add a
$ hg commit -m "initial revision"
Move incorrectly:
$ mv a b
$ hg remove a
$ hg add b
$ hg status --copies
A b
R a
$ hg commit -m "incorrect move"
$ hg log --follow b
changeset: 1:b22f3e94133b
tag: tip
user: Laurens Holst <...>
date: Wed Oct 19 14:41:37 2011 +0200
summary: incorrect move
Correct the move:
$ hg update 0
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg rename a b
$ hg status --copies
A b
a
R a
$ hg commit -m "correct move"
created new head
$ hg log --follow b
changeset: 2:5deabbcb5480
tag: tip
parent: 0:b82f89f0c7d9
user: Laurens Holst <...>
date: Wed Oct 19 14:46:35 2011 +0200
summary: correct move
changeset: 0:b82f89f0c7d9
user: Laurens Holst <...>
date: Wed Oct 19 14:36:35 2011 +0200
summary: initial revision
Merge it with the broken move:
$ hg merge 1
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg commit -m "merge with broken move"
$ hg log --follow b
changeset: 3:ce65fc7b35e4
tag: tip
parent: 2:5deabbcb5480
parent: 1:b22f3e94133b
user: Laurens Holst <...>
date: Wed Oct 19 14:47:13 2011 +0200
summary: merge broken branch
changeset: 2:5deabbcb5480
parent: 0:b82f89f0c7d9
user: Laurens Holst <...>
date: Wed Oct 19 14:46:35 2011 +0200
summary: correct move
changeset: 1:b22f3e94133b
user: Laurens Holst <...>
date: Wed Oct 19 14:41:37 2011 +0200
summary: incorrect move
changeset: 0:b82f89f0c7d9
user: Laurens Holst <...>
date: Wed Oct 19 14:36:35 2011 +0200
summary: initial revision
As you can see, the history now correctly shows all affected changesets. If the files are moved in several commits, the basic principle stays the same just merge across more than just 1 commit. If you have any commits made after the move, I recommend to merge them in separately (step 6 in the steps above) in order to avoid spurious conflicts.
I had good luck with this kind of thing by deleting the new (the "moved") file, then going back to a revision when the file was still in place, doing the move properly (including commit) and merging the two heads.
There's a --after option to hg rename which lets you tell Mercurial about a rename after the fact, but it has to be done before you commit the rename.
You could try doing hg convert on the repository and specify the --filemap parameter, which will let you rename a files and directories.
https://www.mercurial-scm.org/wiki/ConvertExtension#A--filemap

How can I see what files changed for each commit in bazaar?

In git, I can use git log --stat to see which files changed in a commit. How can I do that in bzr?
$ git log --stat
commit dbdc98ccc1ce12a31a0bf29173b4990ccbff98
Author: Me <Me#Me.com>
Date: Thu Jan 29 19:03:10 2011 -0800
Add snipMate v0.83
vim/after/plugin/snipMate.vim | 35 ++
vim/autoload/snipMate.vim | 433 ++++++++++++++++++++++++++
vim/doc/snipMate.txt | 286 +++++++++++++++++
bzr viz doesn't show changed files either.
bzr log --verbose will list the files under a modified: header.
Also, bzr help and bzr help <command> are helpful.

Mercurial: diff file

I'm actually trying something simple, but I get strange results:
I want to compare the current version of a file with a specific revision.
In NetBeans 6.9.1 I didn't find any such function. I can only call the history and then diff between successive revisions. Am I missing something?
I tried with the command line tool (Linux):
hg diff --rev 527 pom.xml
But I get:
diff -r 1018d7890ea1 pom.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pom.xml Sun Jan 30 22:45:28 2011 +0000
## -0,0 +1,167 ##
+
followed only by "+" lines.
How can I get the diff I want? How can I get this diff with NetBeans (or otherwise with another graphical diff tool)?
You usage of the command-line tool looks correct. However the output
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
Indicates that the file you want to diff did not yet exist in the revision you chose.
Addendum:
In the comments you mention the file was renamed and you need to use -g
You can enable -g for all diffs by adding:
[diff]
git=1
to your .hgrc file (usually located in your home directory)
hg diff -r revision1:revision2 file
Where revision1 and revision2 can be a tag, changeset etc.
By default, your revision2 should be "tip" (without quotes) if you want to compare a revision to the current one.

Can't apply unified diff patch on Solaris

For example, if I have two files:
file1:
This is file 1
and file2:
This is file 2
and create patch with the following command:
diff -u file1 file2 > files.patch
result is:
--- file1 Fri Aug 13 17:53:28 2010
+++ file2 Fri Aug 13 17:53:38 2010
## -1,1 +1,1 ##
-This is file 1
+This is file 2
Then if I try to apply this patch on Solaris with patch command:
patch -u -i files.patch
it hangs on:
Looks like a unified context diff.
File to patch:
1. Is there a way to use Solaris native patch command with unified diffs?
2. Which diff format is considered most portable if it's not possible to apply unified format?
Update:
I've found answer on the first part of my question. Seems that patch on Solaris hangs if the second file (file2 in this case) exists in the same folder as the first one (file1). For example, the following quite common diff:
--- a/src/file.src Sat Aug 14 23:07:29 2010
+++ b/src/file.src Sat Aug 14 23:07:37 2010
## -1,2 +1,1 ##
-1
-
+2
will not work with quite common patch command:
patch -p1 -u -d a < file.patch
while the following diff (note second file is renamed):
--- a/src/file.src Sat Aug 14 23:07:29 2010
+++ b/src/file_new.src Sat Aug 14 23:07:37 2010
## -1,2 +1,1 ##
-1
-
+2
will work perfectly.
For the second part of my question see accepted answer below.
On Solaris /usr/bin/patch is an old version required to comply with some ancient standards.
A modern version of GNU patch is provided as /usr/bin/gpatch on Solaris 8 and later.
diff -cr old.new new.txt > patch.txt
gpatch -p0 < patch.txt
Works perfectly for me (using gpatch)
Single Unix v2 and v3 both support context diffs but not unified diffs, so for better portability you should use context diffs (-c option to diff and patch).
On older Solaris releases (pre-10, I think), you need to make sure that /usr/xpg4/bin is before /usr/bin in your $PATH, otherwise you may get compatibility versions of some utilities instead of standard ones.