I want to search for a filename across all my commits/branches and find out which commits/branches contain that filename. I don't know which subdirectory/subdirectories of the repo the file would be in.
I've tried hg grep <filename>, but that only seems to show files containing "filename".
I've also looked at Mercurial - determine where file was removed?, but that really help me if a file was created on a different branch. The person asking that question suggested hg log myfile -v, which seems like it could work, but doesn't. I know that somewhere in my repo the file exists because I get something back when I do find .hg | grep <filename>, but that doesn't tell me (at least not clearly) which commits/branches.
You have to read hg help patterns and maybe hg help filesets in order to write correct pattern for the file (most probably you'll be happy with just pattern)
If file exist now in working directory (i.e. was added and not removed later), you'll find it with hg file <PATTERN> and will determine full path by output, see above (pattern used)
>hg file **/test-extra.t
tests\test-extra.t
and call hg log with full filename
In any case (hg file returned 0 for removed file or file still in WD) you can call hg log <FILESET> and get history too. Log for existing will be too long, will show deleted unique filename sample
>hg log set:**/dulwich/tests/__init__.py -Tcompact
223 0b6c08800d16 2009-07-23 08:48 +0100 a
delete the dulwich fork we have
2 c43c02cc803a 2009-04-22 16:59 -0700 schacon
added dulwich library and got the script to call it for clone
If your set will be too wide and (may) include files with the same name in different folders, you have to verify filenames by calling log with more details about files, f.e. with -Tstatus
hg log 'glob:**/<filename>` -Tstatus
seems to do the job. It doesn't give me the commits containing <filename>, but it does give commits (and their branches) involving filename.
Credit to Lazy Badger's answer for pointing me to this.
Related
I have several repositories that I am building a tool to interact with. I have not been able to find a way to grep a specific file in a specific revision that was unchanged in that revision.
The help for hg grep says that the -r option -r --rev REV [+] only search files changed within revision range. If I update the revision in question, I can grep appropriately, and I get the desired results. Because my file in question is unchanged in that revision, it will not get grepped. Does anyone know a way to do this?
My end goal is that I would like to ignore files that meet a certain pattern matching. I am not sure that using the --all option would be feasible, because I would have to parse the revisions that the pattern appeared and disappeared in.
Thanks in advance.
edit:
Actual problem I'm trying to solve:
There are several tagged revisions in a repository.
For each of those tagged revisions, I would like to extract a particular file (assume source/a.c or something like that) to a folder structure that others can access (a website for those outside of our group, whom we cannot give repository access to).
But, I would only like to extract the file if it does not contain a particular pattern. This is why I would like to check the file at a specific revision, even if it has been unchanged.
Right, hg grep indeed does not analyse the file contents at a particular revision but only when the file actually changes. Thus I suggest a slightly different way:
Get the revisions to check as a nice list:
hg log -r"tag()" --template="{rev}\n"
Using it this way (instead of tags) allows to also look at revisions which are not tagged. If it's really only tags, you might resort to the hg tags command directly: `hg tags --template="{tag}\n". It would make the $i in the small script below a nice tag name instead of a revision :)
You can use this list to get the file FILENAME at those respective revisions and then you need some small script which actually checks that file for the content in question:
for i in $(hg log -r"tag()" --template="{rev}\n"); do
if hg cat FILENAME -r$i 2>/dev/null | grep PATTERN > /dev/null; then
hg cat FILENAME -r$i > path/to/whereever/FILENAME.$i
fi
done
From one source file I made a copy using hg copy.
Now I'm going to Change some stuff in the second file (the copy) and I want to be able to merge the future changes of the original file into the second file.
Can this be done using hg merge? Right now when I try to do something like
hg merge NewFile.html -r 130:f24199b5b945
using the most current changeset of the original file, I get an error: abort: please specify just one revision.
No, the two files are separate after that, and except for one file originating from the other, they do not share any history after that.
You will either have to duplicate your modifications in the other file, or you need to find another way to do this.
Git has the cat-file command to inspect internal files, e.g. git cat-file blob 557db03 will show the contents of the object whose hash starts with 557db03.
Are there similar tools for mercurial that allow me to look at all the different data files that merfcurial uses internally?
Try hg --debug help and you can see the list of all the debug commands:
debugancestor:
find the ancestor revision of two revisions in a given index
debugbuilddag:
builds a repo with a given DAG from scratch in the current empty repo
debugbundle:
lists the contents of a bundle
debugcheckstate:
validate the correctness of the current dirstate
debugcommands:
list all available commands and options
debugcomplete:
returns the completion list associated with the given command
debugdag:
format the changelog or an index DAG as a concise textual description
debugdata:
dump the contents of a data file revision
debugdate:
parse and display a date
debugdiscovery:
runs the changeset discovery protocol in isolation
debugfileset:
parse and apply a fileset specification
debugfsinfo:
show information detected about current filesystem
debuggetbundle:
retrieves a bundle from a repo
debugignore:
display the combined ignore pattern
debugindex:
dump the contents of an index file
debugindexdot:
dump an index DAG as a graphviz dot file
debuginstall:
test Mercurial installation
debugknown:
test whether node ids are known to a repo
debugpushkey:
access the pushkey key/value protocol
debugrebuildstate:
rebuild the dirstate as it would look like for the given revision
debugrename:
dump rename information
debugrevlog:
show data and statistics about a revlog
debugrevspec:
parse and apply a revision specification
debugsetparents:
manually set the parents of the current working directory
debugstate:
show the contents of the current dirstate
debugsub:
(no help text available)
debugwalk:
show how files match on given patterns
debugwireargs:
(no help text available)
There are a lot of them, and they pretty much expose everything.
The closest commands would be:
hg cat -r rev aFile
hg cat: Print the specified files as they were at the given revision
This is not completely the same than git cat-file though, as the latter can also list SHA1, type, and size for a list of objects.
In that second case, hg manifest might be more appropriate.
I am trying to extract a folder (call it Project1) from an existing Mercurial Repo (call in MainRepo) using the Convert extension for Mercurial to Mercurial conversion. I have followed the methods described by Mercurial developers (and elsewhere on the web) under Windows XP:
C:\MainRepo>echo include Project1 > ~myfilemap
C:\MainRepo>echo rename Project1 . >> ~myfilemap
C:\MainRepo>hg convert --filemap ~myfilemap . C:\Project1Repo
C:\MainRepo>cd \Project1Repo
C:\Project1Repo>hg update
This creates the new repo (Project1Repo) with the Mercurial folder/files in place.
But it does not:
1) Carry across the History relating to the changes made for the Project in folder Project1. (Only the very first history entry for MainRepo and a Convert item are present).
2) Copy across all the source code files from the MainRepo\Project1 to Project1Repo.
I have seen the other similar questions and answers in stackoverflow but these do not appear to help (I have followed methods discussed in them):
Can I clone part of a Mercurial repository?
So the question is: How do I extract a sub-folder from MainRepo with only the sub folder history intact and complete to a new Repo and transfer the source files at the same time? (though I guess a straight copy will do the last). It's keeping the history that is important - In this case I can make this after a date or Changeset number.
Any help much appreciated as I'm relatively new to this
Thanks
The workflow you listed is correct. That is the way the convert extension is intended to work.
Your question states that the repo output by hg convert is actually empty (except for "the very first history entry for MainRepo and a Convert item"). This would indicate that convert was not able to find the path specified in your filemap.
Are you certain that the path given your include statement is correct?
The directory name given in your include statement must be the full path from your repository root. For example, your include statement:
include Project1
requires that the path to Project1 actually be:
C:\MainRepo\Project1
If Project1 is actually located somewhere else in MainRepo, you will end up with an empty repo after the conversion.
ok, when I was young, I put severial big files(like resource file, dll, etc..) in my mercurial repos. and I found the size of it is so big that I cannot easily push it into bitbucket,
any way to delete this files history EASILY?
I put all those files in /res and /dll path.
edit:
this is a solution, but it will delete part of the history, so maybe there is a better solution.
Mercurial Remove History
Your best bet is to use the convert extension, but warning you'll end up with a totally different repo. Every hash will be different and every person who cloned will need to delete their clone and re-clone.
That said, here's what you do:
Create a filemap file named filemap.txt containing:
exclude res
exclude dll
and then run this command:
hg convert --filemap filemap.txt your-source-repository your-destination-repository
For example:
hg convert --filemap filemap.txt /home/you/repos/bloatedrepo /home/you/repos/slenderrepo
That gets you a whole new repo that has all of your history except the history of any files in /res and /dll, but again it will be a new, unrelated repo as far as mercurial (and bitbucket) are concerned.