This repository has been archived on 2024-09-12. You can view files and clone it, but cannot push or open issues or pull requests.
svrjs-blog/source/_posts/Mastering-the-Basics-of-Git-The-Ultimate-Guide-to-Git-Commands-for-Software-Developers.md
2024-03-15 23:24:27 +01:00

370 lines
12 KiB
Markdown

---
title: >-
Mastering the Basics of Git: The Ultimate Guide to Git Commands for Software
Developers
tags:
- git
- development
- vcs
category: Tips
thumbnail: >-
/images/covers/Mastering-the-Basics-of-Git-The-Ultimate-Guide-to-Git-Commands-for-Software-Developers.png
date: 2024-03-05 05:13:30
---
Git is a popular distributed version control system (VCS), often used for collaborative software development. It is created in 2005 by Linus Torvalds for use in developing his Linux kernel and it is maintained by Junio Hamano since then.
As of 2022, nearly 95% of software developers use Git as their primary version control system. There are many popular Git repository hosting services, including GitHub, GitLab, Bitbucket and Sourceforge.
This post will guide you through `git` commands.
## Initializing a repository with `git init`
If you want to initalize an empty Git repository, you can use `git init` command like this:
```sh
git init <repository_name>
```
This command creates an empty working tree of a repository. A working tree is what software developer works on. Git servers however have bare repositories, which can be created with `git init` command with a `--bare` parameter like this:
```sh
git init --bare <repository_name>
```
The default branch is `master`. If you want to initalize repositories with default branch other than `master`, you can run this command before initializing the repository:
```sh
git config --global init.defaultBranch <branch>
```
![The result of `git init` command](/images/git-init.png)
## Setting up the origin...
If you have an empty remote Git repository and an newly-initalized local repository, you can use this command:
```sh
git remote add origin <remote_repository_path>
```
The remote repository path can be accessed through Git protocol (like `git://repo.or.cz/svrjs.git`), SSH (like `ssh://git@repo.or.cz/svrjs.git`), HTTP(S) (like `https://git.svrjs.org/svrjs.git`) or local computer (like `/home/username/mynewrepository`)
If you want to change the origin, you can use this command:
```sh
git remote set-url origin <remote_repository_path>
```
## Cloning a repository with `git clone`
Often, you need to clone a Git repository to your development environment, e.g. to contribute to the project, or simply to build some program from source code. In this case you can use this command:
```sh
git clone <remote_repository_path>
```
If you want to replicate the repository into a server, you can use this command (it clones into bare repository):
```sh
git clone --bare <remote_respository_path>
```
If you want to clone specific branch, you can add `-b <branch>` parameter.
![The result of `git clone` command](/images/git-clone.png)
## Changing the code
After editing the code, you can commit the changes to the repository. But before committing these changes, you will need to include the files to be committed like this:
```sh
git add <files>
```
You can also use `git add .` to prepare entire current working directory.
After including the files, you can commit using this command:
```sh
git commit
```
Or with specified commit message:
```sh
git commit -m <commit_message>
```
If you want to also commit without a prior `git add` command, you can use this command:
```sh
git commit -a
```
If something gone wrong with the commit, you can modify the current commit by adding `--amend` parameter to the `git commit` command.
If you don't specify a commit message, you will fill it in the editor as shown below:
![Commit name filled in the editor](/images/git-clone.png)
You may see "Please tell me who you are" prompt along with commands to set up your name and email address. You can use these commands:
```sh
git config --global user.email <email_address>
git config --global user.name <committer_name>
```
You can skip `--global` parameter to set it just for one repository.
You can also define files not to be included in commits through `.gitignore` file in the repository root. This file contains paths to files not included in commits. An example of a `.gitignore` file can be:
```sh
node_modules
package-lock.json
```
In this case, `node_modules` and `package-lock.json` are not included in commits.
If you don't want the commit, you can first off check which commit to revert via `git log` command. Once you found out the commit ID, you can use this command:
```sh
git reset <commit_id>
```
If you add `--soft` parameter, you will not remove files to be included in commits. If you add `--hard` parameter, any changes to files will disappear.
You can also use those as a commit ID:
* `HEAD` - latest commit
* `HEAD^` - next to latest commit
* `HEAD~4` - four commits before the latest commit
* `origin/HEAD` - latest commit in the origin
* `somebranch` - latest commit in the `somebranch` branch.
* `sometag` - latest commit tagged with `sometag` tag.
If you want also to create commit reverting the changes, you can use this command:
```sh
git revert <commit_id>
```
If you want to revert the changes for one file to the latest commit, you can use this command:
```sh
git checkout -- <file_name>
```
## Pushing and pulling the changes!
After modfiying the code and committing the changes, you can use this command to push these changes to the remote server:
```sh
git push
```
Or if you are pushing a newly-initialized repository:
```sh
git push --set-upstream origin <current_branch>
```
Or if you want to push all the branches:
```sh
git push --all origin
```
You can replace `master` with whatever branch you want to create. You may be asked then for credentials for a remote Git server.
![This `git push` command has failed.](/images/git-cant-push.png)
If you want to synchronize your repository with the remote repository (for example in situation shown above), you can use this command:
```sh
git pull
```
Or if you don't want to merge the trees:
```sh
git fetch
```
## Working with branches...
You can display all the local branches with this command:
```sh
git branch
```
You can also display both local and remote repositories using this command:
```sh
git branch -av
```
![List of branches in a Git repository.](/images/git-branch.png)
If you want to switch branches, you can use either `git checkout` or `git switch` command like this:
```sh
git checkout <new_branch>
```
Or like this:
```sh
git switch <new_branch>
```
If you want to create a new branch, you can use this command:
```sh
git branch <new_branch>
```
If you want to delete the branch, you can use:
```sh
git branch -d <branch_to_delete>
```
If you want to force the deletion, replace `-d` with `-D`.
If you want to move the branch, you can use:
```sh
git branch -m [<branch_to_move>] <new_branch>
```
If you skip `<branch_to_move>` parameter, the current branch will be moved. If you want to force the moving, replace `-m` with `-M`.
If you want to copy the branch to a new one, you can use:
```sh
git branch -c [<branch_to_copy>] <new_branch>
```
If you skip `<branch_to_copy>` parameter, the current branch will be copied. If you want to force the copying, replace `-c` with `-C`.
If you want to merge two branches, you can use this:
```sh
git checkout <destination_branch>
git merge <source_branch>
```
If you want to merge only one file, you can add `-F <filename>` parameter. Note, that you may need to manually modify files to fix merge conflicts.
![A Git merge conflict.](/images/git-merge-conflict.png)
When facing merge conflicts, you may see this if you open a conflicting file:
![Marks related to a Git merge conflict.](/images/git-merge-conflict-marks.png)
`<<<<<<<` marks the destination branch, `>>>>>>>` marks the source branch, while `=======` separates the conflicting contents. There may be even `|||||||`, which marks original text in the conflicting area.
You may need to remove those marks and some of confliciting content. After resolving the conflict, you can run `git commit` in order to commit the merge.
If you want to rebase all commits on one branch to another branch, you can use this command:
```sh
git rebase <branch_new_base> [<branch_to_rebase>]
```
If you skip `<branch_to_rebase>` parameter, the current commit will be rebased.
If you want to tag a commit you can use this command:
```sh
git tag <tag> [<commit>]
```
If you skip `<commit>` parameter, the current commit will be tagged.
If you want to remove the tag, you can use:
```sh
git tag -d <tag>
```
If you want to push these tags, you can use:
```sh
git push --tags
```
## Observe your repository!
If you want to see the state of repository or list new or modified files not yet committed, you can use this command:
```sh
git status
```
![Status of a Git repository.](/images/git-status.png)
If you want to see changes to files not yet staged, you can use:
```sh
git diff
```
Or if you want to see changes to staged files:
```sh
git diff --cached
```
Or if you want to see both changes:
```sh
git HEAD
```
If you want to see changes between two commit IDs, then you can use this command:
```sh
git diff <commit_id_1> <commit_id_2>
```
![Differences between commits.](/images/git-diff.png)
If you want to see author and dates for each change in the file, you can use:
```sh
git blame <filename>
```
![Blame view of a file](/images/git-blame.png)
If you want to show file at the specific commit, you can use:
```sh
git show <commit_id>:<filename>
```
If you want to show entire Git commit history, you can use this command:
```sh
git log
```
![A Git commit history.](/images/git-log.png)
## Configuring Git itself with `git config`
If you want to configure Git, then you can use `git config` command:
```sh
git config <option> <value>
```
By default it is per-repository. For per-user configuration you can use `--global` parameter, while for system-wide one you can use `--system` parameter.
These are some of configuration options:
* `user.name` - committer's name
* `user.email` - committer's email address
* `core.editor` - editor to use
* `color.ui` - if set to `true`, then `git` will use colors
* `init.defaultBranch` - default branch when initializing a repository, defualt value is `master`
* `http.sslVerify` - if set to `false`, then `git` will not verify SSL/TLS certificates
You can also add `-c <option>=<value>` parameter to any git command (right after `git`, but before command name, such as `clone`, `push` or `add`)
You can see configuration options in [The Git Book](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration).
You can also list configuration parameters using this command:
```sh
git config --list
```
The repository configuration is stored in `config` file in `.git` directory in the repository directory. Per-user configuration is in `.gitconfig` file in the user home directory. System-wide configuration is stored in the `/etc/gitconfig` file.
## Git patches
If you are contributing to open-source project that uses Git as version control system, you may need to send patches to project maintainers. You may need to first format the patches.
You can create regular patches using this command:
```sh
git format-patch <commit_id> -o <directory_with_patches>
```
You can then send these patches to project maintainers.
Project maintainers will then use the inverse of `git format-patch` command - the `git apply` command. First, the maintainer will check the statistics about patch:
```sh
git apply --stat <patch>
```
Then maintainers will perform a dry run to detect errors in the patch:
```sh
git apply --check <patch>
```
Finally, maintainers will apply the patch:
```sh
git apply <patch>
```
Maintainers may also apply series of patches with this command:
```sh
git am <directory_with_patches>
```
If you want to send emails using `git` command, you need to first configure the SMTP server like this:
```sh
git config sendemail.smtpServer <smtp_server>
git config sendemail.smtpServerPort <smtp_port>
git config sendemail.smtpUser <smtp_user>
git config sendemail.smtpPass <password>
git config sendemail.from <email_address>
#Optional, specifies encryption
git config sendemail.smtpEncryption (ssl|tls)
```
Then format the patches with `git format-patch` command and send these patches with `git send-email` command like this:
```sh
git send-email --to=<destination_email> <patches>
```
## Git command help
And finally, you can use this command for usage of specific `git` command:
```sh
git <command> --help
```
![Help for `git branch` command.](/images/git-help.png)
You may also see [Git documentation](https://git-scm.com/docs) for more information.