UFO Sightings Solution¶
bill@gates:~$ git branch green
bill@gates:~$ git branch purple
bill@gates:~$ git switch green
bill@gates:~$ echo "background-color: green;" > style.css
bill@gates:~$ git add style.css
bill@gates:~$ git commit -m "changed background color to green"
bill@gates:~$ git switch purple
bill@gates:~$ echo "background-color: purple;" > style.css
bill@gates:~$ git add style.css
bill@gates:~$ git commit -m "changed background color to purple"
bill@gates:~$ git switch main
bill@gates:~$ git merge purple
bill@gates:~$ git branch -d purple
bill@gates:~$ git branch -D green
Explanation¶
-
First, lets review
git log
(before running the commands above ).bill@gates:~$ git log --oneline b02c4b1 (HEAD -> main) initial commit
-
Create branches using
git branch <branchname>
.bill@gates:~$ git branch green bill@gates:~$ git branch purple
Now we can run
git branch
to see which branches exist and which one we're on (i.e. which branch is referenced by HEAD).bill@gates:~$ git branch green * main purple
We're on main. This is also apparent when we run
git log
.bill@gates:~$ git log --oneline b02c4b1 (HEAD -> main, purple, green) initial commit
-
Switch to the green branch, modify
style.css
, then commit the change.bill@gates:~$ git switch green bill@gates:~$ echo "background-color: green;" > style.css # (1)! bill@gates:~$ git add style.css bill@gates:~$ git commit -m "changed background color to green"
- Here we've modified
style.css
using the shell commandecho
, but you could also edit the file in your favorite text editor.
bill@gates:~$ git log --oneline 2efc22d (HEAD -> green) changed background color to green b02c4b1 (purple, main) initial commit
- Here we've modified
-
Switch to the purple branch, modify
style.css
, then commit the change.bill@gates:~$ git switch purple bill@gates:~$ echo "background-color: purple;" > style.css bill@gates:~$ git add style.css bill@gates:~$ git commit -m "changed background color to purple"
Let's recap. At this point, the full commit tree should look like this.
Let's see if that's what
git log --oneline
shows us.bill@gates:~$ git log --oneline 3d72cab (HEAD -> purple) changed background color to purple b02c4b1 (main) initial commit
Nope. That's because
git log
shows the commit history starting from HEAD. In other words,git log
follows the path backward from HEAD. -
Switch back to main. Then merge with purple.
bill@gates:~$ git switch main bill@gates:~$ git merge purple Updating b02c4b1..3d72cab Fast-forward style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Notice that Git recognizes this as a fast forward merge. In other words, Git just needs to update main's pointer from commit ID
b02c4b1
to commit ID3d72cab
.To see this for yourself, inspect the contents of
.git/refs/heads/main
before and after the merge. -
Delete the purple branch using
git branch -d <branchname>
.bill@gates:~$ git branch -d purple # (1)! Deleted branch purple (was 3d72cab).
-
Delete the green branch using
git branch -D <branchname>
.If we try to do
git branch -d green
(similar to step 6 above ) we'll get an error!bill@gates:~$ git branch -d green error: The branch 'green' is not fully merged. If you are sure you want to delete it, run 'git branch -D green'.
In this case deleting the branch means we'll lose commit ID
2efc22d
forever.Remember, commits point to their parents, not the other way around. So if we lose the green branch, commit ID
2efc22d
won't be reachable from any other commit or branch.By contrast, when we deleted the purple branch, we didn't lose access to any commits because there wasn't anything reachable by purple that wasn't reachable by main.
Since we're super certain we want to delete the green branch, we can force Git to remove it with the
-D
flag.bill@gates:~$ git branch -D green # (1)! Deleted branch green (was 2efc22d).
-D
is an alias for--delete --force
.
garbage collection
Technically, commit
2efc22d
isn't immediately deleted after we delete the green branch. It lives in our git repo until it gets garbage collected . (You can force a garbage collection withgit gc
).