• git was initially written by Linus Torvalds on the idea: how to create source code management system that does not suck.
  • source code management is very useful when the developer team is x > 1 developer.
  • it allows fast syncing of projects (e.g. from work-desktop to home-laptop and vice versa)
  • It seems to be a very holistic/complete/robust design and implemented file-based (no mysql server needed) source control system,
  • that has some complexity to it. Complexity might be reduced by using scripts or tools (vscode, eclipse) to simplify the tasks.
  • git is not only good for source code management
  • some even use it as content management system (version control of documents and  other files (anything where organized cooperation between multiple users/developers/designers/content creators is important)).
  • GitHub is not run by Linux Foundation or Linus, it is basically not more than “web frontend” for a centralized source code on a not-owned-by-the-user-server system, sold for $7.5 billions to M$
  • thus would avoid it, as the user will see, if the user can setup a ssh server, the user actually already has a git server, as simple as that)
  • but it is possible to setup a self-hosted gitlab (nice web gui)
  • git-server-side-storage-style: when trying to find the files pushed to the git-repo-server, by their filename, the user will probably not get lucky because…
      • “git logically stores each file under its SHA1 as filename, because: if the user has two files with exactly the same content in a repository, only one copy is stored” (src) (Torvalds, what have you done? X-D)

be aware! git is a complex system!

only god & nobody is perfect thus complexity means: errors & problems and this means: frustrations

if the admin-dev-user does not plan to use it on a daily basis, it might not be worth diving down on it and maybe (for small teams might be okay) use (S)FTP? (also very easy to setup)

there definately need to be more tools to simplify the usage of git (pull, merge, push)

GNU Linux SFTP (ftp over ssh) – how to limit users to their home directories

git over ssh is THE IDEAL combination because

  • every GNU Linux / OSX and even Windows (putty) can do ssh
  • ssh enables secure encrypted transfer of the files
  • ssh server is very easy to setup and with strong passwords also very secure (filtering of brute force traffic should non the less be done as well, bash savy admins can look here for inspiration)
  • does DELTA transfer meaning: small changes to big files can be transferred/synced fast (faster internet/more bandwidth is always a plus) (so in theory even large movie.mp4 and sound.wav files should be possible)

given that the requirements:

free -m; # superbly efficient
              total        used        free      shared  buff/cache   available
Mem:            231          65          30           2         135         154
Swap:          1020           0        1020

are already in place (https://dwaves.de/2017/05/05/linux-ssh-generate-public-private-keys/)

one can setup one’s own git repository in 10min:

# tested on
hostnamectl; # client
   Static hostname: client
         Icon name: computer-desktop
           Chassis: desktop
  Operating System: Debian GNU/Linux 10 (buster)
            Kernel: Linux 4.19.0-8-amd64
      Architecture: x86-64

hostnamectl; # server
   Static hostname: git
         Icon name: computer-vm
           Chassis: vm
  Operating System: Debian GNU/Linux 10 (buster)
            Kernel: Linux 4.19.0-8-amd64
      Architecture: x86-64

# for conveniance an ll alias is recommended
# create ll alias to nicely display folder contents
alias ll='ls -lah --color --time-style=+%F'
# add this line to /etc/bashrc or /etc/bash.bashrc

# ===== on (ssh-enabled)server =====
# create repository directory (where to store project on server)
mkdir -p ~/projects/test.git
cd ~/projects/test.git

# initialize the server folder as git repository
git init --bare

# ===== on client =====
# create repository directory (where to store project on client)
mkdir -p ~/projects/test.git
cd ~/projects/test.git

# initialize the client folder as git repository
git init

# create some test data
echo -e "this is a test git repository created on $(date '+%Y-%m-%d-%H:%M:%S')" > README.txt;

# make git realize there are new files
git add .

# the git-system will not proceed, stating it needs to know more about the user
# okay let's give X-D
# this identifies all changes-commits by username@hostname
# (usefull in teams to track: what user from what machine did those changes)
git config --global user.name "user"
git config --global user.email "user@$(hostname)"

# create a commit
git commit -m "added new file README.txt" -a
# connect the server git repository to client
# if 1234 is git-server-ssh-port (change)
git remote add origin ssh://user@server.com:1234/home/user/projects/test.git

# or if the admin-dev-user is on the git-server, it is possible to add "remote" origin just like
git remote add origin /home/user/projects/test.git
# push/sync local changes to server
git push origin master

### HURRAY! :) ONE JUST CREATED A NEW GIT REPO!
# AND SYNCED CHANGES TO IT! :)
# CONGRATULATIONS ALL INVOLVED!

# now let's see if one can pull the changes
# (maybe on a different 3rd (virtual)machine?)
# (anything but localhost works)

# create new test dir
mkdir -p ~/projects/test.clone.git
cd ~/projects/test.clone.git

# pull repo to local folder (folder test will be automatically created)
git clone ssh://user@server.com:1234/home/user/projects/test.git

Cloning into 'test'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.

# let's see what one got
ll

total 28K
drwxr-xr-x   3 user user 4.0K Apr 25 13:29 .
drwxr-xr-x 357 user user  20K Apr 25 13:27 ..
drwxr-xr-x   3 user user 4.0K Apr 25 13:29 test

ll test
total 16K
drwxr-xr-x 3 user user 4.0K 2020-04-25 .
drwxr-xr-x 3 user user 4.0K 2020-04-25 ..
drwxr-xr-x 8 user user 4.0K 2020-04-25 .git
-rw-r--r-- 1 user user   52 2020-04-25 README.txt

cat ./test/README.txt
this is a test git repository created on 2020-04-25

### HURRAY! one just successfully pulled the project from server to client :)

# view status of this git repo (what branch)
git log

# to change the location on server or the server
git remote remove origin
git remote add origin ssh://user@newserver.com:12345/new/location

how to clone the repo?

“cloning” aka downloading the files inside the repo to the local machine works like this:

git clone ssh://user@server.com:1234/home/user/projects/test.git

how to update local?

before changing files!

always pull the latest changes from git-srv! 🙂

this can easily be forgotten…

clone yesterday… work-make-changes today… argh… local files not up to date and might need merging

in order to refresh the local files with the latest changes from git-srv cd into the project folder then:

git pull origin master

PS: git pull origin master does NOT delete newly created local files

let’s script it:

its always more convenient, to just run /scripts/do_stuff.sh ProjectName

than to actually go through each and every necessary command

NOTE!

instead of ~/projects one has (unwisely) chosen /projects (subfolder of root) (please modify X-D)

server:

create new project script

vim /scripts/git.server.add_project.sh

#!/bin/bash
echo "===== create new dir for project ====="
mkdir -p ~/projects/$1

echo "===== change into that dir ====="
cd ~/projects/$1

echo "===== git init --bare ====="
git init --bare

client:

note: my project folder is /projects not /home/user/projects (which might be an better idea depending on how one runs backups)

git.client.add_project.sh

the idea is to create an empty local folder and git repo (which this script generates)

add folders

commit them (commit itself does not upload the files, git push does)

need to be changed: ip and username and port of ssh-git-server

cat /scripts/git.client.add_project.sh

#!/bin/bash
echo "=== create repository directory (where to store project on client) ==="
mkdir -p /projects/$1
cd /projects/$1

echo "=== remove exisint maybe old .git dir if present ==="
rm -rf .git

echo "=== initialize the client folder as git repository ==="
git init

echo "=== make git realize there are new files ==="
git add .

echo -e "this repository was created $(date '+%Y-%m-%d-%H:%M:%S')\n\r and this file is the first/initial commit" > README.txt

echo "=== create a commit ==="
git commit -m "first-initial commit, added README.txt" -a

echo "=== connect the server git repository to client ==="
# 2223 is the port ssh is running on
git remote add origin ssh://$USER@123.ip.of.server:port1234/home/$USER/projects/$1

echo "=== push/sync local changes to server ==="
git push origin master

download = clone a repository server2local:

to download a repo from server2local is called to clone

if ther user pulls a repo it is not cloned (no files visible)

cat /scripts/git.download.project.sh

#!/bin/bash
echo "=== create repository directory (where to store project on client) ==="
mkdir -p /projects/$1
cd /projects/$1

echo "=== remove exisint maybe old .git dir if present ==="
rm -rf .git

echo "=== initialize the client folder as git repository ==="
git init

echo "=== make git realize there are new files ==="
git add .

echo -e "this repository was created $(date '+%Y-%m-%d-%H:%M:%S')\n\r and this file is the first/initial commit" > README.txt

echo "=== connect the server git repository to client ==="
# port1234 is the port ssh is running on
git remote add origin ssh://$USER@123.ip.of.server:port1234/home/$USER/projects/$1

echo "=== push/sync local changes to server ==="
git clone ssh://$USER@123.ip.of.server:port1234/home/$USER/projects/$1

upload/commit changes to server script:

this script is meant that when changes were made to the empty local repo

to upload = commit them

cat /scripts/git.client.commit.sh

#!/bin/bash
echo "=== sync changes from client to master git repo@server ==="
echo "= project: $1 ="

echo "= changing directory ="
cd $1

echo "= adding files ="
git add .

echo "= committing changes ="
git commit -m "$2"

echo "= uploading changes ="
git push origin master


git digital workflow in a nice chart:

Links:

https://www.linux.com/training-tutorials/how-run-your-own-git-server/

https://dwaves.de/2013/11/20/crash-course-g-i-t-git-the-opensource-sourcecode-management-system-by-linus-torvalds-tutorial-getting-started-fast/

https://dwaves.de/2016/10/01/github-com-cheat-sheed/

PS: as with all complex systems/tools, if not used on a daily basis, the usage could be forgotten and needs to be relearned.

but maybe one does not need ALL of it’s features from day one 😉

admin