Prevent a directory from being pushed in mercurial - version-control

I created a new repository on my local computer, added files and committed giving me the following structure in my working copy:
-/a
-/b
I want to push my initial commit to a remote repository on Bitbucket. I however want to ignore directory b so that it doesn't get pushed. I added
syntax:
glob b/**
to my .hgignore file. The b directory gets pushed anyways.
How can I prevent this?

This cannot be done in Mercurial: you cannot push only an initial version of a file and then ignore later modifications. You can also not push part of a changeset — you either push the entire changeset or not. This way Mercurial makes sure you have a consistent snapshot of your project in all clones.
Preet is correct when he writes that the .hgignore file is a filter for untracked files. The .hgignore file is used to filter the output of commands like hg status and to filter the files added by running hg add with no further arguments.

in .hgignore add:
^b/.*
or b/* if you are using the inferior glob syntax (regex gives you much more control).
The syntax is defined on the first line, and all rules are defined in following seperate lines.
if you want globbing, the first line would be syntax: glob and if regex, the first line would be syntax: regexp (implied by default). Refer to the documentation.
Note that mercurial does not actually push empty directories, so the only way you will be able to test it is if you have a file in b/

Related

Avoid Git to do any merge to a certain filetype

I am working on a quite big project versioned on a Git repositories that have several file of different types versioned. Among those, we use the QM Modelling tool that uses .qm files, which are actually xml files with a certain structure.
The structure of the .qm and the meaning of its content makes it unadvisable to use a merging tool to merge any change.
What I would like to do is have git issue a conflict in case it finds changes to any qm file even if it could merge those changes ( even if it could, the result is not guaranteed to be meaningful ), so that I can manually merge them using the tool.
Pros if the same is true if I perform a rebase instead of a merge.
Ok, answering myself as I found a solution.
I found this answer and modified it a little bit. I added a new merge strategy that basically takes the file as it is in the incoming branch and uses it untouched, then marks the file as with conflict.
So i created this script:
#!/bin/bash
# ${1} is the base common file
# ${2} is the file as modified by the base branch, and where the results must be
# ${3} is the file as modified by the incoming branch
# ${4} is the path of the file being merged
# ${4%.qm*} is the path without extension
# ${4##*.} is the extension of the path
# makes a backup of the original file to ease edits comparison
cat "${2}" > "${4%.qm*}.bk.${4##*.}"
cat "${3}" > "${2}"
exit 1
which uses the incoming file as a result as it is, and returns 1 to mark it as conflict.
Then I added in the .gitattributes the option to use this strategy for my .qm file, so that when I merge two branches, I take the incoming version as it is and use the graphical tool to modify and integrate my changes.
I'm going to leave this question as unresolved to see if anybody got another solution that would enable me to use both rebase and merge.
EDIT: I updated the script, I added a few lines to take the version of the local branch and make a backup of it, so that it is available to use in a comparison tool to identify my changes more easily.

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.

Force Mercurial (Hg) to add new files automatically

I'm looking for the opposite mechanism to the .ignore file, which should add all files of a given pattern automatically, for example *.tex for any LaTeX documentation project or *.def for any file that was added by OASIS (an MS Access addin for version control).
hg add with no arguments will add all files not explicitly ignored. You can also use hg commit --addremove to add all unknown files (and remove all deleted files, i.e. hg rm any which hg status lists as '!') to do this automatically when committing.
Adding files only happens when you run hg add. If you want to add all files matching a pattern, use the --include (-I) switch.

Clearcase: How do I merge in a specific file from one view, into another, to avoid the Evil Twin scenario?

I have a file that needs to be brought into a different branch. How do I do this from the command line. Everything seems to be geared to merging, where the file already exists in both branches.
You have to merge the parent directory first, so that the file shows up in the directory in the destination branch. At this point the new file will have zero size. You can then merge the file itself. The easiest way to do both of these operations is via the Version Tree view - much less error-prone than doing it via the command line.
Much simpler:
1/ rmname the file in the destination directory
ct co -nc .
ct rmname -force file.txt
2/ merge the directory
ct findmerge . -ftag view_tag
with 'view_tag' a view on the source directory
I no longer have access to a clearcase environment, so this is from memory, but what you want is to link in a version from another branch into the one that you are working with.
Let's assume that you have a file new_file that have been added on the branch new_feature (the latest version is new_file##/main/new_feature/5) which you want to merge/bring into the branch maintenance.
prompt>cleartool checkout -nc .
checking out some_dir##/main/maintenance/2
...
prompt>cleartool ln .##/main/new_feature/LATEST/new_file/main/new_feature/5 .
...
prompt>cleartool ci -c "linked in .##/main/new_feature/LATEST/new_file/main/new_feature/5"
prompt>
The commands above are probably not 100% correct, but should give you the idea. You want to use cleartool ln to avoid evil twins, because that will bring in a version from the already existing element (i.e. not creating a new twin).

What is the difference between hg forget and hg remove?

I want mercurial to remove several files from the current state of the repository. However, I want the files to exist in prior history.
How do forget and remove differ, and can they do what I want?
'hg forget' is just shorthand for 'hg remove -Af'. From the 'hg remove' help:
...and -Af can be used to remove files
from the next revision without
deleting them from the working
directory.
Bottom line: 'remove' deletes the file from your working copy on disk (unless you uses -Af) and 'forget' doesn't.
The best way to put is that hg forget is identical to hg remove except that it leaves the files behind in your working copy. The files are left behind as untracked files and can now optionally be ignored with a pattern in .hgignore.
In other words, I cannot tell if you used hg forget or hg remove when I pull from you. A file that you ran hg forget on will be deleted when I update to that changeset — just as if you had used hg remove instead.
From the documentation, you can apparently use either command to keep the file in the project history. Looks like you want remove, since it also deletes the file from the working directory.
From the Mercurial book at http://hgbook.red-bean.com/read/:
Removing a file does not affect its
history. It is important to
understand that removing a file has
only two effects. It removes the
current version of the file from the
working directory. It stops Mercurial
from tracking changes to the file,
from the time of the next commit.
Removing a file does not in any way
alter the history of the file.
The man page hg(1) says this about forget:
Mark the specified files so they will
no longer be tracked after the next
commit. This only removes files from
the current branch, not from the
entire project history, and it does
not delete them from the working
directory.
And this about remove:
Schedule the indicated files for
removal from the repository. This
only removes files from the current
branch, not from the entire project
history.
If you use "hg remove b" against a file with "A" status, which means it has been added but not commited, Mercurial will respond:
not removing b: file has been marked for add (use forget to undo)
This response is a very clear explication of the difference between remove and forget.
My understanding is that "hg forget" is for undoing an added but not committed file so that it is not tracked by version control; while "hg remove" is for taking out a committed file from version control.
This thread has a example for using hg remove against files of 7 different types of status.
A file can be tracked or not, you use hg add to track a file and
hg remove or hg forget to un-track it. Using hg remove without
flags will both delete the file and un-track it, hg forget will
simply un-track it without deleting it.