I came on board about 6 months ago, and when I arrived, my group was using NO form of versioning. I have since convinced mgmt to use Mercurial in new projects, so we have on our webserver the following structure:
-MainFolder (which includes files for the main project)
+Subfolder A, which contains (old) project A with NO hg repo
+Subfolder B, which contains (old) project B with NO hg repo
+Subfolder C, which contains (NEW) project C AND a hg repo
+Subfolder D, which contains (NEW) project D AND a hg repo
Note that the only folders which currently have a repo are subfolders C and D, which represent seperate projects.
I would like to add a repo to track everything which is currently not tracked, but want to ignore the folders which currently have their own repositories. I know about using .hgignore files, but from what I understand that would require me to explicitly ignore every folder which contains a repo. This isn't a problem in the above example (with only two existing repos), but our actual setup has more projects than this.
Is there any way to tell Mercurial to dynamically ignore all folders which have a repo in them, and track everything else?
It will already do this out of the box. Try the following demonstration:
hg init demo
cd demo
hg init foo
cd foo
echo foo>>foo.txt
hg stat
? foo.txt
cd ..
hg stat
# Nothing!
You should probably look into setting up the main repos to use subrepositories for tracking changes in the folders that already have their own repos. If you don't do that, changes in one of those projects wouldn't automatically be committed when you commit in the main.
Related
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 been trying to follow the instructions in the answer to this question, using kiln.
i'd like to be able to arrange things as follows:
/somepath/thirdparty maps to a kiln repository "thirdparty" and contains assorted code
/somepath/common maps to a kiln repository "common" and contains shared code i have written
and
/somepath/project1 maps to kiln repository "project1"
/somepath/project1/thirdparty maps to branch of thirdparty above
/somepath/project1/common maps to branch of common above
and
/somepath/project2 maps to kiln repository "project1"
/somepath/project2/thirdparty maps to another branch of thirdparty above
/somepath/project2/common maps to another branch of common above
I found that when I created the .hgsub file as instructed and added/pushed it to Kiln, I could no longer view the Kiln files in the Kiln web file viewer — it displayed an obscure message about the Kiln "overheating" :-) Additionally, whilst it did automatically create the subfolders in the correct place, they were not populated with files, (possibly because the pull failed).
Anybody tried anything like this before, using Kiln?
As I intend to develop a number of apps using the common code (and potentially eventually release the library as open source), I would like to have it managed in discrete repositories. As some of the projects are for end clients however, I need to be able to give them a single repository that includes things as described above.
Kiln does currently not support subrepos that use nested URLs on the server. This means that you cannot have both the following URLs working:
http://server/kiln/somepath/project1
http://server/kiln/somepath/project1/thirdparty
So you should setup Kiln so that you have four repositories on the server:
http://server/kiln/somepath/project1
http://server/kiln/somepath/project2
http://server/kiln/somepath/thirdparty
http://server/kiln/somepath/common
That's easy — just four normal repositories. Then clone "project" and create the .hgsub file with:
thirdparty = http://server/kiln/somepath/thirdparty
common = http://server/kiln/somepath/common
When you push that back to Kiln, it will notice and display links for the subrepositories. However, the subrepositories wont end up being nested on the server. So there wont be any project1/thirdparty path on the server.
It's also far from clear that you would want that. When you have several projects that collaborate and use some common code base, then you want "project1" and "project2" to get each other's changes to this common code base. So it very useful that the common subrepo in both projects push and pull from http://server/kiln/somepath/common.
In Mercurial, we normally recommend that you use paths of the form common = common in the .hgsub file. This means that the server must support nested repositories. When Kiln doesn't support nested repos, you can use full paths instead.
When you initially setup the subrepositories, then remember that you need to update them manually. So with the above URLs, you would setup "project1" by running:
$ hg clone http://server/kiln/somepath/project1
$ echo "common = http://server/kiln/somepath/common" > .hgsub
$ echo "thirdparty = http://server/kiln/somepath/thirdparty" > .hgsub
$ hg commit -m "Created subrepos"
This creates initial empty subrepositories. They are empty because you haven't told Mercurial which changeset you need in them. This is tracked in .hgsubstate where you'll find:
0000000000000000000000000000000000000000 common
0000000000000000000000000000000000000000 thirdparty
To populate the subrepositories you do
$ cd common
$ hg pull --update
$ cd ../thirdparty
$ hg pull --update
$ cd ..
$ hg commit -m "Updated subrepos"
This updates the 000... lines in .hgsubstate with the current tip changeset IDs for the two subrepos. Future clones of "project1" will notice the .hgsubstate file and make sure to update the subrepos to the revision mentioned there.
I'm starting with Mercurial. I'm reading the mercurial book but still have a question.
I've started my project month ago, and i have a lot of files and directories in it. Now, i want to use Mercurial and made myself an account in bitbucket. Now, i want to set this project up in Bitbucket. How can i add all those files to the bitbucket repo?
This is what i was thinking i could do:
I could try to (1) clone the empty repo (from bitbucket) (1) copy all files into that directory, (3) issue an "hg add" and after that (4) commiting.
Maybe you have a better way to do this.
Thanks!
(1)
hg clone https://ME#bitbucket.org/ME/myproject
(2)
cp existing-project/* myproject/
cd myproject
(3)
hg add
(4)
hg commit -u ME
(5)
hg push (i think i have to do this to make the changes visible)
You can simply hg init, hg add, and hg commit in the original project folder, then edit ~/project/.hg/hgrc to add a default-push location of your bitbucket repo (you can clone it to a temporary folder to get the hgrc created for you which you can copy into your project, even, without needing to RTFM for the right syntax.)
Because of the distributed nature of mercurial, this hgrc entry is the only thing relating your local repo to bitbucket at all; you can even hg push https://ME#bitbucket.org/ME/myproject without making the link explicit anywhere. Each copy of a repository is completely self-sufficient.
Wooble's answer is ok, but it's missing something, so I'm supplementing here.
When you first create an empty repository (by hg init or creating on bitbucket), it has no identity. However, as soon as it has any changesets, it has an identity and you can only push/pull between it and repositories that share that identity.
If you had 2 repositories A and B for separate projects, you wouldn't be able push/pull between them. Once you create a new repository on bitbucket you can push changesets from either A or B to that repo once. If you push changes from B that first time, the bitbucket repository is now related to B. You can't then push changesets from A into it, or pull changesets into A from it.
So when Wooble says,
...this hgrc entry is the only thing relating your local repo to bitbucket at all;
That is correct while it is still empty as it is not related to any repositories until it has changesets. And you still need that address to be able to push/pull between your local repo and the bitbucket repo, but once you've pushed changesets to it it also has that identity that relates it to your local repo.
I have a repository, called "my project" based in a framework called "framework". The two of them have each it's repository, unrelated between them, with each branches and tags. I want to receive "framework"'s updates in my repository, but only from "default" branch and not from others. And, of course, I do not want to have "framework"'s tags in my repository, as it is a totally different project.
I have Mercurial HG, and I would like to be able to pull changes from "framework" repository directly from my "Manage repository" page.
Furthermore, I only want to download latest changesets, since I started my project not long ago. And It would be perfect if I could rename the "framework"'s default branch to other name in my repo, e.g. "Framework Changesets".
Note: I do not have write access to the "framework" repository.
I tried to do what mercurial wiki said:
hg pull -f -r default "framework"
It was OK, until I realised I had downloaded all the tags from the "framework" repository, and I had downloaded all the changesets from the remote repository. Furthermore, when in TortoiseHG->Configuration->Synchronization I put the "framework" repository as a remote repository for that project, and pulled from the remote repository, I got all the branches from that repository.
Of course I wasn't able to change default branch name, and updated my default branch, even though I tried to use hg convert --branchmap (but I didn't know how to use it).
Is there any solution to my problem? or even a partial solution?
I think you can address this issue through a combination of these things:
Pulling specific branches
Using the command line: hg pull -r <branch name>
Using TortoiseHg v1.1.X:
Check for incoming changesets by using the button labeled Download and view incoming changesets
Right-click on the tip of the branch you want to pull and select Pull to here
Reject the rest of the changesets using the Reject button
Removing existing tags
You can always hand-edit the .hgtags file to remove tags created on the "framework" branch, but I don't know of a way to pull changesets without the tags.
Changing branch name
Using the mq extension you can change the named branch that your new "framework" changesets live on. See answer to "Apply patches in branch" for instructions on how to do this in TortoiseHg v1.1.X, as well as the CLI. The basic idea here is to create a named branch with the name you want, import all of the "framework" changesets you pulled into a patch queue, and then apply them to the new named branch. They will shed the branch name from "framework" and use the branch name of the branch you applied them to.
If you are going to pull from "framework" more than once, you would need to use the patch queue to move only the new changesets with each pull. It should be easy to see which changesets you haven't moved yet.
We can specify the branch name by appending branch name with a # symbol in the clone url.
e.g.
hg clone --verbose https://user#cloneurl/my_product#MY_BRANCH "C:\myCode"
Is it possible to clone a part(a single folder or even a single file) of a repository?
Basically it's not possible, there is nothing like Subversion's svn checkout http://example.com/project/dir1.
But you can get a partial clone by rewriting the changeset history with hg convert. On the upside, it will be a partial clone. On the downside, the resulting repository will be not related any more to the initial one. The changeset IDs will be different and it will be very hard to continue interacting with the source repo.
An example of creating a partial clone. Suppose you want to clone only the doc directory from the repo:
$ hg clone http://example.com/project local-project-repo
$ cat > filemap.txt << END
include doc
exclude .
END
$ hg convert --filemap filemap.txt local-project-repo docs-only-repo
Nope. That's called partial cloning (some file paths but not all) or shallow cloning (some revisions but not all), and not provided because the point of a DVCS is that everyone has a full copy of the full repository.
Some online repositories will let you download .tar.gz files of all the files in a specific revision or a specific file from a specific revision, but that's not done using the Mercurial tool.