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.This command will be useful to us later.git log
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 entryTo 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:
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.git pull
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: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 branch testing
There is a way to create a new branch and switch to it simultaneously. We do this with the command:git checkout 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.git checkout -b testing
Previewing All Branches
The command: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 branch
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
-
Discarding your changes since the last commit:
git reset --hard
-
Committing all changes:
git add .
git commit -m "commit message" -
Stashing changes:
git stash
to restore changes, after switching back to the appropriate branch, enter
git stash pop
Browsing Through Repository History
The commandlists 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 log
You can also switch a specified number of snapshots back.git checkout hash
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 HEAD~2
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.