Patch the move of an image on Mercurial - mercurial

In my project, I've an PNG file and I want to move it on another directory.
I've done
mv f.png foo/f.png
hg addremove
hg diff > patch.diff
But I get this in my patch :
diff -r f0a573ab03b1 Bundles/rc/f.png
Binary file Bundles/rc/f.png has changed
diff -r f0a573ab03b1 Bundles/media/rc/f.png
Binary file Bundles/media/rc/f.png has changed
So when I apply it, it doesn't work... Is there someone who can help me ?

First of all, you should use hg mv instead of mv. That way, Mercurial knows that you renamed the file. When you use addremove, you pollute your history with a file delete and then a file add.
The next problem is the patch. The patch format doesn't support binary files. There is no way to create a patch for images.
Try hg export --git instead of hg diff. See this question: Why are my dlls not included in my exported patches?
hg export and hg import know how to handle all kinds of corner cases (like preserving your commit messages).

Related

Refetching a locally deleted file from Mercurial

I deleted one of the files that was in my repository locally (just at the file system level, not using hg remove). I now want to get that file back from the repository to my local directory. When I do hg status, it knows that the file is locally deleted, but there are no changes to be commited which is what I would expect.
$ hg revert your-file
will restore it.
Edit: see http://www.selenic.com/mercurial/hg.1.html#revert
The following will revert all deleted files in the current repo:
hg status -nd0|xargs -0 hg revert
cd to your dir and do "hg revert ." to restore all files or used any appropriate mask like *.java, etc.. This will effect only the current dir (not sure about subdirs).

Mercurial, how to remove file from repository?

I push in our repository more big video files, my fault, I did not notice them and forgot to add the folder with the video to ignore file. Now my friends can not upgrade because a shortage of memory (abort: out of memory). How do I remove a video from the master repository? I tried to just delete the folder with the video in /home/hg/project/.hg/ But then do not start updating with an error. Help me pliz and sorry for my english/
See the Mercurial FAQ:
4.14. I committed a change containing nuclear launch codes, how do I delete it permanently?
4.15. I committed a large binary file/files, how do I delete them permanently?
There are some options described on the Editing History page as well.
You:
$ hg rm video.ogv
$ hg ci -m "removed video.ogv"
Other:
$ hg pull your-repository
$ hg update
The HG FAQ merely gives a few vague pointers. Here's how to do it:
Add to your .hgrc:
[extensions]
hgext.convert=
[convert]
hg.saverev=false
Create a filemap of what files you want to remove (myfilemap)
exclude "relative/path/to/file.mp4"
Use hg convert to make a new repo
hg convert --filemap myfilemap myrepo myrepo.new
Now you have the new repo without the excluded files.

Would like to do a mercurial clone with filter of patterns in hgignore

Over time a number of the developers have committed files that were then added to the .hgignore. From what I hear there is no way to remove items from the history of mercurial, which is ok. But I also heard that there is a way to do a clone, I think using the convert plugin, to clone/export a repo while specifying which files to not include in the conversion.
I can't help but think that someone out there has a script that does this export/filter/convert using the patterns from the .hgignore file.
Has anyone created such a beast?
You could create a filemap from .hgignore doing something like this:
hg clone -U yourrepo temprepo # create a temp repo with no files in working dir
cd tmprepo
hg revert --all # put files in working dir
hg forget ** # un-add the files
hg status --ignored --no-status | sed 's/^/exclude /' > ../filemap
that will get you a filemap you can pass into hg convert that removes all the added files that would be ignored given your .hgignore.
Do understand though, that running convert creates a whole new repo that is unrelated to your previous repo. All existing clones will be unusable with the new one. It's not normally worth it.
hg convert is indeed the thing you want to use.
You will want to create a file map (just a text file) which will list all of the things you either want to include, exclude, or rename:
include subfolder
exclude subfolder/supersub
etc...
Read the following for a more concrete example:
https://www.mercurial-scm.org/wiki/ConvertExtension#A--filemap
Once you have created this file you will just use the following command:
$ hg convert --filemap my_file_map /path/to/source/repo /path/to/dest/repo
The source repo will not be modified and a dest repo will be created. I don't want to just copy verbatim what the documentation already says so here is the link:
How to keep just a subdirectory (or run on the mercurial repo):
https://www.mercurial-scm.org/wiki/ConvertExtension#Converting_from_Mercurial

Accidentally Working on the Wrong Named Branch in Mercurial

I have been making some changes to my working directory, and noticed that I have accidentally been working on the wrong branch. I have not committed anything yet, and I would like my next commit to go against another branch. What is the best way to do this?
The Shelve extension can give you grief, and this can be done entirely with Mercurial commands. Krtek almost had it but he used export instead of diff. Try this:
hg diff --git > ~/saved-work.patch
hg update --clean desiredbranch
hg import --no-commit ~/saved-work.patch
You should be able to just hg up otherbranch. It is important that you do not use the --clean option to hg up, either directly or via an alias as that will discard your uncommitted changes.
Another option is to use one of the extensions that provides hg shelve. The process would then be:
$ hg shelve --all
$ hg up otherbranch
$ hg unshelve
That will create a patch of your changes within the .hg directory, returning your working directory to a clean state, switch to the 'otherbranch', and then apply the saved patch.
I don't know if it is the best solution, but you can follow these steps :
1° hg diff --git > modifications.patch
2° hg update -C the_right_branch
3° hg patch modifications.patch
Maybe it's better to copy modifications.patch somewhere safe, just in case.
edit: update with diff instead of export. Thanks to the commenters.

How can I recover a removed file in Mercurial (if at all)?

Accidentally, by using a GUI as opposed to CLI, I removed every file in a Mercurial project.
I recovered with Revert ok and lost some work, which as I have time machine I could easily get back. But is there a way of un-remove/undelete such files? Trawled through the manual and googled but cannot see anything. Any plugins?
I am probably answering my own question here but the files were gone from the directory and were not in the trash to recover so I am assuming Remove is irrevocable?
p.s. I know that hg forget or hg remove -Af will remove without deleting from the directory but my question has to do with the error I made as opposed to cool thinking the action through.
First, use hg grep to find the deleted file you wish to recover. The output of this command will show you the last revision for which the file was present, and the path to the deleted file.
Second, run hg revert -r <revision number> <path to deleted file>
The deleted file will now be in your working copy, ready to be committed back into head.
Quote from comment:
I set up a repository, committed all, Removed and then committed again
If this is the case then you just need to update the working directory to the previous revision:
$ hg update -C -r-2
Note the negative revision number. If the files you deleted aren't in the previous revision, you can find them by using:
$ hg log -v
For Mercurial 1.6 and above
If you know the name of the delete file you can find its revision easily with:
hg log -r "removes('NAME.c')"
This will give you the revision in witch a file called NAME.c (in the root) is deleted.
Then you can revert the file to the previous revision with (like other answers):
hg revert -r <revision number> <path to deleted file>
You can use a file name pattern instead to adapt to what you know, for example you can use **/NAME.c to search in all directories. You can read about it in File Name Patters. And use this link to know about the new revset specifications.
Well this worked for me.
hg revert -r revision pathToTheFile
An addition to the accepted answer - this is faster if you want to undo all removals in a commit. I deleted a large folder with a few hundred files in it and did hg addremove, which was not at all my intent, so had to undo all of those deletes.
Using Find deleted files in Mercurial repository history, quickly? + xargs + tr, revert all revision -3 removals to the version from revision -4:
hg log -r -3 --template "{rev}: {file_dels}\n" | tr ' ' '\n' | xargs hg revert -r -4
Note that this will fail if any of your files have spaces in the name; http://hgbook.red-bean.com/read/customizing-the-output-of-mercurial.html doesn't appear to have any templates where {file_dels} is split by \n at the moment.
You can undo the last commit on a repo with hg rollback. There's only one level of rollback available, so if you did the remove with more than one commit, this won't completely undo your change. This only works on your local repository, so if you've pushed you won't be able to undo it in the remote repo.
You can remove committed revisions using the hg strip command, which is provided by the mq (Mercurial Queues) extension. This should give you back your files.
Make a backup before trying that out, because it will alter Mercurial's database of changesets.
The following worked for me.
hg revert -r <Revision Number> <File Name>
(Optional, to revert all files)
hg revert -r <Revision Number> --all
The below method is straightforward and so stupid that it cannot go wrong.
If you have deleted or renamed multiple files, it will be ok.
hg clone mydirectory mydirectory1
and now you start mc (or Far Manager) and compare what it was vs what it has become.
when it's done, just delete mydirectory1.