Disabling +S filetype in Perforce - perforce

Perforce's filetype system includes the +S modified to denote that a file is a temporary file. The implication of this is that no file history is stored for that file - only the most recent version is maintained, and it is replaced with each new checkin.
This is obviously a dangerous flag to set accidentally, which we recently discovered. Is there a way to ensure that this is not used in the future?

You can write a pre-commit trigger that looks at the file list for this flag, rejecting the commit if this is the case.
See this chapter of the Perforce manual for details.

Related

Can you set the perforce filetype (especially revisions stored) of a file in the depot without syncing or submitting it?

I have a number of files in our depot that have filetype binary. I want to change them to binary+S, so only the latest revision is stored. The only way I can see to do this involves using p4 edit or p4 reopen, which means syncing down the file and checking it out. Then to commit the change, I have to submit the file, too.
This wouldn't be a big deal, but there are hundreds of these files, and they are a gigabyte each, and it's taking perforce forever (hours) to get them submitted.
Is there any way to do this, using the command-line or an API, that doesn't involve syncing down and submitting the unchanged large binary files?
Use the p4 retype command to change the type of existing revisions.
C:\Perforce\test>p4 help retype
retype -- Change rev type or archive (storage) type (unsupported)
p4 retype [-l -n] -t filetype file[revRange]
Retype changes the filetype of each revision of the named files
to the new specified filetype. 'filetype' may be a full or partial
filetype. See 'p4 help filetypes'.
...
'p4 retype' does not purge older revisions when a filetype is
retyped to a '+Sn' type. Subsequent edits cause revisions to be
purged.
After changing the type of a file, any client workspaces which
currently have this file should be refreshed by issuing
'p4 sync file#none' followed by 'p4 sync file', to ensure that the
client copy of the file reflects the new filetype.
Note the caveats around the +S filetype (old revisions aren't retroactively purged) and needing to do a special re-sync of workspaces that already have the file (you can cheat this with sync -k to avoid transferring the file). If you skip the re-syncing step, a workspace that had the "old" filetype and opens that file for edit will default to the old type (since that type is in the have record for that client file).

Avoid vim eating input after quit

Some irritating issue when doing git commit (for example, there are other non-git scenarios): what I'd like to type (really fast):
git commit -a --amendEnter:wqEntergit push -fEnter
My problem is that after :wqEnter I have to wait until vim exits, and as I have a big vimrc it takes some time. I know, I'm spoiled.
I'm pretty sure there is a flag to git commit that will not open vim at all, but I'd prefer a more generic vim solution that will make vim not eat my input.
My vimrc is here
Git
While the OP wants a vim-centric solution, I offer these git workarounds as
temporary band-aids (and useful information).
At the bottom, I provide resources for discovering the issue in vim.
no-edit flag
Amending with the --no-edit flag causes vim not to launch (which is a good
idea if you do not need to edit the commit message: this is what the flag is
designed for).
Use a "different" editor for commit messages
There are a couple of different configuration options here, and a couple of
different "vims" to try.
See also git(1), section ENVIRONMENT VARIABLES, variable GIT_EDITOR.
One-off configuration
This is good for occasional usage (you can alias it, of course).
Use the -c flag on git:
git -c core.editor='vim variant' commit...
You could also set GIT_EDITOR via your shell (e.g., env, export, or
bash-isms).
Permanent configuration
This is good if you cannot resolve the vim issue and need it permanently.
Edit your configuration file (e.g., git config --edit --global), and add
[core]
editor = vim variant
Vim variants
Vim's command line switches let us control various aspects of its behavior. You
might want to
disable plugins (--noplugin)
disable a vimrc (-u NORC)
disable both (-u NONE)
use a 'clean' vim (--clean)
use a completely different vimrc for git (-u DEFAULTS or -u ~/.mygitvimrc)
The vimrc option allows us to craft an extremely efficient and minimal vimrc for
git work, while keeping our original for full-time stuff.
Experimentation may show that -N (not compatible mode) is necessary with some
of these.
Once you've chosen a setup that works, simply use vim <args>... as your git
editor, in one of the spots above.
Vim
The first things to try on the vim side are binary-split debugging your
vimrc and profiling your
vimrc to
find out what the root cause is.
It helps to be comfortable debugging for these steps. If you need to debug
vimscript, see :help debug-scripts.
Once you've identified the root cause, the next step is to squash it. You may
need to
disable a plugin (possibly to be loaded on demand)
change an autocommand to not be so nasty (look especially for autocommands
that are accidentally triggered more than once such as those not in
augroup)
avoid expensive function calls in your vimrc
help convert a heavy plugin to autoloads
or a myriad of other performance-enhancing techniques.
As always, the key is to know where the problem lies first.
For OP, using pathogen and vundle together seems like a mistake (two different runtimepath/plugin managers?). Also, vundle provides vundle#begin as a possible time-saver over vundle#rc.

Disable vim E211: File no longer available

After switching git branches, any files that existed on my previous branch raise an E211: File "path/to/file.txt" no longer available warning. I already know that and I find it very annoying that I'm warned about it every time I change the tab or pane that I'm focused on. Especially if I need to close 8 panes of files that no longer exist.
Is there any way to disable this warning or make it something that does not require any input to continue?
You can tweak Vim's default behavior via the :help FileChangedShell event.
This autocommand is triggered for each changed file. [...] If a FileChangedShell autocommand is present the warning message and prompt is not given.
Unfortunately, by defining an :autocmd (e.g. invoking a no-op like an empty :execute), you'll lose all the default functionality, and would have to re-implement parts of it (without the message on deletion) by inspecing v:fcs_reason. If the sledgehammer approach is fine for you, this will do:
:autocmd FileChangedShell * execute
Instead of *, you could enumerate all of your Git working copies, to make this a bit more targeted.

Vim forgetting its history when a file becomes read-only

After I commit a file to Perforce with vi, it will become read-only.
If I have this file open in vim, then when it becomes readonline I lose my undo-redo history, without even being asked.
Is there an option in VI to preserve the undo-redo history when the file becomes read only while you are editing?
It is a Vim bug. Whenever you :edit filename, implicitly or explicitly it seams that Vim is zeroing all undo history for this file because ( I guess ) it think that it is newly opened file. And after perforce commit, your file is kind of “changed outside” and Vim should ask you “Reload file?” unless you set “autoread”.
Check you vimrc for “set autoread” option.
Maybe you could try to make it readable with modelines :
#vim : set noreadonly:
I wrote # but of course you must replace it with the adequate symbol for a comment.

Vim: apply settings on files in directory

How do I specify Vim settings for all files under the current directory?
The ideal solution would be if Vim searched for and read a .vimrc in the current directory before searching for ~/.vimrc, and apply the settings there for the entire tree.
I've seen a plugin, but this means the applied settings aren't transparent since they require the plugin to be installed. In contrast, a modeline is transparent since regardless of a user's vimrc or specific vim invocation the modeline settings will be applied for that file.
Things I tried are
placing a .vimrc in the working directory
:so vimrc in the modeline.
I suppose both don't work for security reasons. I don't need the full power of a vimrc; being bound to settings acceptable by a modeline would suffice. My goal is to make it easier for vimmers to adopt coding standards in a project.
You can put something like this in $VIM/vimrc
autocmd BufNewFile,BufRead /path/to/files/* set nowrap tabstop=4 shiftwidth=4
I'd strongly suggest not using set exrc
Even with set secure, under *nix, vim will still run autocommands, shell, et al, if you own the file. So if you happend to edit a file in that tarball I sent you with a .vimrc containing:
autocmd BufEnter * :silent! !echo rm -rf ~/
you'll probably be less amused than I will.
I'm an advocate of the plugin way.
For several reasons:
Modelines are particularly limited: we can't set variables (that tunes other (ft)plugins, like "should the braces of the for-snippet be on a newline ?"), or call function from them (I don't limit myself to coding standards, I also set the makefile to use depending on the current directory)
DRY: with modelines, a setting needs to be repeated in every file, if there are too many things to set or tunings to change, it will quickly become difficult to maintain, moreover, it will require the use of a template-expander plugin (which you should consider if you have several vimmers in your project).
Not every one uses vim to develop. I don't want to be bothered by other people editor settings, why should I parasite theirs?
It's easier to ask vimmers to install a same plugin, instead of asking them to copy-paste, and maintain, the same lines in their .vimrc
The settings can be saved with the other project files (cvs/svn/git/whatever)
It's really easy to have a configuration file per project -- with the plugin, I have a global configuration file for the coding standards of the overall project, and specific configuration files for each sub-project (which makefile to use, which executable to call, ...)
BTW, sth's solution can be used to source a single configuration file. This is very similar to the plugin approach except the .vimrc has to be parasited with non global options, and it does not support easily multiple/shared configuration files.
This question is old, but it seems like a pretty natural and persistent concern.
My solution is pretty simple. I place a .vimrc file in the root directory of my projects. The first line of the .vimrc file usually sources ~/.vimrc, and then adds the particular configuration I want. I alias tvim='vim -u .vimrc', and use tvim in my personal project directories. "tvim" for "trusted vim," meaning that if I execute it in a directory with a .vimrc file and something goes wrong, I've got no one to blame but myself, since I explicitly said I trusted it. Also, I keep a group of these stored away so that I can sometimes just softlink the one I want for a particular kind of project.
Placing a .vimrc in the working directory actually is supported, only disabled by default. See :h 'exrc' and :h startup for details, setting 'exrc' will enable reading .vimrc from the current directory.
It's also recommended to :set secure when using this. This locks down :autocmd, shell and write commands for .vimrc in the current directory.
Another thing that might be worth looking at is setting up a session (:h session) with a standard view and settings for the project.
All that said, I would probably go with the plugin option detailed by Luc Hermitte myself.
To minimize security risks with ANY "autorun" features for ANYTHING these days, may I advise you to utilize vim's existing features instead of plugins (portability baggage)?
Eg.
My local folder's vimrc file is named "_gvimrc" (on purpose). This reduces the hope for people like phen from amusing himself at our expense. :-)
In my $VIM/.vimrc file, I inserted:
if filereadable("_gvimrc")
source _gvimrc
endif
at the end.
I use "filereadable()" over "fileexists()" as the later has some quirkiness when tortured with opening multiple (10+) files simultaneously, (not sure why).
Of course, you can give your own unique filename to obfuscate potential trouble-makers further. Such as "_mygvimrc", "_gobbledygook", etc. You just need to settle on one standardized name and source it accordingly in your $VIM/.vimrc. Relying on vi/vim internals for this rules out portability issues. BUT, DO NOT name it .vimrc (or _vimrc) to prevent recursive sourcing in case you're editing the $VIM/.vimrc file with vim later.
Been using this since Windoze 98SE, through Windork XP Pro, and now Windorkier 7 (5+ years already). I'll mark a list of .txt files in Explorer and then use "Edit with multiple Vim", resulting in multiple vim windows opening simultaneously. For my work, I do this several times a day, daily. All files got treated with what I set in my local _gvimrc.
Use "editorconfig"
If the kinds of coding standards you would like to enforce are related to indentation style, tab size, file format and charset, then you might want to look into "editorconfig", which is a cross-editor standard to specify this kind of settings in a specific project, and have all editors follow that configuration.
The "editorconfig" specification allows projects to request different settings depending on file extensions or names within the project. (So you can have Makefiles using TABs, your Python scripts using 4 spaces and your shell scripts using 2 spaces for indentation.)
You need a plug-in to use "editorconfig" in Vim. The official website provides one, but personally I'd recommend sgur/vim-editorconfig, which is written in pure Vimscript, so you don't need to worry about external dependencies too much.
Since "editorconfig" aims at cross-editor compatibility, it's quite limited in what it does, so if you want is consistent whitespace, file format (DOS vs. Unix) and encoding (Unicode utf-8, etc.), then "editorconfig" is for you.
Assuming people aren't adding files every few days, you can probably add a modeline at the top of each file. In fact, if your version control system allows it, you could probably enforce a rule that says that each file must have a modeline when it's checked in.
I agree with the plugin approach for security reasons.
There is a very good plugin which has not been mentioned yet. It lets you use a .lvimrc in your project directories.
Try "localvimrc" out:
http://www.vim.org/scripts/script.php?script_id=441
https://github.com/embear/vim-localvimrc
Try vim-localrc
~/
|- .local.vimrc (1)
`- project/
|- .local.vimrc (2)
`- src/
|- .local.vimrc (3)
`- main.c
https://github.com/thinca/vim-localrc/blob/master/doc/localrc.txt
I looked at the plugins that existed and didn't really fancy any of them, so I wrote a simple function that piggy backs on vim-fugitive. The advantage of this is that it knows the root of the project is always the root of the repository, and additionally I can hash the file to keep a trust table. Just put the following in your .vimrc file.
function LoadRepoVimrc()
let l:path = fugitive#repo().tree('.vimrc')
if filereadable(l:path)
let l:sha1 = fugitive#repo().git_chomp('hash-object',l:path)
if !exists('g:SAFE_VIMRC') | let g:SAFE_VIMRC = {} | endif
if has_key(g:SAFE_VIMRC,l:path) && g:SAFE_VIMRC[l:path] ==? l:sha1
execute 'source '.fnameescape(l:path)
elseif confirm("Trust ".l:path."?", "&Yes\n&No",2) == 1
let g:SAFE_VIMRC[l:path] = l:sha1
execute 'source '.fnameescape(l:path)
else
execute 'sandbox source '.fnameescape(l:path)
endif
endif
endfunction
autocmd User FugitiveBoot call LoadRepoVimrc()
set viminfo ^= !
If the ! option is set on the viminfo setting, then the SAFE_VIMRC dictionary will be preserved between runs (note the ^ to prepend the option so it doesn't mess up the n option).

Resources