Intermediate Git Exercise (using Git commands)
Intro
- This practice exercise repeats the actions from the Intermediate Git tutorial without the detailed explanations.
- It uses only the Git commands from the command line.
- The next exercise uses the VS Code Source Control GUI.
- Go through the actions one or more times until you are comfortable with all the concepts and commands. Use the CheatSheet as reference.
Log alias
Make sure you have aliases for online and graph logs:
- Set alias to log on one line, so you can enter: git olog
- git config --global alias.olog 'log --oneline'
- Set alias to log on one line with commits indented by branch, so you can enter: git glog
- git config --global alias.glog 'log --graph --oneline'
Reset Git back to the beginning of the tutorial:
- The Git/GitHub tutorial series uses the git-demo project to demonstrate the concepts.
- To reset the project back to the beginning of the Intermediate Git tutorial enter:
- git reset --hard v1-beginning-git
- Then delete the tag:
- git tag -d v1-beginning-git
- Delete the practice branch:
- git branch -D practice
Intermediate Git (using Git Commands)
Tags
Add tag to last commit from Beginning Git project.- git glog to get the list of commits.
- git tag v1-beginning-git Add tag to last commit.
- git glog Tag is listed in the log
- git tag -l List tags in alphabetical order. We just have the one.
- git tag -d v1-beginning-git Delete the tag.
- git tag -am 'Beginning Git' v1-beginning-git Add tag again, with a message annotated.
- git tag -ln List all tags including the message.
Merge Conflict
Create a conflict then resolve it.
- Check out a new branch called feature3:
- git checkout -b feature3
- Add file feature3.txt, modify app.txt, and save them:
feature3.txt
Some text.
app.txt
This is a demo app to learn Git.
Second line modified.
Third line modified in feature3 branch.
Feature 1.
Feature 2. Feature 3.
- Stage and commit the changes in the branch:
- git add .
- git commit -m 'Add feature 3'
- Switch branches back to main:
- git checkout main
- Make conflicting change to app.txt:
app.txt
This is a demo app to learn Git.
Second line modified.
Third line modified in main branch.
Feature 1.
Feature 2.
- Stage and commit the change in the main branch, then log the commits:
- git commit -am 'Modify app.txt'
- git log --graph --oneline
- The feature3 branch is now out of sync with main, and has a conflict.
- Switch back to feature3 branch then log the commits. You will see they are out of sync:
- git checkout feature3
- git log --graph --oneline
- Try to sync feature3 branch with main by merging in the new commit in the main branch. Resolve the conflict:
- git merge main
- Click
Resolve in Merge Editor
button. - The two versions are shown side by side. You can accept one or the other. Click "Accept combination" to combine them. And customize the line to read:
- Then click the
Complete Merge
button. - Enter git status
- The app.txt file is in the staging area with the changes we just merged in. Go ahead and commit them:
- git commit -m "Resolve app.txt merge conflict"
- git log --graph --oneline The log will show the added commit.
Third line modified in main branch and modified in feature3 branch.
- Switch branches back to main and merge in feature3, then delete the feature3 branch:
- git checkout main
- git merge feature3
- git branch -d feature3
Add log alias
- Create an alias for the git log with the graph and oneline options:
- git config --global alias.glog 'log --graph --oneline '
- View the commit log: git glog
- In the Beginning Git tutorial we made an alias that logs the commits on one line: git olog
- If you don't have that alias, make it now:
- git config --global alias.olog 'log --oneline '
Git Undo/Redo
Rename and Delete files with Git commands
You can rename and delete files with your text editor, with Unix commands, or with Git commands.
The Git commands will automatically stage the changes. They use similar syntax as the Unix commands.
- Create and check out a branch named practice: git checkout -b practice
- Rename file3 to file3b and stage it with one command: git mv file3.txt file3b.txt
- Delete file4: git rm file4.txt
- git status will show the changes are staged and ready to commit.
Unstage Changes
- The changes are in the staging area. There are two git commands you can use to move them back to the Working Directory (i.e., unstage them):
- Git restore with the stages option: --stages is the long option, -S is the short option.
- git restore --staged . | git restore -S . Use . as the argument to unstage all files.
- git restore --staged filename Or list specific files to unstage.
- The git reset command also unstages all changes:
- git reset
- git status Check the status to confirm they are back in the Working Directory (unstaged).
Discard changes from the Working Directory - restore command
- Git status shows you have two tracked files with changes in the working directory.
- Discard the changes with git restore followed by the file name or a dot for all files in the working directory:
- git restore .
- git status shows the changes in the working directory are gone. Note, the restore command won't delete untracked files so file3b will still be there.
Delete untracked files from the Working Directory - clean command
- You can delete untracked files like file3b manually from the Explorer sidebar.
- git clean -n will show what files will be deleted without actually deleting them.
It tells us that file3b would be deleted.
- To actually delete it, enter git clean then the force long or short option:
git clean --force | git clean -f
- git status Shows the working directory and staging areas are clean.
Amend the last commit
- Add a file called practice.txt with some text.
practice.txt
Some text.
- Stage and commit the changes:
git add .
git commit -m 'Add practice.txt'
git commit -m 'Add practice.txt'
- Add a line to the file and save it:
practice.txt
Some text. Second line.
- git add . Add the changed file so the staging area.
- git olog -3 Log last 3 commits.
- git status Shows the staged change
- Amend the last commit to include this change:
- git commit --amend -m 'Add practice feature' Changes the commit message.
- git commit --amend --no-edit Keeps the original message.
- git status Status shows there is nothing to commit and the working tree is clean.
- git olog -3 Logging the last 3 commits shows the last commit was replace with this amended commit.
Commit identifiers: commit id, refs (branch, tag, remote name), head
- git show head Head is the identifier for the last commit in the current branch.
- git show head^ Get the second to last commit.
- git show head^^ | git show head~2 Get third to last commit.
Revert - Reverse a commit with a new commit
- The last commit added the practice.txt file.
- Undo the last commit by reversing it with a new commit.
- git revert head
- The commit message is at the top of the auto-generated COMMIT_EDITMSG file. You can modify it or leave it as is. Let's leave it as is. Closing the file will apply the message and commit the revert changes.
- git olog -3 Shows that a new commit was made, and the prior commit remains in the commit history.
Reset - Undo commits
- Clear the screen and log the last three commits again:
- clear | Cmd+K
- git olog -3
- To undo a commit use the reset command passing in the last commit you want to keep as the argument. All commits after that will be undone like they never happened. Head^ removes the last commit.
- Our last commit is the one that reversed the one before it. Let's undo it with the reset command. We have three options:
- git reset --soft head^ Removes the last commit and puts all changes in the staging area.
- git reset head^ Removes the last commit and puts all changes in the working directory.
- git reset --hard head^ Removes the last commit and discards all changes.
- Enter the last option to remove the commit and discard the changes:
- git reset --hard head^
- git olog -2 Shows that the previous last commit has been removed.
- git status Shows there is nothing staged or in the working directory.
- Undo the next commit that added practice.txt and put those changes in the working directory:
- git reset head^
- git olog -1 Logging just the last commit will show the "Add practice.txt" commit is gone.
- git status Shows the practice.txt file is unstaged, in the working directory.
- Add the file to the staging area and commit it again:
- git add .
- git commit -m 'Add practice.txt'
- git olog -2 The log shows the Add practice.txt commit is back, with a different commit number.
- Enter the reset command again, and put the changes from that commit in the staging area:
- git reset --soft head^
- git olog -1 The log will show the Add practices.txt commit is gone again.
- git status Shows the practice.txt file is unstaged, in the working directory.
- Commit it again:
- git commit -m 'Add practice.txt'
- git olog -2 The log will show the commit is back, with a different commit Id.
Rebase - Change prior commits: reorder, combine, change message, edit, delete
- We are still in the practice branch with just one commit. Add the below additional changes and commits:
practice2.txt
Some text.
- git add .
- git commit -m 'Add practice2'
- And a practice3 file, with some text. Stage it and commit it.
practice3.txt
Some text.
- git add .
- git commit -m 'Add practice3'
- Clear the screen and log the last four commits. The 4th commit is the last commit from the main branch
- clear | Cmd+K
- git olog -4
- Use the rebase command to change the order of the commits after the commit in the argument, so we will rebase the three commits in the practice branch.
- git rebase -i main
- Change the commit order: Cut and paste the practice2 commit below practice3. Save the file and close it.
- git olog -4 will show that the order has changed.
- Use rebase to change the commit message of a prior commit:
- git rebase -i main
- Change message on last commit. Change "
pick
" to "reword
" or "r
" then save the file and close it. - The commit edit message file will open. Change commit message to "
Add practice2 reworded
". Then save and close it. - git olog -4 will show the commit message has changed.
- Use rebase to combine two commits:
- git rebase -i main
- Combine the last two commits. On the bottom commit change "
pick
" to "squash
" or "s
". Save and close it. - When the the commit edit message file opens, change commit message to "
Add practice2 and practice3
". Save and close it. - git olog -3 will show the last two commits were combined into one.
- Use rebase to edit a prior commit:
- git rebase -i main
- Edit the first commit in the branch. Change "
pick
" to "edit
" or "e
". Save and close the file. - In the practice.txt file, add a "Third line" and save it.
practice.txt
Some text. Second line. Third line.
- Add the changes to the staging area then make an amended commit:
- git add practice.txt
- git commit --amend
- Optionally modify the commit message to "
Add practice.txt amended
". Save and close the file. - Once you are done with your changes run git rebase --continue
- And we got a message saying our rebase was successful.
- Log the result: git olog -3
- Use rebase to delete a prior commit:
- git rebase -i main
- Delete the first commit from the practice branch by changing pick to "drop" or "d", or just delete the line. Save and close the file.
- git olog -2 Logging your latest commits will show the Add practice.txt commit is gone.
Abort Rebase
Create problematic rebase by including commits from both the practice and main branches:- git rebase -i main^
- Try to reword the commit from the main branch by changing "pick" to "r" on the commit at the top from the main branch. Save it and close the file.
- It will give you a merge conflict message.
- Abort the rebase with:
- git rebase --abort
Stash code
- Go back to the main branch then clear the screen
- git checkout main
- clear | Cmd+K
- Add a line to the app.txt file. Then save it.
app.txt
This is a demo app to learn Git.
Second line modified.
Third line modified in main branch and modified in feature3 branch.
Feature 1.
Feature 2.
Feature 3.
Work in progress.
- Stash the change: git stash
- List your stashes: git stash list
- Remove the stash and put it back into your working directory: git stash pop
- You should have no stashes: git stash list
- Discard the change to app.txt: git restore app.txt
- Add the
Work in progress.
line back in app.txt and save the file. - Stash it again but add a message to the stash: git stash -m 'Add line to app.txt'
- Add file named feature4.txt.
feature4.txt
Some text.
- Stash the file. Add the -u option because the file is untracked. Include a message:
- git stash -um 'Feature 4'
- git stash list List the stashes.
- git stash show 1 Show information about the stash with index 1.
- git stash show 1 -p If you add the -p option it will show the specific changes.
- git stash apply 0 Retrieve the stash code without deleting the stash
- git stash list Shows the feature4 stash is still there.
- git stash drop 0 Will delete the stash with index 0.
- git stash list Feature4 stash is gone.
- git stash -um 'Feature 4' Stash it again.
- git stash clear Removes all stashes. Our feature4 is now completely gone.
- git stash list Returns nothing.
Add tag to last commit
- Add a tag to the last commit with a tag message.
- git tag -am 'Intermediate Git' v2-intermediate-git
- List all your tags: git tag -l
- List all your branches (main and practice): git branch
- Log all your commits: git glog