today I want to make post about most useful IMHO commands. Honestly speaking as usually I prefer to use tortoise git with it's gui. But quite often it happens that even the best gui tool can't give you necessary flexibility. For this purpose git commands come on your rescue. In this post I'll describe some basics of git, some most useful commands, so it's going to be one of my longest articles, and hopefully not the most useless.
In git you can have three levels of configuration:
- --local - configuration of single repository
- --global - configuration of user for your account ( for example user Administrator on your local machine )
- --system - configuration for all users ( all users on your machine )
For example if I want to see, what is global email set, I can use folloiwng command in git console window:
$ git config --global user.email
It will give as output:
If you want to set working email, you can do it like this:
git config --local user.email email@example.com
after that local repository email will be set to firstname.lastname@example.org
User name checking
Ever wondered what is your user name in git? Actually it can be recorded at three levels: local, global, system.
You can get what is there like this:
$git config --system user.username
If you want to set it to value Yuriy Zaletskyy, you can do something like this:
$ git config --system user.username "Yuriy Zaletskyy"
It will set your global user name to Yuriy Zaletskyy.
Checing global configuration information
Ever wondered what is global configuration values? Following command can tell you:
$ git config --global --list
Similarly you can check local and system list.
Also for local level you can go to file .git\config and see local settings.
Setting line endings
Have you ever been in situation when somebody changed each line in the file, you open it, and to your surprise, you don't see any change visually? That can happen in case if that somebody uses another line endings style then you. For dealing with it I recommend to use following command:
$git config --global core.autocrlf true
This commands says to git the following: please add CRs back when you check out file to the working directory.
Two types of push defaults
I don't know have you ever heard about it, but in the past by default Git used to push all branches. For now it pushes only currently selected branch. Those two kinds of pushes are named:
- Simple ( default starting from Git 2.0 )
Do you know how to configure it?
$git config --global push.default simple
with this setting only one currrently selected branch will be pushed. Others will not. For you it means that if you made changes in ten branches, then only one will travel to server, and others will not. Also it means that push will happen faster.
Avoid merging on each pull
If you want to avoid merging messages for each pull, I recommend you the following:
$git config --global pull.rebase true
Cooperation on source control
In gitlab on distinction from GitHub you don't have role of colaborator. You have two options:
- Work through branches
- Work through Fork and Merge request
Workflow for branches is the following:
- You clone repostiory
- Make Branch based on Master
- Make changes in the code
- Push your changes to your branch
- Somebody or you makes merge of branches into master
Workflow for Fork-> Merge request is like this:
1. You create fork. During fork you can give some name to your repository
2. Clone forked repository on your dev machine
3. Make changes to code
4. Make pushes to your repository
5. You create Merge request, and then somebody ( or maybe you ) fulfills your request
Useful commands for Pull Requests
$ git fetch
This command will download all branches
$ git branch -a
this command will show you all branches
$git checkout <branch_name>
obtain working copy of branch <branch_name>
Fast forward vs Recursive
In git you can have two kinds of history: fast forward and recursive. Difference you can see on the picture below:
difference between recursive and fast-forward is how changes will be displayed. Question for meditation, which tree is more informative: recursive or fast-forward?
I for me personally recursive is much more informative then fast-forward.
Tagging, branching, releasing
Another interesting feature of git+GitLab is tagging. Question which often raises is how often tag should be added? General rule of thumb is to add tag for those commits that will go to production.
The only exception can be case if you have CI/CD configured, in that case there is not sence in adding tags.
In Gitlab you can use two kinds of tags:
Take not that this set of tags is different from Github. Github has three kinds of tags:
Lightweight tag stands for tag without any message. Annotated tag stands for adding info on who tagged, possibly when and why. Signed ( not available in GitLab ) has public key to prove identity of tagger.
Consider following example of tags usage:
$git tag -a v1.5.3 -m "Tag message"
this tag will add tag v1.5.3 with message "Tag message".
Important detail. After you've created tag, you need to inform git that tags should be pushed. You can do it like this:
$git push --tags
There are some commonly accepted standards in naming tags related to version. Often following format is used:
Release: major.minor.patch. In case of this command $git tag -a v1.5.3 -m "Tag message" following is understood: version 1, with minor changes 5 and patch changes 3.
Main difference between major and minor is backward compatibility. Quite often ( not always ) changes in major version means breaking of backward compatibility. While minor hardly can mean and minor actually means fixing of bugs. This principle is not written in stone, but I observed it myself in plenty of products.
Honestly speaking I not very often use git commands from console when work with sourcecode in gitlab. I prefer to use Tortoise Git for source code management. But sometime when I can't grasp where is this menu item in Tortoise Git I jump to bash, and enter commands there.