# Git and Github

It is a version control system.

* Case 1 - Say you are working on a project. You add some extra code and after that the project is not working anymore. The one thing you would want to do is, go back to the previous stage. Basically, the saving the history of your project. In such cases, <mark>Git</mark> can be a really useful tool. As, it helps to save the each stage or each changes in your project. (Maintaining history of a project).
    
* Case 2 - Say a group of developers are working on a single project remotely, and they want to share the code with each other. In this situation too, <mark>GitHub</mark> can be useful as it is a platform which allows sharing code with each other. (Sharing of code).
    

All the changes made to project with the details on who made the change and when did the change happen are stored in a folder called <mark>git repositories</mark>.

<mark>Note: All the commands are written in Windows terminal.</mark>

1. *git init* - Initializes a empty git repository in the project folder. It is hidden.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700153481870/8d99158f-4271-488d-bf45-4ac55618a13b.png align="center")
    
    To see the hidden run this command.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700153584592/8cb42555-9146-4eae-bb3e-95b708133bf7.png align="center")
    
    Inside the .git folder.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700153673319/54046c29-6ba8-4371-b1a8-6193bf59d2f9.png align="center")
    
2. ***git status*** - to check the history of a file or folder.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700153992952/e266a94a-7e03-4d87-bd25-6103d2cdc9bd.png align="center")
    
    Here, created a new folder 'NewProjects'. Add a file named 'Sample.txt' manually. Now checking the status of the file using the git status command.
    
    As you can see, it is showing the file to be untracked.
    
3. ***git add filename*** - To start tracking a particular file.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700154271111/0790f6dd-6aa0-43ea-8c78-a4333f2bda49.png align="center")
    
    You can also, use, ***git add .*** In this command, the dot (.) *represents adding all the files into tracking mode.*
    
    Also, as you can see, now file is in green color, earlier it was red color. Thus, <mark>red means untracked</mark>, while <mark>green means tracked</mark>.
    
4. ***git commit -m "your message"*** - Now to see the changes made to the file, and details on the change.
    
    The "your message" provides the detail on the change you made.
    
    Before running this command, make sure to run these commands:-
    
    ***git config --global*** [***user.email***](http://user.email) ***"***[***you@example.com***](mailto:you@example.com)***"*** // Your git hub account
    
    ***git config --global*** [***user.name***](http://user.name) ***"Your Name"*** // Your name, the person who made the change
    
    Running the ***git status*** again, we can see this:-
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700154964090/c4c31331-0167-41d3-a08a-85899c3b1a87.png align="center")
    
    Now, I have made some changes in the "Sample.txt" file. Add a a line Hello World in the file by opening it in the notepad.
    
    After that when you run the ***git status***, you can see.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700155122889/67000967-12e4-440b-b634-595400a2041f.png align="center")
    
    Now, let's save this change.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700155278329/c714da15-69f2-4062-828d-9beb2e38452f.png align="center")
    
5. ***git restore --staged filename*** - Removing the particular change, like deleting it from the history itself without committing.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700155417775/3380639c-cdf8-4e23-8566-8bbbdc148a4c.png align="center")
    
    Now adding changes again
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700155549443/e739831b-d027-42ae-8f5a-00db2437aae7.png align="center")
    
    As you can see, it shows 1 insertion. As we only added a Hello World line inside the file.
    
6. ***git log -*** To see all the changes made to the file. It shows the details who made the changes with their name and email it, when the change was made with the date and time.
    
    Try deleting the file, using the following commands.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700155978974/22c21270-d3f0-4871-b1d9-8cc3fb33ad0f.png align="center")
    
    Now run the ***git log*** and see the changes.
    
7. ***git reset commit-id*** - Goes to the previous stage based on the changes that were saved.
    
    The commit id, can be accessed by typing the ***git log,*** in this we can see commit then the commit id associated with it.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700156239595/3282398d-85f1-4ace-895f-a3c256871460.png align="center")
    
    Now try typing ***git log***, and see the changes.
    
    Typing ***git status***, will show that all the previous are now in untracked stage.
    
8. git ***git stash -*** Suppose, you adding some changes but neither you want to add them to existing changes or lose the changes which you did.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700603591165/eed8c255-20f4-4db8-818c-6c1871ed2792.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700603627691/72eeb3f1-eb2b-4e5d-ad07-72fc304d7547.png align="center")
    
    In this scenario, I deleted the "names.txt" file.
    
    Created a new file "newNames.txt" file.
    
    Again created a new file "houses.txt" file.
    
    Now, I haven't committed any changes i.e., creating of the files. However, in case if my need them in future I stored that history using the ***git stash*** command. Thus, when I check the status of the file, it's still in the first commit. Try it yourself by typing *git log* command.
    
9. ***git stash pop -*** Now in order to save the history to the main part, I mean the one which we earlier saved for future, we can get it back using this command.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700603962451/27bbd3d3-2190-4de3-87ba-e21052753f9f.png align="center")
    
10. ***git stash clear*** - Deleting the above changes, it will completely gone now by using this command.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700604134964/94797919-2abe-4740-bf53-93666763b8ea.png align="center")
    
    You can also, verify it by ***git log*** command.
    
11. ***git remote add origin repository\_url -*** Connecting to GitHub (local computer to git hub server).
    
    origin - url of own project from own account.
    
    Before running this command, make sure do these.
    
    1. Login to git hub with your account details
        
    2. Create a new repository
        
    3. Copy the repository url, replace it with the repository\_url in the command.
        
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700604480196/40717006-6fe7-49d4-bb67-26604d332128.png align="center")
    
12. ***git remote -v*** - Show all the urls attached to the repository.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700605421413/44fee3be-acdd-4d5e-8849-95da9426ec0d.png align="center")
    
13. ***git push origin branch\_name*** - To add the files into a particular branch.
    
    To forcefully, pushing a change, ***git push origin branch\_name -f***.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700605631015/690cea01-70f4-4f94-b474-f7ef92494834.png align="center")
    
    For the time being, we have added the file into the master branch.
    
14. ***git branch branch\_name -*** Adding a new branch to the repository.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700607018271/355d1036-8f85-4099-b6d1-466c205e05bd.png align="center")
    
    Just created a new file "random\_file.txt", added it to the "new\_branch" branch.
    
15. ***git checkout branch\_name*** - Switching between branches.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700607544053/eb2b7d6e-4c6a-4104-b912-f75dcedfbada.png align="center")
    
16. ***git merge branch\_name*** - Adding the branch to the master branch, basically making the changes visible to everyone who is working on a project.
    
    Created a new branch "new\_branch00", switched to it.
    
    Added a "random\_file4.txt".
    
    Committed the changes.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700608624120/173e1c21-b2ca-4e2d-bb4c-c303a43f03d6.png align="center")
    
    Added the file to the "new\_branch00".
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700608609903/b29d9a17-398a-468a-bca9-d014cbe3407d.png align="center")
    
    Switched to "master" branch.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700608584663/380b55ea-4852-4c08-a1b7-78a8e665b729.png align="center")
    
    Combined the branches, thus adding the "new\_branch00" results to git hub.
    
    Finally, pushing all the changes to "master" branch.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700608594983/dccca5a7-fdd0-47a2-b9b6-0d32a388e7e9.png align="center")
    
    Login to git hub account and see the changes, after running these codes.
    
17. ***git clone url*** - Basically downloading a project from the github to your local computer.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700609211754/7f52e38a-1a03-4829-8dbd-c204a21fd92d.png align="center")
    
18. ***git remote add upstream project\_url*** - Upstream is the url of the project from where you forked/copied the project.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700609435288/0200e0c0-b7dd-477e-bd40-c2bc9e6c65fe.png align="center")
    
19. ***git fetch --all --prune*** - To get all the commits, including the one that were deleted (prune).
    
20. ***git pull upstream main*** - Combination of ***git fetch --all --prune*** and ***git merge main*** commands.
    
21. ***git rebase -i hash\_id\_of\_the\_commit*** - Squashing all the commits into a single commit.
    
    You either squash (s) or pick separately (pick) a commit.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700611537749/406328b4-34b2-40ee-9445-2ab0e5ca0841.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700611551700/7c2a7d24-21b2-4005-96bb-56979b0fa510.png align="center")
    
    Then add a commit message.
    
    Type ":q!" to exit out of it.
    
    Also, type ***git log*** to see the changes i.e., the commits being merged.
    

**Branches:** Branch is similar to the real life branch which we see in a tree.

Try randomly adding some files and contents inside the files. Then, commit them.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700606169245/ef3aa77b-4ee7-4f2a-9f6e-e41b63bcca49.png align="center")

After this, run ***git log*** command and you will see a master branch for the very first commit you made and for the rest of the commits there is nothing.

The structure is kind of like this:

master -&gt; commit\_1 -&gt; commit\_2 -&gt; commit\_3 -&gt;.... commit\_n

The idea is to save each changes as separate which you make in the project. Thus, if the code crashes or any other problem occurs or you want to go back, you don't have keep editing in the current code base.

Eg:- Say you are creating a food delivery app.

Master branch - Page 1 -&gt; the login details.

Commit 1 - Page 2 -&gt; Select the restaurant where you want order from.

Commit 2 - Page 3 -&gt; Delivery address selection.

Commit 3 - Page 4 -&gt; Payment page

Commit 4 - Page 5 -&gt; Confirmation page

Assume that, the app crashes in the payment page. So, instead of tampering in the confirmation page, all you need to do it go to commit 3 and do the necessary changes and then attach the commit 4.

**HEAD:** Inside, the .git folder, there is "HEAD", which basically is like a pointer to indicate that currently which branch is in control i.e., if you make any changes, which branch will have the new changes or which branch will contain the new commits.

Try running git log command, to see where the HEAD is pointing in each scenarios:-

1. Before creating the "new\_branch". You can see that in this case, The HEAD is master.
    
2. After creating the "new\_branch". You can see that in this case, The HEAD is "new\_branch".
    

**Fork:** Making copy of an existing project in the git hub.

Say you are trying to add some changes to someone else project named "FoodDeliveryProject" present in another account person's account named "Abbas".

You cannot directly make changes in it, instead you fork it. Basically, creating a copy of the "FoodDeliveryProject" project in your own account. Then you can do whatever you want.

**Merge conflicts:** Making same changes by two or more different persons in a project.

Consider the same example of food delivery app.

Say two developers dev1 and dev2 created 'confirmation page' and then send their commits to the git hub. The git will get confused since both of them worked on the same page.

Thus, in order to resolve this, we need to manually check which pull request we need to accept whether it be dev1 or dev2. And then adding it to master branch.
