V e r s i o n C o n t r o l S y s t e m Git
Brackets | Example | Meaning |
---|---|---|
Square | [argument] | Argument is mandatory. |
Curly | {argument} | Argument is optional. |
Round | (argument) | Argument is not part of the syntax but was inserted as an explanation. |
Angle | <argument> | Argument is a variable to be replaced by a value. |
-
Before 2016, there was no acute need for a Version Control System (VCS).
Internal implementation projects were merely feasibility studies: Only the final version of each implementation (branch) would be secured using the same standard backup procedure as for the rest of my data.
Future projects might require a sophisticated maintenance of sources: They will include more sources, they will manage concurrent branches, they will possibly require cooperation between distant developers.I will not debate whether Git - compared to other VCS - is a better choice or why: I cooperate with developers who use Git extensively. Focus of this documentation are issues that I have (or will have) to solve in projects I will be involved in.
-
In their book
Pro Git Book, Scott Chacon and Ben Straub explain the model behind the Distributed Version Control System (DVCS) implemented in Git. If users bear it in mind, they will avoid misunderstandings or wrong handling. There are several conceptualization levels to explain a model. Scott Chacon and Ben Straub distinguish 2 levels:
- A general level listing abstract characteristics of Git - say its general modelling principles
- A more precise representation of features that should allow developers to come to theirs conclusions.
-
Git considers data history as a stream of snapshots.
Git does not store a list of file-based changes but rather view the data as a set of snaphots of a miniature file system. Every time you commit or save the state of project, Git takes a picture of what the files look like at that moment and stores a reference to that snapshot.If between two snapshots a file has not changed, Git just links to it (instead of storing the same data twice).
Each Git repository stores the complete branching information locally.
This is especially the case, if a team of developers cooperates remotely. Each part of the team may have a Git repository on their server that will be 'synchronized' from time to time. From the Git perspective, no repository is more important as any other.
-
Git attributes to each controlled file one of the following state:
- committed: The file is safely stored in the (local) repository,
- modified: The file has been changed since the last commit,
- staged: The modified file will be included into the next commit.
Git structures its git repository into 3 "trees":
The working Directory
holds actual project data/files (more exactly, it is a single checkout of one version of the project):
Each file in the working directory can be either tracked or untracked.- Untracked files are ignored (not under source control).
- Tracked are those files that were in the last snapshot: They can be unmodified, modified or staged.
Meta-data index
designates the staging area (Staged files are modified files to be included into the next commit(-object)).Meta-data HEAD
is a pointer to the last commit-(object) of the current branch i.e. a pointer to the tip of the current branch.
Note that in Git terminology a head (lower case) is a pointer to a tip of one branch: HEAD (upper case) simply designates the head of the current branch.
The tree organization above as well as the fact that each local repository is a complete replication account for what seems to be additional user steps in order to secure changes - at least in comparison with some other source control programs.
Roger Dudler)
The repository structure above bases on the way how the Git designers perceive the software development process:
- A Developer changes/updates files.
- Git action add transfers state of file from changed to staged.
- Git action commit transfers state of file from staged to committed.
-
Branching:
Branching is a fundamental functionality of any VCS. Most development projects do not maintain a single (time) line, but rather concurrent versions of sources - the so-called branches - that may merge as the project progresses. According to S. Chacon and B. Straub, Git makes branching comparatively easy - lightweight - because of the manner it proceeds.When a content is staged:
Git processes each modified file into a repository file called blob that is named after the checksum (
SHA-1 hash) of associated content.
When a content is committed:
Git processes each subdirectory of the working area to a tree-file stored into the repository. A tree-file basically links the names of all source file in the subdirectory with their currently associated blob names. Tree-files are also named after the checksum of an associated content. (S. Chacon and B. Straub write: "Git checksums each subdirectory".)
Git creates a commit-object containing following meta-data:
- A pointer to each tree-file.
- The author's name and his email
- The commit message
- Pointers to the predecessor commit-object(s): the so-called parent(s). Initial commit-objects have no parent. Commit-objects have several parents, if they result from a merge of two or more branches.
SHA-1) of associated content.
git Chapter 3 by S. Chacon and B. Straub)
Above, the simplified representation of the git repository tracking a project with only 3 data files README, LICENSE, test.rb.
- The data files have been staged as blobs 5b1d3, 911e7, cba0a.
- Since this project has no subdirectory, there is only one tree-file 92ec2 listing 3 pairs [blob (id)] [file (name)].
- The commit-object 98ca9 points to tree-file 92ec2 representing the "project snapshot".
As the project progresses, developers add successive commit(-objects): A development line is simply a chain of commits, pinpointing valuable stations as the project matures. Each commit points to a snapshot (to retrieve the content) and to its predecessor(s) (to retrieve the history).
git Chapter 3 by S. Chacon and B. Straub)
- Commit(-object) 98ca9 the initial commit-object points to the original snapshot of project A (allowing to retrieve the state of the working directory as the repository was initiated).
- Next commit(-object) 34ac2 points to the next snapshot of project B. It also points to its parent commit 98ca9 and so on.
The development line shown above is obviously the main development line - since it begins with initial commit 98ca9.
git Chapter 3 by S. Chacon and B. Straub)
Each development line - linear chains of commits - is associated with a branch-object, pointing to the last commit of that branch, its tip: A branch is identified by its branch-object. By default (unless the user explicitly decides otherwise) the main development line is associated with the Git branch named master.
Fig. 4 shows the same project as in Fig. 3, at the development line level. The main line is a branch like any other - with the property that its first commit has no parent. By default, Git names the branch(-object) representing the main line master - master points to the last commit in the main line.
Git knows which branch is currently activated by means of an additional pointer - more accurately a pointer to a pointer - called HEAD. Project displayed in Fig. 4 has only a main development line: HEAD points to master.
Creating a branch (command branch) prompts Git to create a branch-object (that is essentially a pointer to a commit-object).
If we assume that the repository state corresponds to Fig. 4, creating branch testing will create a branch-object pointing at commit-object f30ab (the active commit-object = current commit-object on the active branch).
git Chapter 3 by S. Chacon and B. Straub)
Creating a branch does not switch to that branch: HEAD in Fig.5 still points to the (main) branch master (not to testing).
HEAD must be explicitly redirected to branch testing (command checkout testing), before the developer can work on it (Fig. 6).
git Chapter 3 by S. Chacon and B. Straub)
Let's assume a developer works on branch testing for a while and commits. The project state might be as displayed in Fig. 7.
git Chapter 3 by S. Chacon and B. Straub)
Switching back to master is easy and fast: It only involves redirecting pointer HEAD to branch master - by means of command checkout master (Fig. 8).
git Chapter 3 by S. Chacon and B. Straub)
Let's assume the developer performs changes on branch master and commits: The two branches master and testing have developed apart. The new situation might be depicted as in Fig. 9.
git Chapter 3 by S. Chacon and B. Straub)
The state of project as shown in Fig. 9 may be displayed using command git-log i.e. git log --oneline --decorate --graph --all displays following output.
git Chapter 3 by S. Chacon and B. Straub)
-
For now, I am primarily concerned with the command line interface - which requires opening a Shell window (e.g. Bash) and call Git.
Note: The command line interface is fully operational, as soon as Git has been installed. On my operating systems - whether Linux or OSX - Git is installed by default - into /usr/bin/git. (Type which git on the command line for verification)
If Git is not already installed, several options to install it manually are available:
- Install Git e.g. via a Package Management Tool
-
Download the latest binaries from the internet, e.g.
git-scm.com.
Note: There are several GUI available that support different subsets of Git commands (Probably none of them will support the complete set).
-
Git comes with a command called git config that allows to determine how it looks and operates. There are two kinds of arguments:
- Arguments defining actions to perform on those data: basically either read or write (key) values
- Arguments defining data (sources) (e.g. identifying the appropriate configuration file).
A "configuration variable" is an ordered pair key value written in one single line of a file that Git recognizes as one of its configuration files.
No. Configuration Level Description 1 System - On my OSX computer, a system configuration file/private/etc/gitconfig was stored. The values stored here are valid by default for every user and repository. Use argument --system to target this file.
- On my Linux system, there is no such file by default. Command (sudo) git config --list --system returns an error message that /etc/gitconfig does not exist.
2 Global On my computer, the global configuration is stored in file <Root_Directory_Of_User>/gitconfig. Those values are specific to a user and his repositories. Use argument --global to target this file.
3 Project Project configuration is stored in file <Root_Directory_Of_Repository>/.git/config.
As would be expected, a more specific level overrides previous ones: configuration values attached to a project override for example those attached by default to a user.
-
The configuration file locations may change according to the operating system. For
unixoid OS, such as MACOSX or my Linux OS , the correct location should be easy to infer. For Windows systems, the matter may be more difficult. To identify a location, the user shall try to edit the configuration values git config --edit at the level he wishes to operate. Git will try to check the appropriate configuration file - which may fail, if the user is not granted sufficient access rights. No. Command Description 1 Git config (without argument) Action Display usage: If no argument is entered, the command displays its usage.
Result: The list displays following categories:Category Key Config file --global use global config file --system use system config file --local use repository config file -f, --file use given config file --blob read config file from given blob object Action --get, --get-all, --get-regexp, --get-urlmatch,
--replace-all,
--add,
--unset, --unset-all,
--rename-section,
--remove-section,
-l, --list,
-e, --edit,
--get-color, --get-colorbool
Type --bool, --int, --bool-or-int, --path
Other -z, --null, --name-only, --includes, --show-origin No. Command Description 1 Git config --system -l
Git config --system --listAction: Display system configuration values
List all Git configuration variables set at the system level i.e. list key=value pairs, valid (by default) for all users and repositories.On my system, no variable is displayed, since file private/etc/gitconfig (that I created separately and moved subsequently) only contains comments (i.e. lines beginning with sign #).
2 Git config --global -l
Git config --global --listAction: Display global configuration values
List all Git configuration variables set at the global level i.e. list key=value pairs valid (by default) for the user and his repositories.On my system, command reads file ~/.gitconfig and lists i.a. following key=value lines:
user.name=Amar Khelil
user.email=akh@khelil.de
push.default=simple
3 Git config --local -l
Git config --local --listAction: Display local configuration values
List all configuration variables set at the local level i.e. list key=value pairs valid only for the current Git repository.In order to display local values, git must know which repository is targeted and therefore the user must cd /to/git/repository beforehand.
4 Git config -l
Git config --listAction: Display current configuration values
List all Git configuration variables known i.e. list key=value that Git can deduce.If the current directory is a repository, variables from all levels are displayed, from general to specific i.e. if a key appears several times the last value applies. If the current directory is not a repository, only system and global variables can be displayed (Git does not know about a specific repository).
5 man git-config
Action: lists all the available configuration options in detail.
Note:
User name and email address (set at the --global resp. user level) are mandatory because Git uses them to identify commits. In other words, if keys user.name and user.email have not been automatically populated, the user must edit them (e.g. Git config --global --edit see next table)
No. Command Description 1 Git config --edit Action: Edit configuration variables
Git opens one configuration file and the user can edit key value pairs (one pair for each line). Each configuration level has its associated file.If no argument is entered, Git assumes that the user wants to operate at --system level. It is recommended that the user always specify his preference: --system or --global or --local).
Examples:
It is convenient to set a preferred editor (e.g. vi: git config --global core.editor vi).
If configuration values are wrong and you don't know which action can fix it, the simplest way is to edit the configuration file (mostly git config --global --edit). Git opens the associated configuration file with the preferred editor and the user can change anything he wants. As an example, I erased configuration variables that made not sense (typos).
Command Description core.editor By default, Git uses the text editor specified by one of the shell environment variables VISUAL or EDITOR, or else falls back to the vi editor to create and edit commits or tag messages. On my system none of the variables above are populated. I set core.editor=gvim as a global option (user default).
commit.template The value of this option is the name of a text file that git will read to initialize commit messages. The use of a template reinforces rules regarding formatting and style, especially within an heterogeneous team.
I defined the (hidden) text file ~/.gitmessage.txt in my home directory as a default message template for all my projects (i.e. git config --global commit.template=~/.gitmessage.txt).core.excludesfile To ignore file patterns for all repositories a user may write them into a file stated in option core.excludesfile. I added following option git config --global core.excludesfile ~./.gitignore_global.
# -----------------------------------------------
# LABEL: Git ignore files option # INFO: lists templates of files that do not belong to any git project
# -----------------------------------------------
# NAME: /home/akh/.gitignore_global
# ignore macos system files
.DS_Store
# ignore temporary files
.*.swp
TODO
# ignore Document files that are not part of the development
# .*.[Pp][Dd][Ff]
# .*.[Pp][Nn][Gg]
# END_OF_FILE
Git doc: gitignore.
Other interesting variables Herewith more configuration values I stumbled upon in the course of time. Without explanation.
- git config {--global} init.default branch main
Git doc: configuration options.
Warnings:
Syntax: Between Git and other VCS, actions bearing the same name might not perform same tasks. (Mostly, due to the versioning model : A VCS may act as a local, a central or - like Git - a distributed data base.)
Sources: Tables below shall be merely regarded as 'field notices', exhibiting only most characteristic features that occurred to me when reading the documentation and practising. Exhaustive documentation about all Git commands, classified according to their tasks, is published on the official site, at
git-reference-page.
-
Start a Git (controlled) project means add a (local) repository. There are 2 ways to achieve this goal:
- Create an Git repository to maintain an existing project (that has not yet be placed under control) - and make it available to other developers.
- Clone an existing Git repository - as a rule, created by third developers and possibly stored remotely.
-
No. Command Description 1 cd /path/to/project/dir
Change to the directory where the files to maintain are located.
2 git init
This creates a new subdirectory into the project directory, named .git that contains all necessary repository files.
Note:- A this point nothing has been tracked yet!
3 git add *.html
git add *.css
git add *.png
git add *.jpg
git add *.gif
git add *.ico
git add *.odg
git add *.odp
git add *.txt
git add *.zipObviously add [file] means 'include files (pattern/s) to tracking list. More precisely add [file] means 'add content to next commit'.
Note:- Git implicitly refuses to track specific file name patterns, like *.pdf.
- Users can define additional patterns to ignore.
4 git commit {-m <comment>}
Example: git commit -m 'initial version of www.khelil.de [0]'
Note:- Added files (marked as staged) are not secured until they have been committed.
- Each commit must be associated to a comment.
Note: A repository may maintain several development branches. In most cases, command argument master will, by default, designate the main development branch in the local repository.
Clone an existing Git repository
No. Command Description 1 cd /path/to/root/dir
Change to the (root) directory where the git project (the files to maintain) will be located (as a sub-directory).
2 Copy from a local repository:
git clone [/path/to/repository]
Copy from a remote server:
git clone {username@host:}[url_of_source] {target_dir}Cloning a repository is more than just checking out a project - as may be the case with other VCS.
Git does not only transfer a screenshot of project data - as might be the case for some source control programs -, but includes maintenance information (almost) one to one - especially, the history of all tracked data is pulled down, by default.
Several transfer protocols are commonly used:
- HTTPS: e.g. git clone https://github.com/libgit2/libgit2 mylibgit
- SSH: e.g.git clone user@server:path/to/repo.git
Note: In most cases, command argument origin will, by default, designate the main development branch in remote repository.
-
Diverse actions are available depending on how developers are currently interacting with the project development process.
The table below (also inspired byRoger Dudler) shows main use cases.
No. Command Description 1 git add <file name(s)>
extend the list of "staged" files.Mark file into the staging tree (set of the next commit candidates)
Files in the working directory, modified or new - since the last commit on the working branch -, are tagged for the next commit i.e. staged.
Note:
- Only "staged" files can be considered when a commit is launched.
- If a file has been staged and then modified anew, before any commit has been performed, Git will differentiate between the (last) modified and the staged version.
- If pathname is a (naked) directory, all files in directory are accounted for recursively.
- git add *: all changed files within control are transferred into the "staged" status.
1b git restore --staged <file name(s)>
It reverses command git add - i.e. "un-stage staged files": After processing <file name(s)> is/are no longer listed as staged files (does/do not belong to the next commit anymore) - see also f.e. TOWER: git restore
2 git commit -m <commit_message>
commit the (staged) files into the current branch
Each time the project reaches a state worthy of recording, its snapshot should be committed. Changes that have not been committed are eventually lost.
For references see following pages:
Note:
- Staged files are committed to HEAD.
- Each commit must be associated to a comment.
- Changes must be pushed in order to affect a remote repository: Even if the local repository is connected to a remote one, nothing has yet been done to update the latter.
-
Change a commit message:
Sometimes, the developer (or another responsible actor in the project) wants to change the commit message text (for example because some piece of information is incorrect or confidential).If the reaction takes place immediately after the commit has been made (before it has been published/pushed), option --amend is appropriate, i.e. git commit --amend -m "<CORRECTED_MESSAGE>"
For more references, see following pages:
- GitHub Docs: Changinng a commit message.
- GitHub Docs: Eine commit-Mitteilung ändern (German translation).
3 git branch <name_of_branch>
Create a new development branch
For example git branch testing to create branch testing as in Fig. 5.
Note:
- Command branch does not switch to the newly created branch automatically (In other words, HEAD. remains unchanged).
4 git {-b} checkout <name_of_branch>
Switch to branch name_of_branch
For example git checkout testing moves HEAD to branch-object testing - see Fig. 6.
Normally a user switches to (checkout) an existing branch.
However, by means of option -b Git allows to perform both steps, creation and switch, at once: git checkout -b <name_of_branch>.5 git tag
A tag (object) is a convenient way to identify a commit, if the associated hash is perceived as too cryptic.
For references see following pages:
Some examples of usage:
- git tag -l <pattern>... or git tag --list <pattern>... lists all tags (if running without further arguments) or only those tags matching the given patterns.
- git tag -l -n<number>... lists all tags. number specifies how many lines from the annotation, if any, are printed. Option -n without number will show the first line of the annotation.
- To get detailed information about a specific tag type command git show [<TAG_ID>] e.g. git show v2.0.0
- git tag -a v3.0.0 -m "[khelil.de] [January 2023] reshaping the formatting and add minor corrections "
Note:
The user can define a list of files to ignore i.e. that must not be tracked. They must be registered into the ignore list - stored in the .gitignore file of the repository directory. Each line corresponds to a file name pattern. Following rules apply:
- Blank lines or line starting with # are ignored.
- Standard glob patterns work.
- Start patterns with a forward slash (/) to avoid recursivity.
- End patterns with a forward slash (/) to specify a directory.
- Negate a pattern by starting it with a exclamation point (!).
See also examples in
gitHub.
Each commit must be associated to a comment (clearly identifying the update).
Mostly, the comment will be inserted in-line (option -m <comment>).
However, if option -m is missing, Git will display a text - invoking the preferred editor. This text includes commented lines (output of git status), supposed to help the user enter an appropriate commit-comment - as uncommented lines.(Note: If commit option -v (verbose?) is activated, the amount of information displayed increases to the output of git diff.)- Removing files
- Moving (renaming) files
-
No. Command Description 01 Update remote repository
Only committed changes are part of the transfer between local and remote development branch. By default,
- [(local) branch-name] (here the source branch) is master.
- [remote-name] (here the target branch) is origin.
02 git remote add [remote-name] <server>
connect local repository to a remote server
This operation can be considered as opposite to project cloning. After this, it shall be possible to push locally committed changes to the selected remote server.
Note:
In many cases, [remote-name] (the name of the remote repository connected) shall be origin. -
Get pieces of Information about a Git Repository
After working on a repository for a while, files may be (still) untracked, changed, staged, committed. There are several commands available to obtain more information about the current status of files.
-
Command git-status
git status {options} {--} <path>
lists paths (files) with following characteristics:- paths where states of index and current HEAD differ
- paths where states of working tree and index differ
- paths in the working directory that are not tracked
See also
manpage git-status.
Note:
If files have been added to the working directory, they are automatically marked as untracked. If registered files have been modified, they are marked as modified. Both untracked or modified files must be staged (Git command add), before they can be part of the next commit.No. Command Description 1 git status
For example, if the command is run directly after cloning, Git issues following message:
On branch master
Your branch is up-to-date with 'origin/master'
nothing to commit, working directory cleanThere is no untracked, modified, nor staged file - otherwise git would mention it.
Note:
Git mentions the associated development branch: By default, the local development branch is named master and the remove development branch is named origin. They can be renamed, if need be.2 git status -s
git status --shortThis short version of 'get status' displays information in a more compact way.
One line for each file. Column 1 shows the status of the staging area, Column 2 the status of the working area. One of the following attributes may appear in each column:- Files that aren't tracked have a ??
- Files that have been added have an A
- Files that have been modified have an M
-
Commands git-diff
git diff {options} <commit> {-- {<path>}}
allow a detailed view about file changes (lines added and removed in each file).
git diff {options} --cached <commit> {-- {<path>}}
git diff {options} <commit> <commit> {-- {<path>}}
git diff {options} <blob> <blob> {-- {<path>}}
git diff {options} --no-index {-- {<path>}}Depending on options and parameters different states may be compared:
- states within current branching
- states of commits belonging to different branches.
See also
manpage git-diff.
No. Command Description 1 git diff {--options} <commit>
Compares the working directory to the named commit.
If <commit> is not named, the default value HEAD applies and git-diff shows changes that would be committed, if command git commit -a is run.2 git diff {--options} --cached <commit>
Compares changes between the index and the named commit.
If (default) commit value HEAD applies, git-diff shows changes that would be committed if command git commit (without -a) is run.3 git diff {--options} <commit> <commit>
Compares changes between 2 arbitrary commits for all entries identified (which may amount to a tremendous set of data).
By inserting additional options -- <path> the user may focus on specific files4 git diff {--options} <commit>..<commit>
As the previous command, it compares changes between 2 arbitrary commits.
However, if one of both commits is not named, the default commit value HEAD applies. -
Command git-log
git log {options} {<revision_range>} { {--} <path> ...} shows a list of commit logs along the current development branch.See also following references:
There are options for control the output flow: which data are displayed, which commits shall be accounted for, which files are of interest. Mostly are independent from each other. Some popular option combinations are shown in the table below.
The command displays all current commits registered with the repository. If they have been marked as a 'branch' - i.e. pointed at by a branch-pointer -, the information is also displayed.
No. Command Description 1 git log
By default (i.e. without option) , git-log displays following 4-tuple (commit name, author, date, comment) in anti-chronological order for all commits in the current branch.
2 git log -p -<revision range> -- <path>
Option -p (meaning 'generating patches'):
Shows the differences introduced in each commit by means of diff (i.e. displays all modified lines for each entry).For example:
git log -p -1 -- Quellcode/PST/Bildbearbeitung/*.cpp will display diff for entries meeting following conditions:- Only the last commit is considered (option -1).
- Only cpp-files in directory Quellcode/PST/Bildbearbeitung are considered.
3 git log --stat -<revision range>
Option --stat:
Shows the differences introduced in each commit by means of diff-stat (i.e. displays a summary of modifications for each entry).For example:
git log --stat -1 All entries involved in the last commit are accounted for. For each of them a summary of changes is displayed.4 git log --pretty=oneline
Option --pretty:
The pretty format has several pre-defined values like oneline, short, medium, full...5 git log --oneline --decorate
6 git log --pretty=format:"{<tag>...}"
The user may even determine a specific format of its own using placeholders (tags) like in the following example: git log --pretty=format:"%h, %ad, %Cred%an%Creset, %s --date=short" will display in one line following data: abbreviated commit hash, author date, author name, subject.
- The predefined format git log --pretty=oneline is equivalent to --pretty=format:"%H %s"
- In the example above, the author's name will be written red (thanks to syntax %Cred ... %Creset).
- Long commit hash would have been %H instead of %h.
-
The user defined format above can be stored into config file (~/.gitconfig),
using following lines of code:
[log]
date = short
[format]
pretty = format:"%h, %ad, %Cred%an%Creset, %s"
Instead of tipping the whole format sequence, the use now just needs to tip git log to shape the output as he defined.
For more details (f.e. creating aliases) see also stackoverflow: the shortest possible output from git log containing author and date
Remarks:
-
If the output does not fit into a single window, the default pager (e.g.
LESS ) is invoked.
-
In option <path> the use of
glob patterns is allowed.
-
I only covered the very basics in the chapter above. This are many more possibilities of treatment that I do not know of to a great part. In this chapter I will treat some of those extensions, if I come across them and if I have the time to report.
Examples of Git projects
The term 'project' in this context refers to a single repository or a group of them associated with the same content. Obviously, I will only mention projects in which I have been involved.-
khelil.de comprises a set of
HTML files describing issues that I studied and documented in the course of years. It has been maintained on a local Git repository that, for the sake of clarity, I will call khelil_de_0.
There are different ways to "export" the local repo to remote ones: a remote (central) repository (theoretically) enables associated persons to work on the same project. In the next chapters (khelil_de 1, khelil_de 2), I will explore some of those possibilities using precisely project khelil.de, that is currently (2023-10) a major project of mine. However, this is not only about khelil.de. The final goal is to maintain (future) projects, designed from the scratch to be distributed: I intend to document how this done in dedicated chapters.
-
Local projekt khelil_de_0:
Status from March 2023 onI used following git commands to set up the project.
git status {--short} Display the list of files bearing following characteristics.
Note: Staged files that changed subsequently are listed in both sets (with a different content).
(1) The ones that have changed but are not yet marked as part of the next commit
(2) The ones that have changed and are marked as part of the next commit. (In git jargon those files are labeled "staged").
git add --all All changed files are marked as "staged" i.e. ready for commit
git commit --file="txt_0" Commit with a message stored in git_commit0.txt - with for example following content: Clean Cut state for [www.khelil.de] (Vorabversion 1)
For ALL pages
- clean CSS Page (remove unused formats)
- relax HTML formatting (u.a. no 'px') and purge unused class token
- copyright label
For single pages
- Introduce a "Contents page" exclusively displaying pages written in English and linking where appropriate
- Improve git documentation
KEYWORDS: Formatting, Copyright, contents display, git
git commit --amend -F="txt_1" If need be, update the message of the last commit, replacing it with the content of git_commit1.txt. (Options --file or -F are the same)
git tag -a v3.0.0 Now that a clean cut state has been committed into the repository, it will be associated to (tagged) version 3.0.0. This is a annotated tag.
-
remote repo khelil_de_1
Status from October 2023 onRemote repo, labeled khelil_de_1, associated with local repo, labeled khelil_de_0, will be stored into the very same web space, where
khelil.de is hosted. It will be created as a bare remote clone of khelil_de_0 and may later serve as a central archive.
By convention, bare git repositories bear the .git extension: the "real" name of the remote project may well be remote_khelil_de_1.git.
remote_khelil_de_1.git theoretically enables a distributed development: Each developer pushing and pulling their work to or from the central repo.
Whether this concept is practical or not, critically depends on one external factor: access rights into my webspace: git needs ssh access to the remote host. The contract with my provider currently allows only one single ssh-user onto the web space, me. No way to create another user named f.e. git, in whose profile the repository would be stored and to which all team members would have access (configuration recommended by the git developers cf. git docs: getting git on a server.This restriction may somewhat be overcome, by adding (RSA) public keys into file ~/.ssh/authorized_keys of my single user account. As a matter of fact, I already authenticate myself into the webspace using a RSA key (rsa-akh-ionos). Whether git using this key will be able to access remote_khelil_de_1.git properly will be documented in the next chapters.
Note however the major disadvantage of the work-around presented above: all team members would have complete access onto my webspace - and not only the repo directory. I cannot afford such a security leak. Still, if the bare repo remote_khelil_de_1.git is successfully configured, I can use it as a valuable personal archive (a backup).
My references (helping me set up and configure remote_khelil_de_1.git)
-
Git Book: Getting a git repository
-
Git Book: Working with remotes
-
Git Book: Getting git on a server
-
Wehner's Blog: Create a git repository on a ssh-server
A succinct description of the steps to perform to create and access a bare remote repo -
Git Reference: git clone
clone a repo
-
Git Reference: git gc
cleanup a repo (delete pending pointers etc.) -
Git Reference: git fsck
check the integrity of a repo -
Git Reference: git remote
access or check associated remote repos
Stackoverflow: git remote, git ls-remote
access or check associated remote repos
-
Git Reference: git push
update remote repo (with new local developments)
Github: git push
update remote repo (with new local developments) -
Github: git pull
re-sync local repo after (possible) changes have been made in the remote repo. -
TOWER: cherry-pick
integrate only parts of the commits of one branch into the main development line.
From the git documentation web site: BOOK
Various tutorials
From the git Documentation web site: REFERENCE
Steps and explanations
Conditions /assumptions
- ssh access to remote (directory) host - where repository remote_khelil_de_1.git will be stored - using RSA key sshRSA_khelil_de for authorisation.
- Local khelil_de_0 project is maintained in local repo local_khelil_de_0.git
Commands
1 git clone --bare --verbose
<local_khelil_de_0> <LocalCloned_khelil_de_0.git>Go to the directory where the initial local git repository stays and clone it locally into a dedicated directory.
Note:
You may want to clean up the repo (git gc) and check its integrity (git fsck --verbose --full --strict) before cloning it.2
(1) scp -r -v <LocalCloned_khelil_de_0> <MyUser@MyWebSpace:/path/to/> or
(2) scp -r -v <LocalCloned_khelil_de_0> <MyHostname:/path/to/>
Transferring the locally cloned bare repository onto the server (remote host) using command scp. The set options are "recursive" (for a directory) and verbose (to verify whether the copy process works fine).
In alternative (2), variable <MyHostname> is an alias for MyUser@MyWebSpace including some more communication parameters, if the ssh communication has been configured properly - see also ssh configuration.
Note that <LocalCloned_khelil_de_0> (the locally cloned repo) and <Remote_khelil_de_1.git> (the remote repo) have the same literal name in this case.
3 -
ssh <user>@<webspace>
-
cd </path/to/myClonedRepo.git>
-
git init --bare --shared
Open a shell on the remote host and go to the directory of the remote git repo and perform proper initialization (all user having a ssh account will be able to push and pull). It is also recommended to check the integrity of the remote repo. 4 git add remote remote_khelil_de_1 ssh://<myHostName>:<remote_khelil_de_1.git>
Go back to the local git project khelil_de_0 and add the remote project khelil_de_1 to the list of the associated remote project, to allow push and pull using alias remote_khelil_de_1.
5 git push remote_khelil_de_1
This is the moment of truth: First time we try to push the next local commit into the remote repo.
Success: The feasibility of this path has been demonstrated.
After both repositories (local, remote) have been synchronised for the first time, the future synchronisation steps will invariably follow the same pattern.
0 git branch --all
git remote -v
Preliminary check of local and remote branches
1 git pull <remote_khelil_de_1> <remote branch>
re-sync (fetch and merge) current branch of the local repo using remote branch as the source. In this project, all new developments take place on the local repo: git pull is not supposed to disrupt anything.
2 git push remote_khelil_de_1
After the pull step is completed, git authorizes the push step from local to remote.
Next step (next chapter) will be to assess remote host
GitHub that is explicitly designed to enable distributed development.
-
-
Repo remote_khelil_de_2
clone Khelil_de_0 to thegitHub webspace?
Status from October 2023 onI have a (free) account on
gitHub, currently with one visible empty public repository: test0. The obvious questions are:
How to export khelil_de_0 to gitHub khelil_de_2 under which conditions, limitations or dangers?⇒ GitHub conditions and limitations
ref. also gitHub: Access to reposHaving a free account, labeled AmarKhelil, I can https-login to my personal webspace at https://github.com (with Username, password).
My profile is labeled personal and public.
In fact, it is an essential part of the gitHub process that actors and results are "public". The paradigm is that developers place their work (i.e. the files in their repositories) under public scrutiny, so that, in return, they may get help, guidance, corrections from (at first) unknown experts who may eventually become collaborators, developing additional branches (features) into the project. As a matter of fact, the primary contents under control are
(software) codes.Note: A personal "private" profile would make little sense - unless being some kind of ghost silently spying on repositories. Companies may create "group" accounts (and associated repositories) accessed by co-workers who are internally individually identified. Another story.
Can any repository be labeled "private" - meaning invisible to the general gitHub folk?
Yes, but they offer - in the free subscription - limited interactions, compared to "public" repos: number of collaborators, branches, etc. ? It is in therefore generally preferable for repositories to be entirely visible for all gitHub users. Everybody will be able to fork the codes for their own purposes. Off course, they will not be able to directly modify the content of the original repo itself, even if public. One must have been explicitly invited to collaborate to get the read/write permission. (Note that a collaborator in a personal account always get both permissions at once).khelil_de is a one man project. No fancy code management here. I will declare khelil_de_2 private.
(Note: it is always possible to declare the repo public, if need be afterwards. Transfer private-to-public is much easier than transfer public-to-private).⇒ Generate and check ssh key
I have created a ssh key (labeled rsa-akh-github) to authenticate myself onto my gitHub account - for details see also ssh key generation. I then uploaded it directly onto my gitHub account, via the https Interface: copy and paste of the public key value into the window provided by the GitHub menu "Settings/Ssh-keys/New"
Note: It is not recommendable to upload ssh key from other folks onto one's gitHub account, because this would give them unlimited access to all repositories - see also next chapter (ssh key use). (Since gitHub - at least in the standard configuration - does not support opening a ssh-shell, one may hope that only repos are compromised in this case, not the whole account.)After rsa-akh-github has been generated and (its public component) uploaded onto my gitHub account AmarKhelil, the ssh communication between local and remote git repos must be configured in the local profile ~/.ssh/config - see also ssh key configuration. Here are the config parameters related to my gitHub:
### ssh login für gitHub
Host github
Hostname github.com
User git
PreferredAuthentications publickey
IdentityFile rsa-akh-github
Retracing the steps...
- Open a bash shell and load the proper rsa key into memory (see e.g. ssh key add). To check whether the task was successfully completed, one can type ssh-add -l (display parameters of publich key) or ssh-add -L (display public key value).
-
Type ssh -T github (The -T option means "disable pseudo-terminal allocation")
It was a success. GitHub returns following message: Hi AmarKhelil! You've successfully authenticated, but GitHub does not provide shell access. As already mentioned, to minimize security leaks, GitHub does not support by default shell access. (But, there may be a way... see below)
⇒ Transfer from local (khelil_de_0) to remote (khelil_de_2)
1 git remote add remote_khelil_de_2 git@github.com:AmarKhelil/remote_khelil_de_2.git
Go to the directory where the initial local git repository (khelil_de_0) stays and add the remote repo remote_khelil_de_2.
2 - git branch -M main
- git branch --list -a
The main development branch used to be called master. And it was at least the case for my local repo khelil_de_0. After the first command has been performed, the master branch is renamed main - which can be verified by typing the second command.
3 git push {-u} remote_khelil_de_2 main
Transfer the main branch (of local) to remote.
I put option -u (= set-upstream-to) as optional. In this case it would set remote_khelil_de_2 as the remote repo - when commands git push or git pull do not specify a remote.The transfer was eventually successful:
remote_khelil_de_2 has been created and populated on gitHub. Branches khelil_de_0/main (local) and remote_khelil_de_2/main are synchronized.
⇒ A shell for GitHub
References
gitHub: installation The git CLI project (gh repository) as well as links describing the installation procedure in widespread operating systems. gitHub: installation Installing gh on Linux and BSD: the exact commands to run. [ ]
gitHub: Quick start CLI
An overview about the most important commands and options for gh gitHub: CLI Manual
Reference documentation about the gh syntax and options To open a shell on the own git repositories on must first install a program named gh. To check the successful installation, type gh --version. Now (2023-11-01) the command responds following on my (bash) termin
gh version 2.38.0 (2023-11-01)
https://github.com/cli/cli/releases/tag/v2.38.0
-
-
-
As a newcomer in the city of Ludwigshafen (LU, Palatinate, Germany), I eventually came to learn about a highway reconstruction project in the city center that a majority of local politicians has been supporting since its initial planning in 2015. In September 2023 they launched its realization after the federal and local states (Bund and Bundesland) agreed in substantially financing the project: 85% of the total cost, estimated in year 2021 to be ca. 600 millions Euro, assuming no inflation during the construction period.
Since the first drawings, engineers and local deciders were unequivocally dedicated to promoting inhibited car mobility through the city center. Their projections onto the year 2040 assume an increased traffic density of 30% up to 50% compared to 2022. The system, 2 highway axes - north and south of the city center -, absorbed about 100 000 cars a day in August 2019, at the time when the south axis was closed because of damages. (The city itself counts about 170 000 inhabitants).The local politicians in LU have already a rich history of failed mega-projects.
The last scandal is located in the city central place named "Berliner-Platz", that has been a building site since 2015 (for 8 years now). In July 2022 the investor went bankrupt. To this date (November 2023) the communal authorities have no idea on how to tackle the situation.Citizens organized protest actions against the failed 'Berliner-Platz Project' and hosted a home page at Bilelu (Bürgerinitiative Lebenswertes Ludwigshafen). At some point, they decided to extend their protest to include the project "LU Central Highway aka Helmut-Kohl-Allee": The more one thinks about it, the more it becomes obvious that this mega-project have huge drawbacks that designers underestimated in 2015 - if they were even aware of them at all. Those omissions may well lead the city into a financial, social and ecological collapse. Still, most local politicians keep repeating that "there are no alternative solutions" (to the mobility question). Is it true? To get elements of response, I will open a web site exploring innovative mobility concepts in LU and comparing them with respect to various criteria.
Contents will be created locally and secured remotely - to allow several people to work in parallel, if they decide to join in.
-
As is the case in project
khelil.de, I will maintain 3 git repositories.
- A local git repository, called mwlu_de_0, on my computer - in a directory called /path/to/mwlu_de.
-
A remote git repository in the
manitu webspace, where the HTML pages are actually hosted - called mwlu_de_1.
-
A remote git repository on my
github account, called mwlu_de_2.
Note that, as the task started, there was only one git repo existing, mwlu_de_2 (on github).
-
In the
manitu webspace, HTML pages mobilitateswende-lu.de are stored in a directory called /web/mobilitaetswende-lu.de.
UNSUCCESSFUL ATTEMPTS:
At first, I tried different approaches involving a "bare" git repository, stored in a dedicated directory /path/to/web/mwlu_de.git. It did not work: I was unable to connect the local git mwlu_de_0 and remote (-bare) /path/to/web/mwlu_de.git.
Command git remote add remote_mwlu_de_1 ssh://<host_manitu>:/path/to/web/mwlu_de_1 throws an error.
/path/to/web/mwlu.git was a copy of a local bare git repository, cloned from local git repository mwlu_de_0, and subsequently sent onto webspace - via command scp.
The connection with remote /path/to/web/mwlu_de.git constantly broke with the same error telling that /path/to/web/mwlu_de.git was not a repository or that access permissions were insufficient. Both allegations proved wrong, after opening a ssh connection and directly verifying. The true cause of the problem remains however obscure.
SUCCESSFUL PATH:
The list of commands that lead to success:
-
[] Create a working git repository within the webspace directory /path/to/web/mobilitaetswende-lu.de where the very HTML pages are maintained. [] Introduce the first commit "initial content of the webpage". [] Verify: git status, git log.
-
Go into the directory where the local repo mwlu_de_0 must be: /local/path/to/mwlu_de.
-
git clone ssh://<host-name>/path/to/mobilitaetswende-lu.de: Clone the remote repo into the local directory: A local git copy of the remote git repository is created.
Note: In the ~/.ssh/config file, there must be a Host <host-name> entry with all the correct ssh connection parameters: Hostname, Port, User, IdentityFile - see also ssh configuration.
-
git add remote remote_mwlu_de_1 ssh://<host-name>/remote/path/to/web/mobilitaetswende-lu.de
This time, the connection local to remote is successful: It can be verified e.g. by issuing command git remote -vv.
Note: I had to issue command git remote rename origin remote_mwlu_de_1, to finally get the remote link-name remote_mwlu_de_1, instead of origin (the default link name). (I don't know what went wrong in the first place. Maybe, I actually forgot to explicitly state the link name).
-
git pull remote_mwlu_de_1 main. If successful, the git pull and push operations between local and remote are available. Job done.
-
-
FIRST ATTEMPT:
I created mwlu_de_2 in my github space before doing anything locally. The first (and only) file incorporated was readme.md describing the general scope of the project - which is some kind of mandatory step when starting a repo on github. (The github readme.md file can be formatted using a simplified syntax as explained in
formatting readme.md files in github.)
-
Step: Open a ssh-communination channel with github.
Assuming that the ssh authentication key (public key) has been stored into the list of accepted keys onto the github account, and that the corresponding (secret) key has been upload into the working memory ( using command
ssh-add), and that the ssh-config-file writes correct parameter values (see
configure the ssh communication), just type command ssh -T <host> to verify that the connection works. (Even after a successful connection, github does not permit opening a remote shell).
-
Step: Clone the github repo - see also
clone a github repo
Using command git clone <name_remote_github_repo.git>. The correct name is easy to find. Login onto your account in github and select the repository in question. Open menu "<> code" and select the communication protocol (https or ssh).
ssh address of mwlu_de_2 in githubUsing command git remote -vv, the connection to the remote github repo becomes visible. By default, the remote repo is named origin. Since I will be working with several remote repos connected to the same local working repo, origin will be renamed to remote_mwlu_de_2 using command git remote rename origin remote_mwlu_de_2.
remote github repo mwlu_de_2Note here that due to having first uploaded the wrong ssh-key for github, I transitorily ended up using the https connection to the remote github repo. This situation can however be fixed using command git remote set-url remote_mwlu_de_2 git@github.com:AmarKhelil/mwlu_de_02, forcing the ssh connection instead of the https connection.
remote github repo mwlu_de_2 -
Step: pull remote
git pull remote_mwlu_de_2 main
SECOND ATTEMPT:After I finally succeeded in connect local mwlu_de_0 to remote mwlu_de_1, I have to reconnect mwlu_de_0 with mwlu_de_2 on github. Note that in the meantime, I renamed the remote github repository mwlu_de_2 (instead of MWLU_de_02), for consistency reason.
-
First re-step is git remote add remote_mwlu_de_2 git@github.com:AmarKhelil/mwlu_de_02
-
Next step is git pull remote_mwlu_de_2 main.
Well that is where the real work begins, because in the meanwhile remote_mwlu_de_1 main and remote_mwlu_de_2 main have diverged. What must be done? a git-merge or a git-rebase? - cf. also atlassian: merging vs. rebasing.
-
-
-
-
Automatic Generation of HTML Pages
-
So far, HTML-files in
www.khelil.de have been written manually and maintained in a single repository.
In the future, HTML files will, under circumstances, be generated automatically. The idea is based on a proposal byPatric Sokoll (PaSo). In
PaSo's virtuelles Röhrenmuseum thousands of pages have been published, each one dedicated to a single item in one museum: electronic tubes, medical devices, computers, etc. Most of the pages are cross-referenced. Manual maintenance is therefore prone to failure. On the other hand, automatic page generation is made easier because of following reasons:
- The data treatment scheme is the same for all items,
- The data is stored in a Data Base (
PostgreSQL).
Patric Sokoll wrote (at least) 2 C++ Libraries on the top of the Qt library. Each maintained in a separate Git repository.
No. Name of Git repository Short Description 1 PST-MuseumsWelt Automatic generation of HTML pages by extracting data stored in a DB into a HTML blueprint. It relies on library PST-Tools 2 PST-Tools It codes the most basic treatment level. Patric Sokoll to generate his museum pages
-
Status 2018
In a first feasibility project, I intend to publish pictures and paintings - see also Virtual Exhibition. Those works will be referred to in a data base (e.g. PostgreSQL) along with their characteristics. Tasks and conditions are similar to those identified by Patric Sokoll for his virtual museums. We agreed on a cooperation: I will clone the PST repositories above. If need be, codes will be adapted / extended into separate Git branches. -
Status 2023
No progress since the declaration of intention, years ago and unfinished HTML-templates: Only a few new pics or images have been published in the meantime. It is unclear whether the project will ever be realized. Probably yes, if a project Photo Exhibition comes into life. However, tools and ways may differ completely from the original design.
-
No. Link/Name Short Description Language 1 Lexicon/Git Git Entry in Lexicon with links to pages containing a general information about download, documentation and tutorials.
German, English 2 git help <action>
git <action> --help
man git-<action>.
Get help for a specific action.
You may for example type git help config to get information about the configuration command.English 3 Manpage git-config
Manpage of Git Config in
www.kernel.org (Linux Kernel Archives).
English 4 Pro Git Book
Written by Scott Chacon and Ben Straub and available to read online for free.
English 5 Git Reference Manual
Git Reference Manual.
English 6 Git: the simple guide
The Git essentials without (I cite) "deep shit". Very worthy.
Many languages. 7 Git Tutorial w3school
Git Tutorial
English Rem.: Another possibility to retrieve specific informations is to type Git help or Git Action help.