Installing Git
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 the 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 a 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:
cd Desktop/gitExample
git init
Git GUI:
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:
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:
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
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:
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
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 branchmaster
in the remoteorigin
.git fetch origin master
: fetches changes from origin to master (local branch) but does not merge, it creates a local copy calledorigin/master
git merge origin/master
: merges the changes that were fetched.
Git Bash
git pull origin master
Git GUI
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
git clone https://github.com/<userName>/<repositoryName>
Now if you execute git branch -a
, you will get the following output:
* 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
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:
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:
git branch taskA #git branch taskB
And then executing:
git checkout taskA
which will enable them to start working on that branch. Another way is to execute one command:
git checkout -b taskA
You can also delete a branch by executing:
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:
# task AHi, Im task A
Now you have to do the following:
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:
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:
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:
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:
git add <file_name>
git commit -m "my changes"
Now my changes are inside the local repository, if I execute:
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:
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:
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:
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:
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
.
List Of Git Commands:
CommandDescriptiongit branch nameOfBranchcreates another branchgit checkout nameOfBranchswitches to the other branchgit branchreturns the current branch you are ingit checkout masterswitches to master branchgit merge nameOfBranchmerges the changes from a branch to mastergit branch -d nameOfBranchdelete the branchgit pushpushes all the changes to githubgit — helphelp pagegit help confighelp about config commandgit config — global user.name “Name”configure git, it adds your name and email to the config filegit show HEADto see the most recent commitgit remote updatebrings remote ref up to dategit status -unotells you if the branch you are tracking is ahead, behind or has divergedgit diffIt shows the difference between the index(staging area) and the working directory after you editgit rebaseRewinds the commits on your current branch, pulls in the commits from the other branch, and reapplies the rewinded commits back on top.[git rebase](https://jeffkreeftmeijer.com/git-rebase/)
Extra Information:
.gitignore
tells git which files (or patterns) it should ignore, it’s usually used to avoid committing transient files from your working directory that aren’t useful to other collaborators, such as compilation products, temporary files IDEs create, etc.FETCH_HEAD
is a short-lived ref, to keep track of what has just been fetched from the remote repository.- In Git a branch is just a label for a commit.
- Fast-forward merge is when the remote branch includes some changes and it is then merged with the local branch.
- Merge commit occurs when both remote and local branches have some changes and you execute git pull command, a new commit will be created with an auto generated commit message indicating that it was merged. A merge conflict can occur when there are changes on the same file and a git pull is executed.
- Git searches for the email and password inside the
config
file in repository or inside thegitconfig
file in the home directory. To set the username and email in thegitconfig
file then use the--global
option. git reflog
will show you the list commits you have done in all the branches, each commit will have aHEAD
with an index that refers to the commit you have done.- If you want to contribute in open source project:
- First you need to fork the project
- Do some changes
- Do a pull request (compares branches), the repository owner will accept the changes if they are correct and merges.