how do you define which changeset a kiln/mercurial subrepository uses? - mercurial

In the answer to this question on the kiln stack exchange site, there is a comment that mentions "if you commit from one consumer of the library, the other library consumers do not immediately see those changesets. You have to explicitly pull the changes on the library repo in other consumers."
i have added a few files to a repository which is referred to in a projects .hgsub & .hgsubstate files, but they are not showing up in the projects subrespository (because the project is quite rightly using the previous change-set it was earlier assigned)
I'd like to know how to edit which changeset a subrepo uses. do I just edit the .hgsubstate file (seems a little "hackish") or is there a command / kiln website option I can use?

In the subrepository, hg update to the changeset you want the main repository to use. Then, in the main repository, issue hg ci to commit the subrepository change. Mercurial will automatically update the .hgsubstate file with the current parent changeset ID of the subrepository.
Example (Windows .bat file):
REM Create main repository
hg init Example
cd Example
echo >file1
hg ci -Am file1
cd ..
REM Create another repository
hg init Library
cd Library
echo >file2
hg ci -Am file2
cd ..
REM Clone the Library into the main repository
cd Example
hg clone ..\Library
REM and configure it as a subrepository.
echo Library=Library >.hgsub
REM Commit it.
hg ci -Am "Added Library sub repository."
REM Note .hgsubstate is updated with the current subrepo changeset.
type .hgsubstate
cd ..
REM Someone updates the original Library.
cd Library
echo >file3
hg ci -Am file3
cd ..
REM Main repo isn't affected. It has a clone of Library.
cd Example
hg status -S
REM Update to the latest library
cd Library
hg pull -u
cd ..
REM View the changes to the library in the main repo.
hg status -S
REM Commit the library update in the main repo.
hg ci -m "Updated library."
REM Note .hgsubstate is updated.
type .hgsubstate

Related

Cant create a clone in Mercurial

i just installed mercurial and tortoise hg and Im a newbie.
I write this commeand at cmd to create a clone: myfile.txt hg clone. But then I cant seee any clone created.And myfile is opened. Can someone help me? Where can I find this created clone?Thanks!
Like Nanhydrin writes: hg clone is to clone repositories.
What is a repository? It is a project folder where you have run hg init. Mercurial. You get a repository by taking a project folder and running hg init. Then you can add any files in that folder or subfolders and use hg add to add them to version control.
Turn a project directory into a repository:
cd my-project
hg init # start a repository in the current directory
# tell Mercurial to start tracking these files
hg add file1 file2 file3 ...
# commit the files you just added. This is the first commit!
hg commit
Clone a repository:
hg clone C:/my-mercurial-repos/my-project
[creates a clone of the my-project repository in my-repo]
cd my-project # Enter the repository
You can't 'clone a file', but you can create a copy that Mercurial will also track.
hg copy my-file.txt my-file-copy.txt
hg commit
For the rest, take Nanhydrin's excellent advice and read http://hginit.com/index.html. It helped me a lot when I started using Mercurial.

mercurial push certain revision

I have searched here, but haven't found any question related to this. I got a problem like this in mercurial:
I manage open source project in bitbucket, so i have clone of the source code in my local. But I also using that project for my own live site, so I made 2 clone of bitbucket repo
Bitbucket Repo
|
==local_clone1
|
==local_clone2-> commit1 => commit2 => commit3
(personalization) (bug fix) (add feature)
The question is, I want to push commit2 and commit3 back to local_clone1, so later on I can push to Bitbucket repo. But don't want to push commit1, since it has my personal data.
Wondering how we do that in mercurial?
This can be done without too much difficulty in this case. See Removing history in the Mercurial guide for more information.
Here's the basics of what you'll need to do:
Go to local_clone2
Get the revision number (hg tip will show you) from the current number. We'll call it 731.
hg export 730-731 > ../local_clone1/changes.diff (or wherever you like)
Go to local_clone1
hg import changes.diff
You may need to edit things manually; refer to that guide for more info in that case.
Here are a couple of options:
backout
Given a history constructed as:
hg init db
cd db
echo >file1
hg ci -Am clone # rev 0
echo >file2
hg ci -Am personalization # rev 1
echo >file3
hg ci -Am bugfix # rev 2
echo >file4
hg ci -Am feature # rev 3 <tip>
Then if the current working directory is the tip, the following commands will "undo" the personalization revision:
hg backout 1
hg ci -m backout
The advantage is history remains immutable, but shows the addition and backout of the personalization changeset.
Mercurial Queues
With the mq extension, history can be edited to remove a changeset:
hg qimport -r 1:3 # convert changesets 1-3 to patches
hg qpop -a # remove all patches (can't delete an applied patch)
hg qdel 1.diff # delete rev 1's patch
hg qpush -a # reapply remaining patches
hg qfin -a # convert all applied patches back to changesets.
The advantage is the personalization changeset disappears. The disadvantage is the changeset hashes change due to the history edit, so this should never be done to changesets that have already been pushed to others. There is also the risk of a mistake editing history.

How can I insert or alter a mercurial revision

How can I alter r0 so it looks like I added .hgignore when I created my repository or insert a commit before my current r0?
I just converted a huge SVN repo using hgsvn to mercurial. It took several hours and had to go through about a dozen branches to get the whole thing. My problem now is that .hgignore isn't committed, so when I hgimportsvn a branch, the .hgignore doesn't seem to come with it. I would like to insert that file as part of r0 or insert it before that (and shift everything by 1). I've also tried committing it at the end of my Mercurial trunk checkout, but it seems hgimportsvn always clones (branches?) from the same Mercurial revision my SVN branch was created from so .hgignore is lost again.
You probably need something like the ConvertExtension. Check out the --splicemap option.
To create a new history with a .hgignore file added as the first revision:
Create a new repository whose only revision is the .hgignore commit.
Create a splicemap file containing two 40-char hashes: rev 0 of your current database, and rev 0 of your new database.
Run hg convert <current_db_dir> <new_db_dir> --splicemap splice_filename
This adds each revision in the current database to the new database. The splicemap specifies editing of parents, so if revision 0 of the current database gets its parent set to revision 0 of the new database.
Below is a Windows batch file that creates a 3-revision database and a 1-revision database with an .hgignore file in it, the splices them together. The result should be what you are looking for. If you have a large original database it could take a while, since the entire history of the source database is re-written to the destination database.
#echo off
#REM Create a 3-revision database
hg init current
cd current
echo >file1
hg add
hg ci -m file1
echo >file2
hg add
hg ci -m file2
echo >file3
hg add
hg ci -m file3
#REM Add the first revision to the splice map
hg log -r 0 --template "{node} " > ..\map
#REM Display the result
hg log
cd ..
#REM Create a 1-revision database
hg init ignore
cd ignore
echo glob:*.txt>.hgignore
hg add
hg ci -m ignore
#REM Specify this node as the parent of the other
#REM database's first revision in the splice map
hg log -r 0 --template "{node}\n" >> ..\map
hg log
cd ..
#REM Here's the resulting splice map
type map
#REM Make a copy to store the result
hg clone ignore result
#REM Add revisions from "current" to "result" honoring
#REM the splice map
hg convert current result --splicemap map
#REM Display the result
cd result
hg log
Maybe you could commit .hgignore and then rebase the commit to the beginning of history (see https://www.mercurial-scm.org/wiki/RebaseProject).

Mercurial Subrepos, how to control which changeset I want to use for a subrepo?

I am reading up on subrepos, and have been running some tests locally, seems to work OK so far, but I have one question.
How do I specify/control which changeset I want to use for a particular subrepo?
For instance, let's say I have the following two projects:
class library application
o fourth commit o second commit, added a feature
| |
o third commit o initial commit
|
| o second commit
|/
o initial commit
Now, I want the class library as a subrepo of my application, but due to the immaturity of the longest branch (the one ending up as fourth commit), I want to temporarily use the "second commit" tip.
How do I go about configuring that, assuming it is even possible?
Here's a batch file that sets up the above two repos + adds the library as a subrepo.
If you run the batch file, it will output:
[C:\Temp] :test
...
v4
As you can see from that last line there, it verifies the contents of the file in the class library, which is "v4" from the fourth commit. I'd like it to be "v2", and persist as "v2" until I'm ready to pull down a newer version from the class library repository.
Can anyone tell me if it is possible to do what I want, and if so, what I need to do in order to lock my subrepo to the right changeset?
Batch-file:
#echo off
if exist app rd /s /q app
if exist lib rd /s /q lib
if exist app-clone rd /s /q app-clone
rem == app ==
hg init app
cd app
echo program>main.txt
hg add main.txt
hg commit -m "initial commit"
echo program+feature1>main.txt
hg commit -m "second commit, added a feature"
cd ..
rem == lib ==
hg init lib
cd lib
echo v1>lib.txt
hg add lib.txt
hg commit -m "initial commit"
echo v2>lib.txt
hg commit -m "second commit"
hg update 0
echo v3>lib.txt
hg commit -m "third commit"
echo v4>lib.txt
hg commit -m "fourth commit"
cd ..
rem == subrepos ==
cd app
hg clone ..\lib lib
echo lib = ..\lib >.hgsub
hg add .hgsub
hg commit -m "added subrepo"
cd ..
rem == clone ==
hg clone app app-clone
type app-clone\lib\lib.txt
Edit: Ok, I got my answer, thanks #VonC, I added the following section to my batch-file, above the rem == clone == line, and re-executed it, and now it locks the subrepo to the correct changeset.
rem == lock ==
cd app\lib
hg update 1
cd ..
hg commit -m "lock to second commit"
cd ..
Not tested, but you should be able to go within your subrepo, update its content to the right commit (hg update), go back up one level (in the main project) and commit.
That should update the .hgsubstate with the right commit.
(extreme workaround, update that .hgsubstate yourself, but that is not recommended.)
The all idea of hg subrepos (or Git submodules) is to allow a dependency management by referencing a fixed id for a given sub-repo. If no id is given when creating the subrepo, then the latest id is selected (v4 in your case), but you can checkout whatever id you need.
Actually, this thread even complains that:
Right now, commit recursively tries to commit subrepositories before committing the current repository.
That allows you to:
record some changes in the sub-repo.
update the .hgsubstate of the main project with the new state (id) of the subrepo.
Your sub-repo revision won't be advanced without you explicitly choosing to do so, so all you have to do is set it up as you'd like initially. When initially creating the sub repo, just use a '-r' argument to clone only up to the changeset you'd like:
rem == subrepos ==
cd app
hg clone -r CHANGESETYOUWANT ..\lib lib
echo lib = ..\lib >.hgsub
hg add .hgsub
hg commit -m "added subrepo"
cd ..
note the modification on line three.

mercurial: how to synchronize mq patches from a master repo as mq patches to a set of clone repos

I have to run a dozen of different build tests on a code base maintained in a mercurial repository. I don't want to run serially these tests on same repository because they modify a set of common files and I want to run them in parallel on different machines. Also, after all tests are run I want to have access to latest test results from those test work areas. Currently I'm cloning the master repository a dozen of times and run in each clone one different test. Before each test execution I do a pull/update/purge preparation sequence in order to start the test on latest clean state. That's good for me.
I'm also preparing new changes using mq extension that I would test on all clones as above before committing them. For testing some ready candidate mq patches I want somehow to deploy/synchronize them to be available in test clones and apply those ready for testing using some guard before running the test.
Did anybody do this synchronization before? What's the most simple way to do it? Do I need to have versioned mq patches for that?
patches can be maintained in their own repository provided you passed the "-c" switch to qinit like so
hg qinit -c
You may still be able to create a patch repo after the fact via
cd .hg/patches
hg init
hg addremove
hg commit -m "my patches"
But I haven't ever tried that personally.
then .hg/patches can be treated like any other mercurial repository. so I think you could probably roll some shell scripting. to get into the .hg dir of your cloned repos and do a
hg clone http://centralrepo.com/patch_repo ./patches
Here is the solution that I've implemented. Few notes:
all patches guarded with ready_for_testing AND those unguarded are applied for testing.
using versioned repos is better because we can make abstraction of queue repository implementation
I use mercurial 1.5.1
master repo is in master dir
clone repos are in clone-x dirs
Here are the steps (some could be optional):
once: put patches in master repository under versioning using mercurial:
a. hg -R master init --mq #no commit happen here, can be done later
b. hg -R master commit --mq --addremove --message 'initial patch queue' #make them visible to clone repos
for each clone, once after clone creation finishes: assuming no patches created yet on clones, initialize mq sub-repository:
a. hg clone master\.hg\patches clone-x\.hg\patches
b. hg -R clone-x qselect ready_for_testing
for each change ready in master (patch created/imported in mq repo): do this before launching tests for it:
a. review/update guards of mq patches: those included for testing should be unguarded or with +ready_for_testing
b. hg -R master commit --mq -A #make them visible to clone repos
for each clone, for each [test] iteration for each clone: do this preparation sequence before running the actual test:
a. hg -R clone-x qpop --all --force
b. hg -R clone-x pull
c. hg -R clone-x update --clean
d. hg -R clone-x purge --all
e. hg -R clone-x pull --mq
f. hg -R clone-x update --mq
g. hg -R clone-x qpush --all
As of Mercurial version 1.5, you can create a patch queue repository in an already existing Mercurial repo using the following command:
hg init --mq
It is OK to have queued patches when you issue that command.