Using symlinks between two projects on git - linux

There is server running under CentOS with php-fpm and nginx on aboard. Two projects are hosted, one of them is primary, the second contains half of the primary project as symlinks and part corresponding to itself. Both projects are in git repos. The primary project works correct under Linux and Windows machines after cloning the repo. But the second project contains symlinks and it doesn't work properly.
I don't know what to do. It's important to save the symlinks, but how should we work with the second project on Windows? Some hooks with git (replace symlinks with files before pull)?

git converts symlinks to text files on Windows, since symlinks are available only on *nix environments, and msysgit doesn't take care of them by default.
You can create a post-commit hook to workaround them.
Check answers on git symlinks in windows, specifically this one where a user has given steps to handle the scenario.

You are looking for git submodules: http://git-scm.com/docs/git-submodule

Related

How to use Git worktree on host-guest file system in virtual machine

I'm opening a new worktree in my local repository in Windows, and can't compile it in my Linux virtual machine, because the ".git" contains a full path starting with "C:/Git" that the virtual machine does not recognize.
I have a git repository that I often need to cross-compile on both Windows and Linux.
I originally cloned the repository in my windows system and mounted my "C:" drive as a shared file system in a virtual Ubuntu machine.
This usually works perfectly fine.
When attempting to open a new worktree in git, the linked repository doesn't have it's own ".git" folder, but rather a link to the original repository's ".git" folder, and this is saved as an absolute path, in the following format:
gitdir: C:/Git/...
When attempting to run:
git rev-parse
I get the following message:
fatal: not a git repository: /mnt/hgfs/WindowsDriveC/Git/WorktreeDir/C:/Git/OriginalGitDir/.git/worktrees/WorktreeDir
Due to this limitation, several of my scripts fail.
Is there any way to "trick" Linux into recognizing the full path and properly identifying the original git repo?
Typically, doing this kind of thing is discouraged because it can lead to corruption, and as you've seen the Windows paths don't play well with the Linux paths.
However, that being said, there are a couple of options. One is to set up the worktree under Cygwin or Windows Subsystem for Linux and share it. That will still result in a path that doesn't exist on the Linux VM, but it would be possible to create a symlink from /cygdrive/c or /mnt/c to /mnt/hgfs/WindowsDriveC and then the rest of the stuff would work.
Another option is just to use Windows Subsystem for Linux, which means that you can do your compilation and produce Windows binaries without leaving Windows. You'd produce Linux binaries, but you wouldn't have to worry about sharing with the VM. The worktree would need to be created under WSL, though.
A final option is to edit the .git file in the worktree to use a relative path to the main repository. This is unsupported and might break, but then again it might work for your needs. Be sure to use forward slashes for that purpose.

How can I help git for Windows better handle a repository sitting on a Linux Samba share?

So I work with a Linux VM, I have several repos there with code that I run on the VM. I have a Samba share setup on the VM so I can access the repos from a Windows machine and edit them in Windows. There are many reasons why I have this setup but that would be beyond the scope of this question.
The editing experience is rather good but there is one thing left that's an annoyance: I use Atom on Windows to edit my files and it is great at handling changes within a file using git diff internally. However it colors a number of files as having changed when they have not.
To troubleshoot, I opened a command line on the Windows box and ran git status on the repo, it incorrectly showed a ton of files changed when there are actually no uncommitted changes in the repo. I do all of my git operations on the Linux box but it would be nice to at least have consistent status.
Is there some kind of git config on either the Linux or Windows side that I could use to make the two a little more compatible?
Ok, after digging some more, I've found the issue was due to different file mode flags because of my Samba configuration. I was able to fix things by disabling the fileMode option at the repo level:
git config --unset core.fileMode
And setting it globally on the Windows box:
git config --global core.fileMode true

git - "ignore" or avoid versioning subdirectories

I want to have all my configuration files versioned using Git in a remote repository at Github. I'm using Debian 7 testing, and all my configuration files are under the /home/user_name/ directory.
I created the usual .gitignore with all the files that I want to ignore and the files and directories that I want to allow versioning. My problem begins when I go to Documents, for example, and I see in zsh that folder is under the same versioning as the home directory.
I understand that Git works that way, but I need to know if it's possible to avoid that.
One classic way to version configuration files is to create a subdirectory like ~/etc/ and let your ~/.something files be symbolic links to ~/etc/something. Then, you can version ~/etc/ normally.
You can manage to ignore everything but your configuration files, but you'll always have little glitches like: the day you run git clean -fdx in the wrong place, you delete all your data.
Write */ in your .gitignore to ignore directories. Make exceptions with !foodir. Consider prefixing with slashes (see documentation for details).

What are the files from the 'make' of git that I actually need to run git?

I'm trying to "portablize" git, so I want to send the required executables from the make process of git to my hosted web server. Can I do that? Do you think the executables will work?
The way I do it is to:
get all Git dependencies (as listed in this Solaris package site, but this works for any Unix platform)
compile those dependencies with --prefix=/home/myuser and install them in the usr/local/lib of my home directory
then compile Git (still avoiding any reference to a system path like /usr/local/lib, but only using the lib and include within my homedir)
and install Git in the /home/myuser/git directory
I can then copy only /home/myuser/git and /home/myuser/usr/local (and $prefix/libexec/git-core as Jakub mentions in the comments) to any other similar server, knowing it will work in isolation from any existing system libraries.

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