I have a project in which I've set up a bitbucket repo using mercurial.
We're actually 3 to work on it, so we're using branches.
When we did merges, we did them quite randomly so many times it failed.
Actually, I'm using Meld, and I don't really know in "which" part of the repo I have to choose which part of the source code I want to merge.
So, when I do merge, where should I do it ?
I'm not really sure if I have to do it on local, base or other, even though I know local corresponds to my last modifications, other corresponds to the last modifications of the branch I want to merge, and well, actually I'm not really sure about what is other ...
On careful review, I have found it out. You want to merge into local
Please correct me if I'm wrong but I am pretty sure after doing some tests
Local
The correct place to merge change to. The local files that will result from the merge. This will likely contain a mix of some auto-merged lines already.
Base
Where you are merging into.
Other
The merges you're pulling
This may not be the "right" answer, but when in doubt, I make them ALL match by making them look ALL merged 'correctly' (sometimes I have to discuss with my coworkers what the 'correct' look is based on their changes).
By doing this, I ensure the merge will be successful because meld cannot and will not actually change upstream data in mercurial. So there's no downside. For the life of me I also cannot tell which pane to merge into (mostly because the term 'base vs local' is ambiguous). So this is kind of an odd way to do it, but it works
Related
I use the "show annotation" functionality quite often. Now, I accidentally crushed the svn and solved it by making a re-commit of everything. Now, every time I use the "show annotation" function, it shows this last commit on every line.
Can I revert this somehow?
I'm assuming you didn't kill the entire SVN and "solved" that by starting over from rev 1. I'm assuming some intermediate revision got corrupted and you had to touch and commit every file in a new revision, but older revisions are visible and accessible in the SVN history. The Annotations feature, and Plan B both rely on that.
What the textbook offers
Excluding a single mid-range revision is not possible, given a certain history. You can only exclude head or tail ranges by specifying revisions other than 1 for the "From" and HEAD for the "To".
Say the "repair" revision you want to exclude is r1000. To exclude it, you can choose to consider either (from-to) r1-r999 or r1001-HEAD, leaving out r1000. So you are confined to either viewing the changes before or after the repair.
You can read up on the possibilities and options of what's internally called svn blame in the SVN documentation.
Plan B
Now, that's not really satisfying, I imagine. Here's something else you can try, but please create a backup of your repo first.
With the help of the SVN history viewer, or log viewer, find the last revision before the corrupted revision, say r997.
Make a branch based off that last good revision.
Then delete or move the current trunk, using the corresponding SVN commands.
In the last step, move or branch(=copy) the branch back to the trunk location.
You have effectively cut out the corrupt revisions. The branch-now-trunk has a "hole" in its revision numbers, because branching off r997 created a new revision younger than the corrupted and repairing revisions. Afterwards, showing annotations on that new trunk will work like before, but wont include the corruption and your "repair".
Here, I made an illustration for you:
This operation can screw up some ancestry operations like merging, but I've done it successfully before, even with large merging operations later on, so you might as well try it, too. Good luck!
First off: I know that hg branches are immutable and they cannot be renamed. I am also aware of the existence of the mutable branches extension for hg. But I'd prefer a different approach, as I can never be sure that all of our developers have it installed and active, it's still "only" an extension.
My question: We have a repo with about 20 branches in it. Due to various reasons (inexperienced use, bad choices, experiments that became production environments) some of those branches were named badly and now our repo is a little confusing. What we'd like to do is rename a few of those branches, because obviously, the more we work with them, the more it's becoming a problem.
Do you have any suggestions? I already thought of a "tool" or some kind of script that recreates the whole repo from scratch, getting changesets of the old repo and committing them - with new branch names - to a new repo, "rebuilding" it. But before I go and waste time in writing something like that, I'd like to hear if there are other possibilities.
FYI: there are about 600 commits with frequent merges across the various branches.
You can rebuild the repository by doing a Mercurial to Mercurial conversion using hg convert. Enable the convert extension first and create a branchmap to do the mapping of branch names from old to new:
a-bad-name new-name
another-bad-name better-name
You can use that to map multiple bad names into a single good name, for example.
After the conversion, you will have a new repository with the same history, but with different branch names. The changeset hashes will thus be different and people will have to reclone (but I think you're aware of this already).
Perhaps I'm biased from years of svn but why would I ever want to merge with a different branch then make some changes before committing. The hg output itself suggests otherwise:
(branch merge, don't forget to commit)
Dear hg, then why didn't you just do it for me?
Because a merge operation is not guaranteed to produce correct output (automatic merges can use bad heuristics for how to deal with conflicts, manual merges can suffer from human error). Usually, what you will do is the following:
Merge.
Build.
Test.
If the test failed, fix the issue, go back to 2.
Commit.
Mercurial does not suggests otherwise, it 's just reminder: "All merge-related changes stored only on Working Dir, commit results into repository for permanent storing" and doesn't prohibit you to make some additional changes in code before commit.
But separation of tasks (merge and not-related to merge changes - i.e changes not initiated by merge-conflicts) into separate changesets is good idea anyway
Let's say I write an atomic change of code. I also write some tests to make sure the change works and keeps working.
I think I should commit the code change together with the tests.
PRO:
This makes sure (as far as possible) that every changeset of the branch results in running code and passing tests.
It documents that these tests "belong to" the code change that I did.
CON:
I may want to backout the change without backing out the tests some time in the future
What reasons more are there for doing it one way or the other?
Has either strategy ever bitten you? How exactly?
Somewhat related: Should change to code be committed separately from corresonding change to test suite?
My only rule is to make sure that code builds prior to checking in.
Yes, ideally you want to check in atomic bits of code. However, how do you define atomic? And then what happens if, later, you have to change one of the bits? Your changes are no longer in one commit.
I think I should commit the code change together with the tests.
I never do, but I would, if I used a non-branching SCM.
In branching SCMs (I've worked with mercurial and git) it's a non-issue.
I use a different branch every time I start working or something; I many times have local branch commits that just commit outstanding changes (that don't even compile) when I move to something else for a while, or when I just need a backup point before I start a major code change). I know that most of those intermediary commits will never be checked out again, when I create them. They don't affect anything though and are really useful when needed.
I only merge branches back when I have code that compiles and tests that run successfully on it.
Whenever I commit, I want to save in a file the revision number of the changeset that I'm creating. I also want that file to be added to the same changeset.
Note that the revision number of the parent of the working directory is not what I want because the changeset being created will have a higher revision number. Usually it's just the parent revision number + 1, but if someone committed since the time I checked out my working directory, it may be higher.
UPDATE:
It's obviously very strange that I'd be interested in this information, since as the comments below say, it's repo-specific and won't match what others see. However, I am the only developer, using a single repository. I find the repo revision numbers super convenient to keep track of what code was used to generated various research results. I can see how it's not great, but it works in this specific scenario.
Obviously, I could use the hash, but that's harder to remember and use in a conversation. If I did want to use the hash, my question would still remain: how to get the hash of the changeset that's being committed.
Related:
mercurial - I want to add some custom code to be run after commit seems to be unable to achieve the desired outcome.
This article is clearly relevant, but unless I miss something, it relies on the fact that nobody committed to the same repository since the last checkout by the current user.
I'm under Windows 7, TortoiseHG, latest version.
You can probably just put this in there:
TIP=$(hg id --num --rev tip)
NEXT=$(($TIP + 1))
but please do keep in mind that those numbers are almost entirely meaningless. When someone else clones that repository the revision numbers can change. Only the nodeids have any meaning outside the repository in which you looked them up.