Avoid changes on a tracked file - mercurial

I've files that are automatically created (empty) that I want to be added in my mercurial repo but never modified after the first add/commit.
I tried to use a precommit hook revert "glob:**.ext" it works on avoiding commit changes but it also prevent commit adding those files. I need those file to be tracked because I use hg purge sometimes and it delete every untracked/ignored files.
I use TortoiseHg (unfornutately I've no choice).
Can you help me with that ?

Have a look at this extension called exclude.
Other options
Add a template file. For eg: Add something.ext.template to your repository and add something.ext to .hgignore.
Add this to your .hgrc
[defaults]
commit = -X something.ext
But i think the above might exclude it from the initial commit as well.

Related

Mercurial - Add tag to committed files on commit

We are looking for a way to add / update a custom tag at the beginning of each file being committed during a commit. Its some kind of local timestamp we need.
I was thinking of hooks.
Unfortunately I cannot find a useful hook for that:
precommit: unsuitable as it fires before hg knows any metadata of the commit
pretxncommit: unsuitable, as the documentation clearly states that we should not change the working dir at this point
commit: unsuitable, as it fires when the commit has already happened.
EDIT:
I can not use hg's inline changeset-hash and / or datetime. For the following reason:
Our files get later imported into an external system (we do not have control over) which does not support any kind of versioning.
To simplify stuff: let's say tag is an ever-incrementing no. (everytime we commit). This tag is then used to help getting an idea of the version / status of the file on the system in respect to the file in the repo - like "no. of changes we're missing" and such.
Any ideas?
I would suggest a two-stage solution. First, create an alias along the following lines:
[alias]
tcommit = !tag-changed-files && $HG commit "$#"
Here, tag-changed-files would retrieve a list of modified and added/moved files via $HG status -ma -n or $HG status -ma -n -0 and tag them. I am assuming that re-tagging files that have been modified but aren't being committed yet is a harmless operation; more on that below. Note that you can even redefine commit if you absolutely want to via:
[alias]
commit = !tag-changed-files && $HG --config alias.commit=commit commit "$#"
However, this is potentially problematic, because it may confuse scripts.
You could also integrate the commit step in the program if you wanted to, and even try and parse the command line arguments to only tag those files that you are committing. For this approach, using hglib might be appropriate to avoid the overhead of invoking Mercurial multiple times. (Note that hglib and other tools that use the command server ignore aliases and command defaults, so this works even if you alias commit).
Second, you'd install a pretxncommit hook that verifies that files that are being committed have indeed been tagged appropriately (to ensure that the tag-changed-files program hasn't been bypassed by accident).
This should work without a problem on full commits; for partial commits, any files that were changed but have not been committed would also have been retagged, but since they will be either committed later (and get tagged properly at that point) or reverted, that should be harmless.
an idea of the version / status of the file on the system in respect to the file in the repo
Just one idea
Stop reinvent the wheel
Incremental counter is just shit, if you task is "to know, which version is on LIVE and which - in Mercurial's tip" (and this is your real business-task, yes?!)
Keyword Extension give you last changes per file.
If you want to inject changeset of repository into files (it's reasonable good way), re-read this part of wiki-page
If you just want to version your entire repo, do not use this
extension but let your build system take care of it. Something along
the lines of
hg -q id > version
before distribution might be well enough if file-wise keyword
expansion in the source is not absolutely required
You can insert hg id output into files at export stage (in planetmaker's sed-style), bu you can also have this additional metadata in files permanently in VCS with special encode|decode filters
There is - to my knowledge - no intrinsic system in mercurial which supports what you describe. However I can recommend an approach which somewhat is adopted from building a software release package from the repository: Make a small export script which replaces a certain KEYWORD in your files with the version information you need. A Makefile target could look like which creates a zip export for revision XXX with version information in all files which support it (thus contain the verbatim KEYWORD - use something truely unique here):
VERSION=$(hg log -rXXX --template="Version: {node|short} from {date|isodate}")
export:
hg archive -rXXX -t files export
for i in $(hg ma -rXXX); do sed -i "s/KEYWORD/$VERSION/g" $i; done
zip -9rq export.zip export
I use a similar approach in my Makefiles where I create versioned export for the source of a particular revision of my software.
EDIT: if your purpose (as stated by the comment) is only to implant the number of commits made to that file: then you can use indeed a pre-commit hook and modify the file. You can count the number of modifications made to a file with hg log FILENAME --template="{node}\n" | wc -l. Do that for every file and do the sed replacement in the header of each file in the pre-commit hook.

TortoiseHG is ignoring folder

I added CKEditor to my project. After final configuration, I am not able to commit folder dialog in folder ckeditor/plugins. When I open TortoiseHG Workbench, there is no dialog folder to commit. Other users after update didn't get that folder, so editor not work for others.
I am not ignoring that folder. Here is my .hgignore file:
syntax=regex
^\.
^target/
^jsTestDriver\.conf$
^node_modules/
^run-ft\.bat$
^run-ut\.bat$
log$
versionsBackup$
main\.css$
\.idea$
\.iml$
When I rename folder dialog to something else (for example dialog2), it automatically appears and I can commit, but dialog2 is useless for me. Please, any ideas?
Yes, it is normal, you have
log$
Which excludes the string if it ends with log, as in dialog...
If you need to exclude .log file, use
\.log$
Use hg add in console and add directory by hand (or move .hgignore temporary out of repository and add in GUI)
Try something like hg add -I ckeditor/plugins/dialog/* -n (and fix probably bad pattern for good result)

how to ignore files in kiln/mercurial using tortoise hg "that are part of the repository"

We use tortoise hg with Kiln. In my vs 2010 c# project there are some files that are part of the repository but I would like tortoise hg to ignore them when I make a commit.
For eg., say in a login screen I may hard code the userid, password for testing. I dont really want this file considered during a commit. I understand .hgignore file but this really works for files that are not part of the repo. Any trick in tortoise hg to ignore files that are part of the repo ? (so they do not show up as modified (M) during a commit.) thanks
I always use a combination of .hgignore and BeforeBuild (in the .csproj file) for things like this.
In one of my pet projects, I have the following setup:
App.config contains my real hardcoded user id and password for testing.
App.config.example is identical, but with fake data like "dummy_user" and "dummy_pw".
App.config is not part of the repository, and it's ignored (in .hgignore).
App.config.example is part of the repository.
Then, I have the following in the BeforeBuild target in the .csproj file of my solution:
<Target Name="BeforeBuild">
<Copy
Condition="!Exists('App.config')"
SourceFiles="App.config.example"
DestinationFiles="App.config"/>
</Target>
All this together has the following effect:
the config file with the real data can never be accidentally committed to the repository, because it's ignored
the repository only contains the config file with the example data
if someone else clones the repository to his machine, he won't have the "real" config file...but if it's missing, it will be automatically created before the first build by Visual Studio / MSBuild by simply copying the .example file (and then he can just put his real login data into the newly created App.config file).
if an App.config with real hardcoded user data already exists, it won't be overwritten when building because the BeforeBuild event will only happen if App.config does not already exist
The answer by Christian is the right one, but I want to mention that TortoiseHg supports what you want with their Auto Exclude List.
One problem with an exclude list is that it cannot work with merges: you must commit all files when you merge and so you'll have to do a little dance with shelve, merge, commit, and unshelve.
When you do a TortoiseHG commit, there is a list of files with checkboxes by them. Deselect the files you do not want comitted.
Or, on the command line, do a commit of the form hg commit --exclude "pattern", where pattern is defined in the hg man page.
You could always use hg forget.

telling mercurial to ignore a file when merging and updating

I want mercurial to ignore my own local copy of log/development.log (I am on RoR).
I used "hg forget filename" to forget the file, and then committed that change.
It seems to be successful now.. but every time I merge with other changesets now, I see
remote changed log/development.log which local deleted
use (c)hanged version or leave (d)eleted?
what am I doing wrong? how can I make this msg go away? I just want my local copy to be separate from the copy in the repository.
Thank you...
If you deleted the file in your line, and you merge it with the one that still has this file, this message is to be expected. The only way to get rid of it is to remove this file from the repos/branches you're merging with (or get their owners to remove it, if you don't control them).
And then never commit a temporary log file into the repository ever again.

Mercurial: Multiple Change sets at once?

Before, when I was using perforce, I could work on multiple bugs at once as long as the code did not affect the same files, by having multiple change sets open at once.
Changeset 1:
A.txt
B.txt
C.txt
Changeset 2:
D.txt
E.txt
F.txt
I could submit changeset 2 to the repository without submitting changeset 1 (because it's still in progress)
Is this possible with Mercurial? other than doing each file as a separate commit?
You can always just do: hg commit D.txt E.txt F.txt to commit just those files which will leave A.txt, B.txt, and C.txt uncommited. Using the -I option to commit lets you do those with patterns if they're, for example, in a common directory: hg commit -I 'dir1/**'
You can have two separate branches (working copies) and make one change in and the other in the other. That's one way.
Another is to use Mercurial Queues. You can use qpush --move to change the order of changesets if they have no dependencies on one another, so you can then use qfinish to 'commit' the first changeset that's ready.
You don't actually hold changesets "open" in Mercurial.
Either you've committed your changes, or you haven't.
You can, however, have multiple files with uncommitted changes, and only commit a few of them. It is even possible to commit parts of files, chunks, instead of the whole file.
If I was to do what you're asking I would simply make another clone locally from my first one, and work on the two different fixes in two different working folders. Then I have all the freedom I need to combine the two (push/pull locally), push to the server, etc.
In Mercurial, cloning is a cheap operation when done locally. Just clone the repository for each thing you are working on. Push back to the main repository as each thing is ready:
hg clone http://project project
hg clone project project-bugfix // uses hardlinks and is inexpensive.
hg clone project project-feature
<edit bugfix and feature as needed>
But remember that the default push location is the project cloned from, so you'll either need to edit .hg\hgrc's default push path for the "project" clones, or make sure to hg push http://project from "project-bugfix" and "project-feature" when complete.
Even if your modifications touches the same file you can select what to include (hunk by hunk). You just have to activate the record extension (it's installed by not activated by default).
To activate the record extension, put this in the [extensions] section of your .hgrc:
[extensions]
hgext.record=
Then to commit, replace hg commit by hg record. Let's assume your example change sets with a G.txt file that have changes for both change sets. Commit with:
hg record D.txt E.txt F.txt G.txt
Answer questions, for example:
2 hunks, 6 lines changed
examine changes to 'D.txt'? [Ynsfdaq?] f # f for full file (help with ?)
... skipped file E and F
6 hunks, 35 lines changed
examine changes to 'G.txt'? [Ynsfdaq?] y
## ... (patch hunk here)
record change 6/16 to 'G.txt'? [Ynsfdaq?] y # y to include the hunk, n to skip