Practice 3: Git commit history
By the end of this practice, you will have:
- Forked an existing repository
- Browsed the commit history of an existing repository
- Restored a previously removed file
- Changed order of commits
- Changed history to omit a commit
Last time: common problems
1. Committing too much
As a rule of thumb, when you're not sure what a commands arguments do, don't add them. In the first practice session, we used the command git commit -a -m "message"
to commit changes. In this command, the -a
arguments stands for "all" and it automatically adds all unstaged files to the commit. That means that if you use this command, ALL of the changes are automatically added to the commit, not only the ones that you staged for commit. This mistake is easily fixed with the tools introduced in today's lecture, if you notice the problem early on, but it's even better not to create this situation in the first place.
Use the bare minimum of arguments and be sure that you know what they do. If you're not sure, consult git manual.
2. Initing a BARE repository
Several students had confusion about bare vs regular repositories. Typically when you create a repository, you use the command git init
. Let's look at an example.
First, we have an empty directory named "project":
If we initialise a repository within this directory, Git creates a hidden directory called ".git".
This directory is the heart of the Git repository. The contents of this directory are files and folders responsible for the way this Git repository works and the databases of the objects contained in this Git repository.
The directory "project", in which we initialized the repository, contains the working copy of this repository. If we create, stash and commit changes in this directory, they are being added to the repository that we created.
---
Now, if we are to initialize a BARE repository in an empty directory, what is created is not the .git directory, but the INTERNALS of the .git directory
Essentially, we tell Git that this directory is the repository itself and directly contains the internal data structures and databases. This kind of repository doesn't have a working copy and cannot be directly worked with. It can be cloned into a different location or used as a REMOTE. Typically these kinds of BARE repositories are created on central servers and used as REMOTES of normal repositories for backup.
In conclusion
Use git status
before any action, as often as possible. This way, you will learn the consequences of various Git commands and learn how data changes in a repository. Before using a command or argument that you're not familiar with, consult the instructor or documentation and make sure you are in the correct directory.
Commit history
This time, you will be working with an existing repository that already has some commits.
- Go to https://github.com/Stopa/cse-prac3-history . This is the repository you will be using for this practice session. But everyone should make their own copy to work with it. In the open source community, making your own copy of an existing repository for your own modifications is called "forking".
- Click the "Fork" button in the top right corner. This will copy the whole repository to your own Github account.
- Clone the repository to your computer. Make sure that you are cloning the copy that was created on your account, not the original repository linked in the beginning of the session.
- Look at the commit history of this repository, using gitk; the git-log tool; Github website or any other tool. How many commits are there in total? When was the last commit made? Who is the author of those commits? What changes were made in the commit with the SHA-1 hash
cebfb97
? Write the answers to those questions into a fileanswers.txt
and commit it to the repository (Hint: usegit add answers.txt
to stash the changes andgit commit
to commit the changes). - This repository used to have a file called
config.txt
. Find when the file was removed and check it out from a commit where it is still present:
$ git log -- config.txt $ git checkout <hash> config.txt
- Add and commit config.txt to the repository.
- Look at the full commit history of the repository. There are commits that add the files "1", "2" and "3", but they are in reverse order and there is an unwanted commit ("Added unnecessary file") between them. Let's use
git rebase
to reorder the commits and drop the unwanted one.
- Find out how many commits into the past you need to go to get access to the commit with the message "Added file 3". Start an interactive rebase from that time>
$ git rebase -i HEAD~<number>
- In the rebase script, change the order of the commits so that the file "1" is being added first, "2" second and "3" last. To remove the unwanted commit, either comment it (by starting the line with a
#
) or choose thed
ordrop
command.
pick 99aa66d Added file 1 pick 8e77a76 Added file 2 pick 605bfe9 Added file 3 drop 75312b8 Added unnecessary file
- Save the rebase script and exit the editor
- Look at the commit history (
git log --oneline
). The commits should now be in the correct order and the unwanted commit should be missing. Notice that you also no longer have the fileunnecessary.txt
(ls -la
).
- Push the new history to your remote. Use the following command. Remember, that this command rewrites the history on the remote end and in real life you should almost never use it, because if you're not sure what you're doing, you may overwrite and completely delete other people's work.
$ git push -f origin master