Recently I started working on a "portable" version of a project by copying all the files to a new directory. The portable directory differs from the stable directory only in terms of what has been deleted or commented out; nothing has been added.
I finally decided it's time to learn source control. Everyone says simply starting is more important than anything else, and I ultimately chose Mercurial since it's good for branching and (more importantly) I liked the tutorials I found online (e.g., http://hginit.com and http://hgbook.red-bean.com/).
I made a repository for my stable directory, and a clone in a central repository (Dropbox). I'm committing, pushing, etc. Now, however, I'd like to link my (already existing) portable directory with the central repository. I'd like to be able to, say, fix a bug in my stable code, push it to the central repo, and then pull the bug fix into the portable version--without changing anything else in the portable code.
I'm unsure what to do first with the portable code. If I clone the central repo to the portable directory, won't all my portable code be overwritten the first time I update the portable directory?
You will need to clone the "central" repository to your portable directory before you will be able to do any work like you describe. However, an easy fix is to copy you portable directory somewhere else and create a new, empty folder. Then, clone your repository into that directory. After that, you should be able to just copy and paste your previous portable directory into the cloned version and allow it to overwrite the files there. That will allow you to commit those changes into version control and be in sync with the central repository.
If this method won't work, you will still have to clone the central repository and then make all of your "pending" changes to the existing portable location by hand to your new cloned version.
It sounds like the portable version should be a branch in your stable repo. Since you've already got an existing version that isn't in the repository I think the easiset way to do this is with the addremove command.
What I would do is first make sure any recent changes to your stable branch and make sure you've got a backup copy of your repo somewhere in case anything goes wrong. Then I would delete everything from your stable repository directory except for the .hg directory and any other repository management files such as .hgignore, .hgsub, .hgeol, etc. Then I would copy the portable version into that directory and run hg addremove. The addremove command will automatically add all new files and remove all missing files (which should be just removes in this case). Now I would mark this as a separate branch with hg branch <branch_name> where <branch_name> is whatever you want to name your portable branch. Then just hg commit as usual.
Now you've got your stable branch (called 'default' unless you've renamed it) and your new portable branch. Now when you make changes to the stable branch you can hg update to your portable branch and run hg merge default (or replace default with your stable branch's name) to merge those changes into the portable branch.
Related
We use Mercurial and have set up a repo server to which all local/developer changes are pushed to/pulled from. I came back from vacation to find that one of our repos has been replaced. Apparently a developer was having issues pushing commits to it and figured the only solution was to blow away the repo on our server and push a new one from his machine under a new name. Not sure how, but in doing this we lost all the change history of the project before it was blown away.
I still have the full repo history on my local machine up to that point and would like to merge the new repo with the old repo and have the full change history retained. I'm hesitant to do a pull/update to my machine in case I lose the history.
I also want to update the name of the repo directory on the server because now some of our tools have broken paths to the repo and would prefer reverting back to the original directory name insted of updating all our tools' references.
I think I can use the hg rename to do what I want regarding the rename, but how do I merge the two repos into one?
I found a way to merge by following (somewhat) the instructions here: https://www.mercurial-scm.org/wiki/MergingUnrelatedRepositories
First I made a copy of my local repo in case things went sideways
I cloned the repo on the server to the name I wanted it to be and which matched my local repo
I did a pull on the server repo to my local one and instead of doing an update, did a merge
Resolved merge diffs and committed locally
Pushed changes to new server repo, confirmed full change history was in place
Removed old server repo
We have a project that lives in a mercurial repository.
Our customer would like to take ownership of the code base by doing the following:
Set up a mercurial repository on a server belonging to the customer.
Import the existing code into the new mercurial repository.
What is the best way to achieve step 2?
Is it a simple matter of doing the following:
Clone the existing mercurial repository:
hg clone <existing mercurial repo URL>
Push the cloned repository into the new one:
hg push <new mercurial repo URL>
Am I missing any steps? What about the hgrc file? Does it have to be modified in any way prior to pushing the project into a new repository?
Yes, you can do what you state, however it is worth noting that if you do a simple hg clone of your main repository, then a link will exist between the two, which may not be what you want. You can remove this link by editing the .hg/hgrc file and removing the default = ... item in the [paths] section.
I find that a better way is to do it without cloning. This way you don't have the link between repositories, which as this is going to a customer may be what you want.
The basic method is to set up a new repository with no changesets, and then bring in all of the changesets in one of three ways:
Push the changes from your repository to the new repository.
Pull the changes from into the new repository from the old.
If you don't have access to the new repository, create a bundle that can be provided to the customer - this can then be unbundled or pulled into the empty repo.
Pushing and Pulling is done as you normally would, but specifying the repository location:
// create the empty repository
hg init .
// pull in everything from the old repo
hg pull /projects/myOriginalRepo
or to push...
// create the empty repository
hg init /projects/myNewRepo
cd /projects/myOriginalRepo
hg push /projects/myNewRepo
Creating a bundle is perhaps a nicer way, as you can write the bundle onto a DVD and give it to your customer wrapped in a bow with a nice greeting card:
cd /projects/myOriginalRepo
hg bundle --all ../repo.bundle
Everything gets written out to a single file, which can then be extracted with hg unbundle repo.bundle or hg pull repo.bundle, into a repository with no existing changesets.
Regarding the hgrc file, as already mentioned in another answer it is not a controlled file, and so won't be copied. However, any contents are likely things like hooks to perform auto-building, or validating changesets before they are applied. This is logic which would probably only make sense to your own organisation, and I would suggest you wouldn't want this to be imposed on your customer - they are, after all, taking ownership of your code-base, and may have their own systems in place for things like this.
In the simple case - it's all.
But if you have modified .hg/hgrc file then you need to move it to the remote server manually and (if necessary) modify it correspondingly to a new environment.
Ie: you could have hooks set up in the original repository.
As of clients - just change a path to a repository in a default section (or any other section if you have several specified)
To move the master repository, you need to (a) create the new master repo and (b) tell the existing clients about it.
Create the new master repo any way you want: cloning or init+pushing, it makes little difference. Be sure to move any contents of the old repo that are not under version control, including .hgrc and any unversioned or ignored files that are not discardable. If you cloned, edit the new master's .hgrc and remove the default path, so that it doesn't try to talk to the old master repo any more.
Existing clones of the old master repo still push/pull from the old master. Everyone must edit their .hgrc, updating default (and/or default-push) so that it points to the new location. (They may also need to update authentication credentials, of course).
Only then is the migration complete. Remove (or move/hide) the original repo so that if someone forgot to update their repo path, they'll get an error on push/pull instead of pouring data down a memory hole.
I have a mercurial repository my_project, hosted at bitbucket. Today I made a number of changes and commited them to my local repository, but didn't push them out yet.
I then majorly stuffed up and fatfingered rm -rf my_project (!!!!!).
Is there some way I can retrieve the changes that I committed today, given that I hadn't pushed them out yet? I know a day's worth of commits doesn't sound like much, but it was!
All the other clones I have of this project are only up-to-date to the most recent push (which didn't include today's changes).
cheers.
mercurial cannot save you. The data from mercurial is stored in a hidden directory in the base of your project folder. In your case, probably at my_project/.hg. Your recursive delete would have trashed this folder as well.
So maybe a file recovery tool?
No. The changes are only stored in the local repository directory (the .hg directory therein) until you've pushed. They're never put anywhere else (not even /tmp).
There is a possibility that you'll be able to recover the deleted files from the disk, though; search around for instructions and tools for doing that.
I'm afraid the commit is deleted together with the working copy and file recovery tools are your only option to recover the missing .hg folder. I see you could recover the code from the install — great!
If you're afraid of this happening again, then you could install a crude hook like
[hooks]
post-commit = R=~/backup-repos/$(basename "$PWD");
(hg init "$R"; hg push -f "$R") > /dev/null 2>&1 || true
That will forcibly push a copy of all your commits to a suitable repo under ~/backup-repos. The -f flag ensures that you will push a backup even if you play with extensions like rebase or mq that modify history. It will also allow pushing changesets from unrelated repos into the same backup repo — imagine two different repos named foo. So the backup repositories will end up with a gigantic pile of changesets after a while and you might want to delete them once in a while.
I tested this briefly and for everyday work I don't think you'll notice the overhead of the extra copy and you might thank yourself later :-)
I am new to Mercurial HG. My friends created a repo and I am going to use it.
I installed TortoiseHG and trying to get the latest code. I found that when using Clone operation, it will pull all code to my local, including the histories (Am I right?). This is not needed for me. I just wanna get the latest code. Is there an operation for this?
In short, no.
In a bit longer: Mercurial doesn't yet support “shallow” clones where you only get part of the history. So each time you clone you pull in the entire repository with all changesets.
Additionally, unlike Subversion, there is no way to make a “narrow” clone where you only checkout a portion of a repository. For example, if a repository has directories foo/ and bar/, there is no way to get only the bar/ directory. In other words, Mercurial always operates on project-wide snapshots.
The easiest way to achieve what you want:
hg archive [destination folder]
Once you cloned a repository, to get the code of the "tip" (the last version of the current branch - the default one if not precised) you just need to update.
You have an update action in TortoiseHG. Once done, you can look at the files in the folder.
If you wanted another state of the repository (an old version, or an old tagged state) then it's still the update command, with other parametters (see the docs or the TortoiseHG interface).
If you only want the latest code, and you don't intend to do anything related to the repository with it, like commit, or diff to older versions, or whatever, then you it depends on where you got the code from and how.
If he is using one of the hosting services, like bitbucket, there's usually a download link which gives you just the source code.
For instance, if you go here, there's a "Get source" link up and to the right which gives you a few choices in the file format (zip or whatnot.)
If you got the files somewhere else, you need to explore the interface you got them from. Try just pasting the link you cloned from into your browser and see what you get.
Sure. Clone the repository, then delete the .hg subdirectory.
I might be a bit late but actually it is possible to forget some history with Mercurial. You just need to enable convert extension from Your mercurial.ini file or .hgrc file.
[extensions]
hgext.convert=
Now you are able to use convert extension to "clone" only changesets starting from the revision specified.
hg convert --config convert.hg.startrev=[wheretostart] path_to_full_history_repo path_to_new_repo
Just note that this is not the same operation with hg clone. That's why the source repository must be a local repository. For example if we have a repository in folder MyProject and we want to forget all the changes done before revision 100. We can use the following command:
hg convert --config convert.hg.startrev=[100] MyProject MyShrinkedProject
If You are going to use this shrunken repository on a "central server" remember to take care of that everybody clones it before they continue working. Repositories are not compatible with each other anymore.
Mercurial now supports shallow clone using remotefilelog extension. Extension is bundled with mercurial probably since version 4.9. Older versions need to download the extension e.g. from github.
You have to enable it on the server e.g:
[extensions]
remotefilelog =
[remotefilelog]
server = True
serverexpiration = 14
and on client
[extensions]
remotefilelog =
[remotefilelog]
cachepath = /some/path
cachelimit = 5 GB
Than you can do shallow clone with much smaller footprint a and faster clone speed:
hg clone --shallow ssh://user#server/repo
It's my first time using a DVCS and also as a lone developer, the first time that I've actually used branches, so maybe I'm missing something here.
I have a remote repository from which I pulled the files and started working. Changes were pushed to the remote repository and of course this simple scenario works fine.
Now that my web application has some stable features, I'd like to start deploying it and so I cloned the remote repository to a new branches/stable directory outside of my working directory for the default branch and used:
hg branch stable
to create a new named branch. I created a bunch of deployment scripts that are needed only by the stable branch and I committed them as needed. Again this worked fine.
Now when I went back to my initial working directory to work on some new features, I found out that Mercurial insists on only ONE head being in the remote repository. In other words, I'd have to merge the two branches (default and stable), adding in the unneeded deployment scripts to my default branch in order to push to the main repository. This could get worse, if I had to make a change to a file in my stable branch in order to deploy.
How do I keep my named branches separate in Mercurial? Do I have to create two separate remote repositories to do so? In which case the named branches lose their value. Am I missing something here?
Use hg push -f to force the creation of a new remote head.
The reason push won't do it by default is that it's trying to remind you to pull and merge in case you forgot. What you don't want to happen is:
You and I check out revision 100 of named branch "X".
You commit locally and push.
I commit locally and push.
Now branch X looks like this in the remote repo:
--(100)--(101)
\
\---------(102)
Which head should a new developer grab if they're checking out the branch? Who knows.
After re reading the section on named branchy development in the Mercurial book, I've concluded that for me personally, the best practice is to have separate shared repositories, one for each branch. I was on the free account at bitbucket.org, so I was trying to force myself to use only one shared repository, which created the problem.
I've bit the bullet and got myself a paid account so that I can keep a separate shared repository for my stable releases.
You wrote:
I found out that Mercurial insists on only ONE head being in the remote repository.
Why do you think this is the case?
From the help for hg push:
By default, push will refuse to run if it detects the result would
increase the number of remote heads. This generally indicates the
the client has forgotten to pull and merge before pushing.
If you know that you are intentionally creating a new head in the remote repository, and this is desirable, use the -f flag.
I've come from git expecting the same thing. Just pushing the top looks like it might be one approach.
hg push -r tip