Mercurial: info on modified files - version-control

Before pulling from the central repositiry, I usually use the 'hg incoming' command to see what I will be pulling. However, this only gives me a list of changesets with some comments, and not a list of the actual files that have been modified.
1) In such a situation, how can I get a list of modified files (including some basic info about the chane, like Removed, Moved, etc)?
2) Similarly, when I do an 'hg status', I get the differences between my local working copy and what is currently on the repository. However, a more useful feature would be to get the differences between what is incoming and my local working copy. How can I get this?
Thanks!

1/ Most options are presented in "how to see files in repository before running 'update'":
hg incoming --stat
Notes:
For remote repository, using --bundle avoids downloading the changesets twice if the incoming is followed by a pull.
--stat: output diffstat-style summary of changes.
(ie: Statistics of changes with the following format: "modified files: +added/-removed lines")
2/ See RDiff extension (and the SO question "Using Mercurial, is there an easy way to diff my working copy with the tip file in the default remote repository")

If you don't have a recent enough version for --stat, you can get a similar overview using status:
cd repo
// grab the newest changes into a bundle
hg incoming --bundle morechanges.bun
// get an id for the current tip
hg tip
changeset: x:abcdef
...
// see what's changed by overlaying the bundle on the repo
hg -R morechanges.bun status --rev abcdef:tip
//info you're looking for
// everything's good; add the bundle to the repo
hg pull morechanges.bun
rm morechanges.bun

Related

Git: How to include working tree status in git log --pretty=format...?

I'm using the following command in an Eclipse CDT pre-build step, to generate a header file containing my current short Git hash as a string macro:
git log --pretty=format:'#define GIT_HASH_STRING "%h"' -n 1 > ../Inc/gitcommit.h
Works great, but it doesn't indicate the status of the working tree. Like when running git submodule status, if there are working tree changes, I'd like it to spit out something like
a289542-dirty
Is this possible? I checked the man page for git-log formats, but didn't see anything that looked pertinent.
Context: The GIT_HASH_STRING macro is displayed when issuing a version command via the CLI of an embedded device. If I can include a -dirty flag in the string, it can serve as a warning that the device is running an unreleased version of firmware that doesn't align with a specific commit.
The git log command does not inspect the work-tree, so it cannot do this.
There are many commands that do inspect the work-tree. One simple one is git describe:
git describe --always --dirty
will print out a string that will end with -dirty if the work-tree or the index is modified with respect to the current commit (i.e., in the same situations where git status would say something is staged for commit or not staged for commit).
If you want to check submodules as well, you will need more.

Mercurial: "no match found" when performing merge, "no node!" if I try to strip

I have a mercurial dropbox hosted in a Dropbox folder on which I push from another repo that I keep in my office PC. In this way I can work on my project from the office and perform hotfixes from home.
Something bad happened while synchronizing, therefore a file wasn't correctly put in sync somewhere. I have a revision (n. 678) which I can't merge with actual head.
If I try to merge I get this message
abort:
data/hotelsclick/src/main/res/values/string-array.xml.i#5f2b6faa86a1:
no match found!
if I try to delete that useless revision with hg strip 678 I get
abort:
data/hotelsclick/src/main/res/values/string-array.xml.i#5f2b6faa86a1:
no node!
and if I perform a hg verify this is the result
checking files [...]/src/main/res/values/string-array.xml#678: 5f2b6faa86a1 in manifests not found
libs/date-interval-picker/.git/index#678: a83e1b77d446 in manifests
not found 8009 files, 681 changesets, 14161 total revisions 2
integrity errors encountered! (first damaged changeset appears to be
678)
what if I try to push?
searching for changes
abort: push creates new remote head 16c4912af9a5!
(merge or see "hg help push" for details about pushing new heads)
So I cannot merge, cannot delete that revision, cannot push. I'm pretty stuck and I don't know why. Can anybody please help? I don't care about the content of revision 678, if I could I'd delete it happily.
First of all, I strongly recommend against using a file synchronization service (whether Dropbox or Google Drive or something else) for use with version control systems. These services do not respect the atomicity of repository operations; even version control systems with single file repositories (such as Fossil) are not 100% safe and even if only a single user is using the service.
Second, you have a partially corrupted repository that you need to repair. In the ideal case, you have a clean backup somewhere, even if it's not perfectly up-to-date and can replay the missing revisions selectively (e.g. with hg export and hg import).
Barring that, the next step would be to see if you can do a partial clone. For example, you can try:
hg clone -r 680 /path/to/repo /path/to/clean_repo
This should normally skip revision 678, if only that data is defective. However, the way that delta compression works, revisions that occur in order after 678 may also have been corrupted. In this case, I would try it with -r 677 instead of -r 680 and see if hg export works for copying revisions 679 and 680.
If that does not work and the corruption goes deeper, I would then try the convert extension:
hg --config extensions.convert= convert --config convert.hg.ignoreerrors=True /path/to/repo /path/to/clean_repo
Note that such a conversion will likely change the hash values of individual repository entries and means that you will have to update the repository contents everywhere.

Is it possible to upload previous changes when using a VCS?

I'm using git as a VCS and I got several commits in a project. I'd like to upload every change made after a specific commit that is not the latest. Currently, if I want to do this, I have to upload practically every file in my project, or manually search for the modified files after a certain date. Both options are kinda tedious.
Is there an option that helps finding the modified files from a certain commit? Or possibly a combination of searching and selecting the files modified in a given range?
Use git log -n 1 --name-only <revision> to get files modified within a specific revision, or git diff --name-only <revision_1> <revision_2> for files that were changed between two particular revisions.

Mercurial workflow for updating with uncommitted changes?

So i've made the switch from CVS to mercurial for my website.
The biggest issue I am having is that if i'm working on some files that I don't want to commit, I just save them.. I then have other files I want to push to the server, however if someone else has made changes to the repository, and I pull them down.. It asks me to merge or rebase.. either of these options will cause me to lose my local changes that I have not committed.
I've read that I should clone the repository for each project on my local host and merge it into the live when it's ready to do so. This not only seems tedious, but also takes a long time as it's a large repository.
Are there better solutions to this?
I would have hoped that Mercurial would see that I haven't committed my changes (even though I have changed the file from what's on the server) so it'd just overlook the file.
Any input on this would be greatly appreciated. Thank you!
Also, i'm using the hg eclipse plugin to work on my files and push/pull from the server.
hg shelve is your friend here I think.
which comes from the shelve extention (maybe - see below)
from the overview:
The shelve extension provides the
shelve command to lets you choose
which parts of the changes in a
working directory you'd like to set
aside temporarily, at the granularity
of patch hunks. You can later restore
the shelved patch hunks using the
unshelve command.
The shelve extension has been adapted
from Mercurial's RecordExtension.
or maybe its the attic extension
This module deals with a set of
patches in the folder .hg/attic. At
any time you can shelve your current
working copy changes there or unshelve
a patch from the folder.
it seems to have the same syntax as the shelve extension, so I'm not certain which one I've used
I second #Sam's answer. However, if you prefer to use standard Mercurial, a simple workflow is to
save your working dir changes in a temporary file,
sync your working dir with a specific revision, then
push, pull, merge .. whatever you want to do and which requires a clean working copy, and
get back your changes from the temporary file into the working dir.
For instance:
$ hg diff > snapshot.patch # save your uncommited changes
$ hg up -C # get a clean working copy
$ hg pull # do things ..
$ hg merge # .. you need a clean ..
$ hg commit -m "merge" # .. working copy for
$ hg import snapshot.patch # get back your uncommited work
First, are you working from the commandline, or using something like Tortoise?
If you're working from the commandline, and you've done a pull, mercurial will not ask you to do anything, as it merely updates your local repository.
If you then do an hg update and have local changes, it should do what you're used to from CVS. It will update to the tip of the current branch, and attempt to merge your outstanding changes in. There are some caveats to that, so refer to the official docs at http://www.selenic.com/mercurial/hg.1.html#update.
Also, for temporarily storing changes, I would recommend MQ over shelve. Shelve only provides one storage area, whereas MQ provides as many as you need. MQ takes some getting used to, but worth the investment.

Mercurial: Getting changed files from revision?

I can't get my head around how I can get only the files that were changed in my last revision, and not the complete repo, which i get by using Clone. This would be super helpful to for instance, deploy the last changed files.
What do I do?
Thanks
You cannot transfer just some files -- you must always have a full clone locally. So I suggest you make that once and then pull in changes incrementally.
You should then use hg status to show the names of files changes been revisions. You normally use hg status to see which files are changes compared to the working copy parent revision, but you can pass --rev to status to see changes between any two revisions!
So use
$ hg status --change tip
to see which files were changed in the tip changeset. Use
$ hg pull
$ hg status --rev .:tip
to see what files will be changed when you do a hg update after a pull. The update will take you from the current working directory parent, denoted by ., to the tip, assuming you are on the same named branch as tip. Otherwise hg update will take you to the tip-most changeset on your current branch.
You can use a template to hg log or hg tip to get all filenames:
hg tip --template '{files}'
or to get e.g. all files changed/added/modified by changeset 5:
hg log -r5 --template '{files}'
You can read more about templates Mercurial: The Definitive Guide, Chapter 11. Customizing the output of Mercurial or short help with hg help templating`
If you want to do something to the files e.g grep through them:
hg tip --template '{files}' | xargs grep foo
Careful this will break with filenames containing spaces!
To process all kinds of filenames something more complicated is needed (thanks to mg on #mercurial for the tip):
We need multiline styles for this suppose a file named zerosep contains:
changeset = "{files}"
file = "{file}\0"
Then you can use this to produce a \0 separated list of filenames and process it with xargs -0:
hg tip --style zerosep | xargs -0 grep foo
Information how this works can be found in: Listing files on multiple lines
Martin has the right way to get a list of what files have changed in a revision, and I've upvoted his answer, but just to expand on why your question is a little off:
In Mercurial every location has a full copy with all changes. If you're going to use Mercurial to deploy to your server then you have to clone everything to your server -- once. After that push/pull will move over only the (compressed) changesets that the server doesn't already have.
If you don't want to have everything that ever was on the server, then you need to use something other than mercurial for your deployment, perhaps something fed from the status commands Martin showed or a snapshot created from hg archive.
Personally, I'm okay with having full history on my servers, and just do a hg pull ; hg update on the server for each new deployment. It's tidy and efficient.