📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Основы Git и GitHub. Курс для начинающих. Установка, настройка, основные команды. Git в WebStorm

Александр Ламков — Friendly Frontend1:16:56

Transcription

Git and GitHub. Every modern developer should know these two things. These topics can be explored infinitely. However, for a beginner specialist, it is enough to master only the basics. That's what we'll talk about today. Before you is a mini-course of concentrated step-by-step practice, with a mix of theory, where we will first talk about why Git is needed at all. Then, for further practice, we will set up Git and GitHub. After that, we will go through the main useful Git commands, and finally, we will discuss convenient work with Git through a graphical interface in the IDE. A minute of useful information. If you are a beginner front-end developer, join our cozy community Friendly Frontend on Telegram. One of the largest Russian-language chats on web development, where you can get free help from more experienced developers, including me. The QR code is in this corner and the link is in the description under the video. Join us, we are waiting for you. Disclaimer: there will be no complex definitions from Wikipedia and documentation here. This is purely my interpretation of only the knowledge you need. No more, no less. So, let's start with the fact that Git and GitHub are two completely different concepts, which should not be confused. Git is a version control system, and GitHub is the most popular site for storing the source code of programs written by developers. We will return to GitHub later, but for now, let's deal with Git and answer the question of why it is needed at all. Git, using special console commands, as well as through the graphical interface in your IDE, allows you to manage the project lifecycle, namely, to manage code and its versions from the first line written 5 years ago to the last hotfix from yesterday. You've probably seen that any program, whether it's professional software, a video game, or an npm library, absolutely any program has a specific version. Usually, it's one, two, or three digits separated by dots. And the larger the digits, the newer the version. With each new version, program authors add new features, fix some known bugs, and sometimes add new ones. In general, any program is a living organism that constantly changes. And what happens between versions at the code level is useful for anyone who works or will work on a project in the future. The most banal example. You released a buggy version of the application into production, and you need to urgently roll back to the previous one. This is where Git will help us, which, when used correctly, stores the history of all code changes that have occurred with it throughout the project's existence. The ability to roll back to any previous version of the code is the first answer to the question: why do I need this Git of yours at all? The second point on this topic. We write code mostly for the computer, and we use Git in our work for ourselves and other project developers. Git allows us to document each line of code or a batch of changes in one or more files. By documenting, I mean briefly describing in ordinary human words what we did and why we wrote specific code. For example, there was version 1.0 of the program, and version 2.0 is being prepared for release. In the second version, a dozen new features are added, and a hundred known bugs are fixed. Each new added feature or the fix of one specific bug is one entry in the so-called commit history, which Git allows us to organize. And finally, the full charm of Git is revealed when working in a team. Complex projects are never developed alone, and dozens of programmers can work on the code simultaneously. As a rule, one developer handles one specific task, and for each task, using Git, a separate version of the application is created, a so-called branch. The project's codebase always has a main branch, called main or master. The main project branch contains the complete, up-to-date version of all the code. When new features need to be developed for an application, for each feature, in companies with proper processes, a separate task is created, which is assigned to one or more developers. And to simplify the simultaneous work of several developers with the same code and minimize the amount of uncontrolled chaos, Git exists for these purposes. Each developer, working on the code to complete their assigned task, branches off from the main main branch, thus obtaining an independent copy of the entire codebase. When a developer finishes working on their task, they take their branch and merge it into the main application branch, roughly speaking, merging all the code into a single whole. And another developer of the project, who was developing a different feature or fixing some bugs, can perform exactly the same actions at the same time. And the role of Git here is that if, when merging several branches by different developers in different branches, the same files were affected, then Git will first try to intelligently merge the code automatically. But if it cannot do it on its own, then Git will offer the developer who initiated the merge of conflicting branches to manually resolve the code inconsistencies through the code editor. That's all with the introductory theory. Let's get to practicing. First of all, we need a service where the code of our projects will be stored. The most popular such service is GitHub. I will leave a link to this site in the description under the video. There are dozens, if not hundreds, of such services. Gitlab, BitBucket, Sber Git, Yandex Sourcecraft. And these are only those that I have encountered in the last 5 years of work. But since all these services are similar in essence, it is enough to understand GitHub, and it will not be a problem to figure out the others if necessary. So, you need to create an account on GitHub. I won't show this step-by-step, you'll figure it out yourself. It's simple. When we have a GitHub account, we proceed to the next step, directly to the Git version control system. To work with Git, we first need to install it on our computer. Now I am on the page with a semi-official, but almost the only complete knowledge base about Git, which is also translated into many languages, including Russian. I will also leave a link to this site in the description. So, on the main page, there is a link downloads. Here are instructions for installing Git on each operating system. For Windows, you can choose the Standalone or Portable installer version here. I usually install Standalone. Then you choose the 64-bit or 32-bit version depending on your system. A regular executable installer will be downloaded. You open it and click Next a dozen times, leaving the default configuration. As for Linux, installation happens through terminal commands. Users of this operating system know this themselves. Well, on MacOS, to install Git, you can type the word Git once in the terminal, click Enter, and then, if Git was not on your computer before, you will be prompted to install XCode Command Line Tools, a set of programs that already include Git. You can bother and install Git separately, but I recommend that a web developer on MacOS still install these XCode Command Line Tools, as these tools may be needed in the future for other professional software. When Git is installed on the computer, you need to manually configure it again using terminal commands. A link to this page about Git configuration will also be in the description under the video. Well, I will go through this entire process with you. If you have Windows, then our first configuration steps can be done through the built-in command prompt application. To open it, type CMD in the Start menu and press Enter. I am on MacOS, so I open the Terminal application. So, we need to identify Git somehow. It will need our name and email. We enter several commands in sequence. First: Git, config, global, space, user.name and then through a space, strictly in double quotes, your name. It's better in Latin, in two words separated by a space. Name and surname with a capital letter. Press Enter. And the second command is Git Config, global, user.email. And here, through a space, without quotes, your email address. To make sure you have filled everything correctly, enter one more command in the terminal: Git, config, list. This data about you will be displayed in the commit history, in the specific record of code changes, of which you are the author. This is needed, for example, so that each team member understands whose work it is when your piece of code is put into production. So, we have installed Git and almost finished configuring it. We have one last step left: generate an SSH key to link our current device with our own GitHub account, so that they can communicate with each other through the Git protocol. Perhaps an SSH key already exists on your device. You might have generated it earlier for other purposes, not necessarily related to Git. To check its availability, you can manually dig through the file explorer in hidden folders, or you can do everything through a terminal command. If you have MacOS, you can stay in the currently open Terminal application. If you have Windows, you will need to switch to a more powerful command prompt that supports an extended list of instructions. You now have the Git Bash application on your computer. It was installed along with Git in the Start menu. Just type Git Bash and open this program. Then, enter the universal command for all operating systems: ls, space, -al, space, .ssh, Enter. The command will display a list of files. If among them there is a file with the .pub extension, then you already have an SSH key on your computer, and you can proceed to the timecode called "SSH Key Binding in GitHub". If you do not see a file with .pub at the end of the name in the terminal, then you need to generate a new key. I will leave a link to the instruction page in the description under the video, but it is not a difficult task, so I will still go through all the steps with you. So, to generate an SSH key, in the same terminal, enter the command ssh-keygen, space, -t, space, ed25519, space, -C, capital C. And then, strictly in double quotes, enter the email that we previously entered during the local Git profile configuration stage and press Enter. Next, you will be prompted to enter the path where the key file will be saved, or you can agree to the default location. To do this, just press Enter. My current device already had an SSH key, so I got a prompt to overwrite the existing key. I press Enter and then Enter again to agree and proceed with the next steps. Next, for added security, you will be prompted to enter a passphrase, but we can do without it. So, just press Enter twice. Our key is ready. However, what we got here in the terminal logs is not suitable. We need the public version of the SSH key. When you have confirmed that an SSH key already exists on your device, you need to find a specific folder in the file explorer. I suggest not to bother and do it again through the terminal. If you have Windows, then you need the Git Bash program. I remind you. So, in Windows, in Git Bash, enter the command start, space, ~/.ssh. And if you have MacOS, then in the terminal, enter open, space, ~/.ssh. That is, the commands for Windows and MacOS differ only in the first word. Press Enter. And before us opens a folder with various key files. We are interested in the file with the .pub extension at the end. Open it with any text editor and copy all the content from the beginning of the file to the end into the clipboard. Now let's bind the SSH key copied to the clipboard to our GitHub account. On the GitHub website, in the upper right corner, click on your profile avatar and go to settings. Here, on the left panel, look for the SSH and GPT keys item in the menu. Before us will open a list of all SSH keys that are bound to our GitHub account. You will probably have it empty here, but I have keys from my work computer, from two personal MacBooks, and from a Windows desktop PC. All this is necessary for me to be able to interact with the code stored in my GitHub profile from any of these devices. So, on the right side of the screen, click the green button New SSH key to bind a new SSH key. In the Title field, enter a name for your device that is understandable to you, so that you can distinguish keys in the future if you plan to bind multiple computers. In the Key type field, do not change anything, and in the multi-line field Key, paste the content of our clipboard. And finally, click the green button Add SSH key. Next, GitHub may ask you to confirm the action. I usually do this through the linked mobile app, but now I didn't have to confirm anything. So, the SSH key of our current device is now linked to our GitHub account, and we are ready to practice basic commands. It will be most convenient for us to practice Git commands on a personal repository. If you are not yet familiar with the concept of a repository, here's a simple analogy. A GitHub account is your personal warehouse, and repositories in your GitHub account are rooms or shelves in your warehouse. And each such repository stores the code of a specific project. And now we need to create our first repository for a sub-project. To do this, on the GitHub website, through the avatar in the upper right corner, go to the Your Repositories section. This page will display a list of your repositories, sorted by the date of the last update. I currently have as many as 139 of them, but initially, it will be empty here. To create a new repository, click the green button New in the upper right part of the screen. The main thing here is to fill in the repository name field. The name must be unique within the list of your existing repositories. Let's enter, for example, My First Project in lowercase in kebab-case notation. Optionally, if you wish, you can fill in the description. Next, an important point, repository visibility. You can make it public or private. I advise you to make all created repositories private by default. And after you are ready to show your code to the world, you can always change the repository's visibility to public. If you do not follow this rule, there is a high probability that over time you will accumulate a public dump of started but unfinished projects on GitHub, which may confuse your dream potential employer. So, we have entered the repository name and set its initial visibility to private. Click the green button Create Repository at the bottom. The repository is created, and before us opens a page with instructions on how to start working with an empty repository. First of all, we need to get acquainted with the Git clone command. With this command, we can clone any public code repository or a private repository to which we have access to our computer. We want to clone the private repository My First Project, which we just created. To do this, from the repository page, copy this command with the SSH tab to the clipboard. There is HTTPS and SSH. We need SSH. To do this, I click on this button on the right to copy this command to the clipboard. Next, we need to open the folder on our computer's terminal where we want to clone our repository. How to navigate through the computer's file structure via the command line, and in particular, how to open a specific folder in the terminal, Google it yourself. I will only show how it's simply done on MacOS. In the file explorer, I right-click on the folder I need and select the "Services" item in the context menu, and then select the "New Terminal at Folder" item. In the opened terminal, we will already be in the desired folder. Now, enter the command Git clone and paste the content from our clipboard with a space. Press Enter. Wait a while for the repository to clone. From the logs in the terminal, we see a warning that we have successfully cloned an empty repository. This is how it should be. Now we can open the newly appeared folder through the IDE as a project. Personally, I work in WebStorm, but in VS Code, our further actions will not differ, as we will still do everything through the built-in terminal. In any modern development environment, particularly in WebStorm and VS Code, there is a graphical interface for convenient work with Git. We will discuss interaction with the Git interface in WebStorm at the end of the video. But for now, to understand the basics of the technology, we will write commands in the terminal. Regarding the .idea folder in the project. It was automatically generated for me when I opened the project folder in WebStorm. You may not have a similar folder. Don't panic, and in any case, repeat all the actions after me and try to understand each step. So, in the root folder of the project, create a new file, for example, index.html. After creating the file, a similar window should pop up. This is exactly the graphical interface that we will get acquainted with later. But for now, check the "Don't ask again" checkbox and reject the offer to add the file to Git. That is, click "Cancel". Before going further, I will mention the existence of the Git init command, and with this command, we can initialize, well, simply put, create a local repository. I am deliberately not doing a detailed breakdown of this command in this video guide, because after executing Git init, you will need to manually link the local repository with the remote one, and this, in my opinion, is a very tedious task. I suggest you not to suffer and use cloning through the Git clone command of a repository pre-created through the GitHub interface, as we did a couple of minutes ago. Well, about Git init, if they ask you in an interview, it's enough to give the basic definition that I mentioned above. So, open the IDE terminal. For me, this is done through this button. And a small tip when working with the terminal, so as not to get confused in the logs, which are often displayed as a solid block here. Don't hesitate to use the shortcut Ctrl + L, which will clear all message history in the current terminal window. I use this feature regularly, automatically, to quickly find the beginning of the message that the terminal outputs as a response to almost any entered command. I press Ctrl + L again, and all previous terminal messages disappear. So, the next really important Git command is Git Status. By entering this command in the IDE terminal, we will see the current status of our local repository. At the beginning, we see "on branch main", the name of the branch we are currently on. We will return to the topic of branches later, but for now, let's look at what else is here. After the branch name, there is information about so-called commits. We will also talk about the concept of commit a little later. But for now, we have the message: "no commits yet", meaning there are no commits yet. After some time, we will repeat the Git status command and see what changes in this place. Next is "Untracked files". Information about which local files Git is currently not tracking. And in my case, it's a list of three items: the .idea folder, .DS_Store, and the index.html file. Next is the message: "nothing added to commit but untracked files present". Use "git add" to track them. Let's follow Git's advice and type this command. Clear the current terminal with Ctrl L, I remind you, and enter Git, space, add. And through a space, specify the full name of our file index.html, that is, the file name and its extension. The Git add command allows you to add files, as well as any changes within these files, to the so-called staging area. Sometimes this area is called the index, but I like the phrase "staging area" the most, so we will use it further. So, the staging area is an intermediate stage where there is a list of files from which we can then make a commit. For now, we have only added one, albeit empty, file index.html to the staging area. Now let's re-enter the Git status command in the terminal and see what has changed. We again see the message "no commits yet", meaning there are no commits yet. That's how it should be. But below, there is information about what changes can be committed: "changes to be committed". And here we see the green inscription: "new file index.html", meaning a new index.html file has been added, the very one we just added through the git add command. Next, let's write something inside this index.html file. And with the snippet "!" we will expand the basic structure of a web page markup. I enter an exclamation mark and press Tab. If your IDE doesn't have autosave, don't forget to press Ctrl S to save. So, let's enter the Git Status command again. And after the "Changes to be committed" block, that is, changes that have been added to the staging area and are ready for further commit. Following this, another block of information appeared: "changes not staged for commit", meaning changes that have not yet been committed to the staging area. And here is a red inscription, meaning that the index.html file has been modified. That is, any change within the project files, whether it's creating a new file, deleting a file, moving it, or making any edits within the file. Git allows you to track all of this precisely. To record the changes in the index.html file in the staging area, you need to execute git add index.html again. Well, and if we enter Git status again, we will again see "changes to be committed: new file index.html". Well, the "changes not staged for commit" block with the description of uncommitted changes has disappeared. The Git add command is actually a bit more flexible than it seems at first glance. We can add not just one file at a time to the stage, but an entire folder. Let's create a "styles" folder in the project. In this folder, let's create two files: variables.css and globals.css. Then, let's repeat the Git add command and add the entire "styles" folder to the staging area as a whole, not its individual files. Just enter Git, space, styles, and press Enter. If we look at Git status, then in "changes to be committed", that is, in our staging area, files from the "styles" folder will be additionally located. Well, and the last of the important features of the Git add command. We can transfer literally all changes in all files of the current project to the staging area. For example, let's add another file "main.css" to the "styles" folder. And in the root folder of the entire project, let's create another file "script.js". And so, to avoid writing several commands, we can simply write git add . and press Enter. And in Git status, we will see that literally all files from all project folders, including the .idea folder and .DS_Store, have been transferred to the staging area. .DS_Store is, I think, not a folder, but a file. Well, it doesn't matter. When working with Git, we may need a blacklist with a list of files or entire folders that should not be transferred to the staging area for commits. For such a purpose, we can create a special file .gitignore in the root folder of the project. Yes, the name is unusual, it starts with a dot, and the file has no extension. In this file, you write the names of folders and files that Git should ignore, line by line. What is usually added there? A file or folder, honestly, I don't remember, .DS_Store. This thing appears if you work on MacOS. And then we add the .idea folder here, which, as I mentioned earlier, is generated by WebStorm itself. And it seems that in VS Code, a similar folder will be created. Then, in .gitignore, we also record the "dist" folder. And project builders usually build projects into a folder with this name. And also, almost always, we record the "node_modules" folder here, which is responsible for project dependency files that are installed through a package manager, for example, through npm. Well, and we also put so-called .env files here, files with environment variables, with sensitive data like API keys, logins, passwords, and so on. That is, data that only the developer themselves should see. How will .gitignore work? Before we figure out how .gitignore works, we have to familiarize ourselves with another command. If we enter the already familiar Git status, here we will see that files from the .idea folder and the .DS_Store file have been added to the staging area. We seem to have written all this to .gitignore, but for some reason it doesn't work. This is normal, it should be so, because we created and filled .gitignore after we added literally all project files to the staging area using the git add . command. To remove everything from the staging area, we can simply enter the command Git reset. And now, when we enter Git status, we will see here that we only have untracked files. And now we enter git add . again to add all project files, except for those that we listed in .gitignore. Now we will enter Git status, and in the staging area, we will see only the necessary files that are not ignored through the .gitignore file. After we have learned to add files and changes in these files to the staging area, we can proceed to mastering the next Git command, Git Commit. With this command, we can form a so-called commit from the list of changes that are currently in the staging area. A commit in this context translates from English as a record. A record in the code change history. And each such commit should have some title or even a full description so that other developers, and you yourself, understand the purpose of the changes made. So, at the end of the current Git Commit command, also through a space, specify the flag -m. Then, again through a space, in double quotes, write a message, for example, "initial project structure". This translates as "initial project structure". Commit messages can be written in any language, be it Russian or Chinese, but in my commercial practice, in all teams where I have worked, commits were written in English. Well, about how best to describe commits, we will discuss at the end of this video. So, press Enter and see in the terminal information that the commit with our message has been recorded and that six files have been affected. Let's add another commit. First, let's make some change in the code.

For example, in an HTML file, within the markup inside the Body, we will write an H1 heading with the text "Git practice". Next, in the terminal, we enter the command `git add .` to move only the recently made changes to the staging area. And finally, we again type `git commit -m` and in quotes, we write, for example, "add main title" and press Enter. So, we have already made two commits, meaning two entries in the commit history. To view this very history, you can enter the command `git log` in the terminal. Press Enter. And in the terminal, we get a list of commits in reverse chronological order. That is, the last commit will always be at the very top. For each commit, we will first see this kind of gibberish. It is called a checksum or hash. You can consider it a unique identifier for a specific commit in the repository. The next line contains information about the author. Name and email. The very same data that we filled in during the initial Git setup on the computer. Then a line with the date and time of the commit. Well, and at the end is the message attached to the commit. An important point. Now the terminal is in a special mode that allows you to scroll vertically through the displayed information using the keyboard arrow keys up and down. By pressing the down arrow key a couple of times, we will scroll to the end of the current commit history and see complete information about our other commit. Well, to exit the current terminal mode, you need to press the key with the Latin letter Q on the keyboard. A very important point regarding Git Commit. With this command, we form commits locally, meaning strictly on our device. This means that all previously committed commits currently exist only on our computer. But they are not yet in the repository on GitHub. And for them to appear there, they need to be pushed there. This is another useful word for you. Remember it. By executing the command `git push` in the terminal and pressing Enter, we will push, or simply send, all local commits to the remote repository, in our case, to "My First Project" in our GitHub profile. Now we can go to the browser to the previously opened GitHub repository page, refresh the page. And now, instead of the starting information, we see the file structure of our project. And in the upper right corner of this panel, there is a link to the commit history. On this page, the same information is displayed as in the terminal after executing the `git log` command, but in a more comfortable format. And by clicking, for example, on this very last commit, we see detailed information about the changes, in which files and which specific lines of code were updated. In our case, in the index.html file, on the eleventh line, the H1 heading tag appeared.

Next, let's consider such a scenario. Imagine that we are not working alone on the project and that while we were sleeping, our colleague added some changes to the project repository. To simulate this situation, we can, through the GitHub interface, directly on the repository page, add, say, a README file by clicking on this green button in the center. This will open an interface that allows you to add a special file. It is called README, and its extension is MD. If you already have this file in your project, well, that is, if you checked the corresponding checkbox when creating the repository, then I will show you an example from my other repository. You can click on this pencil icon in the upper right corner next to README, and you will get the exact same interface. So, returning to the tab of our previous training project, we enter "bla bla bla" here, anything. If anything, this field is extensive. Yes. And in the upper right corner, we click on the green "Commit Changes" button. This way, we will effectively make and automatically push a commit. As a commit message, the text "create README.md" is automatically suggested here. Let's leave it as is. Click the "Commit Changes" button. And now we see that the README.md file has been added to the repository. Returning to the IDE. Note that in our local version of the repository, there is currently no README file. This is important. Let's now make some edits to the project. For example, in the script.js file, let's write the following instruction: `console.log("Hello")`. Now, in the terminal, enter the commands `git add .` one by one. This way, we will add the latest changes to the staging area, and then type `git commit -m` and in double quotes, write the message "add high message". By the way, pay attention to the combination of double and single quotes around this word "high". If we wanted to use double quotes in this place, we would have to perform so-called character escaping. So, press Enter. We see that the message has been added to the commits. And finally, enter the command `git push`. And we get an error: "rejected". There is a lot of explanatory text here, but in short, the state of our local repository is lagging behind the actual version of the remote repository. And we need to pull the current changes. To pull the current changes from the remote repository into the local version of the project, you can execute the command `git pull` in the terminal. From the messages in the terminal, we see that something went wrong. Looking ahead, I will say that this is related to the topic of branching and synchronization conflicts when trying to merge code. Often, Git knows how to resolve these synchronization conflicts automatically. Git has several scenarios that it will follow in such situations: Merge and Rebase. We will definitely discuss the difference between these approaches a little later. So, we could set a global configuration for Git once. Meaning, when executing the `git pull` command, choose a specific synchronization scenario. Or, we can add a flag to the `git pull` command at the end, for example, `--rebase`. In most cases, the `git pull` command should be executed with such a flag. Press Enter. And finally, from the logs in the terminal, from the clean logs in the terminal, we see that the current changes from the remote repository have been pulled. And in the list of local project files, we now see the very README file that we added through the GitHub interface. Now we can re-execute the `git push` command. And now we have successfully pushed the commit with the change in the script.js file to the remote repository.

So, at this point, we know how to clone repositories, check the current status of a local repository, add changes to staging, form commits from these changes. We know how to push commits, meaning to transfer them from a local repository to a remote one. Well, and finally, we know how to get changes from a remote repository to a local one. Next, we will familiarize ourselves with the most important mechanics of the version control system, branching and merging branches, in particular. As I mentioned at the beginning of the video, complex projects are often developed in a team, where each developer is engaged in a specific task. And so, to organize comfortable simultaneous work of several coders on one project, Git has an excellent branching system. Any Git repository has one main branch. In different systems, it is called differently, but on GitHub, it is simply called "main". This main branch always contains the current codebase of the project. On the repository page of our training project, we can see the list of current branches by clicking on this button in the upper left corner of the main panel. Now we only see one main branch here, "main". In simple projects, there might be only one branch, but there can also be more complex branching schemes. For example, the "main" branch stores the current application code. Then there can be a "stage" or "prod" branch. It stores pre-production code, roughly speaking, a pre-release test version of the application, which is usually published on a closed server for internal testing. Then there can be a "dev" branch. A branch for code being developed at the moment, but not ready for release to pre-production. Then, from the "dev" branch, there can be two more, say, "frontend" and "backend", meaning two branches for specialists of a certain direction. Well, and finally, there can be branches for specific tasks from a task tracker. For example, at work, we currently use CRM GRA. And in this system, each task has some short name, for example, "JD-DEV-555". It is under this name that we create a new branch to work on a specific task. That is, the branch name is a short task identifier. Thanks to this scheme, it is very easy to understand among all branches which specific task is being solved in one branch or another. So, every developer in the team, when starting a new task, branches off from a specific repository branch, say, from the "main" branch. Creates their own branch and thus gets a snapshot, meaning a complete copy of the entire project codebase. Let's do this too. Returning to the IDE. Imagine that we are working in a team on a large and complex web application. We are given a new task: to make the main page of the application have a red background. To create a new branch for this task, you can enter the command `git branch` in the terminal, and then specify the branch name in Latin letters and without spaces. For example, "frontend-updates". Press Enter. This way, we branch off by default from the "main" branch. Meaning, we create a copy of this branch and name this copy, this new branch, as "frontend-updates". But if we now enter the command `git status` in the terminal, we will see information that we are still in the "main" branch. That is, after creating a new branch, we also need to switch to it to continue working in it. To switch to another repository branch, you need to enter the command `git checkout` in the terminal and specify the branch name. In our case, "frontend-updates", the branch we created minutes ago. Press Enter. And in the console, we see a message that we have switched to the corresponding branch. And let's re-enter the `git status` command. Now, the first line we see here is "On branch frontend-updates". That is, we are now in our newly created branch, not in the "main" branch. We continue working in this new branch. As a reminder, our task is to paint the background of the main page red. To do this, let's write the following directly in the index.html file. Add the `<style>` tag and here write the following rule: `background: red;`. And now imagine that our task turned out to be much more complex than adding a couple of lines of code. And what to do? We still need a few days for it. But suddenly a manager comes to us and says that there is a critical bug in the front-end part in production, meaning in the live application, which we need to fix urgently. And we are forced to fix it directly in the main branch. And we, as a reminder, were in the process of working on another task in a branch allocated for this task. So, when trying to switch to another branch, we may get an error that our local changes may be lost during the switch to another branch. We have several ways out of this situation. Firstly, we can simply commit our changes, or we can stash them. In a nutshell, the difference between committing and stashing is that a commit is a meaningful fixation of specific changes. That is, when we can come up with a meaningful message for our made edits, like, "added red background to the main page." But the stash action is necessary in a more chaotic situation. We will talk about stash a little later, but for now, let's do what we already know. First, let's add the current changes to staging. To do this, type the command `git add .` in the terminal to prepare all the latest edits for a future commit. Next, type `git commit -m` and in double quotes, write the message "add red background to main page", as the changes we made to the code only do this and nothing more. Well, the commit is ready. Next, we can push it, or we can not rush with it for now. We need to rush with something else now. We need to switch to the "main" branch and make a hotfix. Type `git checkout main`. And we have successfully switched to another branch. Pay attention to the content of the index.html file. Since we are in the "main" branch, we do not see the changes we just made within the "frontend-updates" branch. That is, there is no style here that repaints the page background red. So, now we are making our hotfix. Let's say, for this, it is enough for us to change the content of the `document.title` element to "Git practice - main fix" within the same index.html file. We have made the fix. Now, in the console, type `git add .` to move the changes to the staging area, and then type `git commit -m` and in double quotes, write, for example, "Hot Fix main page title". Press Enter. Next, it remains to push the local commits from the current "main" branch so that they appear in the remote repository. To do this, it is enough to enter the short command `git push`. The command has been executed, and now we are ready to switch back to the previous branch. Enter `git checkout frontend-updates`. And now, let's imagine that we have finished working within the "frontend-updates" branch, and we are ready to push our commit with repainting the background. If we now simply enter the command `git push`, we will see a message that the current branch "frontend-updates" has no changes from the branch into which we are trying to push the commit. This is because the `git push` command is now trying to send commits from the "frontend-updates" branch directly to the "main" branch. We have the possibility to do this, but it is not usually done this way. For now, let's do everything correctly. We want to push the commits made within the "frontend-updates" branch to the "frontend-updates" branch itself. To do this, enter `git push`, and then specify the name of the branch from which we want to send commits, and then specify the name of the branch to which we are pushing commits. Instead of the specific name of the branch from which we want to send commits, we can simply specify "origin". This way, Git will automatically take the name of the branch we are currently in, i.e., "frontend-updates". Well, and after "origin", we specify the specific name of the branch to which we are sending commits. "frontend-updates". Press Enter. And now our commit with repainting the background has been sent to the remote repository.

Let's continue working in the "frontend-updates" branch. Let's imagine that our task now is to display a section with three paragraphs of text on the main page. It doesn't matter what they are, the task is abstract. And so we jump into the index.html file, and after this heading, add the markup for a section with one paragraph of text for now. We still need to add two more paragraphs. But our manager is pulling us again and asking us to urgently switch to another task. That is, we now need to create a new branch through the Git command, switch to it, and make code changes related to the new task. However, we are still in the process of completing the task of adding a section with three paragraphs of text to the main page. We haven't finished this task yet. It turns out that changes have been made to our code that will not allow us to switch to another branch so easily. If last time in a similar situation we committed everything beforehand, then now we decide that committing is not expedient, as we were interrupted in the process of completing the task, not even at an intermediate stage, and we are not ready to come up with a meaningful commit. In this case, we can execute the command `git stash`. It translates from English as "to hide away". If we enter this command, all recent uncommitted edits will be moved to a special local storage and will be stored there until we retrieve them. Personally, in my mind, regarding stash, I always had an analogy, like sweeping the dirt under the carpet, meaning a quick action that saves in emergency situations. And now we see that in the index.html file, after executing `git stash`, our latest code changes, i.e., the markup with the new section, have disappeared. And if we enter `git status`, we will confirm that there are no untracked changes. And now we can switch to any other repository branch without any problems. We have learned how to move edits to local storage using Git stash. And now let's immediately deal with their extraction. Enter the command `git stash pop` in the terminal, press Enter, and we see the result of performing the exact opposite action. The markup for the section with one paragraph has returned to the index.html file. Next, let's add two more paragraphs to the section, making it three in total. Then, let's format the commit and push it. Let's pretend we've finished the task. Type `git add .` to add all changes to staging. Then `git commit -m` and in double quotes, the message. For example, "add section with 3 paragraphs to main page". And finally, `git push origin frontend-updates`. So, we will push commits from the current "origin" branch, in which we are now, i.e., from the "frontend-updates" branch, and push everything to the same "frontend-updates" branch. Press Enter.

Next, we will discuss the issue of merging branches and the differences between the `git merge` and `git rebase` commands. Merging branches is a process in which code changes, meaning commits, from one branch are combined with changes from another branch. For example, we have now finished all tasks within the "frontend-updates" branch, and we are ready to merge, in other words, combine this branch with the main branch, i.e., with the "main" branch. For this action, we have the `git merge` and `git rebase` commands, but these commands have small, but in some situations serious, differences. Let's break this down in order and start with `git merge`. First, we need to switch to the branch into which we want to merge the changes. Usually, such a branch is the main branch, "main". We switch to it using the command `git checkout main`. Now we will type the command `git merge` and specify the name of the branch that we will merge into "main". That is, type "frontend-updates", press Enter, and we get a classic situation: a merge conflict. As I mentioned at the beginning of the current video, Git often handles the branch merging process itself, but sometimes conflicts can arise that the developer who decided to merge one branch into another is forced to resolve. So, in the console, we see a message, saying, a conflict occurred in the index.html file. Automatic merge failed. Fix conflicts yourself, and then commit the resulting commit. Let's do that. Within the opened index.html file, we see a message at the top that the file has unresolved merge conflicts. And further in the code, we see that some strange lines have been added with various symbols. Firstly, `<<<<<<< HEAD` is the branch we are currently in, i.e., the "main" branch. From this line to this line with equal signs are the edits made within the "main" branch. And from this line with equal signs to this line with angle brackets and the signature "frontend-updates". And here are the edits that were made within the "frontend-updates" branch. There can be many such combinations of code within files during branch merging. And each such piece of code needs to be correctly resolved. Meaning, resolve the conflict. We now need to leave this first encountered title, and remove the second title, and leave the style. Then delete all the technical lines with these symbols and branch names added by Git. Then, fix the edits in the staging area. Type `git add .`. Then, format everything into a commit: `git commit -m` and in quotes, write "fixes for merge". After making the commit, the actual merge of the "frontend-updates" branch into "main" is complete, and we are left to push the changes to the remote repository using the `git push` command.

Now we have merged the branches using the `git merge` command. To understand the result we got, let's look at our repository page on GitHub. Reload the page. In the upper left corner, in the dropdown menu, we have two branches here: "main" and "frontend-updates", between the versions of which we can switch. Now we are in "main" view mode. Let's stay here. In the upper right corner, click on the commit history. To better understand what happened as a result of `git merge`, we need a visualization of the commit history. GitHub has this feature paid for enterprise accounts, but there is a free solution. The Chrome browser extension "Git Graph". I will leave a link to it in the description below the video. Install it. Then, in the opened tab, click "Continue" and click on the green button "After Git Graph". After successful authorization and clicking through the tutorial, click "Start and Finish". Go to our repository page. Let's go to its main page. I'll reload the page for reliability. And in the Git interface, a new tab "Commits" will appear here. Go to it. On this page, the same commit history is displayed as we saw earlier, but additionally, this visualization is added here. In the upper left corner, by clicking here, we can filter the branches that we want to view at the moment. Let's leave only "main" and click "Show selected branches". So, here, from top to bottom, commits are listed in order of freshness, from the most recent to the oldest commit. Here we now see all commits made within the "main" branch, as well as all commits that were merged into this branch, in our case, using `git merge`. The red line and red circles on it are responsible for the history of the "main" branch. And the blue one with circles for the "frontend-updates" branch. Each circle is a specific commit. So, the main feature of the result of executing the `git merge` command. After merging, in the commit history, in addition to the specific commits of the main branch, we see absolutely every commit of the branch that we merged into "main". That is, here we clearly see two circles, two commits on the blue line of the "frontend-updates" branch. And the last commit, meaning the topmost one, is this one, which we made manually when merging branches: "fixes for merge". An important point. If there were no code conflicts when trying to merge via `git merge`, then such a commit would still appear in the commit history. Simply, the commit message, the header for this commit, would be automatically generated by Git. If we hover over the circle of this commit, then in the tooltip, we will see that this commit has two parent commits. This is the direct result of merging two branches. That is, `git merge` took the last commit from each merged branch and then tried to combine them. Well, and visually, it is also quite clear from the number of lines leading to this circle that this commit is a mixer of several branches.

Let's leave the current browser tab open and go to understand `git rebase`. Returning to the IDE. Now we are in the "main" branch. Let's create a new branch "backend-updates" and switch to it immediately. Instead of entering the `git branch` and then `git checkout` commands sequentially, we can enter `git checkout` in the terminal, specify the `-b` flag, and then specify the name of the new branch that we want to create and to which we want to switch immediately. Enter "backend-updates". From the response message in the terminal, we see that we have done everything correctly. So, our task before checking the operation of `git rebase` is to make several arbitrary commits within the current "backend-updates" branch. To do this, let's sequentially add a couple of lines in the script.js file. `const API1 = "some_value";` with this value, it doesn't matter what. Then, let's make a commit. Type `git add .` to add edits to the staging area. Then `git commit -m` and in double quotes, "add first API". Add a similar line `const API2 = "some_url";` to the script.js file. Again, type `git add .`, `git commit -m` and the message "add second API". And finally, `const API3 = "another_url";`. And again, `git add .`, `git commit -m` "add third API".

Next, we will merge the "backend-updates" branch into the "main" branch using the `git rebase` command. To do this, first, while in the branch being merged, "backend-updates", enter the command `git rebase main` in the terminal. With this step, we will place the recently made commits within the current branch on top of the latest commits of the "main" branch. When performing this action, as with `git merge`, merge conflicts can sometimes arise, which also need to be resolved manually. If they had arisen, we would have also made edits in the code, then typed the command `git add .` in the terminal, and then, attention, `git rebase --continue` to continue the rebase process. In any case, after all these actions, we must switch to the branch into which we are merging the code, to the "main" branch. Type the command `git checkout main` in the terminal. And attention, type `git merge backend-updates`. Yes, yes, the rebase process is completed. The `git merge` command, this is normal. And finally, execute `git push` to push the current "main" branch to the remote repository. Done.

Let's return to the previously opened GitHub page. Let me duplicate this tab. Again, go to the "Commits" tab. Also, through the dropdown in the upper left corner, filter the displayed branches. Leave only "main" and click "Show selected branches". Before us is the result of executing `git rebase`. The differences from the classic `git merge` are immediately striking. The commits that we made within the "backend-updates" branch are displayed in the commit history as if they were made directly in the "main" branch. Let's look again at the adjacent, previously opened tab with the result of `git merge`. Here, the commits made within the "frontend-updates" branch are clearly separated from the commits of the "main" branch. What conclusion can be drawn from all this? To maintain a convenient commit history, so that there is a clear separation of commits into their corresponding branches, you should use the standard `git merge`. If you don't care whether a more accurate commit history is preserved or not, then you can use `git rebase`. When you perform all these actions through terminal commands, it might seem that it is easier to always perform `git rebase` and not worry. But I will say this, in real practice, you will more often use the visual interface in your IDE. Well, what about the IDE?

In that case, for you, in the end, any of these actions will boil down to pressing one button. Despite the fact that in practice I literally always use the visual interface of Git in WebStorm, I still prefer Gitmer Merch actions more, as when working in a team, it is sometimes very important to know in which specific branch certain commits were made. Of the useful Git commands, I suggest considering one more. The Git Revert command allows us to roll back to any point in the commit history. To implement this, we need to know the so-called commit hash to which we want to return. This can be found in various ways. For example, through the GitHub website. We can go from the main page of our repository or follow the commits link in the upper right corner. Thus, we will get to the standard page for viewing commit history. Or, we can open the Commits tab, which appeared due to the previously installed Chrome plugin LegitGraph. I prefer the second method to see a more understandable commit history. So, I suggest rolling back to the Add First API commit. By clicking on the commit title, we will go to the detailed information and see in which files exactly what changes were made. In this case, in the Script JS file, after the console log, a constant named API1 was added. When we use Git revert to return to this commit, we will return to the state before these changes were made. That is, we should see only one console log instruction in the Script JS file. So, on the detailed commit page, in the upper right corner, there is this Copy Full SHA button. We click on it, and a forty-character data set will be copied to the clipboard. If anything, we can find this same button on the previous page of viewing the full commit history. Here it is. So, let's return to the IDE. Currently, we are in the main branch. We can perform all further actions directly in the current branch, or we can create a new one. Let's stay in main for now. So, we enter the Git Revert command in the terminal and, with a space, paste the contents of our clipboard. We press Enter. And Git will try to do an after-merging, that is, a code merge. And it failed because a conflict occurred, and we will have to resolve it manually. In the already open Script JS file, we find the added lines. Here we have, as it were, two versions of the file. The last current one from this to this line and another version. The version of the file before the edits made within the commit we are trying to return to. This merge conflict is resolved simply. We delete this piece of code and this Git line. The conflict is resolved. Next, we type git@ space dot and write git revert def continue in the terminal to complete the commit rollback process. After executing this command, the system's built-in text editor will open, where you will be prompted with a message that will title the commit that will be the result of executing the Git revert action. This description suits me, so I just close the current window and return to the IDE. According to the information in the terminal, we see that the Revert command was executed successfully. Now our local repository is in the state before the edits were made within the commit to which we rolled back. We have familiarized ourselves with the main capabilities of Git and its console commands. Now let me quickly show you how you can conveniently work with Git through the visual interface of Git in the IDE using WebStorm as an example. VS Code also has this. Everything is a bit different there, but you won't have trouble figuring it out. In any case, in all IDEs, the Git interface is quite rich, and demonstrating the operation of all the buttons and menus would not be enough even for a ten-hour course. Therefore, I will only show what I use practically every working day. So, let's start with the fact that if Git was previously initialized in the project, i.e., you executed Git init or Git Clone, then WebStorm will add several tabs and buttons to the interface. Firstly, in the upper left corner, the repository name and the name of the branch we are currently in are displayed. For me, it's main. To the right of the branch name, some icons may be displayed, signaling various statuses. Like, there are commits to push to the remote repository, some changes need to be pulled from the remote repository to the local one, and so on. By clicking on the branch name, a window will open with a list of all branches existing in the repository. Here, lists of recent, local, and remote branches will be listed. Well, that is, if we created a branch but haven't pushed it yet, then it will initially only be in the recent and local lists. And you won't be able to find it in remote yet. In this multifunctional tooltip, there is a button to create a new branch. Let's click on it. Now we will branch off from the branch we are currently in, i.e., from main. In the window that appears, we enter the branch name. Let's say, example. There is also a checkbox with a checkmark that asks: whether to switch to this new branch after creation. This checkbox is checked by default. We click create. The new branch is created, and we immediately switch to it. We can see this by the changed inscription in the upper left corner. We click on this inscription again. And in the recent and local lists, we see our new branch example. Well, since we haven't pushed this branch yet, it won't be in the remote list. Next, by clicking on the name of any branch from these lists, for example, on main, a context menu will appear with a list of various actions. Here we have checkout, switching to a branch. Here you can create a new branch from a specific selected branch. There is also update, an action that allows you to update the local branch to the remote state. Well, and finally, there are several important composite actions that are reduced to a single click. These are merge main into example and rebase example onto main. You should already have a superficial understanding of the result of performing these actions, but in any case, I advise you to practice to fully comprehend everything. In addition to this menu, let's also look at the Commit tab. Here it is with this icon. On the opened panel, we will see the current status of the local repository. Well, so to speak, this is an analog of Git status, only much more powerful. Let's make some changes to the code. The Commit tab usually replaces the previously opened Project tab, where the project's file structure is displayed. Let's switch back to it. Let's open the index HTML file and add anything. For example, let's repaint the text color of the paragraphs in blue. And in the script js file, let's add another message via console log with the text "wait". And finally, let's go to the Styles folder, to the Global CSS file, and write something like this. Then we click on the Commit tab and see that a list of files where changes have been made has appeared. You may notice that the files are displayed as a solid block, as if without a folder hierarchy. I recommend fixing this. We click on the eye button and click group by Directory. Now we have a convenient file structure displayed, where it is immediately clear in which folder the file is located, where changes have been made. Next, an important function of this panel. If you double-click on the file name, a window will open, divided into two columns. In the left part will be the code before the changes were made, and in the right part, the code after the changes were made. As for me, this is as convenient and informative as possible. I deliberately did not show you a similar function through Git console commands in this video, because without such a graphical shell, analyzing code changes without dancing with a tambourine will not work. By the way, a similar window will automatically appear when merge conflicts occur. Only there will be not two, but three columns. In the left part, the code of the branch into which we are merging, in the right, the code of the branch that is being merged, and in the center, the result, which we manually edit, selecting only the necessary pieces of code from the left and right parts. So, the next cool feature that is done through the current tab is the ability to roll back all changes within a specific file, files, or even folders. To do this, you can select the desired files or folders while holding down the Ctrl key and right-click. In the context menu, select the Rollback option. In the confirmation window, click the Rollback button, and the changes made in the previously selected files and folders will be rolled back. And the next function of this tab, by clicking on the checkboxes to the left of the name of any file or folder, consider that we are moving the selected ones to staging. For example, let's select only the scripts file. To make a commit with the edits made within only this file, in the lower part of the current open panel, we can enter the message add by message. Then we have the option to click either the commit button or commit and push. The difference between these actions, I think, is obvious. For now, I just want to perform a commit, so I click the corresponding button. In the lower right corner, a notification appears about the successful formation of the commit. Next, let's double-click on the name of the remaining file index HTML on the commit panel and recall what edits we made here. Aha, we repainted the text color of all paragraphs in blue. We close the window and put a checkmark next to the index HTML file name. And in the lower part of the panel, we write the commit message add color to all paragraphs. Then we click the commit button to make the commit. Now the commit tab is empty. We have made several commits, but now we need to send them to the remote repository. To do this, in the upper left corner, we click on the name of the branch we are currently in. And in this tooltip, there is a push action. We click on it, and a window opens with a list of all commits that are proposed to be sent. And where and to where, we can see this in the upper left corner of this same window. Commits are sent from the Example branch to, in fact, the Example branch. By clicking on each of these commits, we can view the details of what exactly and in which files were changed within the respective commits again. When we are convinced of what, from where, and to where we are sending, we click the push button in the lower right corner of the window. During the push, yes, or any other network-related processes, a progress bar may briefly appear at the bottom of the status bar, responsible for the status of uploading our local commits to the remote repository. The next thing I want to show from the Git graphical shell in WebStorm is the Git tab. This button is displayed for me here at the bottom left. The opened panel displays extensive information about the commit history in various branches, including. In this list, by default, all commits are displayed, again in order of freshness. The most recent commit will always be at the top. By clicking on a specific commit, a window will appear in the right part with a list of files in which some edits were made. By double-clicking on a file, the familiar two-column window with code will open, where in the left part is the code before the edits, and in the right part is the code after. And the last couple of moments about Git in WebStorm that I want to demonstrate. Killer features that have saved me more than once. On the file structure panel, right-click on any file, for example, on index HTML. In the context menu, go to the Git item and then click the Show History button. At the bottom, a panel opens with a list of only those commits that affected the current file. And let's again in the project file structure panel select some file, but open its code. Next, I suggest selecting some piece of code, for example, this line with the H1 heading. Right-click and in the context menu, go to Git and Show History for Selection. A window will open, which will list only those commits that affected the specific piece of code in the specific file. This function literally at any time of the project's existence allows you to answer the question: who is responsible for a piece of code? In practice, I usually apply it like this. During project refactoring or implementing a new feature, if I encounter a piece of code that is unclear to me, I use this Show History for Selection feature to find the name of the colleague who wrote that piece of code. And then, if this code is unclear to me, I ask that person for clarification, like, explain the code, please. In general, I think this is very, very convenient. That's all about the main features of Git in WebStorm. If there is a request from you, the viewers, for a more detailed breakdown of Git in the WebStorm interface, leave comments. Finally, I want to mention Conventional Commits. This is a generally accepted agreement on how to correctly and, most importantly, clearly for everyone, format commit messages. This website provides excellent Russian-language documentation that will help you understand everything. I will leave a link to this resource in the description under the video. Everything is stated very briefly here, don't be too lazy to familiarize yourself. Well, today we have figured out what Git and GitHub are, why they are needed, and how to set them up. We have covered a ton of useful commands from cloning and checking repository status to merging branches and resolving conflicts. We also briefly familiarized ourselves with the convenient graphical interface of Git in the WebStorm IDE. Well, and finally, we learned about the existing commit convention, which will help improve the quality and value of your commits. As I have mentioned many times in this video, Git can be studied endlessly. Tens or even hundreds of hours will be spent memorizing every command and all its flags. I believe there is no point in sacrificing so much personal time. Instead of memorizing another command from the documentation, it's better to learn Git in practice. Dig into your personal project, make commits, roll back changes, and don't be afraid to juggle branches and resolve merge conflicts. The more bumps you hit during the learning process, the easier it will be for you to work in a real team. Don't forget to subscribe to the channel and like this video if you haven't already. Thanks for watching and see you in the next videos.