SVN Error: Can't convert string from native encoding to 'UTF-8' - linux

I've got a post-commit hook script that performs a SVN update of a working copy when commits are made to the repository.
When users commit to the repository from their Windows machines using TortoiseSVN they get the following error:
post-commit hook failed (exit code 1) with output:
svn: Error converting entry in directory '/home/websites/devel/website/guides/Images' to UTF-8
svn: Can't convert string from native encoding to 'UTF-8':
svn: Teneriffa-S?\195?\188d.jpg
The file in question above is: Teneriffa-Süd.jpg notice the accented u. This is because the site is German and the files have been spelt in German.
When executing a update on the working copy at the Linux command-line no errors are encountered. The above error only exists when the post-commit hook is executed via a commit by a Windows SVN client.
Questions:
Why would SVN try to change the encoding of a file?
Are filenames allowed to contain chars that are outside the Windows standard ASCII ones?
Update:
It turns out that the file in question's filename correctly displays as Teneriffa-Süd.jpg when viewed from a Windows machine (via Samba) but when I view the filename from the Linux server (using SSH and PuTTY) where the file resides I get Teneriffa-Süd.jpg

Yet another example:
$ svn update
svn: Error converting entry in directory '.' to UTF-8
svn: Can't convert string from native encoding to 'UTF-8':
$ export LC_CTYPE=en_US.UTF-8
$ svn update
(... and all is fine now)

It does not change the encoding of the file. It changes the encoding of the filename (to something that every client can hopefully understand).
Allowed by whom ? NTFS uses 16-bit code points, and Windows can expose the file names in various encodings, based on how you ask for it (it will try to convert them to the encoding you ask for). Now... That bit (how you ask) depends on the specific svn client you use. It sounds to me like a bug in TortoiseSVN.
Edit to add:
Ugh. I misunderstood the symptoms. the svn server stores everything in utf-8 (and it seems that it did that successfully).
The post-commit hook is the bit that fails to convert from UTF-8. If I understand what you're saying correctly, the post-commit hook on the server triggers an svn update to a shared drive (the svn server therefore starts an svn client to itself...) ? This means that the configuration that needs to be fixed is the one for the client on the server.
Check the LANG / LC_ALL on the environment executing the svn server.. As it happens, the hooks are run in a vacuum environment (see Tip). So you should set the variable in the hook itself.
See also this page for info on how svn handles localisation

If Error is -
[abc#288832-web3 public_html]$ svn update
svn: Error converting entry in directory 'images' to UTF-8
svn: Valid UTF-8 data
(hex: 46 65 6e 65 72 62 61 68)
followed by invalid UTF-8 sequence
(hex: e7 65 2b 46)
Then do this.
[abc#288832-web3 public_html]$ printf "\x46\x65\x6e\x65\x72\x62\x61\x68\n"
Fenerbah
(This means that the system has some file name starting with "Fenerbah" in that folder.)
[abc#288832-web3 public_html]$ cd images
[abc#288832-web3 images]$ rm -rf Fenerbahçe+Forma+2.jpg
So you can see that there is a special character in the name and it is not supported by SVN.

put this in your post-commit
export LANG=xxxxx (your lang)

Just use the following line in your script before executing any svn command.
User appropriate language codes, in following example I used japanese
export LC_ALL=ja_JP.UTF8

Don't forget to generate those locales in your system
(as root)
example for Ru
locale-gen ru_RU.CP1251
locale-gen ru_RU.UTF-8
dpkg-reconfigure locales

It changes the encoding to a location-neutral encoding in case someone with a different encoding checks it out.
Of course. But it's not "Windows" ASCII (Windows actually uses some strange encoding like CP1251 or so).
The best way to fix this is to make sure that your system uses UTF-8 whenever possible (check $LANG).

It seems that all LC_ varables need .UTF8 at the end. For example, I happened to have LC_ALL, LC_TIME, and LC_CTYPE defined. After setting LC_CTYPE the problem was not solved, so I needed to type LC_ALL as well and then it worked:
LC_ALL=en_US.UTF-8
LC_TIME=en_DK.UTF-8
LC_CTYPE=en_US.UTF-8
In order to avoid the problem again, I copied the file to a different name, removed the old one from svn, added new one to svn, and send a message to a collaborator not to do this.

I got a similar problem when running "svn add" on a directory, but the solution was different. I couldn't see the "hex" digits using printf (actually no hex output was shown by svn), but this command allowed me to see the results, and fix it:
LC_ALL=C svn add probealign
I think, in general, sticking LC_ALL=C before your command allows you to see the offending files... and is a lot easier than pasting in a lot of \x72 stuff (which apparently may not be available).

For information, I got this error on commit native encoding to 'UTF-8'with a windows client tortoise svn,
when my URL of repository was :
http://x.x.x.x/svn/myrepos
I changed my URL of repository for :
svn://x.x.x.x/myrepos
and now all is perferct.
I think this information will be useful to some.

In my case, I had the setting in ~/.subversion/config as below
log-encoding = ...
Commenting it worked.

Related

Cannot access files within launched crouton but can from within chroot?

I recently updated a chroot on an old Chromebook from Ubuntu bionic to focal. The chroot has encryption enabled.
I usually work with Git repositories and other files within the Chrome's Downloads folder and haven't had any issues with this previously.
Since the update though, I found I was unable to run things like git clone -- I get an error saying cannot create worktree dir: no such file found. I looked around and found people had similar problems but there's been no clear solution.
Then I decided to look inside one of the existing folders within Downloads and noticed a problem there...
I can open a repo within my Downloads folder on ChromeOS and see all files as I used to.
I can enter-chroot and run ls on the same folder and see all files as I used to there too.
But when I launch the chroot/crouton (I used xfce4), and try to ls the folder from within the terminal, or even look at the folder contents from a UI window, the contents of the repo look encrypted -- as in all the filenames have changed to strings of equal-length and apparently random characters.
It's almost as if encryption is working in reverse -- so my files are unencrypted outside the crouton, but as soon as I go into the xfce UI, they're encrypted and there's no decryption happening. But that's speculation on my part...
Any ideas as to what is going on here? And how I can continue to work within crouton?
It seems this is to do with the fact that Chrome OS encrypts files and that something had happened since I updated Crouton (rather than my updating Ubuntu from Bionic to Focal).
I realised this was a bigger issue when even command line tools like tar and git (which I'd installed) weren't working.
When I tried to unpack a download of Firefox with tar xjf I got an error saying "Required key not available". Some searching around that led me to issue #3261 on the Crouton Github repo.
The solution for me was:
Ensure /etc/pam.d/su-l was writable. (I did ls -l /etc/pam.d/su-l to check but ultimately used sudo...)
Edit the file /etc/pam.d/su-l. (I used sudo vi /etc/pam.d/su-l to ensure the file wasn't read-only in that instant, and because I had no other text editor options but vi available.)
Comment out the line session optional pam_keyinit.so force revoke. (So it should read # session optional pam_keyinit.so force revoke.
Save the file.
Restart the chroot.

Add a comment to SVN file

I'm exporting a file in one folder and moving it to production without performing an change, using this command:
svn export --username user --password passwd --non-interactive --force svn://svnserver.com/trunk/patch/115/sql/TestFile.sql
After the movement I would like to add a comment/tag that file was moved successfully. For this, I tried the commands below but they didn't work:
> svn commit -m " Test" TestFile.sql
svn: '/home//SVNTEST/1' is not a working copy
> svn commit -m "Test" svn://svnserver.com/trunk/patch/115/sql/TestFile.sql
svn: Must give local path (not URL) as the target of a commit
Will it be possible if yes how to do so?
To summarize, you're copying a file from the repository to your local machine, then you want to somehow indicate in the repository that this action happened.
Without knowing more about your setup, I think creating a tag is probably the most straightforward way to do this. Use this command:
svn copy svn://svnserver.com/trunk/ svn://svnserver.com/tags/115 -m "Test"
Use whatever unique key for the tag name (here I used '115' since it seemed like that was a patch identifier).
Let's discuss why the commands you tried did not work.
Since you're exporting rather than checking out the file, you don't have a working copy. Exporting is basically equivalent to downloading a file from an HTTP or FTP server; there are no strings attached.
Now, the subcommand commit requires a working copy (in order to know where in the repository to put your local changes), which explains why in the first command you tried the error indicated you aren't in a working copy. The second command errored because you (I think) are trying to tell SVN the remote location to upload your local TestFile.sql, which is not a valid use-case for the commit subcommand.
My suggestion creates a tag, but does so entirely on the server which means you don't need a working copy.

Git/Jenkins/Windows (not ordered) line ending issue

I'm playing with a Qt project in Windows. Actually I'm preparing it to build on Linux also. The problem is that the build.sh script (below) inflates 1 byte per line (*) somewhere in the process which makes it fail when it gets executed by the end user.
*I'm comparing the size in the developer machine against the size in the end user machine. Between these, Jenkins (running on Windows) get things from git server and packs a tar.gz file (using cygwin), which the end user gets after all.
#!/bin/bash
qmake Project.pro
make
make clean
How should I approach this issue?
May I provide more information?
To me it looks like git Jenkins is using on Windows has crlf conversion enabled - it will take Linux line endings \n and convert them to \n\r. The symptom you usually see is
/bin/bash^M: bad interpreter: No such file or directory
You should probably set core.autocrlf = input, or at least prevent automatic conversion on script, binary, archives, etc...
See here for more details: https://help.github.com/articles/dealing-with-line-endings/#platform-all. I know it suggests using core.autocrlf = true for Windows, but you are actually using Cygwin on Windows, and you are packing scripts for Cygwin so you probably want core.autocrlf = input (no conversion).

problem using VCSCommand Vim plugin with Mercurial

I just installed VCSCommand and I'm getting an error of "No suitable plugin" whenever I try to run a command. I have a filed loaded in Vim that is in a directory with a mercurial repository.
I found some explanations that the "No suitable plugin" error may be displayed if you're not in a "working directory", which I took to mean that the file you're editing should be in a "working directory" of files checked out from the repository. The problem may that (as a new user to Hg) I don't grok Mercurial properly. The file I'm editing is in a directory where I created an Hg repository just to track my local changes. Commands I issued were 'hg init', then 'hg add' and I've been using 'hg commit', 'hg log', and 'hg diff' happily since. Is this directory not a "working directory" of the repo? Assuming this is the problem, how do I "checkout' the files from the hg repo into a working directory?
Or maybe the above isn't the problem with the "No suitable plugin" error at all. I do have the vcshg.vim file in the correct plugin directory, so the plugin is there.
Thanks, any help appreciated.
UPDATE: Just in case my use of mercurial was the problem I tried creating a 'clone' of my main mercurial repo and editing files in the clone. Still get same 'No suitable plugin.' message.
ALSO: I left out of original message that I'm running on Windows, and I think I've tracked things down to improper quoting of escape codes in strings. Will provide further update once I get full resolution.
I did get VCSCommand going fine. I think the issue had nothing to do with Mercurial, rather it had to do with problems in VCSCommand with quoting of system commands on Windows. At least that was the major problem.
To get VCSCommand working I first made sure that the variable b:VCSCommandVCSType was set to 'HG'. It was not getting set for some reason and that was why I was getting the 'No suitable plugin" error.
Second, I had to modify a line in vcshg.vim. The s:Executable() function consists of a one line 'return . . . ' function. The shellescape() wrapper around the system call was quoting improperly; after I removed that it works just fine. (Same problem may exist in the vcsXX.vim files for systems other than Mercurial, I haven't checked that.)
I think this quoting problem exists only on Windows, and may have cropped up because the main developer doesn't have a Windows machine to test on. . . .
First to answer the "working directory" question: your repository is your working directory. Unlike cvs/svn, you do not need to checkout files to edit. You just edit.
(FYI hg aliases its update command to checkout and co to help svn users, but hg update is a very different animal.)
Without knowing your complete environment (platform, vim installation, etc.), I can only guess that the "No suitable plugin" error is due to your VCSCommand files not in the right place. I tried its latest version 1.99.42 with my ancient vim 7.2 on cygwin by cp VCSCommand/plugin/* ~/.vim/plugin/, vim a file in an hg repo, then :VCSStatus shows me the correct result.
If you have other VCSs that VCSCommand supports (cvs, svn, svk, git, bzr), try it in one of their repositories and see if you get the same error. If you do, then it's definitely a VCSCommand installation problem.

Managing user configuration files across multiple computers

I commonly work on multiple computers. I have various configuration files, eg, .bashrc, .gitconfig, .irbrc, .vimrc and configuration folders, eg, .vim/ that contain valuable customizations.
Sometimes I want small variations in configuration between the different computers.
I want to use version control to manage these different files.
do others use version control to manage their configuration files?
what are some hints that might make this easier?
what's the most elegant way of dealing with variations between the computers?
I'm comfortable with git; any other suggestions?
I keep a folder at ~/config/ which is a bzr repository. I push/pull the repository between my various computers to sync it up. I have an install script which I use to make symlinks to my home directory:
#! /bin/sh
# link all files to the home directory, asking about overwrites
cd `dirname $0`
SCRIPT_DIR=`pwd`
SCRIPT_NAME=`basename $0`
FILES=`bzr ls --versioned --non-recursive`
cd $HOME
for FILE in $FILES; do
ln --symbolic --interactive $SCRIPT_DIR/$FILE
done
rm $TARGET_DIR/$SCRIPT_NAME
If you want to use git instead of bzr, you can instead use:
FILES=`git ls-tree --name-only HEAD`
(I had to ask SO to figure that out)
EDIT: I don't actually do this anymore, now I have a dotfiles repo on github, with a nice rake install script that someone else wrote.
At the moment, I use a cloned git repo. To keep things simple, the only file that needs to vary between the different machines is .bashrc. It's nice if there can be just one version of this file that responds differently on different machines. Thus, in my .bashrc:
if [ $(hostname) == 'host1' ]; then
# things to do differently on host1.
elif [ $(hostname) == 'host2' ]; then
# things to do differently on host2.
fi
This obviously has some limitations (such as that a different technique would be required for .vimrc or other config files needing customization), but it works fairly well.
If you use git, you could define an "origin" repo to be the master; and then do a clone on each computer you work. you could use a branch for every computer to have your set of config files.
With CfEngine you can manage config files across machines and do also many more things!
The learning curve is maybe a bit high but worth it if you have to manage/update/maintain a pool of computers running linux regularly.
Easy. Use DropBox for that:
http://www.nixtutor.com/linux/sync-config-files-across-multiple-computers-with-dropbox/
I use slack for a similar situation. slack allows definition of roles/subroles so you can manage files with small variation either through a cloned file or patch. The slack directory is then managed by git in my deployment.
Here are some dotfile managers:
homesick: Based on Ruby
homeshick: Same as first one, but without ruby dependency
dfm: Written in Perl
git with branches for custom computers, with automated sync at login seems like a good solutions to me.
I've used etckeeper for versioning configurations, but I've never actually expanded to user configurations.
This kind of question comes up occasionally, and I've never seen a tool to handle this common use case, so I wrote a script that uses git and symlinks to manage these files.
See http://github.com/bstpierre/dotfiles
It is not perfect. There is currently a bug related to handling directories, and there is no support yet for variations across computers.
Before using any tool of this nature, make sure you have good backups!
I think what you want could be similar to what I've been doing...
Make a directory in home called .host_configs/ . This is version controlled. Or in my case it lives in a special folder on a central computer, I scp it down on any new machine. Inside it make a folder for every host that you want different configurations for. The folder for each host should be named after the short hostname for that machine. So in your git repo you have:
.host_configs/
homecomp1/
girlfriendcomp1/
workcomp1/
workcomp2/
In each host specific folder, put the .vimrc, .irbrc, etc., configuration files for that specific box.
And also, in each host folder make a file called .[SHORT_HOST]_rc. For instance, if your machine is name "sane" have a file named .sane_rc ... This file will contain the lines that would normally be in .bashrc that are unique to that host. For instance, if it's a mac and it needs alias ls='ls -GF' instead of alias ls='ls --color=auto' which works for most nix machines for ls with colors, put that line in the .[SHORT_HOST]_rc for that machine, along with whatever special functions, declarations, etc, that would normally go into the .bashrc or .profile etc. (or .zshrc, .tschrc, as the case may be). So the version controlled ~/.host_configs/ folder looks like:
.host_configs/
homecomp1/
.homecomp1_rc #special shell configs for this hostname
.vimrc #you know the rest
.irbrc
.Xresources
girlfriendcomp1/
.girlfriendcomp1_rc
.vimrc
.bubblebathrc
workcomp1/
.workcomp1_rc
.bashrc
.vimrc
workcomp2/
.workcomp2_rc
.bashrc
.vimrc
I use all the same barebones $HOME/.bashrc (or ~/.tshrc etc) on all of my machines. I just take the basic one that comes with the distro in question and move all of the host-specific configuration into the .host-configs/[SHORT_HOST]/.[SHORT_HOST]_rc file.
Put this at the bottom (of $HOME/.bashrc):
export SHORT_HOST="sane"
for file in `find ~/.host_configs/$SHORT_HOST -name ".*"`
do
ln -s $file `basename $file`
done
source ~/`.$SHORT_HOST`_rc
(Finds all of the dot-files for the host and makes a symlink in home to the~/.host_configs/foo_host folder).
Your dot files are in their normal location but they are symlinked to version control. The above also sources all of the lines in your [$SHORT_HOST]_rc file into .bashrc
You can commit back to git from the ~/.host_configs/ folder whenever you have changes.
That's what it looks like in shell, which is probably all you need, but if you need other features, I would write something that uses the same principles (sourcing an external .rc file into .bashrc and symlinking all the config files to the structured version control folder) in something more versatile/less ugly than shell. So instead of the above in your .bashrc, there could be:
export SHORT_HOST="sane"
ruby ~/import_conf.rb $SHORT_HOST
...and write your import_conf.rb to do more complex conf management, like placing a specific configuration file in some directory besides home, or handling a config folder like .ssh/, .subversion/ etc. That's what I do, it's pretty elegant for me, but there may be better solutions. Dropbox with some creative symlinks is also an excellent idea, though you're relying on a third party, and you need to be in a graphical environment. Also note there are inconsistencies between what you can do with symlinks + dropbox in Linux and shortcuts + dropbox in Windows if you implement something that wants to play with Windows.
Now there is also vcsh
From the README:
vcsh - manage config files in $HOME via fake bare git repositories
[...]
vcsh allows you to have several git repositories, all maintaining their working trees in $HOME without clobbering each other. That, in turn, means you can have one repository per config set (zsh, vim, ssh, etc), picking and choosing which configs you want to use on which machine.
Works perfectly, but may be a bit daunting if you are not an experienced git user.
Most of these answer address sync, but not how to tailor the files for the specific device. filetailor is an open-source Python program for this exact issue. Based on a YAML configuration file, it can make small changes to the files using device-specific variables or using device-specific comments in the files. Then, use another program such as Syncthing or Git to transfer the files.
For example, the following line would be commented out on every device except the one with hostname device1.
alias MYHOME='/home/dev1home/' #{filetailor device1}
Disclaimer: I had this same issue and made filetailor to solve it.

Resources