Git Basics
Git intro and commands explained
Website Visitors:Git is an open-source version control system used by software developers to manage changes to their code. In this article, we will cover git and basic commands you need to know to get started with it.
What is Git?
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.
When you are writing scripts, for the very first time, you add some code and make it work. After sometime, you like to add more functionality to your script and you add more functions or add more code to your script. If you want to maintain them locally, you would end up multiple files with different names as version1, version2 and so on.. But Git handles this issue very efficiently. Every time you pull the file, you would get latest file and you can have historic data on when and who changed the script or code.
Let’s look at Git commands
Git init demo – to initialize git repo called “demo”. You can name it as whatever name you like.
Working directory – contains all the files and folders for your application(or the script)
Staging Area – files/folders that are added (or changes are made to the content) to git but not committed yet.
Git Repository – contains all the saved changes and modified/updated files and commit history.
Git index
- The git “index” is where you place files you want committed to the git repository.
- The index is also known as cache, directory cache, current directory cache, staging area, staged files.
- Before you “commit” (checkin) files to the git repository, you need to first place the files in the git “index”.
- The index is not the working directory: you can type a command such as git status, and git will tell you what files in your working directory have been added to the git index (for example, by using the git add filename command).
- The index is not the git repository: files in the git index are files that git would commit to the git repository if you used the git commit command.
Global parameters
You can specify global parameters like your username and email. This information will be used whenever you commit. Ex, setup your name and email as:
git config –global user.name "gitadmin"
git config –global user.email "Your email"
To list all the global values configured in your machine, use git config --list
. More info about global parameters here: Git - First-Time Git Setup
Git Remote
Git remote is used to work with remote git repositories like github, bitbucket etc. Use git remote to pull your repository to your local machine and have a connection between your local scripts and push them to your remote repository.
- To add remote repository use below command:
git remote add origin https://gitadmin@bitbucket.org/GitUsername/projectname.git
Go to your git folder and execute, git remote -v
command to see the remote branches associated to our local git repo.
- You can also clone your existing repository and start working on files locally, and push them to your remote repo. Use below command to do so.
git clone https://gitadmin@bitbucket.org/GitUsername/projectname.git
Enter username and password when prompted git status
– to check the current status or current situation of your repository. Note: you should be in git repository folder for this command to give the correct output.
Git clone vs git remote
git remote
adds a reference to a remote repository for further tracking, while git clone
, well, clones locally a remote repository.
In git remote, you don’t have all the files in your project( i.e. remote repo). You just have a link between your local git folder or repo and remote repo. You can push all the files to your remote repo.
In git clone, you copy/clone your remote repo completely, make changes locally and push them to remote repo(i.e. your project in GitHub or bitbucket etc.). Check below link for more info: Git remote vs Git clone
Create a new repository
Create an empty file echo "# testproject" >> README.md
Initialize git repository: git init
Add README.md file to git: git add README.md
Commit this new file: git commit -m "first commit
Clone existing repository: git clone https://github.com/gitadmin/testproject.git
Using Remote repository
Add an existing repository as remote: git remote add MyRemoteRepo https://github.com/gitadmin/testproject.git
Here, MyRemoteRepo is the alias name of the remote repository. You can name it anything you like.
Push your local working directory updates to your git repo: git push -u MyRemoteRepo master
.md means markdown which is file extension for git files. Git has its own github flavored markdown – which basically tells you how to to write code in github, syntax and structure of GitHub code. (Writing on GitHub - GitHub Docs)
To create a new file, using your favorite editor, use – notepad README.md. This would create README.md file in your demo folder. If you use git status now, it shows different output than earlier. It says there is an untracked file, README.md. And it says use git add
command.
|
|
So far our README.md file is in working directory, and using git add README.md
command, moves this file from working directory to staging area. Use git status
to see the status of this transaction.
|
|
Remove file from staging area
If you have cloned a repository from external git repo, you have to use restore command as discussed below to remove it from staging area and put it back to working directory.
-
To remove a file from staging area and put it back to working directory, use the command
git restore –staged README.md
. Rungit status
command to see the status of the file. -
If you are not using any remote repository, and using only local git repo in your machine, then you should use
git rm --cached filename.txt
command to move the file from staged to working directory. Rungit status
command to see the status of the file.
Remove files
In case if you want to remove, use rm -rf .git
to remove .git folder. When you do this, none of git commands work as the git folder is removed. To reinitialize, use git init
. This will reinitialize git in the current folder.
You have to reinitialize your git folder as well. Let’s say our git repo name is demo. If you have removed demo folder completely, then you could reinitialize it with git init demo
command. But if demo folder exists, just want to reinitialize git in demo folder, so use git init
Add all files to staging area
To add all files in a folder to git repository, use git add .
or git add -A
. Any of these two commands will add new, deleted and modified files to your git staging area.
dot indicates current directory. You should be at the root directory of your git project when using dot. If you are in any subfolder and use git add .
only the files in that subfolder will be added to git. If you’ve made any changes to files outside your current folder, they will not be added when you run git add .
from a subfolder in git.
To add only deleted and modified files use the command, git add -u
Files which are in git working directory but not added to git repository, are shown as red color when you use git status
command. Now they are in working directory.
Files which are added to git repository but not committed are shown as green, when you use git status
command. Now they are in staging area.
You can also add extension specific files like git add *.js
to add all files ending with .js file extension. Similarly, you can add all text files using git add *.txt
and so on..
Commit files
To commit this file, use git commit -m “First file in this demo project”
command. Use git status
command to check status again.
If you have already added a file to git using
git add
command, and then modified the file, you can directly use thegit commit
command to commit the files. You don’t have to usegit add
command and add files again.
In your git folder, .git is the folder which maintains all the git scripts and git files/folders. These are git files and not related to the files or folders that you use in your git repository. If you remove this .git folder, you won’t be able to execute any of the git commands.
Commit multiple files at once
To commit multiple files:
-
Add all the files and enter the command
git commit
orgit commit -a
Executing any of these commands will open git editor. You have to enter a commit message and save it. -
git commit -m "save description for multiple files"
or using a dot as shown below.git commit -m “save description for the multiple files” .
(. means use this commit message for all untracked files.) When using -m parameter, you enter the commit message directly in the terminal.git add . and git commit -m “commit Message” . – These two commands will add all the files in current directory and commit all files with “commit message”
Add and Commit in Single command
You can add modified files to git and commit them with a single command as shown below:
git commit -am "adding test file"
-am
command should be added and committed to git already. If you are working with new file(s) this command will not work.View all commits
Use git log
or git show
to see all the commits.
NOTE: if you have removed .git folder, all your earlier commit information will be lost.
View git files
If you have modified file in your git working directory, and a new file added to this folder, when you use git status
it shows the files details as modified for one file and untracked for other file.
- use
git ls-files
command to see what files are already committed to staging area or git repository. Ex, you have two files and If you add a new file to git working directory, and then usegit ls-files
command, it will only show 2 files as the 3rd file is not pushed to git repository yet.
If you edit a file in working directory, you need to add that file again to git, and then commit using git add and git commit commands.
Reset added file to git
Create and modify a file (filename.txt). Use git add filename.txt
to add it to git (not yet committed). To remove this file and reset it to last saved version in git run, git reset HEAD filename.txt
– to remove this changed file from git. You pushed the updated/changed file to git, but didn’t commit yet. Using above command will only remove the file from git.
git checkout -- filename.txt
– to remove any updates you made to the file and reset it back to last saved in git. For example you have one line in the file, and saved it to git. Now you add two more lines, and added it to git, but didn’t commit. When you use reset command, it will remove file from git. When you use checkout command, it will remove the new content that is added to the file. So that your file will have only one line.
- Reset command is to remove file from staging area back to working area.
- Checkout command is to reset file back to original content.
Git Reset
There are 3 types of reset in git: Soft, Mixed, Hard. Mixed is default.
When you modify a file in your repository, the change is initially unstaged. In order to commit it, you must stage it—that is, add it to the index—using git add. When you make a commit, the changes that are committed are those that have been added to the index.
git reset changes, at minimum, where your current branch is pointing. The difference between –mixed and –soft is whether or not your index is also modified. So, if we’re on branch master with this series of commits:
– A – B – C (master)
HEAD points to C and the index matches C.
–soft
When we run git reset –soft B, master (and thus HEAD) now points to B, but the index still has the changes from C; git status will show them as staged. So if we run git commit at this point, we’ll get a new commit with the same changes as C.
–mixed
Okay, so starting from here again:
– A – B – C (master)
Now let’s do git reset –mixed B. Once again, master and HEAD point to B, but this time the index is also modified to match B. If we run git commit at this point, nothing will happen since the index matches HEAD. We still have the changes in the working directory, but since they’re not in the index, git status shows them as unstaged. To commit them, you would git add and then commit as usual.
–hard
And finally, –hard is the same as –mixed (it changes your HEAD and index), except that –hard also modifies your working directory. If we’re at C and run git reset –hard B, then the changes added in C, as well as any uncommitted changes you have, will be removed, and the files in your working copy will match commit B. Since you can permanently lose changes this way, you should always run git status before doing a hard reset to make sure your working directory is clean or that you’re okay with losing your uncommitted changes.
From Difference between git reset –mixed, –soft, and –hard
To delete the most recent commit, keeping the work you’ve done: git reset --soft HEAD~1
To delete the most recent commit, destroying the work you’ve done: git reset --hard HEAD~1
View all commits
git log --oneline --graph --decorate --all
: View all commits only with commit numbers and commit messages.
Git show “commit number”
(we can get commit number from above command): To see changes in any single commit. Ex, git show ff1e54e
Create Alias in Git
To create alias for command, git log --oneline --graph --decorate --all
, use below command.
git config --global alias.history “log --oneline --graph --decorate --all”
Here, history is the alias that you create for log --oneline --graph --decorate --all
command. So directly use git history
to see history without that command. The word history is replacement for log --oneline --graph --decorate --all
command.
So now you can use git history — filename.txt
(or just git history filename.txt
)( Here filename.txt is any file which is already added to git) to see history of that file.
To see global config details use: git config --global --list
Removing git global values
use any of the commands: git config --global --l
or git config --global --list
to see the git configuration in your system, like default name, email id, git version, proxy etc..
To remove any specific values from the global config list, run unset command with the value name as shown below:
git config --global --unset alias.history
to remove the alias, history that we’ve created above.
Commands to reset git on http, https and core proxy:
|
|
Rename git files
To rename a file which is updated and pushed to git, use git mv originalfilename.txt newfilename.txt
and commit the change by git commit -m “renamed file”
To rename git file, use git mv command
and then commit it.
Similarly to delete a file from git, use git rm filename.txt
and then commit it. At any stage, use git status
to check the current status of your files.
You can also use rm filename.txt
to delete a file, but again you need to use git rm filename.txt
and then commit. Because rm filename.txt
is not git command. So, we have to use git to remove file and then commit.
Never use non-git commands in git repository because git doesn’t recognize those commands, and you need to execute the same commands using git again. Ex, if you remove file with rm filename.txt
you have to remove the file in git using git rm filename.txt
and commit. Instead, use git rm filename.txt
and commit. If you have used non-git commands, use git add -A
command for git to recognize all the changes you made. Next, commit your changes, git commit -m “bla bla bla”
when you used non-git command to add or rename files, use git add -A
Ex, mv filename.txt newfilename.txt (filename.txt is already in git repo) and then commit.
When you delete file without git and later you want git to recognize it, use git add -u and then commit.
Exclude or ignore specific files in git repo
When you create a file in git repo folder, git would see the file as not added to git, not committed etc.. But if you want to exclude specific files or specific file extensions, create a .gitignore file and add file names in it or file extensions like *.txt, *.log etc. Either individual files or all the files with the extension you mentioned, will be ignored by git.
Ex, notepad .gitignore – would create an empty .gitignore file.
type *.txt or *.log or any specific file name to be ignored by git.
HEAD command
Head is last commit of current branch. Head location can be changed manually if needed, to other commits(not the last commit). The HEAD in Git is the pointer to the current branch reference, which is in turn a pointer to the last commit you made or the last commit that was checked out into your working directory. That also means it will be the parent of the next commit you do. It’s generally simplest to think of it as HEAD is the snapshot of your last commit.
The HEAD is a special pointer that simply points to the currently checked out branch or commit. And again, it’s a simple file inside the .git folder called HEAD which in our case currently contains the string master.
Diff command
using “diff” command, we can get the difference between two commits or any one commit and HEAD.
use git log --oneline --graph --decorate --all
to see all commits. note the commit id for any file you want to get the differences for.
use git diff COMMITID FILENAME
Example, git diff ca33992 README.md
.. This command will display differences between commit id, ca33992 and README.md file.
Note: ca33992 is a commit on README.md file.
To use GUI mode for diff, use git difftool command as below:
git difftool 7711148 README.md
This will open default difftool. P4merge is good difference tool.
Use “git diff” command to see differences between recently changed in working directory and HEAD(last commit on the branch)
we can use “git difftool” for GUI.
Branch
Branch is timeline of commits. They are names that we give to commits. If you have 10 commits on a branch and create a new branch from that existing branch, all the commits in that existing branch are copied to this new branch.
A branch in Git is simply a lightweight movable pointer to one of these commits. The default branch name in Git is master (or main). As you initially make commits, you’re given a master branch that points to the last commit you made. Every time you commit, it moves forward automatically.
Create New Branch
Use Git branch
command to see the list of all branches. The one in green and * symbol represents the current branch.
Note: you need to commit atleast one file to use git branch command.
To create new branch, use git checkout -b NEWBRANCHNAME
ex, git checkout -b branch1
To switch branches use git checkout OTHERBRANCHNAME
Move to new branch and modify a file. Add and commit it. Now move to old branch and use git diff newbranch oldbranch so that you can see the differences.
Use git log --oneline --graph --decorate --all
to see the commit history. We are using –all parameter here, so this command will show commits from all branches. Now you will see commits from above branch too. To merge branches, use git merge OTHERBRANCHNAME
. Ex, if you are in master branch and you have another branch name branch1, use git merge branch1
to merge all the commits from branch1 to master. You will see what merging method is used, ie., fast-forward or automatic or manual.
To delete a branch git branch -d OTHERBRANCHNAME
to delete branch. You have to move out of the branch that you want to delete. If you are in that branch, and try to delete it, it wont delete.
Clone to different branch
By default when you use git clone https://github.com/username/reponame.git
it clones the master/main branch from that git repo. If you have multiple branches on that repo and you want to clone a different branch from that repo, use the command shown below:
|
|
git push origin master
, it fails because you cloned DevBranch branch. You should use git push origin DevBranch
to push your updates to that DevBranch branch.Merging
Fast forwarding – This happens when there are no commits(or no additional work is detected) on master branch. Git will apply all commits from other branch to parent branch(master). We can disable this merge if not needed.
Automatic- This happens when there are no conflicting changes between other branch and master branch(parent branch). Git would automatically resolve if it detects any conflicts and a new merge commit is created when conflicts are resolved. So that we know a conflict happened and git resolved it.
Manual – when git is unable to resolve any conflicts manual merge should take place. Git creates a conflicting merge commit state when it is not able to resolve any merge commits. All merge conflicts should be resolved before we commit. Once all conflicts are resolved, then a new commit is created.
Resolving conflicts
When you end up in any conflicts in your branches, use mergetool and save any of the files shown there. Once you save, commit your changes. Ex: git mergetool
Tagging
You can think of a branch as one of those sticky bookmarks:
You can think of tags as chapter headings.
Create tag, git tag TAGNAME
ex, git tag mytag.
List tag, git tag –list
to show all the tags.
Delete tag, git tag -d TAGNAME
ex, git tag -d mytag to delete the tag, mytag.
To delete all local tags at once, git tag | xargs git tag -d
.
Git annotated tags
- When you use
git tag <tagname>
, Git will create a tag at the current revision but will not prompt you for an annotation. It will be tagged without a message. - When you use
git tag -a <tagname>
, Git will prompt you for an annotation unless you have also used the -m flag to provide a message. - When you use
git tag -a -m <msg> <tagname>
, Git will tag the commit and annotate it with the provided message. - When you use
git tag -m <msg> <tagname>
, Git will behave as if you passed the -a flag for annotation and use the provided message.
Basically, it just amounts to whether you want the lightweight tag to have an annotation associated with it or not.
The big difference is perfectly explained here. Basically, lightweight tags are just pointers to specific commits. No further information is saved; on the other hand, annotated tags are regular objects, which have an author and a date and can be referred because they have their own SHA key. If knowing who tagged what and when is relevant for you, then use annotated tags. If you just want to tag a specific point in your development, no matter who and when did that, then lightweight tags are good enough. Normally you’d go for annotated tags, but it is really up to the Git master of the project.
From Difference between an annotated and unannotated tag
Git Stashing
Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the git stash command.
Stashing takes the dirty state(or current modified state) of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time.
From Git Tools Stashing
How to Stash
When you have modified one or more files in current branch, type git stash
to save the current state of your branch files. To view all stashed files, use git stash list
. Now if you use git status
there wont be anything, normally when you edit a file and use git status
, it should show the modified file in red color. But now you don’t see anything as current state is saved.
NOTE: Stashing only works with files that are modified which are already created and committed in git. WHICH ARE ALREADY CREATEAD AND COMMITTED IN GIT. If you add new file and try to stash it, it doesn’t work. You should have a file in git, already created and committed. If you work on these files, you can stash them. NOT ON NEW FILES.
To continue working on the statsh again, use git stash pop
. This will let us continue working on the files we saved earlier. Now you can edit the file again, add the file to your git and commit and so on.
Git status
– to check current state.
Git stash
– to save current state, now use git status
you don’t see your modifiled files. They are in saved state now.
You have modified a file already in git, and used git stash
. Now it is in saved state. You modify another file in git, and again use git stash
. Now when you say git stash list
, you will see multiple stashes.
Git stash list
– see all the saved sessions/stashes on all branches.
Git stash pop
– to come out of the stash and continue working on the files again. Remove a single stashed state from the stash list and apply it on top of the current working tree state.
Git stash pop stash@{0}
and git stash pop stash@{1}
and so on to pop your individual stashes when you have multiple stashes.
Note: your new stashes will be saved from the beginning of stash list. Ex, You modified file1 in git, and stashed it. It will be in stash@{0}. Now you modified file2 in git and if you stash it, it will be stash@{0} and the one you saved earlier for file1 would be in stash@{1}. All new stashes will be added to the top of the list. Now if you want to work on file2, you should say git stash pop stash@{0}
. If you want to work on file1, you should say git stash pop stash@{1}.
Now you can edit the file again, add it to git and commit.
For a single file edits and commits, you can use the following commands:
- git config –global user.name “username”
- git config –global user.email “user email”
- git clone https://remoterepository.com/username/projectname.git
Note: By default when you clone, git will create same folder as the one you have in your remote repository( ie., a folder with your project name in your local machine, in your current folder). If you dont want it, and you need a different folder name, use git clone https://remoterepository.com/username/projectname.git foldername - git add filename.ps1
- git commit -m “Adding filename”
- git push
This will clone your existing repository, add a file, commit it and push it to your remote repository.
Remove remote repository
To remove remote repository use: Git remote rm origin
Note: git remote rm does not delete the remote repository from the server. It simply removes the remote and its references from your local repository. git remote rm origin
removes the connection to the remote server. git remote add origin <user>@<url>
will recreate this connection.
Differences between fetch and push
In a general scenario, when you have changes only on your local repo, you can use git push to send all your local changes to your remote repo. But when you modify a file on your remote repo, like on github via browser, your local repo cannot identify that change.
So you must first fetch your remote repo changes first(note, this doesn’t merge anything, we are just acknowledging that there are changes on remote repo) and then use git pull to pull the online(remote) repo changes to your local repo. Now you can make changes to the same file in your local repo, and then use git push to push the changes.
Use git fetch origin master
to fetch all the files from your master branch.
Git fetch would only pull references from your online repo. It doesnt merge any files or copy any changes you made to files in your online repository.
This would be very useful when multiple members are working on the same project or code. You import/fetch all the code written by your team, and you start working on it.
If you have modified files on online repo, ie., browser and in local repo, when you try to push, it says “updates are rejected because remote contains work that you do not have locally.”
Now you need to fetch and pull. If both files are different, you fetch them, pull them , and push your local repo.
But if same file is modified on browser(online repo) and in your local repo, When you try to push,
- If you dont commit your local repo file changes, it will throw an error as below:
- branch master -> FETCH_HEAD
Updating 216d42f..91a8fef
error: Your local changes to the following files would be overwritten by merge:
another file on local repo.txt
Please commit your changes or stash them before you can merge.
Aborting
- branch master -> FETCH_HEAD
- If you commit and then try to fetch and pull, it says this:
- branch master -> FETCH_HEAD
Auto-merging another file on local repo.txt
CONFLICT (content): Merge conflict in another file on local repo.txt
Automatic merge failed; fix conflicts and then commit the result.
- branch master -> FETCH_HEAD
So, you need to remove your changes locally, then have a clean fetch and pull, and then edit your local file, and push.
Git Fork
A fork is a copy of a repository. Forking a repository allows you to freely experiment with changes without affecting the original project.
Copying existing repository from someone else’s GitHub account to your GitHub account and working on it is called Forking. You can work on your forked copy and it doesn’t affect or change the original repository that you copied from, because both repositories are in different GitHub accounts.
Most commonly, forks are used to either propose changes to someone else’s project or to use someone else’s project as a starting point for your own idea.
Propose changes to someone else’s project
A great example of using forks to propose changes is for bug fixes. Rather than logging an issue for a bug you’ve found, you can:
- Fork the repository.
- Make the fix.
- Submit a pull request to the project owner.
If the project owner likes your work, they might pull your fix into the original repository!
Use someone else’s project as a starting point for your own idea.
At the heart of open source is the idea that by sharing code, we can make better, more reliable software.
When creating your public repository from a fork of someone’s project, make sure to include a license file that determines how you want your project to be shared with others.
For more information on open source, specifically how to create and grow an open source project, we’ve created Open Source Guides that will help you foster a healthy open source community by recommending best practices for creating and maintaining repositories for your open source project. You can also take a free GitHub Learning Lab course on maintaining open source communities.
Pull Request:
From Github’s Using Pull Requests Page
Pull requests let you tell others about changes you’ve pushed to a GitHub repository. Once a pull request is sent, interested parties can review the set of changes, discuss potential modifications, and even push follow-up commits if necessary.
Pull Requests are commonly used by teams and organizations collaborating using the Shared Repository Model, where everyone shares a single repository and topic branches are used to develop features and isolate changes.
So, other team members fork your project, update their own code in that repo, and send a pull request. Meaning, they have a piece of code that works and they send you(admin or owner) a request to pull that code into your repo. Now, as admin, you can accept it and merge it in your repo or reject that pull request.
When you(not the owner or the project, but someone else) open a pull request, you’re proposing your changes and requesting that someone(typically owner or admin of the original repo) review and pull in your contribution and merge them into their branch. Pull requests show diffs, or differences, of the content from both branches. The changes, additions, and subtractions are shown in green and red.
Git Pull vs Git Fetch
If you want to update your local repo from the remote repo, but, you don’t want to merge any differences, then you can use: git fetch
Then after we download the updates, we can check for any differences as follows: git diff master origin/master
After which, if we’re happy with any differences, then we can simply merge the differences as follows: git merge
On the other hand, we can simply fetch
and merge
at the same time, where any differences would need to be solved. This can be done as follows: git pull
Posted in Medium.com
Check what you’ve modified
Let’s say you have modified a file content in your local repository on your machine. Before you push it to your remote repository, you’d like to view the content that you’ve added. If you want to see those changes use
git diff -- yourfilepath
Example: git diff -- folder1\folder2\filename.txt
Note that there is a space after --
in the command.
Setup Local Git Server
You have to run git init anyname.git –bare
command to create git server locally. Check out this post for more information.
Git commands pictorial representation
Learn Git
-
Git Immersion : A guided tour to teach you the basics of Git.
-
Try Git : An interactive series of challenges to learn about and experiment with Git.
-
GitHub Learning Lab : Setup github training in your repository and run labs. Very useful.
Conclusion
In this article, we’ve explained what is Git and its basic usage. We’ve also demonstrated examples for all the topics that are discussed in the article. We hope you have learned something new in this article.
Having all this information about Git in hand, it is now time for you to choose a version control (aka source code management) software like GitHub, GitLab, AWS CodeCommit (and more). Which one would you use and Why? Let us know in the comments section below.
Your inbox needs more DevOps articles.
Subscribe to get our latest content by email.