Peter
Peter Software Developer | Technical Writer | Actively helping users with their questions on Stack Overflow. Occasionally I post here and on other platforms.

Understanding Git Part 1

Understanding Git Part 1
Follow me on

Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. Git can be used to track old versions of files and to check all the different changes.

Installing Git

You can check part 2 article in the below links:

First you need to install Git to be able to use it. Since not everyone prefers to use the terminal, then you are able to install a Git Gui and a Git Bash from git-scm. After finishing the installation, if you are using windows operating system then you can right click and click Git Gui to open the graphical user interface.

In the below tutorial, I will give comparison between the Git Gui and Git Bash.

Initializing a Repository and Using it


First you need to navigate to the location where you want to create a new repository, then do the following:

Git Bash

1
2
cd Desktop/gitExample
git init

Git GUI

git gui new repo

This will create a new hidden file called .git inside the folder gitExample, thus making it a local repository with a branch called master.

Adding files to the repository

First create a file inside the folder newfile.txt and write some text inside of it. Then you need to add this file to the staging area(index), to be able to commit it later on. You can also use git status that will inform you in which branch you currently reside in and if you have any untracked files.

Git Bash

1
2
git add newfile.txt #tracks the file and adds it to the staging area
git commit -m "initial commit" #adds tracked files to the local repo

Note: If you want to add all files in the folder to the staging area then use git add -A (the option -A)

So as you can see git add adds the files to the staging area or index and then git commit adds the files to the local repository.

If you did a mistake you can execute git reset newfile.txt and it will remove the staged file from the local repository. If you want to add multiple files then do the following git add <file-name-1> <file-name-2> <file-name-3> or if you want to add a file then do git add 'fileName/'.

Git GUI

add a new file

Here you need to click on Stage Changed which will add the files to the stage area and then write a message and click Commit.

Pushing files to the repository

After you commit the files, you are now ready to push them! You need to push the files to the server so your team members, or the community if you are pushing to GitHub, can access the code.

But, first you need to add the remote repository. Remote refers to any repository that is not in your local machine. Example, if you want to use Github you need to first create an account there and then create a repository to be able to push and pull. After adding a remote, you will be able to push the file to the repository.

Git Bash

1
2
git remote add origin https://github.com/<userName>/<repoName>.git 
git push -u origin master

Note: origin is an alias to the URL of the remote repository, which means you do not have to write the url everytime you want to do a pull or push operation. Also master is your local branch.

If you execute git branch -a then you will get the following output:

1
2
master
remotes/origin/master

remotes/origin/master is a remote tracking branch which is located inside .git/refs. Its purpose is to keep track of the current state of a remote branch, git status will also give you information about the remote tracking branch.

Git GUI

git push

Here you need to click on Push and then add the remote url in the Arbitrary Location.

Pull the Changes

Now if any changes were added to the file in the remote repository, then you need to pull first and then push your local changes to the repository. git pull does a git fetch origin master followed by a git merge origin/master. Basically git fetch will fetch all the commits from the remote repository but it will not merge them with your local branch(safe command). After doing git fetch you can execute git status to see if your branch is up to date with the remote branch. You can also execute git log --all to see the latest commits and the authors or git show origin/master to see the latest changes in the commits done.

Note:

  • origin: is the remote branch.
  • master: is the local branch.
  • origin/master: is a representation or a pointer to the remote branch, basically it is a local copy of the branch master in the remote origin.
  • git fetch origin master : fetches changes from origin to master (local branch) but does not merge, it creates a local copy called origin/master
  • git merge origin/master : merges the changes that were fetched.

Git Bash

1
git pull origin master

Git GUI

git merge

Here you need to first add the remote url after clicking Remote/Add, then click Fetch From and Merge. Also refer to this answer pull in git gui.


Cloning a Repository

If there is a repository in github, then you want to use locally in your computer then you need to clone it(copy).

Git Bash

1
git clone https://github.com/<userName>/<repositoryName>

Now if you execute git branch -a, you will get the following output:

1
2
3
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master

master is the current branch you are reside in and it is the local branch, the second line is a symbolic branch referenced by the remote repository. The third line is the remote tracking branch.

Git GUI

git clone

To clone a repository, simply click on Clone new repository, the Source location field should contain the remote url and the target directory should contain a folder.

Working With Branches

Branches in Git are nothing but pointers to a specific commit. Whenever a new branch is created, Git creates a new pointer while keeping the original code base untouched. Basically, what this means is that when you create a new branch, all the latest content of branch master or a different branch will be copied to the new branch and you can start modifying it without affecting branch master.


So, Let’s say there are three developers working on one project, and developerA assigned to do taskA while developerB was assigned to do taskB. Each of them already have the local repository since they cloned it:

1
git clone https://github.com/<userName>/<repositoryName>

Now the owner of the repository wants everyone to create a branch for each task so he/she can later review the changes before accepting the pull request and merging with the master branch. So the two other developers will create a branch by executing:

1
git branch taskA #git branch taskB

And then executing:

1
git checkout taskA

which will enable them to start working on that branch. Another way is to execute one command:

1
git checkout -b taskA

You can also delete a branch by executing:

1
git branch -d taskA

Note:

  • git checkout: Updates files in the working tree to match the version in the index or the specified tree.
  • working tree: are the files that you are currently working on.
  • index: is where you place files you want commit to the git repository (staging area).

So basically, git checkout <branch> will write the contents of <branch> to the working tree. You can also use git checkout to overwrite the changes that you did in the local repository. So first execute git fetch which will fetch the latest commits without mergiing and then fo git checkout which will update the files in the local repository matching the files in the index.

You can also do git checkout master -b taskB, which will write the content of master to the working tree and git then creates a branch called taskB.


Now, you can start working on branch taskA, let’s say the branch contains a README.md file with some content and you changed the content to the following:

1
2
3
# task A

Hi, Im task A

Now you have to do the following:

1
2
3
git add README.md
git commit -m "feat: added new text for taskA"
git push -u origin taskA

The above will commit the changes and publish the taskA branch to the remote repository. Finally, the owner of the repository can compare the branch and create a pull request. Then the owner can merge the pull request with the main branch, and delete the taskA branch.

Merge Conflicts

So, let’s say someone in the team added their changes to the staging area, and then commited to their local repository and pushed those changes to the remote repository. But both you and the other developer are working on the same file, and if you have done some changes on the file but didnt push you will get some problems.. so let’s see what will happen.

First, you do:

1
git fetch origin master

As I said before this will fetch the changes done but it will not merge. Now if you do git status, you will get the following:

git status started

So, as you can see I modified the file understading-git-part1, but the changes are not staged. But before staging, first we executed git fetch origin master, now we have to do git merge origin/master to add the changes to our local repository. So if we execute that we get the following:

1
2
3
4
error: Your local changes to the following files would be overwritten by merge:
	_posts/2018-08-19-understanding-git-part1.md
Please commit your changes or stash them before you merge.
Aborting

Unfortunately git is not able to merge the changes, because I have changed the content of this file and the remote repository contains some changes also.

So, now if I want my changes that are not staged to be in the remote repository and I want to be able to merge the changes in the remote repository to my local repository, I have to do the following:

1
2
git add <file_name>
git commit -m "my changes"

Now my changes are inside the local repository, if I execute:

1
git merge origin/master ## or git pull origin master

I will have a merge conflict, I can fix the conflict by opening an IDE or editor like vscode, merging the changes from the repository to my file, keeping my local changes and then I can do git push origin master to send my file with changes to the repository.


Second way to solve the following error:

1
error: Your local changes to the following files would be overwritten by merge.

is to execute git reset --hard and then git pull origin master, but note git reset will override all your local changes, so basically all your work will be gone, you can do git reset --hard when you just want the changes in the repository and don’t want your local changes. Or instead of reset you can do:

1
git checkout -- <file>

When executing this command, git will take the version of this file that is in the index to the working tree, thus overwriting your local changes. But before doing that make sure that file is not staged via git reset HEAD <file>, this command will remove that file from your staging area.


Third way is to stash your changes, so basically this will save your uncommited changes in a stash, removing all your changes from the repository but keeping them hidden. So after you do git fetch and git merge and get the error, you can then do:

1
2
3
 git stash
 git pull
 git stash pop

After doing git pull the changes will be added to your local repository and then when you do git stash pop, git will add your saved changes back to the working tree which may lead to a merge conflict, if you click save on vscode, you will get the following:

git status started

Then you have to click compare, add the changes, and commit/push. Usually git stash is used when you want to hide your changes but don’t want to commit, if you actually want to commit then it’s better to just use the first way specified in this article. Also in git stash you can either pop or apply. git stash pop will throw away the stash after applying it, whereas git stash apply leaves it in the stash list for possible later reuse. You can also delete the applied stash later by executing git stash drop.

I hope you enjoyed reading this git tutorial about how to push/pull, please feel free to leave any comments or feedback on this post!!

 

Become a Patron!