Git is used as version control system of the Linux kernel source. One really nice feature is that it needs no tricky server setup. The software can be developed in a directory not be worried about version control. Once when the need having a version control system pops up, the program git needs to be installed the usual way as any other program on your Linux distribution. Using git the hidden directory .git (the repository) will be added there where the source code is developed. A bare repository is kept inside this hidden directory .git that holds everything a version control system needs. The code being developed in the above directory becomes the working tree. In case of putting it on a server to have a master for different persons, just the content of the bare repository is required and no working tree makes sense to have on the server. A Git repository can be easily put on a server, however if the server is on the Internet then some security settings of the server make the setup difficult.
Instead of setting up a server https://github.com/ can be used. Github allows easily to start a new repository, however it might be better to start with a local repository first and when convinced that the project will have some lifetime move it to github.
For git see:https://git-scm.com/. To get help type:
git <git command> --help
man git-<git command>
git help <git command>
Before starting the first time with a fresh git installation let git know who created it:
git config --global user.name "<name>"
git config --global user.email "<name@email>"
git config --list
To put a project under git clean up the directory first, it is recommended that object files, backup files and executables are not in the same directory (however a file .gitignore can be added that controls what will be checked). To put all files in the directory under git do:
cd <working directory>
git init
to create and initialize the .git directory
git add . or git add -A to add all untracked files to the staging area.
git status
git commit -m 'Initial commit'
To add individual files (git add . adds all files) under git (or use wildcards as git add *.c), do:
git add<new file1><new file2>
Git uses two steps to put the files in its archive. First you add them to the staging area, so the files change from untracked files to tracked files. Then the tracked files can be committed.
git reset <file name> to remove from the staging area. Alternatively the file can just be deleted and then commit will take care about the removal.
After that work normally. When it is time to have a good status of the work type:
git status
to see what has been done. The files modified, created, plus what new steps can be done is shown.
After that do a:
git commit
Having a clean directory (no backup files, no objects and runnable executables), this could be done faster:
git commit -a
git log or the more compact version git log --oneline important is the commit id or just the first 10 characters of the commit id as git log --oneline shows
Inside the directory that git observes, there might be files and directories that should not be version controlled. Such directories and files might contain files automatically produced be integrated project environments.
To ignore files and directories, put the file .gitignore inside the directory. It is a text file that could contain something as:
# ignore backup files *.h~ *.c~ # ignore compilation results default/*
If not yet committed, getting rid of recently done modifications is easy. git status shows what has been modified since the last commit. git checkout -- <filename> will then get last version. -- seems to be there to mark the name as filename. If -- is missing then a commit name with the same name as the file might be taken. git checkout -- . will do it with all files not committed.
If it comes to release, you should give your release a tag. Commits are identified by a commit number as af8dad733ecf500a859a09357576cbb5605cf543 that can be obtained by git show, git log or git log --oneline. Instead of dealing with those numbers or descriptions.
Commits can be tagged either annotated git tag -a 1.0.0 -m "first version using pymodbus-3.6.9" that stores meta data as author and message from -m
A alternative but not recommended lightweight way is git tag <version>.
<version> is just a string that can be everything. It needs therefore some discipline to not end up messy. Examples are:
1.0.0
1.0.0-rc0 (release candidate 0)
Links how to do it:https://en.wikipedia.org/wiki/Software_versioning and https://www.python.org/dev/peps/pep-0440/.
An other issue is if V, v, Ver, ver , version, Version, ... should be put in front of the number? To not create a mess and confusion (what is a tag and what a version) keep it as pure number.
If something other than the head is tagged, the commit number can be passed git tag -a 1.0.0 af8dad733ecf500.
The commit number does not have to be inserted completely, It just needs enough characters to be unique.
To see what tags there are type git tag or better git tag -n to see the message strings. git show 1.0.0
To delete tags git tag -d <tag name>
To create a zipped tarball of the latest version (HEAD)in the working directory (make sure you have committed everything):
git archive -o<name of the archive>.tar HEAD && gzip <name of the archive>.tar
git checkout 1.0.0 to get it back in the future
git checkout -b bugfix-based-on-1.0.0 1.0.0 to get it back in the future by creating a branch from it
If a well working version gets larger risky modifications or if a second programmer starts doing something, it recommended an a common habit to create a branch, this means a new version that exists in parallel to the stable version the master. If the work done is useful the branch can be merged with the stable version, if not the branch can be deleted. To see what branch there are type:
git branch will show just all local branches
Creating a branch does not mean working on it. To work on it it must be switched to it: git checkout <my branch>
More important * shows what branch is active and gets the work
To create new branches type:
git branch <name of new branch> <tag from where it branches>
git branch -a will show all the branches (lists local and remote branches) and marks selected branch with *
git switch <my branch> will switch between branches
git checkout <name of new branch> to checkout the branch (creating does not checkout)
To create and checkout
git checkout -b <name of new branch>
git checkout -b <my-fork-branch><commit as e4f5g6h> branches at a specific commit and switches to this branch
git checkout main goes to the main branch
git push -u origin <my branch> copies the branch to the remote repository
git push origin master will then put the change to the remote.
git push origin HEAD:master --force is the command to overwrite the head master on the remote in case something went wrong on the remote repository
Merging is the step to get the master branch all of the work done in <my branch>
Merging starts with switching back from <my branch> to the master branch git checkout master. To make sure the local master branch matches the remote master branch git pull origin master
git merge <my branch> will finally merge it into the master branch
git branch -d<name of new branch> to delete a branch
git log --oneline shows on single lines what commits have been done
git branch --merged will show what branches are merged with the master branch and might therefore be deleted on the local repository as git branch -d <my branch> and on the remote repository as git push origin --delete <my branch> to see that all branches are deleted git branch -a
git clone <uri> or git clone <uri><path to local directory>.git creates a clone of the git repository from the Internet on the local computer. It is a good habit to put .git to such directory names.
On local filesystem the directory containing git (the git repository) could be simply copied but the clean way is git clone file://<path to local source directory><path to destination directory>
git clone <path to local source directory><path to destination directory> will try to create hard links between source and destination. so use file:// do have a real copy.
When created a clone a complete copy is created changes will affect just one of them. To see where the local repository fetches and pushes its changes git remote -v or git remote show origin to update it to the newest on the server git pull
Remote repository are bare repository that have no working directories (working tree) where the files are checked out. The purpose of a remote repository is that the files checked out are on a remote machine and not on the server. A remote bare repository is a .git directory with a visible (not hidden) directory with a name as . <name>.git
Such a remote bare repository can be created from a regular repository.
git supports different ways of communication. The following uses http and does not require to have git installed on the server. On the server machine run
cd /var/www/htdocs or where the server data is
git clone --bare <path to the source repository><name of remote repository>.git
Some magic work needs to be done
cd <name of remote repository>.git
mv hooks/post-update.sample hooks/post-update
chmod a+x hooks/post-update
git update-server-info
Now when the magic is done a user can clone it with git clone http://<server name>/<name of remote repository>.git
git diff will show the differences between the two repositories
The remote repository might have been changed (as by other developers) since the cloning. To get this update git pull origin master
git push origin master will then move back the work
Git has also its Gui:
git gui
or
gitk
Since this GUI is quite complex to support everything it is recommended to not loose focus and start first with the simple console commands.
When a project has some success it is ready to share it with others so https://github.com/ is a way to go. Everything can be done very intuitive in a web browser as create repositories.
The way to work in GitHub is create a branch from the master, so the master stays intact and ready to be used by others. Then do the work (commits) on the branch, make a pull request and merge it with the branch.
https://codeberg.org/ is an alternative for github.
Sign up and sign in in https://github.com/
Create a new repository using the github gui, add all files and directory to github and commit them using the gui.
mkdir ~/GitHub create a directory
cd ~/GitHub/ and go into this directory
git clone https://github.com/linurs/linursoverlay.git get the repository from the Internet to the ~/GitHub local directory where a sub directory linursoverlay gets automatically created.
cd linursoverlay go into the repository
git branch <my-branch> even being local create a branch to keep also the master branch intact. This is later important to merge your work with the master branch on the Internet (GitHub)
git checkout <my-branch> now let git know that you are going to work with your branch and that you like to keep the master branch intact.
Now to all the work in the directory.
When coming to an end do git status, git add and git commit until the git repository is happy.
Remember the login username and access token to do the following. The access token is a long number that is used instead of the password to get access. Access tokens will be required in the future. The access token can be created using a web browser accessing GitHub.https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token
Finally do git push --set-upstream origin <my-branch> to have it on GitHub
Now on https://github.com/ create a pull request and if having the privileges merge it. The branch does not need to be deleted when planing new activities.