How to freeze a file for changes but leave it in the repository using Mercurial - version-control

Quite often I have a situation like the following:
some Hg repository with a bunch of configuration files that are shared
some configuration files contain passwords, that should not be shared, they are local to the user
I would like to keep a version history on these files, but they will only occasionally be updated. It is annoying if every time you do a commit or merge or update you have to remember that you do not want to commit your locally changed password.
How can I freeze a file in the repository (and conversely, for the occasional legitimate update, unfreeze it) so that it does not appear in the commit list, but does appear as versioned in the repository and everyone can share a base copy?

This question gets asked a lot, and the answer is always the same: there's no good way to do what you want. A file that's tracked is tracked for all changes.
The setup everyone settles on is committing a configurationfile.example to the repo where changes everyone needs are shared, and add configurationfile to your ignore. If you're savvy you then have your launch script copy configurationfile.example to configuration location if it doesn't already exists. If your configuration format is flexible enough to support an include (most are these days) you have you configurationfile committed and have it do an include of a non-tracked (ignored) configurationfile.local where people override things. This is how everyone does it in both git and Mercurial.

-X option for commit, none (easy) for merge
-X --exclude PATTERN [+] exclude names matching the given patterns
i.e most times you commit hg ci -X FILENAME, sometimes - pure hg ci. You can define hg ci -X FILENAME as new alias and use two different commands for different commits
In case of merges you can try to define for config-file special merge-tool (provably internal:local or internal:fail)
Anyway, you selected wrong and error-prone method of storing local configs as shared common files. (Viable) alternatives may include (in order to name a few)
Config.TEMPLATE in repository and modified for local needs hgignore'd Config
LocalBranch, in which you store code with location-specific changes
MQ extension (somehow related to 1-st solution) - repository stored "vanilla" config, all local-only changes placed in MQ-patch

Related

How to prevent a folder from being pushed to mercurial repository?

my problem is quite simple: there is a folder in my project which I want versioned, but not pushed along with the rest of the project when I push updates. The situation is that I made an Android app stub along with the project, and I don't want to push it until it is actually somewhat functioning. It's a pretty bulky folder.
I do not want to make a separate branch for that folder, because of two problems: firstly, updating that branch whenever I pull from remote will require a merge; secondly, swapping between the two branches requires noticeable waiting time as the thousands of Android files are created/deleted, and this is very annoying to me.
I was thinking about editing .hgignore in some way, but I think it is wrong that the remote repo will then have my local folder as ignored.
Any suggestions?
You can add this snippet to your repo's hgrc file:
[ui]
ignore = /path/to/.hg/hgignore
where the point about this hgignore file is that it is non-versioned and local to you. The contents hgignore can be anything that would also be suitable for the (versioned) .hgignore. e.g:
syntax: glob
/directory/to/ignore
The name of the file, hgignore, can be called anything, but it's what I use.
You can use the configuration [defaults] section to add some "--exclude" options to usual commands (see my answer to Mercurial hg ignore does not work properly ) for more details. You can even specify which files you do not want to commit in your directory, e.g., stub/**.c for all C files in the hierarchy of directories below stub.
But.. be careful that it is dangerous to silently ignore modifications to files and also that this [defaults] section has been marked as deprecated (it is still present in 2.9.2).
If this is a temporary situation, it would solve your problem though: you would just have to remove the --exclude parts when you feel ready to commit and push your stub.

cvs: updates fail to merge

I've just discovered, a surprising for me behavior of cvs.
I change file1 localy
During this time people change other unrelated parts of the same file, and commit to the repository
I update my local copy from repository
At this point I expect my local copy of file1 to contain all changes made by others to this file, unless the update above reported a conflict. However, when I do now diff with head, I discover lot's of differences coming from changes made by others in parts of the file that I did not touch at all.
Any ideas? Is this just the limited abilities of cvs to merge? Any wrong setting? Something in my workflow?
CVS has very limited merge facilities. Switch to a modern system such as Git (perhaps via git-cvsimport if the repo maintainer is uncooperative) if you want a better merge experience. See also Best practices for using git with CVS
The final solution is :
1. Save your local code to another place manually
2. Revert the files which may has conflict to the HEAD (most latest) version on CVS server.
3. Add back your change to the Reverted file.
The concept for above solution is to CLEAR UP all the possible issue by REVERT and get a 100% clean version from repository then add back our changes.
It can resolve below issues which caused by code out of date / code base messed up.
CVS commit had a conflict and has not been modified
CVS update failed
CVS not sync

VCS capable of files versioned per user

I have already used some VCS like CVS, SVN and Git. One feature that I am missing cannot be found anywhere.
There are files which I would like to have in the repository but every user should have its own. So when you checkout you get a default of that file and that commit your changes only for yourself.
Why do I want this? There are some files like configuration where I would like to have a default version in the repository (e.g. for building releases or a starting base for new team members) but the changes to that file are only relevant to a certain developer (or working copy) because it will contain paths only valid for that developer/working copy.
Currently when I do not add this files:
- I miss them when creating a new working copy or exporting for a release build
- Have no history which changes I might have done for myself for experimenting
Currently when I add this files to the repository:
- I might never commit them so I have a default in the repository but my file is always flagged "changed". In SVN I can add it to the "ignore-on-commit" changelist to improve a bit.
- I might loose my very own changes of a difficult configuration file (data crash, laptop theft, etc.)
Is there a VCS capable of this? Do SNV or git support something regarding this I might have overseen?
If I understood and decomposed your task correctly
"Have a set of default templates of something, which are starting point of per-user customization and these customized versions must be stored separately and be accessible only by responsible person"
you can use this workflow (draft, subject of modifications and corrections), Subversion based for simplicity and transparent management (strong point of any CVCS really)
Subversion repository
Each user of repo have own predefined path inside repository-tree (with common path-pattern for manageability and easy automation of processes)
One special admin-only managed path also exist, not accessible by ordinary users
Our tree may seems like this (where Repository dir is a root of repository)
z:\>dir /s /B
z:\Repository
z:\Repository\Users
z:\Repository\Template
z:\Repository\Users\Alpha
z:\Repository\Users\Bravo
For every user-path we use Path-based Authentication, which provides access for every and each user only to own subtree in repository,
Template contains (as name assumes) templates stub for all user's documents
Adding new users to repo, obviously, becomes simple and easy automated task:
svn copy Template into new user's dir
add rw permissions for created location for user in authz-file
tell user URL of his personal tree in repo
I don't think the VCS is the problem here. It looks like if you have a file whose contents are dependent on the local environment, you should auto-generate it with a script. This way, you ignore the generated file, but version the script and each developer still gets a perfectly valid copy of the config files at run time. This is the same approach that is used, for example, with user specific IDE settings: .suo files on Visual Studio for example.
Update:
If you specifically need a set of defaults, then the solution is this:
Add the defaults to the repository.
Each dev works in their own branch. This way, they can version the
changes to the config files.
When re-basing onto master and/or merging, the devs simply never
merge their customized configs.
You can always set up a hook to check if the default config has been modified, and if so, maybe email the dev. You simply view such a commit the same as you would view a commit that does not compile.
Devs are smart. Sure, they make mistakes. But never under-estimate the power of some simple communication.
Of course, when the default configs do get overwritten with the customized ones of Dev X, then you use the powers of git to fix that commit immediately.

Mercurial workflow for updating with uncommitted changes?

So i've made the switch from CVS to mercurial for my website.
The biggest issue I am having is that if i'm working on some files that I don't want to commit, I just save them.. I then have other files I want to push to the server, however if someone else has made changes to the repository, and I pull them down.. It asks me to merge or rebase.. either of these options will cause me to lose my local changes that I have not committed.
I've read that I should clone the repository for each project on my local host and merge it into the live when it's ready to do so. This not only seems tedious, but also takes a long time as it's a large repository.
Are there better solutions to this?
I would have hoped that Mercurial would see that I haven't committed my changes (even though I have changed the file from what's on the server) so it'd just overlook the file.
Any input on this would be greatly appreciated. Thank you!
Also, i'm using the hg eclipse plugin to work on my files and push/pull from the server.
hg shelve is your friend here I think.
which comes from the shelve extention (maybe - see below)
from the overview:
The shelve extension provides the
shelve command to lets you choose
which parts of the changes in a
working directory you'd like to set
aside temporarily, at the granularity
of patch hunks. You can later restore
the shelved patch hunks using the
unshelve command.
The shelve extension has been adapted
from Mercurial's RecordExtension.
or maybe its the attic extension
This module deals with a set of
patches in the folder .hg/attic. At
any time you can shelve your current
working copy changes there or unshelve
a patch from the folder.
it seems to have the same syntax as the shelve extension, so I'm not certain which one I've used
I second #Sam's answer. However, if you prefer to use standard Mercurial, a simple workflow is to
save your working dir changes in a temporary file,
sync your working dir with a specific revision, then
push, pull, merge .. whatever you want to do and which requires a clean working copy, and
get back your changes from the temporary file into the working dir.
For instance:
$ hg diff > snapshot.patch # save your uncommited changes
$ hg up -C # get a clean working copy
$ hg pull # do things ..
$ hg merge # .. you need a clean ..
$ hg commit -m "merge" # .. working copy for
$ hg import snapshot.patch # get back your uncommited work
First, are you working from the commandline, or using something like Tortoise?
If you're working from the commandline, and you've done a pull, mercurial will not ask you to do anything, as it merely updates your local repository.
If you then do an hg update and have local changes, it should do what you're used to from CVS. It will update to the tip of the current branch, and attempt to merge your outstanding changes in. There are some caveats to that, so refer to the official docs at http://www.selenic.com/mercurial/hg.1.html#update.
Also, for temporarily storing changes, I would recommend MQ over shelve. Shelve only provides one storage area, whereas MQ provides as many as you need. MQ takes some getting used to, but worth the investment.

Half-ignored files in VCS - is this supported?

I am using Eclipse and Subversion for Java development, and I find myself wishing for a feature in version control systems (one that is not available in SVN, to the best of my knowledge).
I would like my project settings files to be half-ignored. To be more precise, I want them to be available in VCS, I want merge to occur when someone checks in changes, but. I want my own changes ignored unless I very explicitly tell the system to take them.
This would allow me to have my local paths (and other settings) in my local configuration w/o screwing up other people's configuration. But, when I have a substantial change, I can still check it in (very very carefully, may be temporarily removing my other local changes) and have it delivered to other people.
Now, the actual question: is there any VCS that supports this feature? Or may be I am missing something in SVN? How do other people solve this problem in Eclipse?
Yes, Git support that feature through filter driver (a clean script can run upon commit, allowing you to clean the content from any of your changes if you want).
But another way would be to never version that setting file, and only version:
a template file
a value file
a script able to replace variables in the template files with the values from the value file, in order to generate the actual (and "private", as in "not versioned") setting file.
That way, you can modifying it at your heart's content without ever committing your changes.
.gitignore for git, .hgignore for mercurial and file paths and patterns can be added that will not be committed. There similar in SVN but i never worked out how to use it myself but my sysop did set it up form me.
git supports this with
git update-index --assume-unchanged <file>
and the complementary
git update-index --no-assume-unchanged <file>
See http://blog.pagebakers.nl/2009/01/29/git-ignoring-changes-in-tracked-files and http://kernel.org/pub/software/scm/git/docs/git-update-index.html#_options for more details.