I want to checkpoint/commit stages (locally) using mercurial, knowing well that these changes would break the build if I pushed them to the remote repository. What I would like to do is fold/collapse/accumulate these changesets into a single changeset that I can push. I do not want the the remote repository to have these intermediate checkpoints in its history. I would like all recorded versions on the remote repository to at least build properly.
Is there any simple way to do this, perhaps an extension. I would have assume that this would be a selling point of a DVCS.
Histedit extension (fold command)
or
MQ extension (qimport + qfold + qfinish cycle) - "Combining entire patches" chapter in chapter Managing change with Mercurial Queues of "Mercurial: The Definitive Guide"
Related
We have some restrictions on what we are allowed to put in our central Mercurial repository.
Is there some way I can keep stuff in my local Hg repository, without having it pushed to the central one?
Note:
The files might be connected to files in the central repository (branches for example).
Local stuff might later be incorporated in the central repository.
If you're using branches, you can set their visibility to secret. This will prevent them to be pushed.
hg phase --secret --force my-branch
When you want to share, you change their phase to draft and then they will be automatically collected during a push operation.
See hg help phases for more information.
You could also use Mercurial Queues. With MQ, you can work with patches (which are changesets) and update or re-order them based on changes in the official repository. This will also make it easier to incorporate some or all of your changes into the main repository or just discard them later.
Commit to your local repo, then push to the remote repo when you are finished.
You can push to your local repo as well, but from my understanding that is where your current development is?
I think you want Shelve Extension or Attic Extension.
The other option is if your using a newer Hg with better branching you can just fork the central repo somewhere like bitbucket and use that as your repository for your temporary stuff and potentially branch that.
Finally you could also just use .hgignore but that could be problematic later when someone does check in the file with the same name.
When I type hg outgoing, I get a response like this:
comparing with ssh://server:1234/path/to/repo
and a delay while it communicates over the network.
Why is this network traffic necessary? Is there something fundamental about Mercurial which means it can't remember which commits have been pushed, and which haven't?
Is there an alternative command which can give me similar information without having to communicate over the network?
As Mercurial is a distributed system, there are multiple ways for your changes to get from your local repo to the remote repo.
For example:
it is possible for someone to pull changes from you and then push those changes to the remote repo
you could actually just copy your local repo using whatever operating system you have and Mercurial would be totally unaware of that. You could then push the changes in this copy to the remote repo.
However, if you have Mercurial 2.1 or later you can use hg phase to determine which changesets have been pushed. Assuming you don't use hg phase to change the status of any changesets then the changesets with a phase of draft or secret have not been pushed and those with a phase of public have. Use
$ hg log -r "not public()"
to see unpublished changesets.
It won't catch the two examples I gave above but it will probably be good enough if you just want to know which changesets you have not pushed.
Look here or check hg help phases for instructions on how to work with phases.
A mercurial repository can potentially connect with multiple other repositories. So, I guess it needs to make sure the changes that weren't pushed from your repository, didn't arrive from another repository already.
I use named branches in Mercurial.
In doing so I have created one branch called playground where I can try out various wacky experiments. I never intend to merge this branch into any others and I never want to push it to our main repository.
Since creating it, every time I do a push I am told I have added a new branch and I have to use the --new-branch flag. At this point hg push -b default (or whatever branch I'm pushing) works fine but it's annoying. Is there any way to suppress that message by letting Hg know that I am not interested in pushing that branch ever?
Starting with Mercurial 2.1 (released in February 2012), you can mark your changesets secret to keep them from being pushed to another repository. You use the new hg phase command to do this:
$ hg phase --force --secret .
This mark the current working directory parent revision (.) as being in the secret phase. Secret changesets are local to your repository: they wont be pushed or pulled. Pushing now looks like this:
$ hg push
pushing to /home/mg/tmp/repo
searching for changes
no changes to push but 2 secret changesets
There is no equivalent mechanism in older versions of Mercurial. There your best bet is to create a local clone for the changesets you don't want to push.
Update:
Mercurial 2.1 introduced the hg phase command which allows users to control what change sets are exchanged with remote repositories. #MartinGeisler answer to this question details this method.
Original Answer:
If you want to create a local branch of your code you have a couple options. You can hg clone the repository which will locally create a branch of the entire repository in your filesystem. The other alternative is you can try to use a Mercurial extension like LocalbranchExtension.
There are many ways to branch in Mercurial without using a named branch. Just find a method that suits your needs.
Further reading: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
In addition to the excellent answer above concerning phases, you can also specify 'default-path' (in the [paths] section of your .hgrc) to refer to the local repository:
[paths]
default = ...
default-push = .
This will cause all outgoing changesets to be compared to the specified repository. In this case, comparing outgoing changesets in your local repository TO your local repository results in nothing to push.
You can still pull/update/merge from the main repository, but no push will ever send anything back to that main repository.
If you work on multiple machines/repositories, you can set one up as described above, and configure the others to specify the 'default' path to point to the server that pushes to itself. In this way, the other machines can push/pull to your local central repository, and these changesets will never escape your carefully configured collection of repositories.
Summarised Question:
Are github-hosted sub repositories within a mercurial/kiln repository possible, and if so are they automatically updated/cloned when the parent mercurial repository is operated on by a hg clone or hg commit command?
Detailed Question:
Following on from my question that was answered so excellently here , some of my third party code is in folders I downloaded a while ago from opensource efforts on github. Since at that stage I was not using version control, those folders where just standard folders that now been incorporated as sub repositories in mercurial.
This is obviously not ideal, as for one thing, new versions of the libraries may have bug fixes, or new features I wish to use in the future. I also may need to locally customise some of the libraries.
I can see from reading this link that it possible to have mercurial "know" about those git server urls (and revisions), so I can then have mercurial clone the github hosted libraries direct from their parent repos.
Am I right in saying that when I clone the parent (mercurial) repos, those files will be pulled from github, without having to separately manage this using git?
What is also not clear is, if I were to do this, and it transpired that code might need to be customized from within that github-cloned repository, would I need to use git to manage revisions of the local files, or would mercurial do that by proxy? eg id I were to hg commit -S would mercurial invoke git on my behalf to handle that?
Am I right in saying that when I clone the parent (mercurial) repos, those files will be pulled from github, without having to separately manage this using git?
Yes, clone of a Mercurial repository that contain subrepositories will trigger a clone of the subrepos too. It really happens on update. Mercurial notices the .hgsub file and issues the needed hg clone and git clone commands for you. It uses the information in .hgsubstate to know exactly what revision to checkout.
The subrepositories can be hosted anywhere. For a Git subrepository declared like
foo = [git]https://github.com/user/repo.git
Mercurial will simply issue the corresponding clone command:
git clone https://github.com/user/repo.git foo
It's then your reponsibility to later go into the foo repo and use Git to fetch new commits as necessary. After you fetch/pull new commits, you can make a top-level commit to record the new state of the subrepo in the .hgsubstate file. Use hg summary to see if a subrepo is dirty in this sense.
[...] would I need to use git to manage revisions of the local files, or would mercurial do that by proxy? eg id I were to hg commit -S would mercurial invoke git on my behalf to handle that?
When you edit files and make a top-level hg commit, Mercurial will make sure to commit the subrepo first (if you use hg commit -S or if ui.commitsubrepos=True). If you make a top-level push, then Mercurial will always push the subrepos first so that you always have a consistent set of changes on your server.
I have been migrating from subversion to mercurial piecemeal and this has created a bit of a tangle. I had an old SVN server (pre 1.4) to start with so here is what happened.
HgSubversion did not want to pull in the full history from trunk, so I did a shallow convert.
My colleagues did their last commits to SVN and I pulled those into Hg.
We moved over to Hg and started pushing to it
Just to be safe one of my colleagues made some more commits to SVN.
I managed upgrade the SVN server and get the full repo to the new SVN.
HgSubversion pulled in the full history successfully - including the few extra/duplicate commits.
Now I would like to "transplant" the commits in the shallow mercurial repository into the full history, the repositories are related in content but unrelated in mercurial hashes.Short of just copy pasting content what would be the best way to migrate the changes ? Eventually everybody should be able:
To switch the Hg repo with full history and keep working
Have automated push from the Hg repos of suitable squashed/rebased changesets to SVN as a service user.
I would like a concrete example with the following scenario.
Last mercurial hash at step 2 - A
Current mercurial hash after pushes step 3 - B
Hash of last commit after pull from upgraded SVN - C
Hash of step 2 commit after full SVN history pull - D
I am not very good at ASCII art, feel free to add one for bonus points.
We did a CVS -> Mercurial migration last week at work. Like in your case, some people continued to use the CVS for a time.
In order to sync the the two repositories when the CVS server was finally shutdown, I did the following :
Convert the CVS to mercurial via cvs2hg
Export each new revision with hg export
Import the patch files with hg patch
There was only a dozen revisions, so this was no big deal... If you have many more revisions, you could maybe take a look at the transplant extension.
Hope this helps.