I am new to Mercurial, having used Git previously. I believe I am using Mercurial incorrectly.
To ignore, e.g. .DS_Store, with git, one would add .DS_Store to .gitignore. Then if one did git add -A, git still wouldn't track .DS_Store.
However, after adding .DS_Store to .hgignore, and then doing hg forget .DS_Store, hg add adds .DS_Store back, as can be confirmed via hg status. The same problem even happens after doing hg forget "set:hgignore()".
Question: What am I doing wrong?
This was a stupid question, since I just figured out the answer. Since I couldn't find the answer on Google or StackOverflow, I will post it here. If this question is a duplicate, please just delete it (without insulting me).
Anyway the answer is that I hadn't done hg commit yet. After doing hg forget .DS_Store and then a hg commit, hg add no longer re-adds .DS_Store, since it is located in .hgignore.
Related
I am using Mercurial Shelve extension to shelve changes from command line. It works nice except when the changes that i like to shelve contain new added files(a) in working directory. Basically, it shelves everything except the new added files. I checked this by looking at the .hg/shelve stored changes.
How to shelve new added files (a status)?
This response is overdue, but you can use the following command to shelve all files (track / untrack) :
hg shelve -A
or
hg shelve --addremove
About this command, documentation says :
mark new/missing files as added/removed before shelving
You must pay attention by using this feature because after unshelving, your old untracked files are track.
These file are already to be commited in the last commit if no files are specified in hg commit command. You should use hg forget if you want untracked them again.
I assume you are talking about currently untracked files? You need to add the first.
So just do hg add for your new files and then hg shelve will also shelve them.
Thank you Tom. I am using Mac, so it didn't really worked. What did work was another mercurial extension 'hgattic' about which you can read more in my blog
http://margotskapacs.com/2012/10/shelving-uncommitted-changes-in-mercurial/
(see section 'Bug – Added Files Unable Shelve')
If the command line isn't absolutely necessary:
then just type (on Linux)
thg shelve
This allows you to easily shelve added (but not yet committed) files.
As a mostly Git user, I find Atlassian SourceTree the easiest way to deal with the odd Mercurial repo that I have to work with. It has shelving built in. The price is right, too (free).
Disclaimer: I work for Atlassian
If you see here, you'll see that I have:
CheeryTomatoe.Examples <--- I want to remove this.
CherryTomatoe
CherryTomatoe.Examples
https://bitbucket.org/sergiotapia/cherrytomato
How can I completely remove this from my repository? What command can I run?
In theory, you can edit the history (provided nobody has yet cloned your public repo), as described in:
Mercurial FAQ 4.14 and 4.15
Mercurial Wiki "Editing the History"
However, that is not the best way to work with Mercurial, so what you did in your third commit is better: hg rename:
See Hg book: "renaming file":
When you use the hg rename command, Mercurial makes a copy of each source file, then deletes it and marks the file as removed.
It is your initial commit.
Delete the repository and start over.
I want to completely delete a Mercurial commit as if it was never entered in the repository and move back to my prior commit.
Is this possible?
If it was your last commit and you haven't pushed it anywhere, you can do that with rollback. Otherwise, no. Not really. Time to change your passwords.
Edit: It has been pointed out that you can clone from an older revision and merge in the changes you want to keep. That's also true, unless you have pushed it to a repo you don't control. Once you push, your data is very likely to be very hard to get back.
You can try to remove mq info about your commit.
For this you need to go File->Settings->Extensions.
There check mq and restart gui.
After that just right click on unneeded commit and
ModifyHistory->Strip
To edit the history I would use the Histedit Extension extension.
hg histedit 45:c3a3a271d11c
However keep in mind this only makes sense in a situation where you have not yet pushed the commits to the public repository, you own the public repository and/or you can account for all the clones out there. If you receive the following error:
abort: can't rebase immutable changeset 43ab8134e7af
It means that Mecurial thinks this is a public changeset (see phases) that has already been pushed - you can force it to be a draft again doing:
hg phase -f -d 45:c3a3a271d11c
I encounter this fairly often. I make a commit and then pull to push. But then there is something incoming that makes my newly made commit unnecessary. A plain hg rollback isn't enough because it only undoes the pull...
This is the thing to do:
hg strip <rev>
Things are painless when you don't push your changesets anywhere.
If it's more than one commit and/or you already pushed it somewhere else, you can clone your repository and specify the last changeset that should be cloned.
See my answer here how to do this:
Mercurial: Fix a borked history
If you only committed locally and didn't push, you can just create a clone locally (as described in my link) and you're done.
If you already pushed to some remote repository, you would have to replace that with your clone.
Of course it depends if you are able (or allowed) to do this.
You can use "hg backout" to do a reverse merge basically. All options are discussed in the freely available book "Mercurial: The Definitive Guide":
http://hgbook.red-bean.com/read/finding-and-fixing-mistakes.html
If using tortoise you can use modify history > strip...
Yes. Unless I am mistaken, as of v2.3 (rel. 2012/08/01) you can use the HisteditExtension with a drop command to drop a commit, along with strip or backout to remove changes.
A simple Google search on the feature: https://www.google.com/webhp#q=histedit+drop
In 2022 I do use evolve extension. It is one of the best extensions for this purpose.
To prune unwanted changeset, if you for example did a quick hack to get the code working:
$ echo 'debug hack' >> file1.c
$ hg commit -m 'debug hack'
Now you have a proper patch you can do hg prune .:
$ hg prune .
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
working directory is now at 2a39221aaebb
1 changesets pruned
If you push the change to the remote repository you will find only obsolescence markers:
$ hg push
searching for changes
no changes found
remote: 1 new obsolescence markers
To check the changes to your local repo you can pull from the remote one:
$ hg pull
pulling from ssh://userid#server/repo
searching for changes
no changes found
When cloning a repository with mercurial you can pass the -U/--noupdate flag to create a clone with no working copy. Can I remove the working copy if I forget to pass this flag at clone time? And if so, how?
This is conceptually similar to this git question, but for mercurial.
Documentation at Mercurial wiki says following about bare repositories:
"Although this is a minor issue, Mercurial can obviously handle a
bare repository; that is, a repository without a working copy. In Git
you need a configuration option for that, whereas in Hg you only need
to check out the null revision, like this:"
hg update null
The null revision is similar to the empty state you have when you have just done hg init. It is the parent of revision 0 (and the second parent of all non-merge revisions) and by updating back to it you again get an empty working copy.
The link may look ironic:
https://www.mercurial-scm.org/wiki/GitConcepts
rm -rf *
This removes all "visible" files (under *nix). Since the Mercurial repository is stored in the "hidden" file .hg, it won't be touched. Unfortunately, neither will any hidden files of your own, such as .hgignore.
To restore the working copy, I'm sure there's an hg update flag that works, but this will as well:
hg revert --all
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.