Committing nested .hg folders - version-control

Forget everything you think you know about sub repositories, sub modules and what not. My problem is very simple.
I have two repositories, repoOne and repoTwo
Contents of repoTwo is only one file: DefaultConfig.txt
Contents of repoOne is:
+ repoOne
+ folderA
+folderB
+repoTwo
+.hg
+DefaultConfig.txt
Ok, now I make changes only to DefaultConfig.txt within repoOne. I also add a sibling file next to it just for fun.
I want those changes to be committed only against repoOne.
That is, repoTwo should not know about these changes what so ever, but I want repoOne to keep getting updates if it chooses to hg pull from within repoTwo. It can also commit to it from inside that folder if I choose to do so.
Why is this not possible? Why does mercurial refuse to commit .hg files? It would be so brilliant otherwise! What other versioning control system would support something like this from scratch?
GIT also suffer from this exact problem! Whyyyyy!?

I'm not entirely sure I understand what you're trying to do, but it seems to me like you just need to specify the repository root directory on the command line, which is something you can do for nearly all hg commands:
cd repoTwo
hg -R ../../.. add DefaultConfig.txt
hg -R ../../.. commit -m "Whyyyyy would I do this!?"
However, I would advise against the structure you're describing, as it will very easily become confused unless you decide to go with SubRepositories, which are considered a feature of last resort.
Update: Having played with it, this doesn't actually work, as it reports that the file is in a nested repo.
Attempting to add the file to the nested repository after adding it to the parent, results in it being marked as "removed" from the parent repository.
One possible solution would be to have the file in question being in one nested repository, and cloned to another nested repository:
+ parentRepo
+ .hg
+ nestedOne
+ .hg
+ DefaultConfig.txt
+ nestedTwo : cloned from nestedOne
+ .hg
+ DefaultConfig.txt
Something like this would mean that you could have two versions of DefaultConfig.txt, and if you make changes to one, you can pass them on to the other by means of push and pull. I'm not sure if that's what you want, but it's the closest I could get, and it's messy.
To answer your question "Why is this not possible?", there are several reasons I can think of, but the main one IMO is that if you needed something like what you're asking, then there is likely an issue with your workflow, that will cause confusion down-the-line.

Related

Mercurial merge results in files labelled modified but which are binary equal

I'm in the process of doing a merge, and I'm ready to commit at this point but my commit dialog in TortoiseHg is showing many files as modified but when I diff to parents it says all files are binary equal.
I do not have and have never had the eol extension enabled.
Revert changes nothing, the file is still registering as modified.
hg parents shows two parents for the file.
hg stat shows the file as modified, e.g.
c:\Projects\MyProject>hg stat Authorization\AuthorityGroups.cs
M Authorization\AuthorityGroups.cs
hg diff --git shows nothing, e.g.
c:\Projects\MyProject>hg diff --git Authorization\AuthorityGroups.cs
c:\Projects\MyProject>
I've tried this on two different machines on two separate clones and I'm seeing the same thing.
Any other thoughts for how I could diagnose or fix this?
Clearly something has changed but if it's not showing in hg diff --git how can I establish what that might be?
Update 2014/12/10:
I've done a bit more checking on the history of the two parent revisions and I think I see why it's getting confused.
We've got the original parent file added in revision 1 on default.
On the Apple branch the file has been renamed to move it to a new location.
On the Orange branch the file has been added to move it to the same new location.
So the file on both branches is binary identical and at the same location, but presumably Mercurial is flagging it as a difference to be merged because they arrived there by apparently different means.
So the question then becomes:
Is there any way to retrospectively repair the move being treated as an add and delete on a long committed changeset (a new commit would be fine, but I can't edit the history) , or do I just need to let it go through in the merge?
Is there any way to retrospectively repair the move being treated as an add and delete on a long committed changeset (a new commit would be fine, but I can't edit the history)
Well... sort of. Update to the most recent Orange commit in which the files had their old names (you can use hg bisect to find it if you're not sure exactly when it happened), do hg rename to the new names, commit, and then merge this into the current Orange head. Mercurial should be smart enough to register the files as properly renamed, and it won't cause conflicts (we know this because the more complex Apple/Orange merge didn't).
or do I just need to let it go through in the merge?
This is easier. Mercurial's merging algorithm is quite smart. It can deal with situations like this just fine.
Unless you have a third branch in which the files were never moved, the second option is unlikely to cause a problem. If you do have such a branch, you should be fine as long as you merge it into a descendant of the Apple rename (or merge from such a descendant). The major difficulty would be with merges to or from the Orange branch.

Fossil SCM - Revert to a specific revision like Mercurial

While using Mercurial if I want to change the current working copy with a specific revision I just do:
$> hg revert good_revision
$> hg commit -m "Now I'm in the good revision"
Then I can see that all my files are int the good_revision state and can start working on it.
So far on fossil I can do a revert but only on specific files, not the entire repository, and update or checkout don't seem to work as I would expect.
How can fossil revert my entire repository to a certain revision?
I'm not sure I quite follow but I think what you want is to be able to create a "multiple heads on one branch" sutuation in Fossil. If yes, then Fossil does support this, just it calls branch's heads "leaves", and this process is called "forking".
To do that, you
fossil update good_revision
and then
fossil commit --allow-fork
You may now spawn fossil ui, navigate to your branch and see it having two leaves.
You now may close the then-current leaf.
Note that, while supported, this does not appear to be a recommended practice. Instead, Fossil recommends a rather peculiar approach for throwing away changes:
Rename the branch at the "bad" leaf to "mistake" (or create that branch if it doesn't yet exist). By doing this you effectively "mark" the resulting subleaf as a mistake.
Note that the name "mistake" name is just a convention; this branch does not exist in a freshly created repository.
Close the "bad" leaf.
Return to the last-good state using fossil update, continue hacking.
Since that "last-good" commit still inherits the branch tag of its parent commit, the next commit you record will also inherit it and won't be on the branch "mistake".
For an example, see how it looks in the SQLite repo—there's a bunch of assorted short chains of commits on this branch. See also this.
My slightly different solution to what I think I understand the question to be (paraphrased: how to work on an older "good_revision" than current leaf of this branch/trunk that I'll call bad_leaf, and treat changes since "good_revision" as bad), which is sort of equivalent to applying diffs between the two versions but in reverse from/to order:
Merge in a (empty) fork from the good_revision, using the baseline from the bad_leaf instead of the default, last common commit; hence the diffs that will be applied are the original branch's differences back to a good_revision fork you create as it won't see they've already been applied. Using the latest as baseline "hides" those which would otherwise make it ignore all changes as they're already applied.
fossil update good_revision
fossil commit --allow-fork --allow-empty
# note the uuid from that commit (for use as forked_basis below)
fossil merge -f --integrate --baseline bad_leaf forked_basis
Then of course once happy,
fossil commit
It doesn't create any branches that should be called "mistake", it just applies the reverse diffs from good_revision to bad_leaf into bad_leaf to put you back where you were and you can continue committing to that same (new) leaf that used to be at bad_leaf.
A diff (straight gnu, not fossil diff) against a checkout at the original good_revision compared to a checkout after the above commands matched. Except for empty directories that had lost their files, but fossil doesn't track/tidy-up dead directories anyway.
caveat: I haven't been using fossil that long and its different in several ways to the common ways I've been used to with cvs/svn/git/hg/ perforce/clearcase.
Reason for adding this answer: I found the existing answers harder to understand and wasn't sure I trusted myself to do them correctly as a result.
If I understand your question correctly, there was a problem somewhere along the development cycle and you would now like to go back one or more revisions to a known good revision and start using that. Furthermore, you'd like that revision to become your trunk. The approach in Fossil is similar to that of Mercurial:
fossil revert -r good_revision
fossil commit -m "Now I'm in the good revision"
This will replace the files in the working directory with the ones from the specified revision. The commit will commit them to whatever branch you're working on (I am assuming that it is the trunk in this example). If you don't specify the revision number, it will use the last committed version.
One of the more common usages of the revert command is to roll back a single file:
fossil revert -r good_revision my_file
(or)
fossil revert my_file_from_the_last_commit
However, as shown in the first example, leaving out the file name causes all files to be reverted. For further information please see https://www.fossil-scm.org/index.html/help?cmd=revert
Sorry for the latest response, but I just came across the question while looking for something else. I post this in case someone else is looking into how to revert to a previously committed version stored in Fossil.

I was working in the wrong repo. They are almost the same but not associated data. How do i diff/merge?

Can you diff with the reverted copy?
I was doing work in the wrong repo. They are almost the same, but have no actual relation.
I just did a pull and an update, can i then copy my changed files into the Right head and then run a diff on it or something similar and then properly merge the 2 together?
I feel an alternate option would be do something like
copy the code over and commit it, then revert back, and merge with the commit to diff what has all changed..
I have changing something like 1500 lines over 9 files, so i dont want to rewrite a bunch of code segments.
How should i handle this?
It really depends on how similar the "almost the same, but have no actual relation" repositories are.
If they extremely similar (as in files have the same names and text is almost identical), you might get by with exporting a patch at the source repo and then importing the same patch into the target repo.
In the source repo:
hg export -r tip > path\to\oops.patch
and in the target repo:
hg import path\to\oops.patch --no-commit
I used --no-commit since I assume you will need to do some cleanup first to make sure that everything looks ok.
Alternatively, you could just compare the two directories using kdiff or BeyondCompare3 and bring over the differences that you want from the source repo to the target repo and commit it that way. This would probably be my approach.
(I am intentionally ignoring the question about why you have two repositories that are that similar but don't have a shared history. For all I know, it might be the right thing to do.)

With TortoiseHg, how do I exclude a file from checkins/pushs, but still get updates to it? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
how to ignore files in kiln/mercurial using tortoise hg “that are part of the repository”
I have a config file that I don’t wish to check in however I do wish to get updates whenever someone checks in a change to it.
In most systems I just need to uncheck the tick mark next to the config file at check-in time, however HG seems to make life a lot harder!
In parforce this even easier, I can just check the config file out in a different change list, how do I do the same in TortoiseHg?
In general, you don't. The usual way to handle this is not to put the config file in source control, but instead to put a template for it in source control. Something like config.sample. You can even tweak your run/build script to copy config.sample to config if config doesn't already exist.
There are plenty of other ways to try and get at this using mq or an alias like mycommit = commit -X config, but at its core a file is either tracked or it isn't and a file everyone has to change themselves shouldn't be.
If you uncheck the file from the file list before committing it won't go into the change set. This means it won't feature in a push (as these are per change set).
This is one feature of Tortoise that makes it useful over the command-line.
If you do a pull with an edited file, you will create multiple heads. You can merge these if you want the file to feature changes, but this might be a manual step.
Alternatively in the case of a config file it is useful to use the Patch Queue functionality of Mercurial. From the command-line this is possible thus (assuming it is changed in your working directory):
hg qnew "localConfig"
hg qrefresh
This creates a new patch queue item called "localConfigs", and puts the edited files (your config file) into the item. You can then:
hg qpop
To remove it from the patch queue (out of your change set path). Or:
hg qpush
To put it in your change set path. This is an easier way of managing file changes that you do regularly on top of keeping pace with the central repository: you pop your queue items out, pull and update, then push the queue items back on (handling any merge conflicts, though these are rare if your items are small). This way you avoid multiple heads.
https://www.mercurial-scm.org/wiki/MqExtension
We tend to use this mechanism in our office.
Note, pushing and popping acts like a stack collection; if "localConfigs" is on top of "moreLocalChanges" you will need both if you wish to push "localConfigs". My example assumes that the "localConfigs" patch is the only one in the queue. It is also disabled by default in Mercurial configuration, but comes bundled with it so you can enable it simply:
[extensions]
mq =

How to prevent divergent mercurial branches from merging?

I have a project stored in mercurial which has grown well beyond its original remit, and now I want to split the repository into two separate projects. Say the file tree looks something like this:
src/
a/
a.h
a.c
b/
b.h
b.c
Say I've hg cloned this repository twice, and in the first clone I've performed an hg rm src/b/*, and in the second I've performed an hg rm src/a/*. This gives me the two separate source trees I want, with history and revision numbering preserved in each branch.
The problem I now have is what happens if, in the future, I ever accidentally pull from the a/ clone into the b/ clone. What I'd like is for mercurial to simply refuse to pull from, or push to, the other branch, if I ever try to do so, as if the two had never shared history.
Is this possible? If not, is there a canonical way to create two parallel projects from one original which preserves history and revision numbering?
The canonical way would be to use hg convert with a filemap like this:
exclude b
rename a .
(and afterwards with the roles of a and b reversed to create the second repository)
This way you end up with two unrelated repositories (which Mercurial will refuse to push/pull without the use of force) only containing the history of a single directory.
Also see this question for reference.