Mercurial pushing update to previous revision - mercurial

I ran hg update -r REVISION to revert a branch to a previous revision, but when I try to push this to a remote repository it says "no changes found". How can I accomplish this?

To revert the files to a previous revision you can use
hg revert -r REVISION
This will change your working directory files to what they were at that revison. Then you
will need to commit these changes before pushing.
hg update -r REVISION changes the working directory's parent to be that revision as well as changes the contents of the working directory to that revision. This is not what you want here.

hg update only affects the state of your working directory, not the repository itself. If you want to "undo" the effects of one or more previous revisions, you will need to change the repository by committing a new changeset that reflects those changes. You could do it manually but hg's builtin backout command makes this easy to do. See a brief description here. There is a detailed explanation of backout here.

Related

What is the name for the commit/head that corresponds to the local checked-out state?

There is a commit in my hg repository with hash 123abc. This is the last commit I made in the repo. When I run hg diff --from 123abc, I see no output. When I run hg log --graph, I see an # next to 123abc.
In Git this commit would be called "HEAD". I'm not sure what it's called in Mercurial. It is not the "tip", because I pulled other changes after the last time I committed (and hg log -r tip shows commit 456def).
What is this commit/head called?
Mercurial calls this the "parent" or the "parent revision of the working directory", and you can see it by running hg parent, hg id, or hg summary.
You can refer to it as . with the hg log command:
hg log -r . # show the commit message for the parent
If 123abc has no children, then it is a "head".
A head is a changeset with no child changesets. The tip is the most
recently changed head. Other heads are recent pulls into a repository
that have not yet been merged.
(https://www.mercurial-scm.org/wiki/Head)
Regardless whether the current working directory derives from a head or a non-head, I would refer to the commit that precedes it as the "working directory parent" changeset or commit. (That may just be the term my team uses - not sure it is "official".)
The parent may be visible in a GUI tool (like Tortoise) or you can get it using hg parent.
Based on the statements about 456def I'm a little confused whether it has no children, or not? (Maybe update the question to clarify / add more detail)

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

hg strip vs hg backout and hg revert

What is the difference between the mercurial commands,
hg strip
hg backout
hg revert
All these commands basically are used to revert/undo the effects of an earlier changeset.
hg strip removes the changeset and all its descendants from the repository. It will be as if the changes never existed. Be careful when using this on public changesets as it will not remove it from any other repository and you'll get them back next time you pull.
hg backout creates a new changeset to reverse the effect of an earlier changeset. The old changeset will still remain in the repository but so will a new changeset to remove the changes.
hg revert with a revision updates the working copy to the specified revision. If you then commit that working copy it will have the effect of reverting all changes since.
Other answers with more info on revert and backout:
What is the difference between hg revert and hg backout?.
Mercurial — revert back to old version and continue from there.
At certain moment of time I had to build Jenkins pipeline where POM files should be reverted each time the job starts. And the problem which I have faced is: how to revert all POM files reversively.
Since this answer is one of the first on google, I want to contribute my solution for people with same problem
hg revert */pom.xml

Mercurial `hg clone` but ignoring all subrepos?

Is there a way to clone a repo that comes with subrepos, but without having Mercurial pull all the subrepos?
It appears that while hg clone -U can be used to obtain an empty clone of a repo, there's nothing that would convince hg update to avoid starting off by pulling all of the subrepos.
I should point out that it is crucial to retain the ability to easily sync to the head revision after creating such a clone.
This should do what you want:
REM Take a new clone, but do not update working directory
hg clone --noupdate %REPO_PATH% %DESTINATION%
REM Update working directory but exclude the certain subprojects
hg revert --all --rev %BRANCH% --exclude %SUBREPO_PATH_1% --exclude %SUBREPO_PATH_2%
This answer may add more than the question required, but provides some valuable notes on working with Mercurial when you can't update do to a bad subrepository path or revision.
Step 1: Clone the repository without any updates
hg clone --noupdate source_repository destination_repository
Step 2: Use revert to get the right files
hg revert --all --rev revision_number --exclude subrepo_1 --exclude subrepo_2 ...
At this point, you have a new changeset; you may need to make sure the parent revision is correct. When I did this, my new changeset's parent was changeset 0. To fix this I had to set the parent changeset AND switch branches (since my changeset was on a different branch).
Step 3: Change the parent of the current changes
hg debugsetparents revision_number
hg branch branch_name
That should do it.
Found a hacky way. It still requires all subrepos to be checked out once, but afterwards they can be deleted.
Clone the whole lot, including subrepos. No way around this.
Delete subrepos
hg remove .hgsub
I tried to convince Mercurial to hg remove .hgsub before the subrepos are cloned, but the best I got is not removing .hgsub: file is untracked.
If you have a subrepo, a working directory must include some version of that subrepo. That version may be a fixed older revision if specified, or the tip if not.
You cannot update your repo without getting the subrepos; if you had a complete working dir without them, you shouldn't be using subrepos - use truly external repos instead.
If your subrepos are pegged against a certain remote version, then updates after the first will not trigger a subrepo update - they're already up-to-date. But for the initial creation of the working directory, you will have to do a remote pull.
You can trick Mercurial by munging the hgsubstate file. But really, your model and the conceptual model differ, so you're probably not a good match for subrepos if this is a concern.
edit: If you find yourself cloning and then updating to the tip many times, try using local branches or mq instead. That way you only have to do the initial clone once.

Throw away a bunch of commits in Mercurial

I comitted few times with mercurial and pushed my commits. Nobody else pulled them. How can I "throw away" these commits to restore my local and remote repo (both repo and working dir) to a specified commit?
Thank you.
The quickest way is to just clone your local repo to the last 'good' revision, and discard the old one.
This only works if those revisions are the last n in the history.
You can copy the [paths] section of the old repo's .hg/hgrc file to the new one if you want to continue pushing to a third 'master' repo.
You can use $hg revert to revert your code to a previous revision.
If you type $hg help revert into your command line you'll get a list of ways you can revert.
These options include:
--all
--date
--rev
--rev will likely be the one you want since it reverts back to a specific revision.
If the revision you want to revert to is the same as another repo or the same as the current tip, the easiest way then could be to just re-clone that repo.