How can I track system-specific config files in a repo/project? - ruby

I have a ruby project, and the database host and port might be different on dev and production. I need a way to get different values for those into my scripts for the two environments.
The project should be complete - so there should be some way to specify default values. I don't want a clone to be missing the config files. So ignoring them completely won't work.
How do you solve this problem with git?

I would recommend using:
a template config file (a file with variable name in place of the host and port value)
a script able to replace those variable names with the appropriate values depending on the environment (detected by the script)
The Git solution is then a git attribute filter driver (see also GitPro book).
A filter driver consists of a clean command and a smudge command, either of which can be left unspecified.
Upon checkout, when the smudge command is specified, the command is fed the blob object from its standard input, and its standard output is used to update the worktree file.
Similarly, the clean command is used to convert the contents of worktree file upon check-in.
That way, the script (managed with Git) referenced by the smudge can replace all the variables by environement-specific values, while the clean script will restore its content to an untouched config file.
When you checkout your Git repo on a prod environment, the smudge process will produce a prod-like config file in the resulting working tree.

Related

Git - fatal: unable to checkout working tree

I uploaded my Laravel project to a shared server, now I am trying to clone the project from a local computer and I am getting the following error:
error: invalid path 'public/C:\xampp\htdocs\pfuxelacolab\storage\logs/laravel.log'
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/'
Help Please...
You have a repository with a commit that you, personally, cannot use on your system. A Linux user can use this commit, but you can't.
The problem here is the file's name:
public/C:\xampp\htdocs\pfuxelacolab\storage\logs/laravel.log
In a Git commit,1 there are no folders: files simply have long names like this one. Each forward slash / in a committed file's name—and only the forward slashes—will, on a Windows system, be turned into the appropriate backwards slash \ and Git will break up the path into pieces such as public and laravel.log and so on.2 Git will then do what your OS demands: treat each of the various pieces as folder-and-file parts, and make any folders needed so that it can create your OS's idea of a file named laravel.log in your OS's idea of a folder. Git itself doesn't hold with such silly notions: you just have a file with a long name with forward slashes in it, but OSes have these dumb and silly folder-and-file requirements, so, okay, Git will deal with it.
In any case, this file's name includes C: right in the middle—not up front, where some DOS/Windows software might be able to deal with it, but in the middle, after public. So Git is trying to create a new folder, named either C: or C:\xampp\htdocs\pfuxelacolab\storage\logs, within a public folder, and that is never going to work: Windows says you can't do that. Linux, by contrast, says Oh you'd like to create that as a folder name? Sure, done!
So, someone on a Linux or similar system can check out this commit. Having done so, they can fix the file's name or remove the file entirely and make a new commit that doesn't have this bizarro name with the colon and backslashes inside it. Remember, Git demands forward slashes. It will make forward slashes for its own commits, from the OS's folders and files. But it will also take any file names with embedded colons and backslashes found on a Linux system, and make a commit from those, that can't be extracted on a Windows system. That's what someone did: they created a folder named C:\xampp\htdocs\pfuxelacolab\storage\logs in a folder named public, and created a file named laravel.log in that, and then added that to Git's index and committed it, presumably on a Linux system.3
The easiest way for you to deal with this will be to boot up a Linux system (perhaps in a VM) and check out the commit in question and make a corrected one to use instead. Whether you can do this at all in WSL, I have no idea.
1Technically, this claim is true not of the commits themselves, but of Git's index. But commits move "through" the index on the way out to your working tree, and are made from the index, so the condition applies anyway.
2Since I don't use Windows, I don't know whether Git will try to break apart the backslashed pieces here too—but it won't matter because of the C: part. It would be interesting to create a file named test\path/file on a Linux system, commit it, and try to check that commit out on Windows, though. Does Windows Git make a test folder? If not, does it (whether intentionally or merely accidentally) use an existing test folder and make a path folder? But Windows forbids colons in path names, and the embedded C: part, with or without any subsequent part, is the first and fatal problem here.
3While I keep saying "Linux" here, any OS that allows this will suffice, so Solaris or one of the BSDs would do the trick too. You could even do this on macOS.

how to assign a value to a property in the configuration file

There is a configuration file of repository in %path_of_repo%\.hg\hgrc
It has the following configuration:
[paths]
default = C:\STORAGE\REPOSITORIES\PROJ_FIRST
[web]
name = The First Project
encoding = utf-8
I want change property into conf-file an example. But commands like as:
hg config web.name=NewNameOfProject
It doesn't work (
What is the correct syntax for a command that edits parameters from the Hg Mercurial console? Thx
If I have understood your question correctly, it is asking how to use the Mercurial command-line modify its configuration files.
As far as I am aware, you have to edit the config files manually.
Its a little hard to prove that you "can't" do something... but looking at documentation etc. there are a few things which seem to corroborate this impression.
From hg help config:
Files ...
Mercurial reads configuration data from several files, if they exist.
These files do not exist by default and you will have to create the
appropriate configuration files yourself
From hg config --help:
hg config [-u] [NAME]...
show combined config settings from all hgrc files ...
With --edit, start an editor on the user-level config file. With --global,
edit the system-wide config file. With --local, edit the repository-level
config file.
Furthermore all the other instructions for hg config only explain how to get it to display configuration information, not how to modify it.
Using TortoiseHG, obviously in its File > Settings GUI it will allow you to modify certain values in the config files; but there is no general capability to modify any arbitrary value.
THG however does have a nice built-in editor for those files which is at least convenient to use.
So for web.name you would probably use the per-repository <repo>/.hg/hgrc file. It should include:
...
[web]
name=NewNameOfProject
...
for your example.

Illegal Byte sequence in a file name while checking out git branch

I am using git in cli to change the current branch:
git checkout dev
and it produces:
fatal: cannot create directory at 'app/src/androidTest/java?com': Illegal byte sequence
As answered in this question and this one, I tried:
LC_ALL=C git checkout dev
or
LC_CTYPE=C git checkout dev
but I am getting the same error as shown above.
Running:
git status
shows that some of the files were changed by the checkout, but I am still on the master branch.
How can I remove the file causing the problems or how can I checkout the branch without getting this error?
The locale only affects how things are displayed. If the file name contains a character which isn't allowed by the file system, no amount of locale tweaking can fix that.
I can't think of a way to force a file system to let you create a file which then cannot be used, or a good reason to want to be able to do that.
Probably as a workaround, create a virtualized host with a bare-bones Linux system formatted to permit old-style 8-bit file names (Latin-1 or CP1252 if you can live with the unsavory Windows flavor of that), check out the file there, rename and commit the rename back to git. You still won't be able to check out versions of the source tree from before the rename.
I have found a few files in various github projects that are not compatible with one or another operating system. Files with a ".nul" or ".con" extension are a real pain on windows, for example. It isn't a problem exclusive to git. For example Subversion will abort nastily if it can't restore a file for local naming reasons.
In some cases the file may have been uploaded in error. If that is the case for your own projects it should be possible to use the git tools to list the archive and perform a delete of the file from the archive without actually instancing the file locally.
In other cases perhaps that particular file is not significant, and perhaps can be ignored. Perhaps a test will fail if it is missing?
One trick I have used is to stop the whole folder containing that file from being synced by manually creating the directory path, but for the last element, create an empty file instead of a folder. Of course, now the whole test suite will fail.
When the version control tries to do the checkout, it will simply fail to restore the folder, rather than giving a fatal error.
Of course, that only works if the folder is non-critical, e.g. some test files.
The alternative is to piecemeal check-out all but the problem file, but that can be a tedious sequence of checkouts. But you can use this attack to restore the rest of the folder that you omitted using the above technique. Alternatively, locally drag the files from the zip download if they are non-critical.

zsh/mercurial help on every command

Every command I make in terminal while in zsh I get the mercurial help appended.
Example:
$ ls
Applications Developer Library Pictures VirtualBox VMs
Consensus Documents Movies Projects
Desktop Downloads Music Public
haaduken at nachi in ~Mercurial Distributed SCM
basic commands:
add add the specified files on the next commit
annotate show changeset information by line for each file
clone make a copy of an existing repository
commit commit the specified files or all outstanding changes
diff diff repository (or selected files)
export dump the header and diffs for one or more changesets
forget forget the specified files on the next commit
init create a new repository in the given directory
log show revision history of entire repository or files
merge merge working directory with another revision
pull pull changes from the specified source
push push changes to the specified destination
remove remove the specified files on the next commit
serve start stand-alone webserver
status show changed files in the working directory
summary summarize working directory state
update update working directory (or switch revisions)
use "hg help" for the full list of commands or "hg -v" for details
$
I have absolutely no idea why. Any ideas how I can stop this? A lot of people are saying alias, but hg isn't in my alias list at all.
Did you add a Mercurial command to your PS1 variable? Some people do this, to display the current branch or bookmark.
What does 'echo $PS1' show?
It's possible you added an incorrect Mercurial command there, which results in printing the help message.

Ruby scripting - how to keep track of configurations

I am writing a system script in Ruby.
I'm using the classic gem structure: lib, bin, spec for RSpec.
I want to build a configurable script: I want to be able to provide options like --set-stuff and alike. A perfect example is:
git config --global user.name "Andrea"
which writes the given information out to a file, in order to be able to retrieve this information later.
How can I do this in a clean way?
I'd rather not use the environment variable solution: I know I could just set an env variable to point to a configuration file, but then I'd have to save this env variable in, say, .bashrc. Then again, how do I deal with zsh? Or how do I deal with people (like me) who keep their .bashrcs super-neat or even have a separate .env-variables file in their system?
Just stick the configuration into a Hash and serialize it into a file in the user's home directory as YAML or JSON...

Resources