Add to rename tracking in mercurial after commit - mercurial

Simple scenario:
I have renamed a file. The changes are committed and pushed. I didn't have used hg rename.
How can I tell mercurial that an add/remove in a commit was a rename? Is there something like the svn .mergeinfo that I can edit manually?
(It is not the last commit, so solution with amending to a commit are nice, but won't help me.)

You could try the following:
hg update to the commit before the file was renamed.
Do an hg rename to the new filename, and ensure the contents of the file are the same as on the main branch.
hg commit.
hg update to the main branch.
hg merge --tool internal:other the new branch into the main branch.
From the merged commit onwards Mercurial should know about the rename.

Related

Purging old directories and files from a remote hg repo

I initially committed my project to a hg repo with the following structure:
myapp/
fizz/
buzz.txt
foobar.cfg
whistlefeather/
vroom-vroom-party-starter.xml
I did so using the following commands:
hg add
hg commit -m "Initial commit."
hg push
I then changed my directory structure locally to look like this:
myapp/
buzz/
fizz.txt
config.foobar
whistlefeather/
vroom-vroom-party-starter.xml
I then ran the same following commands:
hg add
hg commit -m "Changing some things."
hg push
When I go to the remote repo, I see it has the following structure (?!?):
myapp/
fizz/
buzz.txt
buzz/
fizz.txt
foobar.cfg
config.foobar
whistlefeather/
vroom-vroom-party-starter.xml
What commands can I run to push/purge the old directories/files from the remote repo (and so that it reflect the directory struture on my local machine)?
The hg add command you issued prior to your second commit did not actually remove files from under version control, but only added new ones. Now your repository is actually a melange of old and new files.
To add new files and remove missing ones, use hg addremove command or hg commit -A
It's actually simple to remember:
hg add adds files to the repo
hg remove removes files
hg move moves or renames files
hg addremove looks at current working dir and adds and removes files from the repo such that only the files still being present will continue to be tracked.
Each of these operation can be done in any sequence. And only a commit will actually create a changeset

Why won't my hg work?

I'm trying to do hg pull from another computer but hg is not giving me the latest version. It might be that I'm on the wrong branch. What can I do to resolve the error? When I make hg diff there is no diff but I know that is is not the latest version.
hg diff will never show you any output irrespective of the currently changeset, assuming that you have no uncommitted changes.
hg pull does not update your working dir to any revision - it just pulls the changesets into your mercurial repository without updating your currently checked our revision
You'll need to update your working copy to whatever revision you want. If there is only one branch involved, a simple hg update will do the trick. If there are several branches involved and the new changesets are on another branch, you'll need to tell mercurial explicitly that you're also ok with a branch change during update: hg update --check. Alternatively you can also try hg update --rev tip after the pull. If there's no branch switch involved and necessary, you can also tell pull to update immediately after a successful pull (but it won't switch branches): hg pull --update

ignore non-existant files when merging in Mercurial

I am working with a repository with stable and experimental branches. Sometimes I add a file on the experimental branch that is not yet ready for the stable branch. When I merge, I want to merge the changes in the files that are common to both branches, but ignore the files that don't exist on one of the branches.
Here's a simple example:
hg init
hg branch stable
(create file A)
hg add A
hg commit -m "Added A"
hg branch exp
(create file B)
hg add B
hg commit -m "Added B, which is really experimental"
(modify file A)
hg commit -m "Some changes to A"
hg update stable
hg merge exp
However I change the merge tool configuration, Mercurial always seems to take B along with the merge. Since it doesn't exist on the stable branch, it's never a conflict.
I could do the following:
hg update stable
hg merge exp
hg commit -m "Merged"
hg revert -r 0 B
but that requires me to know which files need reverting.
Any thoughts on the simplest way to make the merge ignore files that don't exist on one branch, and preferably do it automatically?
You cannot ask Mercurial to do what you want.
You do not merge individual files, you merge the entire branch, which means that all the files that are part of the branch becomes part of the merge. This is how Mercurial is designed and how it operates.
Now, you could revert/forget/delete the files you don't want before you commit, but then you're just setting yourself up for disaster later.
I recommend you separate things you want to keep from things you don't know if you want to keep so that you can merge one branch and let the other be separate for now.

Using Mercurial, do we need to "hg merge -r 6880" if there is an extra branch?

For Mercurial, right now there is default branch and newfeature branch... is it true that if I am on
the newfeature branch, and do an hg pull and hg update, it will always ask me to merge? (if there are changesets that I pulled)
Also, it seems that I cannot just do hg merge? I need to use hg heads and then look at what the newfeature branch's head is (say it is revision 6880),
then I need to hg merge -r 6880? Because otherwise, will Mercurial merge the newfeature branch with the default branch automatically? I cannot do hg merge -b newfeature, it seems, as there is no -b option for hg merge.
Is there an easier way other than using hg heads to look for the revision to merge? Isn't there a more automatic way?
You've got two questions there, let me take them one at a time (with a little paraphrasing):
Q. When I hg pull and get a new head Mercurial suggest I hg merge. Do I have to?
A. No. Mercurial is just warning you you have more heads than than you did, and that if you don't like that arrangement you can merge to stop it. Named branches are heads, so you'll see that warning if pulling gets you a new head
Q. If I want to merge one named branch into another do I have to provide the revision number?
A. No. It's true that hg merge will only automatically select heads on the same named branch, but you can do hg merge -r newfeature and that merges in the changeset from the point of divergence up to the head on newfeature (6880 in your example) exactly the same as hg update -r 6880 would.
In either case, after committing that merge you'll have no heads on newfeature (the new, resulting head is on default because that was the branch name of your parent before you started the merge. However, just doing this after the merge:
hg update newfeature
...code....
hg commit
will create a new head on the newfeature branch, and you're right back as you were before the merge, except all of the changes that were on new feature are also available in default now.
If you pull a changeset or changesets from one branch into another branch that share the same root changeset. Mercurial will have multiple heads as you have so noticed. It will only suggest that you merge when you do an hg update on one of the branches.
You shouldn't have to specify which revision to merge to, assuming that you want to merge the tips of each of the branches. hg merge should suffice.
Your command structure should look as follow
hg pull -b 'branchYouWantToPullFrom`
hg update
hg merge
hg commit
hg merge works in your working copy, which is always connected to a specific branch.
You have to specify a branch name only if you want to merge your current branch with another branch: hg merge branch_name.
hg pull updates your repository with all remote changes. Then you have to update your working copy, that is connected to a specific branch. So, when you type hg update command, you update your working copy with all changes in your current branch.
If you want to switch to another branch you have to type hg update branch_name. You can type hg branch to know your current branch.
The only reason to merge with a specific revision is when you have three or more heads, a strange situation probably caused by some hg push -f (extremely bad practice). If you are in this situation, the right way to know which revisions you have to merge is hg heads. In a normal situation hg heads returns one head per branch, so you don't have to merge two heads of different branches if you don't want.
If you're working on a branch and someone has committed and pushed some changes on the same branch, you have to pull and merge before your push, simply with hg merge, no revision or branch.
I hope this will help you.

How to apply a collapsed revisions patch to trunk in Mercurial?

I am looking for best practices to do the following:
When I need to implement a feature or fix a bug, I am creating new Mercurial repository from the main one (a trunk).
Then, within some days, or weeks, I am implementing the task in newly created repository, making commits and periodically merging with trunk. After the code in new repository will pass all code reviews, I should provide a repository with all changes collapsed into single revision.
My common way to do this (rdiff extension should be enabled):
hg clone ~/repos/trunk ~/repos/new-collapsed
cd ~/repos/new-collapsed
hg diff ~/repos/new > new.diff
patch -p1 < new.diff
hg commit
This works almost well except when there are binary files present in the changes from ~/repos/new. Another way could be:
hg clone ~/repos/trunk ~/repos/new-collapsed
cd ~/repos/new-collapsed
hg pull ~/repos/new
hg update
hg rollback
then resolve possible conflicts and manually commit the changes
Both ways look for me somewhat ugly and non-native, so I am looking how this operation could be simplified. I've played with rebase extension, but seems its hg rebase --collapse command does not work with workflow described above.
Any ideas are welcome.
Sounds like a good case for mercurial queues.
I do something similar with the histedit extension.
My workflow is something like:
clone a central repo
commit incremental changes to local repo
clone my local repo to make collapsed repo
hg histedit and select/discard/fold the revisions as needed
hg push the collapsed repo to central repo
pull central repo to local or refresh local from scratch
I ensure that my local repo never gets pushed to the central repo by adding an invalid default-push path to the .hg/hgrc file in the local repo root directory.
Solved: Just add
[diff]
git = True
to your hgrc file, and then use my first solution with rdiff extension, replacing patch with hg import:
hg clone ~/repos/trunk ~/repos/new-collapsed
cd ~/repos/new-collapsed
hg diff ~/repos/new > new.diff
hg import new.diff
hg commit