Git is an extremely good distributed version control system. The system can record every change to a user’s files and also has powerful team collaboration capabilities: everyone can commit changes to the text without worrying about overwriting the operations of others. Github is furthermore a software source code hosting service version-controlled with Git. As of 2015, Github had more than nine million registered users and 21.1 million repositories. Github has become the largest code hosting website and open source community in the world.

GIT usage tutorial

Creating a repository

Choose a suitable place and create an empty directory

mkdir <dir-name>
cd <dir-name>  #operate inside the repository
pwd  #you can check the current directory
git init #turn the directory into a repository Git can manage, that is, initialize the repository

Afterwards a .git directory is created in the current directory; this directory is used by Git to track and manage the repository. A non-empty directory can also be used to create a Git repository

Writing and saving files

Write the file and place it in the <dir-name> directory (or a subdirectory)

Edit and save the file in plain text, saving the file encoding in UTF-8 format

git add <filename1> <filename2> ...  #tell Git to add the files to the repository
git commit -m "..."  #commit the files to the repository; enter the description of this commit after -m; multiple files can be committed at once
git status  #check the current status of the repository, telling the user whether any file has been modified
git diff  #check what exactly was modified in the files, or compare files
git log  #show the commit log from most recent to oldest (the parameter --pretty=oneline can be added to change the display view)
git reset --hard HEAD^  #revert the files to the previous version

In Git, HEAD represents the current version, the previous version is HEAD^, the one before that is HEAD^^, and N versions back can be written as HEAD~N

git reset --hard <fileID>  #jump the file version to the file with version ID <fileID>
git reflog  #records every operation of the user, from which you can check the version number before the file was reverted

Working directory and staging area

  • Working directory

The directory you can see on the computer is the working directory, used to store files

  • Repository and staging area

There is a hidden directory .git under the working directory; this is the git repository, and the repository contains the staging area (stage/index)

  • Roughly how Git works

Adding files to the Git repository takes two steps:

  1. git add adds the file into the staging area, that is, adds the modification or related operations on the file to the staging area
  2. git commit commits the changes, that is, submits everything in the staging area to the current branch

Undoing changes to files

git checkout -- <filename> undoes all modifications to in the working directory; the -- in the command is very important, without -- it becomes the command for switching to another branch

Cases of undoing changes to files

As for when changes to a file need to be undone, there are roughly two cases:

  • If <filename> has been modified but not yet put into the staging area, then after the command executes the changes are undone and the file returns to exactly the same state as the repository
  • If <filename> has already been added to the staging area and then modified again, then after the command executes the changes are undone and the file returns to the state it had after being added to the staging area In short, it makes the file return to the state of the most recent git commit or git add

Summary of undoing and reverting

  1. When you have messed up the content of a file in the working directory and want to simply discard the modifications in the working directory, use the command git checkout -- <filename>
  2. When you have not only messed up the content of a file in the working directory but also added it to the staging area, and want to discard the modifications, do it in two steps: use the command git reset HEAD <filename> to go back to case 1, then continue with the operation in 1
  3. When you have already committed an inappropriate modification to the repository and want to undo this commit, refer to version reverting — provided it has not been pushed to the remote repository

Version reverting: git reset --hard <ID> jumps the file to the version with version number ID; HEAD represents the latest file version

Undoing deletions in Git

Deletion is also a modification operation in Git

Normally, after committing to the repository, we delete a file directly in the file manager (or with the rm command); git status will tell you which files have been deleted, and there are then two choices:

  1. If you really want to delete it from the repository, run the git rm command to delete it and then git commit
  2. If you deleted it by mistake, you can run git checkout -- <filename> to restore the mistakenly deleted file to the latest version
  • git checkout in fact replaces the version in the working directory with the version in the repository; whether the working directory version was modified or deleted, it can be “restored with one click”, The command git rm is used to delete a file. If a file has already been committed to the repository, you never need to worry about deleting it by mistake, but you can only restore the file to the latest version, and you will lose the content after the most recent modification commit

Creating an SSH Key

ssh-keygen -t rsa -C "youremail@example.com"

After creating it, you can find the .ssh directory in the user’s home directory, containing the two files id_rsa and id_rsa.pub; these two files are the key pair of the SSH Key. id——rsa is the private key and must not be leaked, while id_rsa.pub is the public key and can be published. Then log into Github to configure it: go to the “SSH Key” page, click “Add SSH Key”, fill in any title and paste the content of the id_rsa.pub file into the Key text box

Github allows adding multiple Keys

Associating a remote repository

First create a new repository on Github (or use an existing one), then run the following command in a local repository:

git remote add origin git@github.com:<accountname>/<localreponame>.git

After adding it, the default name of the remote repository in Git is origin; it can be changed:

git push -u origin master

The git push command actually pushes the current branch master to the remote, If this is the first time you push the master branch you need to add the -u parameter; Git will not only push the content of the local master branch to the new remote master branch, but also associate the local master branch with the remote master branch, which simplifies the command for later pushes or pulls. Afterwards, as long as you have made a local commit, you can complete the submission with the command: git push origin master When using Git’s clone or push command for the first time you will get an SSH warning; just type yes

#associate a remote repository
git remote add origin git@server-name:path/repo-anme.git

Cloning a remote repository to local

After creating a repository in Github, you can use git clone to clone a local repository git clone git@github.com:<git repository address>

Git supports multiple protocols, including https

windows systems: git clone <URL of the Git remote repository>

Git branches

git branch  #view branches
git branch <name>  #create a branch
git checkout <name>  #switch branches
git checkout -b <name>  #create + switch branch
git merge <name>  #merge some branch into the current branch
git branch -d <name>  #delete a branch

Multiple branches share the staging area, that is, if you only add without committing on branch 1, the staging area has in fact already recorded that modification, and even switching to branch 2 afterwards and committing there is a valid operation When Git cannot merge branches automatically, the conflict has to be resolved first. Commit after resolving the conflict, with the git log --graph command you can see the branch merge graph, and git status can also show the conflicting files

e.g: git log --graph --pretty=oneline --abbrev-commit

Git branch management

When merging branches, adding the --no-ff parameter allows merging in normal mode; the history after such a merge has branches, so you can tell that a merge was once done, whereas with fast-forward merging you cannot tell that a merge was done

git merge --no-ff -m"..." <name>

Merging a branch in normal mode (that is, disabling fast forward) requires creating a new commit for this merge, so add the -m parameter and write the commit description

Branch strategy:

  • In actual development we should manage branches according to a few basic principles:
  • The master branch should be very stable, that is, used only to release new versions, and you do not normally work on it;
  • Work happens on the dev branch, that is, the devd branch is unstable, and at some point the dev branch is merged into the master branch;
  • Everyone works on the dev branch, and each person has their own branch; when it needs to be saved, just merge it into the dev branch

Bug branches

The git stash command is equivalent to taking a snapshot of the current working environment, so that you can restore the environment later and continue working

Fix the bug on whichever branch it should be fixed on, and create a temporary branch from that branch

Commit and delete the branch after fixing

git stash list  #check whether a stash exists
git stash apply  #restore the stash content; this command does not delete the stash content after running
git stash drop  #delete the stash content
git stash pop  #restore the stash content and delete it at the same time

When fixing a bug while the work at hand is not finished, first git stash the work in progress, then go and fix the bug, and after fixing it git stash pop back to the work in progress

Feature branches (adding new features)

When developing a new feature it is best to create a new branch, To discard a branch that has never been merged, you can force its deletion with git branch -D <name>

Collaboration

git remote shows information about the remote repositories

git remote -v shows detailed information about the remote repositories (it displays the addresses of the for fetching and pushing; if you have no push permission, the push address is not shown)

  • Pushing branches:

Pushing a branch means pushing all the local commits on that branch to the remote repository. When pushing, the local branch must be specified

git push <remote repository name> <local repository name>
git pull  #fetch the latest commits from the remote repository

Merge locally after fetching and push again after resolving conflicts

  • Working pattern:
  1. First, you can try to push your changes with git push origin branch-name
  2. If the push fails, it is because the remote branch is newer than your local version, so you need to try to merge first with git push
  3. If the merge has conflicts, resolve them and commit locally
  4. Once there are no conflicts or the conflicts have been resolved, pushing again with git push origin branch-name will succeed

If git pull says “no tracking information”, it means the link between the local branch and the remote branch has not been created; use the command git branch --set-upstream branch-name origin/branch-name (this command establishes the association between the local branch and the remote branch)

Tag management

When releasing a version, we usually first tag the repository, so that the version at the time of tagging is uniquely determined. At some point in the future, taking a certain version of a certain tag means taking out the version corresponding to the moment the tag was created. A tag is also a snapshot of the repository

Although a Git tag is a snapshot of the repository, it is in fact a pointer to a certain commit (branches can move, tags cannot)

A tag is just an easy-to-remember name bound to a certain commit

git tag <name>  #to tag in git you should first switch to the branch that needs the tag
git tag  #view all tags; by default a tag is created on the commit of the latest submission
git tag <name> <commit ID>  #tag the commit with the corresponding ID

Tags are not listed in chronological order but sorted alphabetically; git show <tagname> can be used to view tag information

git tag -a <tagname> -m "..."  #create a tag with a description; -a specifies the tag name and -m specifies the description text
git tag -d <tagname>  #delete a local tag, because created tags are only stored locally and are not automatically pushed to the remote
git push <remote repository name> <tagname>  #push a certain tag to the remote
git push <remote repository name> --tags  #push all local tags not yet pushed to the remote in one go

If in the first line of code above the parameter -s is used instead of -a, a PGP-signed tag can be created

Deleting a tag that has already been pushed to the remote:

git push <remote repository name> :refs/tags/<tagname>

On Github you can freely Fork open source repositories;

you have read and write permission on the repository you Forked;

you can push Pull requests to other people’s repositories to contribute code;

after Forking someone else’s repository, clone the repository under your own account, so that you can push your modifications

Customizing Git

git config --global color.ui true  #git will display different colors appropriately
  • Ignoring files

In the root directory of the Git working directory there is a .gitignore file (create it if it does not exist); fill in the names of the files to be ignored, and Git will automatically ignore these files

Principles for ignoring files:

  1. Ignore files automatically generated by the operating system, such as thumbnails;
  2. Ignore intermediate files and executable files generated by compilation — that is, files automatically generated from other files do not need to be put into the repository;
  3. Ignore your own configuration files containing sensitive information, such as configuration files that store passwords

Afterwards commit .gitignore to Git as well, and the ignored-file configuration is complete

git check-ignore  #check the .gitignore file
git add -f <filename>  #force adding a file

We can also version-manage .gitignore

  • Setting aliases

git config --global alias <alias> <original command name> The –global parameter is a global parameter, meaning these commands are effective in all Git repositories on the computer

When configuring Git, adding --global applies to the current user; without it, it only applies to the current repository. Each repository’s Git configuration file is stored in the .git/config file, with aliases after [alias]; to delete an alias just delete the corresponding line. The current user’s Git configuration file is the hidden file .gitconfig in the user’s home directory

Setting up a Git server (linux ubuntu or debian)

  1. Install git: sudo apt-get install git;
  2. Create a git user to run the git service: sudo adduser git;
  3. Set up certificate login: collect the public keys of all users who need to log in, that is, their id_rs.pub files, and import all public keys into the /home/git/.shh/authorized_keys file (the name can be changed);
  4. Initialize the Git repository: sudo git init --bare <reponame>; the parameter –bare creates a bare repository, that is, one without a working directory (Git repositories on a server usually end with .git; after creating it change the owner to git with sudo chown -R git:git <reponame>);
  5. Disable shell login: for security reasons, the git user created in step 2 is not allowed to log into the shell; this can be done by editing the /etc/passwd file Find a line like: git:x:1001:1001:,,,:/home/git:/bin/bash and change it to: git:x:1001:1001:,,,:/home/git:/usr/bin/got-shell so that when the user logs in with a shell they are automatically logged out;
  6. Clone the remote repository: git clone git@server:/srv/<reponame>; run it on each person’s own computer

Reference:

Liao Xuefeng’s Git tutorial