How to deploy Gitlab project branch to directory - php

I have a Gitlab server (Ubuntu 14.04) where I am trying use it as both a host for my repositories as well as a testing server for my PHP projects. Ideally, I would like to have Gitlab/Git export the "release" branch to /var/www/git/<project-name> when that branch is updated.
My Question: How can I export a specific branch in Gitlab, to a specific directory on the localhost, when the branch is updated?
I am aware that there are webhooks available in Gitlab, but it seems unnecessary and wasteful to have the server POST to itself for a local operation.

I suppose you are running the community edition of gitlab.
Then, only the server administrator can configure hook scripts by copying the required scripts into the affected repositories.
gitlab itself is using the $GIT_DIR/hooks directory for its own scripts already. Fortunately they forward control to any hook script in the gitlab specific $GIT_DIR/custom_hooks directory. See also this question about how to run multiple hooks with the same type on gitlab.
The script itself could look like this:
#!/bin/bash
#
# Hook script to export current state of repo to a release area
#
# Always hardcode release area - if configured in the repo this might incur data loss
# or security issues
echo "Git hook: $0 running"
. $(dirname $0)/functions
git=git
release_root=/gitlab/release
# The above release directory must be accessible from the gitlab server
# and any client machines that want to access the exports. Please configure.
if [ $(git rev-parse --is-bare-repository) = true ]; then
group_name=$(basename $(dirname "$PWD"))
repo_name=$(basename "$PWD")
else
cd $(git rev-parse --show-toplevel)
group_name=$(basename $(readlink -nf "$PWD"/../..))
repo_name=$(basename $(readlink -nf "$PWD"/..))
fi
function do_release {
ref=$1
branch=$2
# Decide on name for release
release_date=$(git show -s --format=format:%ci $ref -- | cut -d' ' -f1-2 | tr -d -- -: | tr ' ' -)
if [[ ! "$release_date" =~ [0-9]{8}-[0-9]{6} ]]; then
echo "Could not determine release date for ref '$ref': '$release_date'"
exit 1
fi
dest_root="$release_root/$group_name/$repo_name"
dated_dir="dated/$release_date"
export_dir="$dest_root/$dated_dir"
# Protect against multiple releases in the same second
if [[ -e "$export_dir" ]]; then
export_dir="$export_dir-02"
dated_dir="$dated_dir-02"
while [[ -e "$export_dir" ]]; do
export_dir=$(echo $export_dir | perl -pe 'chomp; print ++$_')
dated_dir=$(echo $dated_dir | perl -pe 'chomp; print ++$_')
done
fi
# Create release area
if ! mkdir -pv "$export_dir"; then
echo 'Failed to create export directory: ' "$export_dir"
exit 1
fi
# Release
if ! git archive $branch | tar -x -C "$export_dir"; then
echo 'Failed to export!'
exit 1
fi
chmod a-w -R "$export_dir" # Not even me should change this dir after release
echo "Exported $branch to $export_dir"
( cd "$dest_root" && rm -f latest && ln -s "$dated_dir" latest )
echo "Adjusted $dest_root/latest pointer"
}
process_ref() {
oldrev=$(git rev-parse $1)
newrev=$(git rev-parse $2)
refname="$3"
set_change_type
set_rev_types
set_describe_tags
echo " Ref: $refname","$rev_type"
case "$refname","$rev_type" in
refs/heads/*,commit)
# branch
refname_type="branch"
function="branch"
short_refname=${refname##refs/heads/}
if [[ $short_refname == release ]]; then
echo " Push accepted. Releasing export for $group_name/$repo_name $short_refname"
do_release "$refname" "$short_refname"
else
echo " Push accepted. No releases done for $group_name/$repo_name $short_refname"
fi
;;
refs/tags/*,tag)
# annotated tag
refname_type="annotated tag"
function="atag"
short_refname=${refname##refs/tags/}
;;
esac
}
while read REF; do process_ref $REF; done
exit 0
The script was started based on this post-receive.send_email script which is already quoted on SO multiple times.
Configure a release area in the variable hardcoded in the script, or e.g. add a mechanism to read a config file in the repo. Maybe you want to give users control over this area. Depends on your security circumstances.
The release area must be accessible by the git#gitlab user, and of course by any client expecting the export.
The branch to export is hardcoded in the script.
The release area will be populated like this:
$release_root/$group_name/$repo_name/dated/$release_date
Plus a symbolic link latest pointing to the latest $release_date. The idea is that this is extensible to later be able to also export tags. If you expect to export different branches, a $branch should be included as a path component, too.
Access control of the gitlab server is not passed down to the directory structure. Currently I do this manually, and that is why I do not auto-populate all new repositories with this hook. I'd rather configure manually, and then adjust unix group permissions (and/or ACLs) on the $release_root/$groupname paths accordingly. This needs to be done only once per group and works because no one else is allowed to create new groups on my gitlab instance. This is very different from the default.
Anything else we can do for you? ;-)

Related

Php exec git pull script with ssh doesn't work but doing it manually works

I'm trying to make a script where I can Git pull on my ubuntu server after push to Bitbucket repository. I've setup ssh keys to Bitbucket and it works to do git pull command on the repository but it doesn't work when I try it from php exec.
I've tried chmod commands like /.ssh/bitbucket_rsa like 775 and 777 and chown -R www-data:www-data/.ssh without any luck.
Response:
array (
0 => 'Host key verification failed.',
1 => 'fatal: Could not read from remote repository.',
2 => '',
3 => 'Please make sure you have the correct access rights',
4 => 'and the repository exists.',
)
Code:
public function gitPull() {
try {
exec("cd " . env("REPO_PATH") . " && git pull 2>&1", $output);
Log::info($output);
} catch (\Exception $e) {
Log::error($e);
}
http_response_code(200);
}
I guess you are stuck with the fact that the user www-data can not establish the SSH connection to the git server. I think the simplest was is to create a home directory for the www-data user and create a .ssh directory with the proper permissions, a config file and the key file in there. You could always test the setup as root with
# su - www-data
$ cd <to your repository>
$ git pull
Google for "SSH connections without password" to set it up correctly. And also be aware that SSH refuses to use a key file if the permissions are to loose.
Host key verification failed.
means that ssh could not verify the host key, most likely because there's no known_hosts file in www-data's home/.ssh directory that contains the expected host key for your repo's server.
There's at least two ways to fix that:
Use ssh-keyscan as described over on Serverfault.se:
ssh-keyscan -H [hostname] >> /path/to/www-data's_home_directory/.ssh/known_hosts
You only need to do that once (unless the key changes), but you should check that the key is indeed correct after you run ssh-keyscan.
Set the GIT_SSH_COMMAND environment variable before running git. You can use this to have ssh use a different known_hosts file:
export GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/path/to/known_hosts"
Note that the above assumes shell syntax (e.g. Bash), you may need to adjust for PHP, particularly the export GIT_SSH_COMMAND= part.
I stack with the same problem working with github:
ssh-keyscan -t rsa github.com | tee github-key-temp | ssh-keygen -lf -
cat github-key-temp >> ~/.ssh/known_hosts
cat github-key-temp >> /etc/ssh/ssh_known_hosts
But that is not all, with next command you can check what is goes wrong (run it throught exec or shell_exec (save out put to some log):
ssh -vT git#github.com 2>&1
So, with help of privious command, i understand that in my case: cron run's command via php script, but duaring ssh connection it could not find my keysfile (i have custom name for that file):
cd /etc/ssh/ssh_config.d/
sudo touch <some_name>.conf
sudo echo 'IdentityFile ~/.shh/<custom_key_file_name>' > <some_name>.conf
Or try to add full path to location of your keyfile (~/ = current user home dir).
You can check cron user by runing, this can helps to:
shell_exec('whoami');
P.S. I have no idea if this solution is enough secure. but i think fine.

Ubuntu export /opt/lampp/lampp into PATH

I'm trying to put lampp into my Ubuntu Path but I'm seemingly doing something wrong because it doesn't work.
I put this into the ~/.bashrc file :
export PATH="/opt/lampp/lampp:$PATH"
and then I ran the following command in ~ :
$ source .bashrc
Thanks for your help
EDIT
Here is the content of the file .bashrc :
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth
# append to the history file, don't overwrite it
shopt -s histappend
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize
# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar
# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
debian_chroot=$(cat /etc/debian_chroot)
fi
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color|*-256color) color_prompt=yes;;
esac
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u#\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u#\h:\w\$ '
fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user#host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u#\h: \w\a\]$PS1"
;;
*)
;;
esac
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi
# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
# Add an "alert" alias for long running commands. Use like so:
# sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
### Added by the Heroku Toolbelt
export PATH="/usr/local/heroku/bin:$PATH"
export PATH="/opt/lampp/lampp:$PATH"
Okay, so I think I know what's going on! Change your $PATH line in ~/.bashrc to the following:
export PATH="/opt/lampp:$PATH"
Then try source ~/.bashrc, or open a new terminal. You should now have the lampp and xampp commands available. Both should do the same thing.
The problem is that the $PATH variable points to directories that contain executable files, rather than pointing to executable files directly. It appears that /opt/lampp/lampp is a symbolic link that points to /opt/lampp/xampp, which is an executable.
UPDATE: When you use sudo, it's likely not honoring your $PATH variable for security reasons. You might try running sudo visudo, and editing the line that says Defaults secure_path="..." to include /opt/lampp. Then sudo lampp start should work!
I also faced the same problem to fix this first goto your .bashrc file in the home directory of your ubuntu type the following command in the terminal :
export PATH="/opt/lampp/lampp:$PATH"
now type this in the terminal
vim ~/.bashrc
like this add your export path command you entered first at the starting
Now you have to edit the visudo so that your path can be in the list of secured paths so that you can use sudo with the xampp or lampp command otherwise it won't work
sudo visudo
Now like in the photo above append ":/opt/lampp" at the end of the secure path
then press ctrl + X then enter
your work is done now now you can use xampp anywhere with sudo privelages
To list all the commands of the xampp you can write in the terminal
xampp
and it'll show this

git does not recognize renamed file with only a change in case [duplicate]

I have changed a few files name by de-capitalize the first letter, as in Name.jpg to name.jpg. Git does not recognize this changes and I had to delete the files and upload them again. Is there a way that Git can be case-sensitive when checking for changes in file names? I have not made any changes to the file itself.
As long as you're just renaming a file, and not a folder, you can just use git mv:
git mv -f yOuRfIlEnAmE yourfilename
(As of a change in Git 2.0.1, the -f flag in the incantation above is superfluous, but it was needed in older Git versions.)
Git has a configuration setting that tells it whether to expect a case-sensitive or insensitive file system: core.ignorecase. To tell Git to be case-senstive, simply set this setting to false. (Be careful if you have already pushed the files, then you should first move them given the other answers).
git config core.ignorecase false
Note that setting this option to false on a case-insensitive file system is generally a bad idea. Doing so will lead to weird errors. For example, renaming a file in a way that only changes letter case will cause git to report spurious conflicts or create duplicate files(from Mark Amery's comment).
Documentation
From the git config documentation:
core.ignorecase
If true, this option enables various workarounds to enable git to work better on filesystems that are not case sensitive, like FAT. For example, if a directory listing finds makefile when git expects Makefile, git will assume it is really the same file, and continue to remember it as Makefile.
The default is false, except git-clone(1) or git-init(1) will probe and set core.ignorecase true if appropriate when the repository is created.
Case-insensitive file-systems
The two most popular operating systems that have case-insensitive file systems that I know of are
Windows
OS X
Using SourceTree I was able to do this all from the UI
Rename FILE.ext to whatever.ext
Stage that file
Now rename whatever.ext to file.ext
Stage that file again
It's a bit tedious, but if you only need to do it to a few files it's pretty quick
Fix git filename case on whole repo:
git rm -r --cached .
git add --all .
git status ##Review that **only** changes staged are renames
## Commit your changes after reviewing:
git commit -a -m "Fixing file name casing"
git push origin master
Explanation from #Uriahs Victor comment:
What this command actually does is deletes the cached version of the
file/folder names that git thought still existed. So it will clear its
cache but leave everything in the current folder (where you've made
your changes locally) but it will see that those other wrong case
folders/files do not exist anymore so will show them as deleted in git
status. Then you can push up to github and it will remove the
folders/files with wrong cases. This answer has a graphic depicting
what the command means.
This is what I did on OS X:
git mv File file.tmp
git mv file.tmp file
Two steps because otherwise I got a “file exists” error. Perhaps it can be done in one step by adding --cached or such.
Sometimes it is useful to temporarily change Git's case sensitivity.
Method #1 - Change case sensitivity for a single command:
git -c core.ignorecase=true checkout mybranch to turn off case-sensitivity for a single checkout command. Or more generally: git -c core.ignorecase= <<true or false>> <<command>>. (Credit to VonC for suggesting this in the comments.)
Method #2 - Change case sensitivity for multiple commands:
To change the setting for longer (e.g. if multiple commands need to be run before changing it back):
git config core.ignorecase (this returns the current setting, e.g. false).
git config core.ignorecase <<true or false>> - set the desired new setting.
...Run multiple other commands...
git config core.ignorecase <<false or true>> - set config value back to its previous setting.
We can use git mv command. Example below , if we renamed file abcDEF.js to abcdef.js then we can run the following command from terminal
git mv -f .\abcDEF.js .\abcdef.js
Under OSX, to avoid this issue and avoid other problems with developing on a case-insensitive filesystem, you can use Disk Utility to create a case sensitive virtual drive / disk image.
Run disk utility, create new disk image, and use the following settings (or change as you like, but keep it case sensitive):
Make sure to tell git it is now on a case sensitive FS:
git config core.ignorecase false
Similar to #Sijmen's answer, this is what worked for me on OSX when renaming a directory (inspired by this answer from another post):
git mv CSS CSS2
git mv CSS2 css
Simply doing git mv CSS css gave the invalid argument error: fatal: renaming '/static/CSS' failed: Invalid argument perhaps because OSX's file system is case insensitive
p.s BTW if you are using Django, collectstatic also wouldn't recognize the case difference and you'd have to do the above, manually, in the static root directory as well
rename file Name.jpg to name1.jpg
commit removed file Name.jpg
rename file name1.jpg to name.jpg
amend added file name.jpg to previous commit
git add name.jpg
git commit --amend
I tried the following solutions from the other answers and they didn't work:
git mv filename
git rm -f filename
If your repository is hosted remotely (GitHub, GitLab, BitBucket), you can rename the file on origin (GitHub.com) and force the file rename in a top-down manner.
The instructions below pertain to GitHub, however the general idea behind them should apply to any remote repository-hosting platform. Keep in mind the type of file you're attempting to rename matters, that is, whether it's a file type that GitHub deems as editable (code, text, etc) or uneditable (image, binary, etc) within the browser.
Visit GitHub.com
Navigate to your repository on GitHub.com and select the branch you're working in
Using the site's file navigation tool, navigate to the file you intend to rename
Does GitHub allow you to edit the file within the browser?
a.) Editable
Click the "Edit this file" icon (it looks like a pencil)
Change the filename in the filename text input
b.) Uneditable
Open the "Download" button in a new tab and save the file to your computer
Rename the downloaded file
In the previous tab on GitHub.com, click the "Delete this file" icon (it looks like a trashcan)
Ensure the "Commit directly to the branchname branch" radio button is selected and click the "Commit changes" button
Within the same directory on GitHub.com, click the "Upload files" button
Upload the renamed file from your computer
Ensure the "Commit directly to the branchname branch" radio button is selected and click the "Commit changes" button
Locally, checkout/fetch/pull the branch
Done
With the following command:
git config --global core.ignorecase false
You can globally config your git system to be case sensitive for file and folder names.
Mac OSX High Sierra 10.13 fixes this somewhat. Just make a virtual APFS partition for your git projects, by default it has no size limit and takes no space.
In Disk Utility, click the + button while the Container disk is selected
Select APFS (Case-Sensitive) under format
Name it Sensitive
Profit
Optional: Make a folder in Sensitive called git and ln -s /Volumes/Sensitive/git /Users/johndoe/git
Your drive will be in /Volumes/Sensitive/
How do I commit case-sensitive only filename changes in Git?
so there are many solutions to this case sensitivity deployment problem with how GitHub handles it.
In my case, I had changed the filename casing convention from uppercase to lowercase.
I do believe that git can track the change but this command
git config core.ignorecase false dictates how git operates behind the scenes
In my case, I ran the command and git suddenly had lots of files to track labeled untracked.
I then hit git add. , then git committed and ran my build on netlify one more time.
Then all errors now displayed could be traced e.g
Module not found: Can't resolve './Components/ProductRightSide' in '/opt/build/repo/components/products and fixed such that git was able to track and implement the changes successfully.
It's quite a workaround and a fingernail away from frustration but trust me this will surely work.
PS: after fixing your issue you may want to run the command
git config core.ignorecase true to restore how git works with case sensitivity.
Also, note git config core.ignorecase false has issues with other filename extensions so you may want to watch out, do it if you know what you’re doing and are sure of it.
Here's a thread on netlify that can help out, possibly
When you've done a lot of file renaming and some of it are just a change of casing, it's hard to remember which is which. manually "git moving" the file can be quite some work. So what I would do during my filename change tasks are:
remove all non-git files and folder to a different folder/repository.
commit current empty git folder (this will show as all files deleted.)
add all the files back into the original git folder/repository.
commit current non-empty git folder.
This will fix all the case issues without trying to figure out which files or folders you renamed.
I've faced this issue several times on MacOS. Git is case sensitive but Mac is only case preserving.
Someone commit a file: Foobar.java and after a few days decides to rename it to FooBar.java. When you pull the latest code it fails with The following untracked working tree files would be overwritten by checkout...
The only reliable way that I've seen that fixes this is:
git rm Foobar.java
Commit it with a message that you cannot miss git commit -m 'TEMP COMMIT!!'
Pull
This will pop up a conflict forcing you to merge the conflict - because your change deleted it, but the other change renamed (hence the problem) it
Accept your change which is the 'deletion'
git rebase --continue
Now drop your workaround git rebase -i HEAD~2 and drop the TEMP COMMIT!!
Confirm that the file is now called FooBar.java
I took #CBarr answer and wrote a Python 3 Script to do it with a list of files:
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import os
import shlex
import subprocess
def run_command(absolute_path, command_name):
print( "Running", command_name, absolute_path )
command = shlex.split( command_name )
command_line_interface = subprocess.Popen(
command, stdout=subprocess.PIPE, cwd=absolute_path )
output = command_line_interface.communicate()[0]
print( output )
if command_line_interface.returncode != 0:
raise RuntimeError( "A process exited with the error '%s'..." % (
command_line_interface.returncode ) )
def main():
FILENAMES_MAPPING = \
[
(r"F:\\SublimeText\\Data", r"README.MD", r"README.md"),
(r"F:\\SublimeText\\Data\\Packages\\Alignment", r"readme.md", r"README.md"),
(r"F:\\SublimeText\\Data\\Packages\\AmxxEditor", r"README.MD", r"README.md"),
]
for absolute_path, oldname, newname in FILENAMES_MAPPING:
run_command( absolute_path, "git mv '%s' '%s1'" % ( oldname, newname ) )
run_command( absolute_path, "git add '%s1'" % ( newname ) )
run_command( absolute_path,
"git commit -m 'Normalized the \'%s\' with case-sensitive name'" % (
newname ) )
run_command( absolute_path, "git mv '%s1' '%s'" % ( newname, newname ) )
run_command( absolute_path, "git add '%s'" % ( newname ) )
run_command( absolute_path, "git commit --amend --no-edit" )
if __name__ == "__main__":
main()
If nothing worked use git rm filename to delete file from disk and add it back.
I made a bash script to lowercase repository file names for me:
function git-lowercase-file {
tmp="tmp-$RANDOM-$1"
git mv -f $1 $tmp
git mv -f $tmp ${1,,}
}
then you can use it like this:
git-lowercase-file Name.jpg
Or simply rename the required file over git repository web UI interface and commit :)
If you're doing more complex change, like directory name casing change,
you can make that change from a Linux machine, because Linux itself (as well as git on Linux) treats files/directories with same names but different casing as completely different files/directories.
So if you're on Windows, you can install Ubuntu using WSL, clone your repo there, open the cloned repo directory using VSCode (use WSL remote extension to access WSL Ubuntu from Windows), then you will be able to make your renames through VSCode and commit/push them using VSCode git integration.

Providing HTTP read-only access to svn checkout on a PHP server?

I have some Subversion repositories (originally created with svnadmin) on a server; there is authenticated SSH read+write access via svn+ssh://. For certain of those SVN repositories, I would like to allow an anonymous read-only access via http://. The problem is I don't have administrative properties on that server, so I cannot really mess with server setups or run svnserve, but I can have PHP scripts. So I was wondering if there is some solution, hopefully in PHP, that would allow me to do that (implement a "bridge" to a subversion repository, that the svn client could check out from)?
I'd like to compare what I want to do with git. If I do a git init in a directory, I get the subfolder .git which contains exactly the same contents of a bare repo. I can clone this bare repo with git clone --bare ... and then upload it to a server - then I can directly clone using git clone http://... and the location of the bare repo (except that at first, git will complain with fatal: ... info/refs not found: did you run git update-server-info on the server?; this means that I should enable the default post-update hook [which] runs git update-server-info to keep the information used by dumb transports (e.g., HTTP) up-to-date.; or run git update-server-info in the bare repo, so info/refs is generated - only then can this bare repo on server be cloned on client via HTTP).
So, I'd consider the svnadmin created repo (with contents dav db format hooks locks README.txt) to be equivalent to the git bare repo (as they both contain the entire history, without the actual files), so I hoped that the svnadmin repo could be setup for read-only HTTP cloning in the same way (that is, just by copying that folder contents on the server). Unfortunately, that is not so - it seems that even with HTTP access, svn actually communicates with a form of WebDAV on the server (Subversion Users: Re: dav directory does not exist; SVN RedBook: What is WebDAV?). So I tried sabre/dav out, but after a succesful plain setup (tested with cadaver DAV command line tool), I can only get svn: OPTIONS of 'http://...': 200 OK (http://...) if I point to a svnadmin repo directory (or to its dav/ subdirectory).
I guess what I want is probably not possible at the time:
Re: SVN or git via WebDav using SabreDAV - Google Groups
The SVN protocol requires a TON of extensions to plain webdav to work. You're basically out of luck here.
... but I wanted to confirm for sure with this question...
Thanks to the answer from #Evert; but unfortunately svnsync doesn't seem to help me here (it fails with "Repository moved permanently"); here is a set of commands that I run in bash on an Apache server directory, with some command responses written prefixed with #:
svn --version
# svn, version 1.6.6 (r40053)
cd /media/www
svnadmin create mytest.svnfs
svn co file:///media/www/mytest.svnfs mytest.svn
cd mytest.svn
echo aaa >> test.txt
svn add test.txt
svn commit -m "init commit"
echo bbb >> test.txt
svn add test.txt
svn commit -m "2nd com mit"
wget -q --no-check-certificate http://localhost/mytest.svn -O - | head --bytes 120
# <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
# <html>
# <head>
# <title>Index of /mytest.svn</title>
cd ..
svnadmin create mytest.mirror
cat > mytest.mirror/hooks/pre-revprop-change <<'EOF'
#!/bin/sh
USER="$3"
if [ "$USER" = "syncuser" ]; then exit 0; fi
echo "Only the syncuser user can change revprops" >&2
exit 1
EOF
chmod +x mytest.mirror/hooks/pre-revprop-change
cat > mytest.mirror/hooks/start-commit <<'EOF'
#!/bin/sh
USER="$2"
if [ "$USER" = "syncuser" ]; then exit 0; fi
echo "Only the syncuser user may commit new revisions" >&2
exit 1
EOF
chmod +x mytest.mirror/hooks/start-commit
ls --ignore="*.tmpl" mytest.mirror/hooks/
# pre-revprop-change start-commit
svnsync initialize file:///media/www/mytest.mirror http://localhost/mytest.svnfs/ --sync-username syncuser --sync-password syncpass
# svnsync: Repository moved permanently to 'http://localhost/mytest.svnfs/'; please relocate
# trying the working copy (even if it shouldn't work):
svnsync initialize file:///media/www/mytest.mirror http://localhost/mytest.svn/ --sync-username syncuser --sync-password syncpass
# svnsync: Repository moved permanently to 'http://localhost/mytest.svn/'; please relocate
I wrote that answer, and it still holds true.
In a nutshell:
The SVN server can speak webdav, Delta-V (a versioning extension for webdav)
The SVN client takes advantage of that server, but also requires svn extensions.
This was true several years ago, so the situation may have changed... but I sincerely doubt it.
However.. for what you want to do, it sounds like you just want to use svnsync.
http://svnbook.red-bean.com/en/1.7/svn.reposadmin.maint.html#svn.reposadmin.maint.tk.svnsync

Checkout Subversion last changes to upload to FTP

If I make small changes in let's say five different files and commit these to Subversion, how can I checkout just exactly these files in original folder structure to upload and overwrite on FTP Server later on?
If I try to check out HEAD non recursive I just get index.php and some different files which have nothing in common with last changes.
Attached solution:
I made a small script - not very elegant but it works ...
#!/bin/bash
URL='http://svn ...';
TARGET='./ftp';
read -p "Please enter start revision: " VERSION1
read -p "Please enter ending revision: " VERSION2
read -p "Remove old? [yes] " remove
# getting changes
svn diff $URL --summarize -r$VERSION1:$VERSION2 > changes
# checkout complete revision
svn checkout $URL -r HEAD
# remove previous
if [ $remove = 'yes'] ; then
if [ -d $TARGET ] ; then
rm -r $TARGET
else
mkdir $TARGET
fi
fi
for entry in `cat changes`; do
e=${entry#*$URL/}
item=$TARGET'/'$e;
DIR=${item%/*}
# create directory
if [ -d $DIR ] ; then
echo '';
else
mkdir -p $DIR
fi
cp './trunk/'$e $DIR
echo $e
done
echo "Done ..."
read any
It checks out the complete trunk and extracting the files which were changed in range of revisions given.
In the root of existing working copy
svn diff --summarize -rN:M
and work with second column
If you have full control of your server, you can svn checkout the particular repo path on the target server, and then run an svn update to acquire the latest files as needed.

Categories