As per Wikipedia:
Git is a version control system for tracking changes in computer files and coordinating work on those files among multiple people. It is primarily used for source code management in software development, but it can be used to keep track of changes in any set of files. As a distributed revision control system it is aimed at speed, data integrity, and support for distributed, non-linear workflows.
In this page, lets have a look at some basic git commands that are used to perform some routine tasks, when using git.
This is a work in progress page, that I created as an alternative to scribbling this down on some page and that getting lost. Hence, the information might not be 100% accurate, is certainly not 100% complete and is for sure not as neatly organized as I would like it to be. I will try to improve on this once I find some time. Till then, I hope this can be of some rough use to you as well.
I am using some formatting conventions here:
The code / command outputs are in this box
Some notes / additional information is in this box.
Plain text is mostly unformatted, except for cases where I might highlight them in some way.
So, let’s get started.
1. git command help:
Before we begin, we have to know that git has its own reference manual for the commands. In my case, this seems to be a set of html pages that have been installed into my system, with the git for windows installation. To see all the topics for which help is available, type in
$ git help
usage: git [–version] [–help] [-C <path>] [-c name=value]
[–exec-path[=<path>]] [–html-path] [–man-path] [–info-path]
[-p | –paginate | –no-pager] [–no-replace-objects] [–bare]
[–git-dir=<path>] [–work-tree=<path>] [–namespace=<name>]
<command> [<args>]
#Pradeep: Removing the content from here to keep this page as small as possible.
…
‘git help -a’ and ‘git help -g’ list available subcommands and some
concept guides. See ‘git help <command>’ or ‘git help <concept>’
to read about a specific subcommand or concept.
To search for any command’s usage guide:
git help <command name>
For e.g., the following opens the help page for the branch command:
git help branch
2. Creating an empty repo:
Open the git bash on windows
Go to the folder where you want a new repo (e.g. c:\testrepo)
Type in
git init
This generates the .git folder inside this directory:
drwxr-xr-x 1 user 197609 0 Dec 28 08:17 ./
drwxr-xr-x 1 user 197609 0 Dec 28 08:17 ../
drwxr-xr-x 1 user 197609 0 Dec 28 08:17 .git/
3. Create a Readme file:
In the command line, type in:
echo “Hello GIT, lets get started” >> README.txt
This creates the README.txt inside our new repo
4. Checking the status of the added file
Type in the following
git status
We see the following:
$ git status
On branch master
No commits yet
Untracked files:
(use “git add <file>…” to include in what will be committed)
README.txt
nothing added to commit but untracked files present (use “git add” to track)
This is because, we have not committed anything to git yet
5. Adding the file to the git repo:
Type in:
git add README.txt
Now, type in
git status
$ git status
On branch master
No commits yet
Changes to be committed:
(use “git rm –cached <file>…” to unstage)
new file: README.txt
6. Committing the changes:
Use the following:
git commit
This opens the editor that you had configured as the default, during the git for Windows installation
I have set this to Notepad++, hence I see that opened.
Add a commit message. Lines starting with # are ignored.
You can add something meaningful about what this commit is for. I shall add:
Adding the README.txt file
Once done, save the file and close the editor. This shall commit the changes to the repo.
7. Checking the commit:
Type in:
git log
This brings up the information about the recent commit:
$ git log
commit 53b4373100cb64399aa31870d332bfa242cec82b (HEAD -> master)
Author: user <user@gmail.com>
Date: Thu Dec 28 09:05:16 2017 +0530
Added the README.txt file
8. Modifying an existing file:
Post the commit, if we change the README.txt file in any way, git shall detect this. Try adding a new line into this README.txt file. Once done, save and type in the following in the command prompt:
git status
On branch master
Changes not staged for commit:
(use “git add <file>…” to update what will be committed)
(use “git checkout — <file>…” to discard changes in working directory)
modified: README.txt
no changes added to commit (use “git add” and/or “git commit -a”)
Type in:
git add -u
The -u option specifies that we are updating the existing files. Note that the -u option doesn’t add the files that git doesn’t know about already. Thus, if you have added some new files to the repo but have not previously added them to the repo using git add, running git add -u will not add these to the repo. These are ignored by the add -u option.
Once this is done, running the git status again results in:
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
modified: README.txt
Thus, the changes are now staged for commit.
git staging area:
The git staging area is where the files that are to be committed next, are kept. Suppose you are working on multiple files, one is ready to be committed, the others are not. You can add just the completed file to the staging area and commit it. Only the staged files are picked up for the commit, the rest are ignored. Another advantage is to commit a set of changes done in the same file. Suppose you are adding 10 new functions to the code. You are done with 5 functions. You can stage this and continue with the others. If you are not able to complete it by EOD, you can commit just these 5 completed functions, while the changes done after the staging was done, still remain uncommitted.
Another use case is if you have multiple changes, that are not directly related. In this case, add one set of related changes to the staging area, commit them and then add the next set of related changes to the staging area and commit them. This way, you know which commit has what changes and you don’t have to merge all into the same commit.
Now, this change can be committed.
git commit
This again opens the editor, for you to add a commit message. Another option to directly add a commit message is by using the git commit -m option:
git commit -m “Modified the README.txt file”
This shows:
$ git commit -m “Modified the README.txt file”
[master 0ae86b1] Modified the README.txt file
1 file changed, 1 insertion(+)
Running git status again results in:
$ git status
On branch master
nothing to commit, working tree clean
To see all the commits done so far, type in git log:
$ git log
commit 0ae86b16762d44bbbf21396dd3f8561361028d3b (HEAD -> master)
Author: user <user@gmail.com>
Date: Thu Dec 28 09:18:38 2017 +0530
Modified the README.txt file
commit 53b4373100cb64399aa31870d332bfa242cec82b
Author: user <user@gmail.com>
Date: Thu Dec 28 09:05:16 2017 +0530
Added the README.txt file
9. Finding the differences between the commits:
We can use the git diff to find the differences between the commits. We need to specify the commit IDs. Specifying the first 5 digits of the IDs seem to be sufficient here (unless you have a situation where the first 5 digits of both these IDs are same)
Specify the older ID, followed by the newer one, so that the added line is highlighted in green. If you do this the other way around, i.e., specify the newer one first and the older one next, we see that the newly added line is shown as removed (in red).
$ git diff 53b43…0ae86
diff –git a/README.txt b/README.txt
index 9f4d96d..04f420b 100644
— a/README.txt
+++ b/README.txt
@@ -1 +1,2 @@
Hello Git
+Adding a new line
\ No newline at end of file
You can specify the full ID as well, obviously. Specifying the newer ID first resulted in this:
$ git diff 0ae86b16762d44bbbf21396dd3f8561361028d3b 53b4373100cb64399aa31870d332bfa242cec82b
diff –git a/README.txt b/README.txt
index 04f420b..9f4d96d 100644
— a/README.txt
+++ b/README.txt
@@ -1,2 +1 @@
Hello Git
-Adding a new line
\ No newline at end of file
Instead of specifying the hashes (commit IDs), we can use the HEAD option. The latest commit shall be specified as HEAD. We can use the ~ option to go back in the commit chain, by specifying the count of how far we would like to go. Thus, to get the previous commit, we can use HEAD~1 (meaning 1 before the HEAD or the last but one commit)
$ git diff HEAD~1…HEAD
diff –git a/README.txt b/README.txt
index 9f4d96d..04f420b 100644
— a/README.txt
+++ b/README.txt
@@ -1 +1,2 @@
Hello Git
+Adding a new line
\ No newline at end of file
10. Adding new files for commit:
Create a couple of new files:
$ touch newfile1.txt newfile2.txt
$ git status
On branch master
Untracked files:
(use “git add <file>…” to include in what will be committed)
newfile1.txt
newfile2.txt
nothing added to commit but untracked files present (use “git add” to track)
As discussed previously, using git add -u option does not add these files to the staging area, since the -u only updates already added files. We need to manually add each of these files by specifying their file names or we can use the -A option:
git add -A
Be careful while using this, since this can potentially add any temporary and unwanted files into the staging area as well.
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
new file: newfile1.txt
new file: newfile2.txt
Once these are added to the staging area, we can commit them:
$git commit -m “Added two new files”
[master cb3411e] Added two new files
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 newfile1.txt
create mode 100644 newfile2.txt
We can check the commit history now:
$ git log
commit cb3411e3b82a0954ef737b70f0d02cb1b376dea0 (HEAD -> master)
Author: user <user@gmail.com>
Date: Thu Dec 28 10:00:19 2017 +0530
Added two new files
commit 0ae86b16762d44bbbf21396dd3f8561361028d3b
Author: user <user@gmail.com>
Date: Thu Dec 28 09:18:38 2017 +0530
Modified the README.txt file
commit 53b4373100cb64399aa31870d332bfa242cec82b
Author: user <user@gmail.com>
Date: Thu Dec 28 09:05:16 2017 +0530
Added the README.txt file
We can check the difference between the head and the previous version:
$ git diff HEAD~1..
diff –git a/newfile1.txt b/newfile1.txt
new file mode 100644
index 0000000..e69de29
diff –git a/newfile2.txt b/newfile2.txt
new file mode 100644
index 0000000..e69de29
HEAD~1.. means that check the diff between HEAD~1 and the HEAD.
Similarly, to check the difference between the first commit we did (which can be referred to as HEAD~2 in our case) and the HEAD:
$ git diff HEAD~2..
diff –git a/README.txt b/README.txt
index 9f4d96d..04f420b 100644
— a/README.txt
+++ b/README.txt
@@ -1 +1,2 @@
Hello Git
+Adding a new line
\ No newline at end of file
diff –git a/newfile1.txt b/newfile1.txt
new file mode 100644
index 0000000..e69de29
diff –git a/newfile2.txt b/newfile2.txt
new file mode 100644
index 0000000..e69de29
11. Deletion of added files:
To delete a file that was added previously, you can manually delete the same from the repo directory. Once done, if we use the git status:
user@User MINGW32 ~/userdata/git/test (master)
$ ls
newfile1.txt newfile2.txt README.txt
user@User MINGW32 ~/userdata/git/test (master)
$ rm newfile2.txt
user@User MINGW32 ~/userdata/git/test (master)
$ ls
newfile1.txt README.txt
user@User MINGW32 ~/userdata/git/test (master)
$ git status
On branch master
Changes not staged for commit:
(use “git add/rm <file>…” to update what will be committed)
(use “git checkout — <file>…” to discard changes in working directory)
deleted: newfile2.txt
no changes added to commit (use “git add” and/or “git commit -a”)
To add this deletion into the staging area:
user@User MINGW32 ~/userdata/git/test (master)
$ git add -u
user@User MINGW32 ~/userdata/git/test (master)
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
deleted: newfile2.txt
Commit this deletion using the git commit option:
user@User MINGW32 ~/userdata/git/test (master)
$ git commit -m “Deleted newfile2.txt”
[master 4b44bcf] Deleted newfile2.txt
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 newfile2.txt
user@User MINGW32 ~/userdata/git/test (master)
$ git log
commit 4b44bcfea84e8f4f9fefdc43f3733cca1cf1330e (HEAD -> master)
Author: user <user@gmail.com>
Date: Thu Dec 28 10:39:03 2017 +0530
Deleted newfile2.txt
… #Pradeep: Removing previous commit logs
12. Renaming an added file:
Rename an existing file, either via the mv command or any other options on your specific OS.
If we run the git status on this now, git assumes that we deleted the old file and created a new unrelated one:
user@User MINGW32 ~/userdata/git/test (master)
$ mv newfile1.txt renamedfile.txt
user@User MINGW32 ~/userdata/git/test (master)
$ ls
README.txt renamedfile.txt
user@User MINGW32 ~/userdata/git/test (master)
$ git status
On branch master
Changes not staged for commit:
(use “git add/rm <file>…” to update what will be committed)
(use “git checkout — <file>…” to discard changes in working directory)
deleted: newfile1.txt
Untracked files:
(use “git add <file>…” to include in what will be committed)
renamedfile.txt
no changes added to commit (use “git add” and/or “git commit -a”)
Once we add this new file using the -A option, git finds out that this was the same file that has been renamed and treats it as such:
user@User MINGW32 ~/userdata/git/test (master)
$ git add -A
user@User MINGW32 ~/userdata/git/test (master)
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
renamed: newfile1.txt -> renamedfile.txt
Now you can commit this change.
13. Undoing unrequired local changes:
Suppose you made some changes that you don’t want. You can fetch the latest committed code from the repo.
Assume you modified the newfile.txt locally. Now, you don’t want these changes but you have saved and closed your editor and have no way of undoing that via the editor’s built in undo options. You can use the git checkout option to get the latest version from the repo. This way, your locally modified file will be removed and replaced with the committed version of the file.
The following is the git status after some changes have been done:
$ git status
On branch master
Changes not staged for commit:
(use “git add <file>…” to update what will be committed)
(use “git checkout — <file>…” to discard changes in working directory)
modified: newfile.txt
no changes added to commit (use “git add” and/or “git commit -a”)
If I don’t want the changes done here, I can do the following:
user@User MINGW32 ~/UserData/GIT/test (master)
$ cat newfile.txt
Hello. I am a new file! I am being modified #Local changed file
user@User MINGW32 ~/UserData/GIT/test (master)
$ git checkout newfile.txt
user@User MINGW32 ~/UserData/GIT/test (master)
$ cat newfile.txt
Hello. I am a new file!
user@User MINGW32 ~/UserData/GIT/test (master)
$ git status
On branch master
nothing to commit, working tree clean
Thus, the local changes have been removed and the file is replaced with the previously committed one.
If we have the scenario where we want to remove all the changes done since the previous checkout, we can use the git reset:
user@User MINGW32 ~/UserData/GIT/test (master)
$ rm README.txt
user@User MINGW32 ~/UserData/GIT/test (master)
$ mv newfile.txt new.txt
user@User MINGW32 ~/UserData/GIT/test (master)
$ git status
On branch master
Changes not staged for commit:
(use “git add/rm <file>…” to update what will be committed)
(use “git checkout — <file>…” to discard changes in working directory)
deleted: README.txt
deleted: newfile.txt
Untracked files:
(use “git add <file>…” to include in what will be committed)
new.txt
no changes added to commit (use “git add” and/or “git commit -a”)
user@User MINGW32 ~/UserData/GIT/test (master)
$ git reset –hard
HEAD is now at 9a146c2 Modified the newfile.txt
user@User MINGW32 ~/UserData/GIT/test (master)
$ git status
On branch master
Untracked files:
(use “git add <file>…” to include in what will be committed)
new.txt
nothing added to commit but untracked files present (use “git add” to track)
user@User MINGW32 ~/UserData/GIT/test (master)
$ ls
new.txt newfile.txt README.txt
Here, since we moved the contents of the newfile.txt into the new.txt, git doesn’t know about the new.txt. Hence, it is indicated as an unknown file. You see, though, that the deleted file is restored and the original newfile.txt is also restored.
14. Undoing unrequired committed changes
Suppose you committed some changes that you felt were unrequired (or they introduced some bug, yikes!). To revert back to that code, you can do a soft reset:
user@User MINGW32 ~/UserData/GIT/test (master)
$ git reset –soft HEAD~1
user@User MINGW32 ~/UserData/GIT/test (master)
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
modified: newfile.txt
Thus, we have the file moved back into the staging area. You can now fix the file to your liking and the commit it again in the usual way.
Let’s see the log now:
$ git log
commit d531ff7d70590f18f2d426898cead8385f8eb5f4 (HEAD -> master)
Author: user <user@gmail.com>
Date: Thu Dec 28 11:48:33 2017 +0530
modifying the newfile.txt to show the hard reset effects afterwards
commit 33fe3148178464dab8f5f3aecd68a82caba90171
Author: user <user@gmail.com>
Date: Thu Dec 28 11:47:20 2017 +0530
Modified the new file after the soft reset
commit 79dd84b69101e08767f5e4b9c606a5056cbaa133
Author: user <user@gmail.com>
Date: Thu Dec 28 10:52:46 2017 +0530
Renamed the renamedfile.txt to newfile.txt
… #Pradeep: Removed the earlier logs
Now, if I use the git reset -hard option as below:
user@User MINGW32 ~/UserData/GIT/test (master)
$ git reset –hard HEAD~1
HEAD is now at 33fe314 Modified the new file after the soft reset
user@User MINGW32 ~/UserData/GIT/test (master)
$ git log
commit 33fe3148178464dab8f5f3aecd68a82caba90171 (HEAD -> master)
Author: user <user@gmail.com>
Date: Thu Dec 28 11:47:20 2017 +0530
Modified the new file after the soft reset
commit 79dd84b69101e08767f5e4b9c606a5056cbaa133
Author: user <user@gmail.com>
Date: Thu Dec 28 10:52:46 2017 +0530
Renamed the renamedfile.txt to newfile.txt
… #Pradeep: Removed the earlier logs
As you can see, the latest commit has been discarded.
user@User MINGW32 ~/UserData/GIT/test (master)
$ git reset –hard HEAD~3
HEAD is now at 4b44bcf Deleted newfile2.txt
user@User MINGW32 ~/UserData/GIT/test (master)
$ git log
commit 4b44bcfea84e8f4f9fefdc43f3733cca1cf1330e (HEAD -> master)
Author: user <user@gmail.com>
Date: Thu Dec 28 10:39:03 2017 +0530
Deleted newfile2.txt
commit cb3411e3b82a0954ef737b70f0d02cb1b376dea0
Author: user <user@gmail.com>
Date: Thu Dec 28 10:00:19 2017 +0530
Added two new files
As you can see, we can move back several commits using the HEAD~ option.
15. Cleaning up the working directory:
You might have some stray files in the working directory. These could be temp files or some backup files created by editors, etc. If you accidentally use the git add -A option, these two get added to the repo. You will want to clear such files. Thus, once you are sure all your actual files are checked in, you can use the following option:
git clean -f
This shall remove any files in the directory, that git is not aware of. Thus, the temp files are deleted. Do be careful not to do this if you have any actually needed files that are yet to be staged or committed.
16. Indicating git to ignore certain files and folders
There are many scenarios where you don’t want git to include all the files and folders in the directory and commit the same. For e.g., you might have the debug / release directories that shall contain the output of your builds. You don’t want to store these in the repo. You can tell git to ignore such directories and / or specific files in such folders, using the .gitignore file.
I have just created a directory called “debug” and added a couple of files into this:
user@User MINGW32 ~/UserData/GIT/test/debug (master)
$ ls
build.exe* build.log
user@User MINGW32 ~/UserData/GIT/test/debug (master)
$ cd ..
user@User MINGW32 ~/UserData/GIT/test (master)
$ git status
On branch master
Untracked files:
(use “git add <file>…” to include in what will be committed)
debug/
nothing added to commit but untracked files present (use “git add” to track)
git does not know about the debug directory and hence states the same.
Now, create a file called .gitignore and add the debug as a folder in this:
user@User MINGW32 ~/UserData/GIT/test (master)
$ vi .gitignore
user@User MINGW32 ~/UserData/GIT/test (master)
$ cat .gitignore
/debug
user@User MINGW32 ~/UserData/GIT/test (master)
$ git status
On branch master
Untracked files:
(use “git add <file>…” to include in what will be committed)
.gitignore
nothing added to commit but untracked files present (use “git add” to track)
As you can see, since we have mentioned the /debug in the .gitignore, git no longer complains about this.
The .gitignore file itself can be added to the repo:
user@User MINGW32 ~/UserData/GIT/test (master)
$ git add -A
warning: LF will be replaced by CRLF in .gitignore.
The file will have its original line endings in your working directory.
user@User MINGW32 ~/UserData/GIT/test (master)
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
new file: .gitignore
user@User MINGW32 ~/UserData/GIT/test (master)
$ git commit -m “.gitignore file added”
[master 01d53aa] .gitignore file added
1 file changed, 1 insertion(+)
create mode 100644 .gitignore
user@User MINGW32 ~/UserData/GIT/test (master)
$ git log
commit 01d53aa0d43999b9367b5d10c633b5bfe4b8d08b (HEAD -> master)
Author: user <user@gmail.com>
Date: Thu Dec 28 12:19:40 2017 +0530
.gitignore file added
user@User MINGW32 ~/UserData/GIT/test (master)
$ git status
On branch master
nothing to commit, working tree clean
user@User MINGW32 ~/UserData/GIT/test (master)
$ ls
debug/ newfile1.txt README.txt
Thus, as you can see, git ignores the /debug directory all together. To specify a file type or a specific file, you can add the same to the gitignore as well:
$ cat .gitignore
/debug
*.html
Thus, git now ignores any html file present and any folder called /debug in the current directory
.gitignore works only the files in the current directory and can be made to ignore files in the sub directories as well. Thus, if you want a common .gitignore for the entire repo, add the .gitignore file at the top most directory.
If you want to ignore the files only in the current directory, put a / before the file name. Thus:
/*.html
will ignore the html files in the current directory only but will not ignore the ones in the subdirectories
You can put a .gitignore in any directory, and it will only affect that directory and its subdirectories.
If you want to ignore files only in the directory with the .gitignore file, use a leading “/”. So your .gitignore file would contain
user@User MINGW32 ~/UserData/GIT/test (master)
$ git status
On branch master
Untracked files:
(use “git add <file>…” to include in what will be committed)
newfolder/new2.html
nothing added to commit but untracked files present (use “git add” to track)
user@User MINGW32 ~/UserData/GIT/test (master)
$ vi .gitignore
user@User MINGW32 ~/UserData/GIT/test (master)
$ git status
On branch master
Changes not staged for commit:
(use “git add <file>…” to update what will be committed)
(use “git checkout — <file>…” to discard changes in working directory)
modified: .gitignore
no changes added to commit (use “git add” and/or “git commit -a”)
$ cat .gitignore
/debug
*.html
Thus, by adding just *.html, the html files even inside the sub directories are ignored. If we add it as /*.html, only the html files in the current directory are ignored.
Note, to check the current global configurations, we can use the following:
git config –global –edit
Coming later on:
We saw how to work on a local git repo. Later, let us see how to work with remote repositories. I will add this section once can. In the meantime, check out the nice Pluralsight lecture, from the sources link below. Its awesome for a beginner!
Sources:
Comments