Empty commit with Mercurial - mercurial

Is it possible to do a commit without any changes in the current repository with Mercurial, like git's --allow-empty?

Trick I read somewhere:
touch tmp
hg add tmp
hg commit -m "tmp"
hg rm tmp
hg commit --amend -m "Real commit message"
Unfortunately it doesn't survive rebasing (and maybe other operations).

The answer from #Thomas above is correct but doesn't fully explain how to modify the file content of a commit.
A simple method to use this feature to force an commit empty is as follows:
Add a new file (say, Dummy.txt) and commit.
hg forget Dummy.txt
hg commit --amend
This will remove Dummy.txt from the previous commit, leaving it empty.

With amend you can change the user, date, commit message and files content:
hg commit -m"new message" -d"$(date --rfc-2822)" -u"new user" --amend
These are probably all the reasons why you would want to commit an empty changeset.

Related

How to make a Mercurial commit with no files?

I'm looking for the Mercurial equivalent of git commit --allow-empty for testing purposes.
Can't be done. There doesn't have to be a change to a source file, but you have to have changes something, be it file permissions, branch name, tag, or something.
You say "for testing purposes". If that's the case I usually just use
echo another line >> README ; hg commit -m 'added another line'
I can hit up-arrow enter on that plenty fast.
I think the best solution I've found is:
touch foo
hg add foo
hg commit -m 'Empty commit'
hg rm foo
hg commit --amend
Works with MQ. Make a MQ changeset with some dummy change, then revert the change and refresh (hg qref) the patch. Voila.

Remove file from a commit in Mercurial

I have a commit onto which I have amended some files. Some of these files that were part of the amend I do not want in this commit. Is there a way in Mercurial to remove certain files from the commit without losing the changes I have made to them? Thank you.
Steps:
Made some changes
hg commit -m
Made some more changes (some of these file accidentally amended)
hg amend
Try out:
hg forget somefile.txt
hg commit --amend
If the file was new (i.e. you had used hg add).
If that file already existed try:
cp somefile.txt somefile.txt.bak
hg revert somefile.txt --rev .~1
hg commit --amend
Which is basically telling mercurial to revert the file (somefile.txt) back to the state it was one revision ago (--rev .~1).
Just make sure to back up the file you are reverting before entering the command so that you do not lose your changes. I was under the impression mercurial does this automatically for you, but after testing it quickly I'm not so sure.
hg uncommit somefile.txt does exactly this for me.
Like plain git reset, it removes the change from the commit but leaves the file contents unchanged, so now hg diff shows the change you just uncommitted.
The uncommit command claims to come from the uncommit extension, but may actually be coming from the evolve extension, I admit I'm not 100% sure!

hg merge says outstanding uncommitted changes; hg commit says nothing changed -- how to exit the loop?

The problem here is that hg' workflow apparently leads in a circle:
hg pull, get another head
hg merge, get warned of outstanding
uncommitted changes
hg commit -m "pre merge commit", get message
saying nothing changed
go to 2 hg status, see output like the
following:
! #foo.py#
? junk.out
? junk2.out
If foo.py is in your list of .hg-ignore'd files try specifying it explicity on the command line when you commit.
e.g.
hg commit -m "commit message" ./#foo.py
edit: looking more closely at your error: the file has been deleted (! in the status list), but hg hasn't tracked the deletion. You need to tell hg about the deletion using:
hg rm -A ./foo.py
The -A / --after means record the removal after it actually occured

Undoing last addremove in Mercurial?

I typed
$ hg addremove
but later realized that some of the files should not be part of the commit. What I should have done was to add these files to .hgignore and after that run addremove and commit.
Is there a way of fixing this?
If you have not commited yet just use hg forget fileToForget or use Tortoise to remove the files.
If you have committed and you don't mind the files to be part of history, just forget them and commit again.
If you don't want them to be part of your repository history, and if commiting them is the very last operation you've made, you can try to rollback (use hg rollback or go in the recovery menu in Tortoise). You will have to forget the file and then commit again
If you're dealing with too many files, you can try to automate the task by getting a list of all added files, forgetting them, modify you .hgignore and do the addremove again.
Example of the first step in powershell with no commit made
hg status --added --no-status | foreach-object {hg forget $_};
To undo an addremove you did not commit yet simply run:
$ hg revert --all

Mercurial Unstage Specific Files from Working Directory

I have an uncommitted changeset. I want to commit some of the changes, but not commit some of the files (like unstaging a file in git). Can this be done in mercurial?
Use the -X option to hg commit to exclude certain files. You can specify it more than once on the command line. For example,
hg commit -X path/to/unwanted/file -X path/to/another/file
You can pass a list of files to commit to hg commit, e.g. hg commit -m msg file1 file2 ....
Yep! You have two options.
Commit just some files.
If you provide file names as arguments to hg commit, only those files will be committed. So if I have the following hg status:
M foo.txt
M bar.txt
I can run hg commit foo.txt to commit just the changes to foo.txt and leave the changes in bar.txt for a later commit.
Use the record extension.
The Record extension gives Mercurial behavior to git's index, letting you commit just some patches of your changes (like git add --patch). See the docs for more info.