Solvro Talks - Basics of GIT

Kształt kółka
Kształt półkola
Ksztalt koła dekoracyjny
Solvro Talks - Basics of GIT

Solvro Talks - Basics of GIT

GIT - Version Control System

Why use Git? Why is it worthwhile

Git ensures that every project participant always has its latest version. Git belongs to distributed version control systems, meaning that besides the project being on a server, each project participant has their local version. So if the server crashes, nothing bad should happen. Git can also handle situations like two people editing the same file. The system will simply attempt to merge the changes made by both people. Moreover, Git stores all versions of a given file, so if something breaks, there's no problem in retrieving the previous version. That's just one reason why it's worth using Git even when working solo.

Working alone:

  1. Ability to easily undo a disaster
  2. Experiment without destruction
  3. Easy work from multiple locations
  4. Easy onboarding of new people
  5. Killing two birds with one stone (CV)

What is Git

Git is a distributed version control system based on very simple assumptions. This is its strength — flexibility and a few clever ideas have resulted in a tool simple to use, suitable for both simple projects and large undertakings (like the Linux kernel).

Git is practically a required skill in many companies, and because a programmer's work is based on teamwork, it's a technology you should master.

SCM — stands for Source Code Management; it is a system that allows archiving and tracking changes in the code, enabling us to go back in history or see who was the author of a particular change.

Repository — a 'container' for a specific set of code, usually one project; a repository allows grouping code and changes so we can view all changes made within one repository, grant permissions to repositories, and download/copy them.

Commit — is the process of 'sending' specific code changes to the repository — if you fetch code from the repository, modify it, and send these changes back to the repository, this process is called committing, and the changes sent together are called a commit or revision.

pull / push — respectively, fetching and sending changes (one or many commits) from/to another repository

diff — (eng. difference) — is the difference between different revisions — this lets us see which parts have changed and how; it also allows optimizing data transfer between repositories

fork — a copy of a repository; especially popular in the case of open-source projects, allowing us to copy the entire project and develop it independently (e.g., adapting it to our needs)

branch — a branch, version within the repository; branches allow multiple people to work simultaneously without constantly getting in each other's way and overwriting changes — everyone can work on their branch and only merge changes with others after finishing their work, resolving issues.

merge — merging many changes from various sources, which may result in incompatible changes requiring manual modifications; merge allows integrating work done in different areas, which may overlap, into one whole in a controlled and conscious manner.

Installing Git

Linux

Fedora:

sudo yum install git-core

Debian-based:

sudo apt-get install git

Mac

http://sourceforge.net/projects/git-osx-installer/

Windows

http://msysgit.github.com/

Git Client

Personally, I sincerely encourage you to use the original Git Bash, or, in the case of Unix systems - the built-in console. I believe it's worth getting used to using the console as it's not as complicated a tool as it seems, and it allows you to quickly grasp the workings of Git. However, for those who shudder at the thought of typing letters into the command line, many tools like SmarGit, SourceTree, or GitKraken have been created.

Git Repository

During the lecture, we will be using GitHub, probably the most popular platform. I recommend getting familiar with it, as it is also a showcase of you as a programmer. You can upload your projects to GitHub, and recently GitHub offers free private repositories, so you can also use it for, for example, assignments. It's worth noting that GitHub is not synonymous with Git, and there are other similar platforms - like GitLab or Bitbucket.

One-Time Configuration

git config --global user.name "John Doe"
git config --global user.email "john.doe@solvro.pl"

Creating a New Repository / Cloning an Existing One

Repository Initialization

git init

This command will create a new subdirectory named .git, containing all necessary files — the skeleton of a Git repository. At this point, no part of your project is tracked yet.

To begin version control of the existing files, you should start tracking them and create an initial revision. You can do this with a series of add commands, selecting individual files you wish to track, and then committing the changes:

git add README
git add *.js
git add .
git commit -m "commit message"

Creating a Repository on GitHub - Navigating the Platform, remote add

git remote add origin https://github.com/okkindel/sample.git git push origin master

Cloning a Repository, Pushing Additional Files

git clone https://github.com/okkindel/sample.git

Working with Git

Checking the status of files:

The basic tool used to check the status of files is the git status command. If you run it immediately after cloning the repository, you'll see an output similar to the one below:

git status

On branch master
nothing to commit, working tree clean

This means you have a clean working directory — in other words, it contains no tracked and modified files. Git also doesn't see any untracked files; otherwise, it would display their list. Finally, the command shows the branch you are currently working on. So far, it has always been the master, the default value.

Adding a File, Status, Tracking, Status

Let's say you add a new, simple file to the repository. If it didn't exist before, after running git status you'll see it as an untracked file, as shown below. It's clear that your new file is not yet tracked because it appears under the "Untracked files" header in the status information. Untracked means Git sees a file you didn't have in the previous snapshot (committed copy); Git won't start including it in future snapshots until you explicitly tell it to. It behaves this way to prevent you from accidentally including in snapshots program output or other files you didn't intend to add.

To start tracking a new file, use the git add command. If you now run the status command again, you'll see that your file is already tracked and is listed under 'changes to be committed'.

okkindel@hajduk  ~/Documents/SOLVRO/Lectures/dump   master  git status
	On branch master
	nothing to commit, working tree clean
okkindel@hajduk  ~/Documents/SOLVRO/Lectures/dump   master  touch file1
okkindel@hajduk  ~/Documents/SOLVRO/Lectures/dump   master  git status
	On branch master
	Untracked files:
  	(use "git add <file>..." to include in what will be committed)
    file1
	nothing added to commit but untracked files present (use "git add" to track)
okkindel@hajduk  ~/Documents/SOLVRO/Lectures/dump   master  git add file1
okkindel@hajduk  ~/Documents/SOLVRO/Lectures/dump   master ✚  git status
	On branch master
	Changes to be committed:
  	(use "git reset HEAD <file>..." to unstage)
	new file:     file1

Modifying an Existing File, Tracking

Now let's modify a file that was already tracked. If you change a previously tracked file and then run the status command, you'll see something like this:

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:     file1

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified: LICENCE.md

The file appears in the "Changes not staged for commit" (Modified but not updated) section, meaning the tracked file has been modified but the changes haven't yet made it to the staging area. To send them there, run the git add command (this is a multipurpose command — it is used to start tracking new files, stage them, and other tasks like marking resolved merge conflicts). Therefore, run git add to place the file in the staging area, and then execute git status again:

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified: LICENCE.md
        new file:     file1

Modifying an Existing File Again

Both files are already in the staging area and will be included in the next commit. Suppose at this point you remember an additional small change you must make to the file before committing. You open it, make the change, and are ready to commit. However, run git status once more.

What the heck? The file is now simultaneously in the staging area and outside of it. How is this possible? It turns out that Git places the file in the staging area exactly as it was at the moment you ran the git add command. If you commit changes right now, the version used will be the one from when git add was run, not the one you see in the working directory at the time you issue the git commit command. If you modify a file after running git add, you must use git add again to include the latest changes in the staging area.

Untracking

If you change your mind and don't want to track your file to commit it later, you can use the git reset command:

git reset file

Ignoring Files

You'll often encounter a class of files that you don't want Git to automatically add to the repository or even show as untracked. These are generally automatically generated files, such as logs or files created during the project build. In such cases, you create a file containing a list of patterns matching them and name it .gitignore.

Committing Changes

Now that your staging area contains exactly what it should, you can commit your changes. Remember that anything not yet in the staging area — any file you created or modified and later didn't run the git add command on — will not be included in the committed changes. It will remain only as modified files on your disk.

In this case, when you last ran git status, you saw that all your changes are already in the staging area, so you're ready to commit them. The simplest way to commit changes is to type git commit:

git commit

This will launch a text editor. After exiting the editor, Git will create a new snapshot with your change description (removing comments and the change summary beforehand). Alternatively, you can provide the revision description while issuing the commit command, preceded by the -m flag.

The commit operation also returned some additional information, such as the branch you added the changes to (master), their SHA-1 checksum, the number of modified files, and statistics on the added and removed lines of code.

To then push the accepted changes to the external repository (in our case, GitHub), use the push command:

git push

This command gathers all committed snapshots and saves them to the pre-configured repository.

Deleting Files

To delete a file from Git, you must first remove it from the set of tracked files and then commit the changes. The git rm command is used for this, which also removes the file from the working directory. You won't see it in the untracked files section the next time.

If you simply delete the file from the working directory and execute the git status command, you'll see it in the "Changes not staged for commit" (Modified but not updated) section (i.e., outside the staging area).

Reverting Changes in a Modified File

The git status command once again comes to the rescue. Git specifically indicates how to get rid of the changes made. So let's do what Git says:

git checkout -- file

You can now read that the changes have been reverted.

You should already be aware that this is a rather dangerous command: any changes you made to the file are lost - in fact, it has been overwritten by the previous version. Never use this command unless you are absolutely sure that you no longer want or need the given file.

Viewing History

After a few revisions, or in the case of a cloned repository that already contains its own history, the time will come when you want to look back into the past and check the changes made. The simplest and most powerful tool for this is git log.

git log

This command will be useful to us later.

Working with a Remote Repository

When we want to push the changes to an external repository, it turns out that someone has made changes before us. This is indicated by the entry
To https://github.com/okkindel/sample.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/okkindel/sample.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Once again, it's best to do what the program suggests. We'll use the git pull command:

git pull

If you are in the master branch and run the git pull command, changes from the remote repository will be merged with the master branch in your local repository immediately after downloading.

Branches

Almost every version control system has support for branches. Branching means diverging from the main line of development and continuing work without causing disorder there. In many version control tools, this is a quite costly process, often requiring the creation of a new code directory copy, which in the case of large projects can take a lot of time. Some consider Git's branch model to be its "killer feature," and it certainly sets it apart from other tools of this kind. What's special about it? The way Git handles branches is extremely lightweight, making the creation of new branches almost instantaneous, and switching between them takes little longer. Unlike many other systems, Git encourages frequent branching and merging of the project, even several times a day. Understanding and mastering this unique and powerful mechanism can literally change the way you work. How to create a new branch? It's very simple and requires only entering one command:

git branch testing

How does Git know which branch you are currently on? It maintains a special pointer called HEAD. In Git, it is a pointer to the local branch you are currently on. In this case, you are still on the master branch. The git branch command only created a new branch but did not switch you to it. To switch to an existing branch, you use the git checkout command. Let's switch to the newly created testing branch:

git checkout testing

There is a way to create a new branch and switch to it simultaneously. We do this with the command:

git checkout -b testing

The new branch contains a snapshot from the moment of its creation, meaning from now on, we can make completely different changes on both branches, and Git will treat them separately for each branch.

Previewing All Branches

The command:

git branch

allows you to list the names of all local branches. To see all branches in the repository, we need to precede this command with:

git pull

Merging Branches

  • Provided there is no conflict of changes between branches

        > git merge branch_name
  • Resolving conflicts using the example of VS Code

If we want to switch to another branch while writing code, Git will inform us that there are uncommitted changes. At this point, we have 3 options:
  1. Discarding your changes since the last commit:

    git reset --hard

  2. Committing all changes:

    git add .
    git commit -m "commit message"

  3. Stashing changes:

    git stash

    to restore changes, after switching back to the appropriate branch, enter

    git stash pop

Browsing Through Repository History

The command

git log

lists all commits on the specified branch. You can not only switch between branches but also between commits in the history. To do this, copy the commit hash from the history and use the command:

git checkout hash

You can also switch a specified number of snapshots back.

git checkout HEAD~2

From such a position, you can create a new branch. To return to the latest changes, you can switch back to a branch, e.g.:

git checkout master

Merge Requests

Using GitHub as an example

Useful Programs

  • zsh + ohmyzsh + git plugin
  • fuzzy finder
  • zsh autocomplete
  • fuck

Shortcuts in the git plugin for zsh

  • g
  • gp
  • gcmsg
  • gst
  • glg

 

That's It

If you have any more questions, feel free to reach out in the contact section.

 

 

 

Awatar Maciej Hajduk

Maciej Hajduk

Założyciel

Front line. At work, he focuses mainly on web technologies, but after hours he becomes a self-taught game creator. An enthusiast of Linux, TypeScript, Angular, and RxJS. Proficient at pretending something works, a veteran of many hackathons. Outside of programming - a fan of climbing and board games. Co-founder of the Science Club KN Solvro.

Paradox Call To Action Image
Paradox Shape Image

Join our team!

Contact us

JoinJoin