This hands-on exercise walks you through a simple Git workflow.
git init
).git add
).git commit
).Along the above “cycle”, you will also learn a few other things.
git configure
).git status
).git diff
)list version history (git log
)
push local repo to GitHub (git remote
, git push
)
Note that all Git commands start with git
.
Now, let’s get started by checking what version of git we have.
$ git --version
git version 2.7.4
If it’s the first time you use Git, you will need to configure a few things. At minimum, you should tell git your name and email address.
git config --global user.name "John Doe"
git config --global user.email "jdoe@example.com"
I configured my git at global/user level (hence the --global
option). This means the setup applies to all my projects. Other users with different login accounts won’t have my setup.
Display the configuration.
$ git config --global --list
user.name=John Doe
user.email=jdoe@example.com
Check the directory I am currently in (pwd
: path to working directory). pwd
is a Linux command. Windows users can use the cd
command to do the same thing.
$ pwd
/home/jdoe
Create a new directory gitworkshop
in the current directory (mkdir
: make directory).
mkdir gitworkshop
Enter the gitworkshop
directory (cd
: change directory).
$ cd gitworkshop
Create a new local Git project.
$ git init
The above command creates a hidden directory .git
. This is where Git keeps all the version control information for this project. Let’s use tree .git
to list all files in the .git
directory in a tree-like format.
$ tree .git
.git
├── branches
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
A lot of things are already in the .git
directory. More will be added along the way we version control our project. Let’s just note that this is where Git keeps its internal data and don’t worry about the details for now.
Create a new file notes.txt
, and add a line line 1: git is cool.
to it. I’ll use a text editor called nano
. You can use your own favorite text editor.
$ nano notes.txt
Check the content of the notes.txt
file (cat [file]
).
$ cat notes.txt
line1: git is cool.
git status
lists all new or modified files to be committed for version control. If we run this command now, it will tell us that the newly created file note.txt
is not tracked yet.
$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
notes.txt
nothing added to commit but untracked files present (use "git add" to track)
The git status
output also shows that we are “On branch master”. This means we are working on the “master” version history line. “master” is a branch reference name. (Git allows you to create new branches and work on different branch lines. We won’t discuss branching in this handout.)
Now, let’s stage all untracked files using the git add .
command. The .
here tells Git to stage all files in the current directory and sub-directories. Staging is the process of preparing files for version control.
git add .
Now, git status
will tell you that the notes.txt
file is ready to be committed.
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: notes.txt
Commit the changes, i.e. record version history.
git commit -m "initial commit"
[master (root-commit) cff7ab5] initial commit
1 file changed, 1 insertion(+)
create mode 100644 notes.txt
The -m
option allows you to write a commit message.
git status
will tell you “nothing to commit” this time.
$ git status
On branch master
nothing to commit, working directory clean
Check the version history so far.
$ git log
commit cff7ab50f5a9337fb588d584b004f5c8a2e7e39c
Author: John Doe <jdoe@example.com>
Date: Mon Apr 22 17:45:07 2019 -0400
initial commit
The git log
output shows you who and when the commit is done. The long string starting with cff7a
is the commit id that uniquely identifies the commit.
Now, add a new line line2: git is fun.
to the notes.txt file.
$ nano notes.txt
$ cat notes.txt
line1: git is cool.
line2: git is fun.
Check git status
again. We see that Git knows the file has been modified, but it’s not staged yet.
$ 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: notes.txt
git diff
shows differences between tracked files in working directory and those in staging area.
$ git diff
diff --git a/notes.txt b/notes.txt
index 0ba590f..a9fc135 100644
--- a/notes.txt
+++ b/notes.txt
@@ -1 +1,2 @@
line1: git is cool.
+line2: git is fun.
Create a new file handout.txt
, and add a line handout for git intro
to it.
$ nano handout.txt
$ cat handout.txt
handout for git intro
This time, git status
will show an untracked file handout.txt
in addition to the modified tracked file notes.txt
.
$ 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: notes.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
handout.txt
no changes added to commit (use "git add" and/or "git commit -a")
We could stage and commit both changes at the same time. However, suppose the two changes are not related. In this case, it’s a good practice to commit the two changes separately. Stage and commit the change in notes.txt
first.
$ git add notes.txt
$ git commit -m "added line 2 to notes.txt"
[master de81fb9] added line 2 to notes.txt
1 file changed, 1 insertion(+)
Stage/track the new file handout.txt
and commit it.
$ git add handout.txt
$ git commit -m "created handout.txt"
[master 7c0b164] created handout.txt
1 file changed, 1 insertion(+)
create mode 100644 handout.txt
Check the commit history so far.
$ git log
commit 7c0b1647007f408e6f40bde09e8942e6711fbedd
Author: John Doe <jdoe@example.com>
Date: Tue Apr 23 09:38:42 2019 -0400
created handout.txt
commit de81fb9b9fb014ff71533c0c54af812eb4758c27
Author: John Doe <jdoe@example.com>
Date: Tue Apr 23 09:37:19 2019 -0400
added line 2 to notes.txt
commit cff7ab50f5a9337fb588d584b004f5c8a2e7e39c
Author: John Doe <jdoe@example.com>
Date: Mon Apr 22 17:45:07 2019 -0400
initial commit
Now, let’s create a GitHub repo gitworkshop
and push our project to GitHub (see GitHub Create a Repo for detailed instructions). The repo on GitHub is called remote repo. After creating it, we need to add its information (path) to our local repo.
$ git remote add origin https://github.com/jdoe/gitworkshop.git
origin
is the name of the remote repo. You can give it any name, but by convention, people use “origin” for a project’s first remote repo (you can have multiple remote repos for a project). https://github.com/jdoe/gitworkshop.git
is the path to remote repo. Within the path, jdoe
is the GitHub username. gitworkshop.git
is the remote repo on GitHub.
We are ready to push the local repo to remote.
$ git push -u origin master
This pushes your master branch (“your master history line”) to the remote repo origin
. The -u
option adds a upstream tracking reference. Next time (when you are on master branch), you only need to type git push
to push new version history to the remote repo. Git knows it must be the origin/master you are pushing to.
Let’s check the version history again. This time we’ll use --oneline
option to make the output concise, and --decorate
option to print out reference names.
$ git log --oneline --decorate
7c0b164 (HEAD -> master, origin/master) created handout.txt
de81fb9 added line 2 to notes.txt
cff7ab5 initial commit
We can see we have three commits so far. We are currently (HEAD
) at our last commit (ID starting with 7c0b164
) on the “master” history line (master
branch). This is also where our remote repo’s master branch (origin/master
) is.