I find the output of hg status too verbose for untracked directories. Suppose I have an empty repository that's managed by both git and hg. So there would be two directories, .git and .hg.
The output of git status is:
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# .hg/
The output of hg status is:
? .git/HEAD
? .git/config
? .git/description
? .git/hooks/applypatch-msg.sample
? .git/hooks/commit-msg.sample
? .git/hooks/post-commit.sample
? .git/hooks/post-receive.sample
? .git/hooks/post-update.sample
? .git/hooks/pre-applypatch.sample
? .git/hooks/pre-commit.sample
? .git/hooks/pre-rebase.sample
? .git/hooks/prepare-commit-msg.sample
? .git/hooks/update.sample
? .git/info/exclude
Is there a way to reduce its output to something like the following line?
? .git/
This works for me :
hg status -q
Option -q/--quiet hides untracked (unknown and ignored) files unless explicitly requested with -u/--unknown or -i/--ignored.
You can just add in your .hgignore file
syntax:glob
.git
.gitattributes
.gitignore
To ignore .git entirely, and other git-related files.
If the goal is to only limit to a directory, you can still use .hgignore if you add an hidden file in that directory (after this answer):
syntax:regexp
^.git/(?!\.hidden).+$
Since Mercurial do not track directories at all, that will ignore all files within .git except the hidden one, effectively displaying only one line in the status.
You would also have the option -q/--quiet (to hg status), which hides untracked (unknown and ignored) files unless explicitly requested with -u/--unknown or -i/--ignored.
But that means .git would not even show up in that case.
But if the goal is to limit in general the output of hg status to only the directories and not their content for untracked files, then I believe this is not possible:
git track content of files and since no content is added, it only mentions the top directory has "having no content added"
mercurial tracks files (not directories), hence the comprehensive list (of files).
I understand the question is about how to reduce the output: I had similar need but did not want to untrack or ignore files. If you are using *NIX, you cloud use grep, and you just want to reduce the output as your question states, for example to get rid of these lines:
hg status | grep -v "^\?\s\.git"
Or for example not showing removed files
hg status | grep -v "^R"
In Windows PowerShell an equivalent would be:
hg status | Select-String -Pattern ("^[^R]")
Related
I'm trying to use mercurial file sets to add all the files in a directory tree, excluding very large files and any binary files. Cribbing from the mercurial documentation, this command should do it:
hg init
hg add 'set: size("<1M") and not binary()'
However this returns a status code of 0, and hasn't added anything to my new, empty repo. I've tried just 'set: not binary()' and that didn't work either.
The frustrating thing is that although I can google for mercurial file sets, and find lots of examples, I can't find anything to help troubleshoot when it doesn't work!
I don't have a .hgignore file, and it's a fresh empty repo. Mercurial 4.2.2.
The directory where I'm testing this has a couple of artificially created files for the purpose of testing. In my real use case, I inherit a multi-gigbyte tarball of assorted sources and binaries from a client, and I want to get all the sources into mercurial before I start hacking to fix their problems, hence the need to exclude the binaries and large files that otherwise choke mercurial.
Here's my little test script:
#!/bin/sh -ex
dd if=/dev/urandom of=binary_1k bs=1 count=1024
dd if=/dev/urandom of=binary_2M bs=1 count=2097152
echo "This. Is, a SMALL text file." > text_small
hexdump binary_1k > text_1k
hexdump binary_2M > text_2M
ls -lh
file binary_1k
file binary_2M
file text_1k
file text_2M
hg init
hg add 'set: size("<1M") and not binary()'
hg status -a
hg add 'set: not binary()'
hg status -a
hg add 'set: size("<1M")'
hg status -a
At the end of this, each status command reports no files in the repo, and the add commands report no errors.
The problem is that file sets do a query of Mercurial's repository data base, which knows only about files that are part of the repository or have been added.
One solution is to add all, and then to get rid of the files that you don't like, e.g.:
hg forget 'set:size(">1M") or binary()'
This works, because the query also requires recently added files, even if they haven't been committed yet.
So here's the problem. I have my configuration file in my home directory ~ under Mercurial control. Part of the
|-~
|.hg/...
|-Dev
|-Project1/...
|-Project2/...
.hgrc
.hgignore
I have Dev directory excluded from the source control in .hgignore file.
However when I am in the directory ~/Dev/Project1 Mercurial thinks that I am in the under the source control. If I type hg root in any directory that is in the .hgignore or its sub-directory hg still considers it being a part of repository.
Is it a bug or a feature ?
UPDATE
So, here's the simple experiment one could do from the command line:
% mkdir -p /var/HgTest
% cd /var/HgTest
% hg init
% echo "this is a repository file" >> test.txt
% hg commit -Am "added repo file"
% cat <<EOT >> .hgignore
heredoc> syntax:re
heredoc>
heredoc> ^Dev
heredoc> EOT
% hg commit -Am "added .hgignore"
% echo "This is not in repository" >> Dev/notinrepo.txt
Now, Dev directory not in repository, if you type hg st anywhere under /var/HgTest it shows you that repo is clean. However if you go into Dev directory and type hg root it will output /var/HgTest. This is perhaps desired result. However, since the path should be ignored, I would think that hg root should effectively exit with -1 return code and message "not in repository" or something like that.
In my case, having HOME directory under source control effectively makes some of the tools consider every new directory (even under ignored paths) as a part of Mercurial repository located in the HOME directory.
It's a feature for when you are in ~/Dev/Project1/deeply/nested and want to keep mercurial commands within the scope of Project1.
A workaround is to hg init in ~/Dev/Project1. Part of the problem is the bad practice of putting your home directory under version control; I can see no benefit to be gained from it and much cost. As an example, almost everything you do with a browser, or music player, or many other programs is going to alter files in ~/.groovy-game/config or ~/.browser/cache-files; there is no meaningful way to choose a commit point. Because of this it would be better to establish good, incremental snapshot backups for $HOME, even if they are stored on the same machine.
This is not to say that dot-directories in your home should never be versioned. for example, suppose I hack on my ~/.vim files because I am working on the ultimate editing environment, cd ~/.vim; hg init can certainly be useful.
Put another way — so long as there is an .hg repository somewhere in the tree above you, Mercurial will seek it out and read the ignore file and not take action on ignored paths. However, hg root only looks for an .hg directory. In your case, there is always a root, you are in your ~ repository by definition. I don't see how it could be done otherwise; you can't find the ignore file until you've inspected the root.
A little while ago I noticed that hg started creating unversioned copies of files in the repository at seemingly random times when I update between branches. I can't for the life of me think of what I might have changed for this to start happening. There is nothing in the verbose or trace output to indicate that these files are being created.
The new unversioned filenames all end with what seems to be a random string added to the end of the extension:
file1.txt-23121dd1
someotherfile.sql-bc769bd2
bizarrofile.cs-40a93ed0
hgisinvadingurhead.ppt-f8e9015a
When trying to determine the pattern of this happening I've noticed the following:
The added characters in the filenames do not correspond with any changeset ID in the repository. I have done a grep -i to the output of hg history and the string in the filename does not appear anywhere in the output.
In all cases the files existed in the branch I was working on but do not exist in the branch I update to.
Sometimes it's only one or two files, sometimes it's several.
It is never the case that these are all of the files that exist in one branch but not the other.
It is never the case that it is the same set of unversioned files between updates.
Others on my team who are cloning the same repositories do not seem to be experiencing this
I thought maybe it was something within the repository but it also happens in other existing repositories and in brand new ones as well.
For example, I have done this (hg output omitted except for hg status output at the end, but no errors come from the output):
c:\> mkdir repo
c:\> cd repo
c:\repo\> hg init
c:\repo\> echo default > default.txt
c:\repo\> hg add
c:\repo\> hg commit -m "Commit default"
c:\repo\> hg branch branch1
c:\repo\> echo branch1 > branch1.txt
c:\repo\> hg add
c:\repo\> hg commit -m "Commit branch1"
c:\repo\> hg update default
c:\repo\> hg status
? branch1.txt-23121dd1
This is not repeatable every time. I could repeat these steps and sometimes the unversioned file will be there at the end and sometimes it won't. It's very sporadic. In larger repositories, though, I almost always see at least one unversioned file between branch updates.
Full output of hg update default follows. The output always displays as such whether or not the unversioned file is created.
resolving manifests
calling hook preupdate.eol: <function preupdate at 0x0000000002571668>
removing branch1.txt
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
I was using an older version of hg when I first noticed it but the problem still exists after updating to 2.3.2. I am using Windows 7 Pro x64 with TortoiseHG 2.5.1 x64. I don't think it's related to Tortoise, however, because I can replicate the problem by just using hg from the command line.
The contents of my mercurial.ini file are:
[ui]
username=myname <myname#mydomain.com>
ignore=C:\users\myusername\.hgignore
verbose=true
trace=true
[eol]
native = CRLF
only-consistent = False
[extensions]
purge =
eol =
I can live with it, but it's a pain to make sure I'm not accidentally adding these files to the repository in changesets with other new files.
If someone has seen this and could point me to the culprit I'd be most appreciative!
If a file is in use when updating between changesets, the in-use file is renamed with the added numbers so the update can succeed.
Does disabling the eol extension help matters? I noticed that your test did not use a .hgeol file as well (that's one of the things associated with this extension). There's another thread hereabouts that is dedicated to some problems with this extension.
Ho to remove all *.bak or *.orig files in mercurial?
example:
C:\dev\web>hg stat
? Views\System\UnderConstruction.cshtml.bak
? Views\Topic\Index.cshtml.bak
? Views\Topic\MasterPage.cshtml.bak
? Web.config.bak
C:\dev\web>hg rem -I *.bak
abort: no files specified
hg remove only removes files that have already been committed. AFAIK, there is no command in mercurial to remove untracked files.
To learn how file patterns work in mercurial, run hg help patterns.
Untracked files ("?" sign) can be removed by OS, not Mercurial
You have to leave files as is, just add patterns to .hgignore and after it files, matching patterns, will not apper in hg status anymore
Correct remove command for remove tracked bak and orig files will be hg remove -I **.bak -I **.orig
You should take a look at the hg purge extension:
Delete files not known to Mercurial. This is useful to test local and
uncommitted changes in an otherwise-clean source tree.
This means that purge will delete:
Unknown files: files marked with "?" by "hg status"
Empty directories: in fact Mercurial ignores directories unless they contain files under source control management
But it will leave untouched:
Modified and unmodified tracked files
Ignored files (unless --all is specified)
New files added to the repository (with "hg add")
If directories are given on the command line, only files in these
directories are considered.
Be careful with purge, as you could irreversibly delete some files you
forgot to add to the repository. If you only want to print the list of
files that this program would delete, use the --print option.
You can do the following two commands:
D:\workspace>hg purge -I **/*.orig --all
and then:
D:\workspace>hg purge -I **/*.bak --all
Tracked files won't be deleted, but I'm guessing that's not an issue for you. Make sure that you enable the purge extension before running this, and you can do dry runs with the --print argument.
I'd like to use TortoiseMerge with Mercurial to resolve conflicts, but its reporting every line in theirs and mine as added as though its not comparing properly
here is my mercurial.ini:
[ui]
merge = TortoiseMerge
[merge-tools]
TortoiseMerge.executable=C:\Program Files\TortoiseSVN\bin\TortoiseMerge.exe
TortoiseMerge.args=/mine:$local /theirs:$other /base:$base -o /merged:$output
I'm using Hg 1.7.5
What's going on?
Update: When using KDiff or BeyondCompare, the base is always empty.
Thanks
Your setup appears correct.
This is symptomatic of having no copy of the file in the base revision, in which case Mercurial acts as if the file was present but empty.
There are a couple ways of figuring out what's going on here. If there are no copies or renames involved, you should be able to simply do:
$ hg log -r "ancestor(p1(), p2())"
..to determine the ancestor of the merge, then:
$ hg manifest -r <rev> | grep <your file>
..to determine if the file was in fact present.
Alternately, you can run 'hg merge --debug' or 'hg update --debug' to see what changeset and file it's choosing for the merge (including rename/copy details).
If you find that the file is present in the common ancestor Mercurial chooses, then you should report a bug (including your debug output) at:
https://www.mercurial-scm.org/wiki/BugTracker