We are using Mercurial and TortoiseHg at work and I always see + sign after my working directory revision number and Google doesn't tell me anything about it. Is there any one who can explain this?
Here is a snapshot of what I am talking about:
Google tells me it means you have uncommitted local changes in your repository.
See also Java: how to get mercurial current changeset number for use in program, https://stackoverflow.com/a/9301105/1848654, and http://stackingcode.com/blog/2011/01/21/assembly-versioning-with-hg.
Related
I received some code as a tar archive (without the .hg directory). I know which repository this code is based on, but not which revision was used as a base for these modifications. Is there some way to find this out by just looking at the files? This is similar to Given a file, how to find out which revision in a mercurial repository this is? but I cannot reach the author of the code, so I cannot control how the files are extracted from the repository. I am also dealing with modified files here so the diff to the base revision would not be empty.
My fall-back plan would be to loop through all revisions and using the one with the smallest diff, but I'm still hoping there is a better solution.
There's no automated way to do it, but you could possibly reduce the time by using a hg bisect --command diff ... command to zero in on it.
As a tip if you (I know it probably wasn't) you ever has to give someone a snapshot again, use hg archive to make it. It includes a .hg_archive.txt file with version info that'll help if you have to do this again.
This is NOT another what are bookmarks/what are branches question - I have read all of these posts and now want to clarify some things about correct usage.
I am developing a website. I want a stable version, and a development version.
So I create two bookmarks 'stable', and 'development'.
If i want to create a new feature I update to the development bookmark, and create my feature.
If i want to correct a typo I do it directly in the stable version.
My confusion is as follows.
I have a central repository at bitbucket.
If i use hg push my bookmark data is not passed. If i do hg push -B stable or hg push -B development respectively then my bookmark data is pushed.
I then have two servers, a testing server and a live server.
If I ssh onto the server and do a hg pull from bitbucket because the bookmarks are not present on the server, what is pulled, and what then is the working copy updated to when I use hg update?
The correct usage for what I want, I believe is as follows. A local repository with my two bookmarks 'stable' and 'development'. I switch between the two as required and push them to bitbucket with hg push -B bookmark-name. Then I login to my testing/live server respectively and pull the correct bookmarked version.
Once I have tested my development bookmark I can merge it with my stable one and pull it onto the live server.
My concern and as such my question is what happens If i accidentally forget to specify the bookmark when pulling to the live server for example?
Thanks
Pulling
From Mercurial 2.3, pulling gets the remote repository's bookmarks as well. Before, you had to specify -B <bookmark> to get bookmarks as well as changesets. So your server repositories will have the right bookmarks after pulling.
If you're using an earlier version, you'll have to pull -B <bookmark> to get the bookmark as well. Of course, you can do that anyway, if you'd prefer not to pull all development changesets onto your live server.
Updating
Using hg update with no arguments will get you tip, which is always the last changeset added to the repository, whether that's stable, development or accidentally un-bookmarked (actually, it'll get you the last changeset added to the current branch, but it sounds like you're not using named branches). To get consistent results when updating, I'd recommend you be explicit about which bookmark you want each server repository to update to. If you're worried about forgetting to specify, use scripts to automate your update process.
The correct usage IMHO is to use named branch instead of bookmark.
I treat bookmarks as local tags and no more. So if I'm wanting to push tagging information then I use actual tags to mark stable releases. Every time I do a release I mark it such as "rel-2.4" for example.
Then on live I can update to the latest revision and know that that is the last good release. My "dev" is simply the head of the default branch and I keep adding new bits of development into it. This way you can just do a push and not worry about the bookmarks.
This might not be what you want or you envisage but it is a workable solution for the situation you describe.
Should we have a fix that we need to do (a typo in your example) I can update to the last release, correct the type, test and if happy tag it as the next release (rel-2.41). Merge that new branch back into default so my dev branch has the fix too. Jump on the live server and pull/update to rel-2.41
Is that any good to you?
Despite the decentralized nature of Mercurial, we have a centralized server that we all push to and that does nightly builds, packaging, etc...
Here's what we want to achieve: One of the files that is source controlled contains the major+minor version numbers which ideally would have to be increased with every commit. Since centralized numbering is not possible on developer's machines, we were thinking of a precommit script on the main server that would write a new minor version number to that file for each commit that is pushed. The question is/are:
since it's precommit, can this file change be part of the same commit?
if not, can precommit cause another commit and how do you prevent it from cascading/recursing?
how would one do that?
is there a better solution?
A "precommit" script is triggered only at commit time. By the time users are pushing to the "central" server they have already committed, and it's too late for a precommit hook to do anything at all. You can have changegroup and incoming hooks that are triggered to run on the "central" server when the developers push, but those can't modify the commits -- the commits are already committed/baked/done at that point, they can only react to them.
As a suggestion don't actually put the version string in the file -- having a file that changes with every commit just makes merging a pain. Instead do one or more of these:
have a CI server (like Jenkins) do builds on every push and use the Jenkins build number, which can be passed into your build script
use the Mercurial nodeid (hash) as part of your version string so you can always knew exactly what revision is in a build -- and don't put it in a file, just query for it in your build (or deploy) script
use a changegroup hook to automatically tag-on-push, which applies a pretty (possibly sequential) name to the commits (note, this pretty much doubles your number of commits since every tag is a commit)
Personally, I use something like this in my build script:
build.sh --version_string=$(hg log -r . --template '{latesttag}.{latesttagdistance}-{node|short}')
That gets me version strings that look like "1.0.3-5fd8ed67272e" which can be roughly read as "built from the changeset three commits since version 1.0 was tagged with nodeid 5fd8ed67272e", which is pretty darn good -- and it's never saved into a file it's either baked into the compile (for compiled languages) or written into a VERSION file when my deploy script uploads it to the server.
See this page in the Mercurial documentation for some comments and ideas about this issue. See also How to expand some version keywords in Mercurial? and the other SO answers referenced there.
I commited (not pushed) a lot of files locally (including binary files removing & adding...) and now when I try to push it takes a lot of time. Actually I messed up my local repo history.
How could I avoid this mistake in the future ? Can I transform a set of local revision 1->2->3->4 to 1->2 with 2 being the final revision of the local clone ?
edit: since I was in hurry I started a new remote repo from scratch with revision 4. In the future I will go with the marked answer as it seems easier but I will dig other solutions to see the truth. Thx for your support.
It's not clear from your question whether those changes got pushed. If they're still local, you can more or less get rid of them easily. convert is one option. You can also use MQ (mercurial queues). Check the EditingHistory wiki article for a detailed explanation. It recommends MQ being the simplest approach.
To prevent that kind of mistakes, you should probably add a hook to reject 'bad' commits, given that you can describe them programatically ;)
Mercurial history is immutable, you can't delete using the normal tools. You can, however, create a new repo without those files:
$ hg clone -r 1 repo-with-too-much new-repo
that takes only revisions zero and one from the old repo and puts them into a new repo. Now copy the files from revision four into the new repo and commit.
This gets rid of those interstitial changesets, but any repo you have out there in the wild still has them, so when you pull you'll get them back.
In general once you've pushed a changeset it's out there and unless you can get everyone with a clone to delete it and reclone you're out of luck.
Is it possible to update a directory to a specific revision without cloning the whole repository (local or on a central server) in Mercurial and how can I use it? This would be great, because to clone the whole repo first takes to much time for me and the folder really don't needs the whole repo. As example: default and the b2.3 branch from which I want to update.
Thanks in advance! :)
You can pull a specific branch, say b2.3 by using hg clone -r b2.3 source-repo target-repo.
If you really need just a non-versioned copy of all the files in revision N, then for some web repositories you may download such a copy using their web interface.
clone is the preferred way to do it in Mercurial. It should take a minimal amount of time when done locally. I'm unaware of any other way to do it.
Search for "hard links" on this tutorial page for more info on the subject.