Working inside a repository
The setup script is located in the git.zip file
in the exercsises folder
. Run ./working.sh
for
setup!
Introduction
In this exercise we will perform some basic task, like committing, partially staging and also some reset.
First we run git status --short
or will use the provided
alias for this git st
and compare it to
git status
.
$ git status --short
M partially_stage.txt
?? commit_me.txt
?? do_not_stage.txt
?? stage_me.txt
compare this to git status
$ git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: partially_stage.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
commit_me.txt
do_not_stage.txt
stage_me.txt
no changes added to commit (use "git add" and/or "git commit -a")
it is quite a bit shorter.
The first column in the short status indicates the index (stage), the second the working tree (working directory).
$ git log --oneline
b460609 (HEAD -> main) initial commit
shows one commit present already.
Stage and commit a file with a full commit message
The first task is to stage and commit the commit_me.txt
file. And add the following commit message:
add commit_me.txt
Added the file because I was asked to.
Questions
After you completed the task:
- Run
git status --short
again, how has it changed? - Run
git log --oneline
, what is your commit message? - Run
git log --pretty=full
which is the default forgit log
, what is your commit message?
Walkthrough
$ git add commit_me.txt
$ git status --short
A commit_me.txt
M partially_stage.txt
?? do_not_stage.txt
?? stage_me.txt
We now see, commit_me.txt
is added to the index
(staged).
git commit
The editor of your choice opens. You can change the default editor
using git config --global core.editor XXXX
.
Inside this editor add this commit message
add commit_me.txt
Added the file because I was asked to.
save and exit the editor. Now, answer the questions.
Partially staging a file
Stage the file stage_me.txt
and partially stage the file
partially_stage.txt
then commit.
The only changes from partially_stage.txt
to be
committed must be do stage this line
. In the end it should
look like
do stage this line
Hint
There are two ways to do this. Either use
git add -p filename
to partially stage a file or use
git add -i
to be fully interactive and select the
patch
option when you have to.
Walkthrough
$ git add -i
staged unstaged path
1: unchanged +3/-1 partially_stage.txt
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now> a
staged unstaged path
1: do_not_stage.txt
2: stage_me.txt
Add untracked>> s
staged unstaged path
1: do_not_stage.txt
* 2: stage_me.txt
# press enter again to exit adding
Add untracked>>
added 1 path
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now> s
staged unstaged path
1: unchanged +3/-1 partially_stage.txt
2: +1/-0 nothing stage_me.txt
What now>p
staged unstaged path
1: unchanged +3/-1 partially_stage.txt
Patch update>> 1
staged unstaged path
* 1: unchanged +3/-1 partially_stage.txt
# press enter to start patching
Patch update>>
diff --git a/partially_stage.txt b/partially_stage.txt
index b9d3530..a31e092 100644
--- a/partially_stage.txt
+++ b/partially_stage.txt
@@ -1 +1,3 @@
-already tracked
+do not stage this line
+do stage this line
+but not this
(1/1) Stage this hunk [y,n,q,a,d,e,p,?]? ?
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
e - manually edit the current hunk
p - print the current hunk, 'P' to use the pager
? - print help
# we do not want to commit the whole hunk, so we edit it
(1/1) Stage this hunk [y,n,q,a,d,e,p,?]? e
# inside your editor edit the file to look like
@@ -1 +1,3 @@
-already tracked
+do stage this line
# save and exit
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now> q
Now we should see a staged file stage_me.txt
and a
staged and modified file partially_stage.txt
.
$ git status --short
MM partially_stage.txt
A stage_me.txt
?? do_not_stage.txt
But what will be committed?
$ git diff --staged
diff --git a/partially_stage.txt b/partially_stage.txt
index b9d3530..2c938aa 100644
--- a/partially_stage.txt
+++ b/partially_stage.txt
@@ -1 +1 @@
-already tracked
+do stage this line
diff --git a/stage_me.txt b/stage_me.txt
new file mode 100644
index 0000000..63bda91
--- /dev/null
+++ b/stage_me.txt
@@ -0,0 +1 @@
+use complete file
Now commit with a message.
git commit -m "partially staged"
Amending a commit
Now, create an empty file forgotten.txt
and add it to
the last commit you make. What happens to the commit hash of this
commit?
Walkthrough
$ git log --oneline
dec3fed (HEAD -> main) partially staged
0173e3b add commit_me.txt
e8886bd initial commit
$ touch forgotten.txt
$ git add forgotten.txt
$ git status --short
A forgotten.txt
M partially_stage.txt
?? do_not_stage.txt
$ git commit --amend
# the editor opens again, this time exit without changes
$ git log --oneline
3bfd8f7 (HEAD -> main) partially staged
0173e3b add commit_me.txt
e8886bd initial commit
The commit hash changed! We have a totally new commit.
Reflog
Run git reflog
. What do you see? Can you spot the amend?
Then run git log -g
to print the reflog in a different
style.
$ git reflog
3bfd8f7 (HEAD -> main) HEAD@{0}: commit (amend): partially staged
dec3fed HEAD@{1}: commit: partially staged
0173e3b HEAD@{2}: commit: add commit_me.txt
e8886bd HEAD@{3}: commit (initial): initial commit
$ git log -g
commit 3bfd8f73691e3645a184acdd9815fba2354c9e85 (HEAD -> main)
Reflog: HEAD@{0} (maschmi <maschmi@maschmi.net>)
Reflog message: commit (amend): partially staged
Author: maschmi <maschmi@maschmi.net>
Date: Sun Jun 8 14:47:58 2025 +0200
partially staged
commit dec3fed8ca4c8067bac9a726f9eb35132c6e7d74
Reflog: HEAD@{1} (maschmi <maschmi@maschmi.net>)
Reflog message: commit: partially staged
Author: maschmi <maschmi@maschmi.net>
Date: Sun Jun 8 14:47:58 2025 +0200
partially staged
commit 0173e3b0059ee5b8fd4657a3979f47ad1f8e8431
Reflog: HEAD@{2} (maschmi <maschmi@maschmi.net>)
Reflog message: commit: bla
Author: maschmi <maschmi@maschmi.net>
Date: Sun Jun 8 14:34:10 2025 +0200
add commit_me.txt
Added the file because I was asked to.
commit e8886bd47b9636c24573b36d6ecde46538251482
Reflog: HEAD@{3} (maschmi <maschmi@maschmi.net>)
Reflog message: commit (initial): initial commit
Author: maschmi <maschmi@maschmi.net>
Date: Sun Jun 8 14:34:00 2025 +0200
initial commit
In both logs we can see the amend.
Detached Head
Git stores snapshots and not changes. Can you load such a snapshot?
We will load the snapshot form our original commit with the message
partially tagged
.
Use reflog to find the original commit hash, check it out and then checkout main again.
Questions
- What is detached head mode?
- How does your reflog look after moving back to main?
Walkthrough
$ git checkout dec3fed
M partially_stage.txt
Note: switching to 'dec3fed'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at dec3fed partially staged
$ git checkout main
M partially_stage.txt
Warning: you are leaving 1 commit behind, not connected to
any of your branches:
dec3fed partially staged
If you want to keep it by creating a new branch, this may be a good time
to do so with:
git branch <new-branch-name> dec3fed
Switched to branch 'main'
$ git reflog
3bfd8f7 (HEAD -> main) HEAD@{0}: checkout: moving from dec3fed8ca4c8067bac9a726f9eb35132c6e7d74 to main
dec3fed HEAD@{1}: checkout: moving from main to dec3fed
3bfd8f7 (HEAD -> main) HEAD@{2}: commit (amend): partially staged
dec3fed HEAD@{3}: commit: partially staged
0173e3b HEAD@{4}: commit: bla
e8886bd HEAD@{5}: commit (initial): initial commit
Hard reset
There might be situation where you want to reset everything to a specific snapshot. Here you can use a hard reset. Be warned, this will reset your working directory and staged files. Every change will be lost.
Make note of your current directory content and status, then perform
a git reset --hard HEAD
to reset everything to your last
commit.
Question
- How have the content of your directory change? Any idea why it looks like it look?
- What does the
git status
look like?
Walkthrough
$ ls -l
total 16
-rw-r--r-- 1 martin martin 16 8. Jun 14:34 commit_me.txt
-rw-r--r-- 1 martin martin 23 8. Jun 14:34 do_not_stage.txt
-rw-r--r-- 1 martin martin 0 8. Jun 15:11 forgotten.txt
-rw-r--r-- 1 martin martin 55 8. Jun 14:34 partially_stage.txt
-rw-r--r-- 1 martin martin 18 8. Jun 14:34 stage_me.txt
-rw-r--r-- 1 martin martin 0 8. Jun 14:34 working.md
$ git status --short
M partially_stage.txt
?? do_not_stage.txt
$ git reset --hard HEAD
HEAD is now at 3bfd8f7 partially staged
$ ls -l
total 16
-rw-r--r-- 1 martin martin 16 8. Jun 14:34 commit_me.txt
-rw-r--r-- 1 martin martin 23 8. Jun 14:34 do_not_stage.txt
-rw-r--r-- 1 martin martin 0 8. Jun 15:11 forgotten.txt
-rw-r--r-- 1 martin martin 19 8. Jun 15:16 partially_stage.txt
-rw-r--r-- 1 martin martin 18 8. Jun 14:34 stage_me.txt
-rw-r--r-- 1 martin martin 0 8. Jun 14:34 working.md
$ git status --short
?? do_not_stage.txt
Untracked files are not affected, but the modified file is reset.