This repository contains a few practice assignments on git.
First, setup git and create a github account as explained in the slides.
Execute the following steps to practice various topics covered in the intro to git session
Fork the repository using the fork icon.
Clone the forked repository into a directory of your choice in your local machine using the command git clone <url_of_forked_repository>
Create a branch with name myFirstBranch using the command git branch myFirstBranch
Now switch to the new branch using the command git checkout myFirstBranch
As shown in the above image, the branch gets changed from main to myFirstBranch
The above two steps can be performed at once by using the command git checkout -b "myFirstBranch". This command creates a new branch with the name specified in the quotes and switches to that branch.
Add a sentence of your choice to the sample.txt file (Ex : Hi I am <your_name>) and add a new text file named new.txt
This is how the cloned repository on your local machine should look after doing the above two changes
The newly added file new.txt and any changes made to it will not be tracked, i.e they are not present in git and git does not recognize any changes made to that file. Since sample.txt was already tracked when you cloned the repository from github, git will be aware of all the changes made to that file.
But, the newly added sentence to sample.txt is unstaged, i.e it is not yet marked for commit. In order to stage it, we have to use the command git add
Now, use the commands git status and git diff and see what happens
The above image says that the new sentence added to the file sample.txt is unstaged and the newly added file new.txt is untracked.
When we perform git diff, it does not show new.txt. This is because new.txt is still untracked.
Now use the command git stash followed by git status.
This command is used when we want to have a clean working directory but at the sametime save our changes. All the tracked work gets saved, but the untracked changes remain as it is and they wont be saved.
Carefully observe the difference between the current and the previous output of git status.
Now use the command git stash pop
As we can see, all our changes are back.
Now use the command git stash -u followed by git status.
This time it even stashes the untracked file.
Now again, use the command git stash pop. You will be able to see both the tracked and untracked changes.
Use the command git add --all to stage all the changes
Again use the commands git status and git diff and see what happens
Since all our changes have been staged, git diff does not show anything.
Now, commit the changes using git commit -m "my first commit"
Switch to the main branch by using the command git checkout main
As shown in the above image, the branch changes from myFirstBranch to main
Now merge the other branch with main branch using git merge myFirstBranch
Use the command git remote -v to see all the tracked github repositories
As shown in the image, it only tracks the forked repository
Use the command git remote add upstream <url_of_upstream_repo> to track the upstream repo as well. Then again use the command git remote -v to check if the upstream is being tracked.
Now push all the changes onto your forked github repository using git push origin main
Open your forked github repository and check whether all the changes have been updated.
git log is used to display the commit history of the repository. Try using this command and you will be able to see the commit history of the repository.
git logHowever, the output of the above command may be too verbose. You can use the following command to see a more concise output.
git log --all --decorate --oneline --graphIn the current state, you should see a commit history that looks like this:
Of course, the commit hashes and messages might be different in your case.
Feel free to use the above command to visualize the commits that you are making.
git rebase is used to reapply commits on top of another base tip. This is useful to maintain a linear project history.
Do the following steps for a rebase:
-
Create a new branch called
mySecondBranch(try to recall how to create a new branch). And don't forget to switch to the new branch. -
Add a new text file called
new2.txtand add some text to it. Add and commit these changes. -
Similarly, add a new text file called
new3.txtand add some text to it. Add and commit these changes. -
Now, switch back to the
mainbranch and add another text file callednew4.txtand add some text to it. Add and commit these changes.If you have followed the steps correctly, you should have a commit history that looks like this:
You can verify this by using the
git logcommand. -
Now, rebase
mySecondBranchontomainusing the following commands:git checkout mySecondBranch git rebase main
-
Verify that your commit history now looks like this:
You can use the
git logcommand to verify this.Notice that the commit history is now linear, and the commits from
mySecondBranchhave been reapplied on top of themainbranch. However, the commit hashes will be different before and after the rebase.
In cases where we want to combine the changes from one branch to another, we can use either rebase or merge.
| Merge | Rebase |
|---|---|
| Creates a new commit that combines the changes from two branches | Reapplies the commits from one branch on top of another branch |
| Creates a non-linear commit history | Creates a linear commit history |
| Preserves the commit history of both branches | Rewrites the commit history of the branch being rebased |
Consider this example:
You have two branches, main and branch1. You have made some changes in branch1 and want to combine these changes with the main branch.
If we merge branch1 with main using the following commands:
git checkout main
git merge branch1The commit history will look like this:
Notice that the commit history is non-linear, and the changes from branch1 have been combined with the main branch by creating a new commit. This is a three-way merge.
Instead, if we had rebased branch1 onto main using the following commands:
git checkout branch1
git rebase mainThe commit history would have looked like this:
Notice that the commit history is linear, and the changes from branch1 have been reapplied on top of the main branch. In order to get main up to date with the changes in branch1, we can now merge branch1 with main.
git checkout main
git merge branch1Remember: Now, it would be a fast-forward merge and the linear commit history would be maintained.
git cherry-pick is used to apply the changes introduced by some existing commits. It is useful when you want to apply a one or more commits from one branch to another.
At this point, if you are on main, you will not have the new2.txt and new3.txt files.
If you switch to mySecondBranch, you will have the new2.txt and new3.txt files as well as the new4.txt file.
Now, consider the following scenario:
You want the new3.txt file to be added to the main branch, but you do not want the new2.txt file to be added.
To achieve this, you can use the git cherry-pick command.
-
Use
git logto find the commit hash of the commit where you addednew3.txt.In the example below, the commit hash is
a96bd72.Note: The commit hash will be different in your case.
-
Make sure you are on the
mainbranch and use the following command to cherry-pick the commit:git cherry-pick <<commit_hash>> -
Verify that the changes have been applied to the
mainbranch by using thegit logcommand. You can also verify this by checking that you now have thenew3.txtfile in themainbranch, but not thenew2.txtfile.
git rebase -i is used to interactively rebase commits. This is useful when you want to modify, delete, or combine commits.
Consider the following scenario:
-
Switch to
mySecondBranch. Add a new text file callednew5.txtand add some text to it. Add and commit these changes. -
Edit the
new2.txtfile and add some more text to it. Add and commit these changes. -
Now, you should have the following commit history:
-
You want to rebase
mySecondBranchontomain, but you have already cherry-picked the commit that addednew3.txtto themainbranch.Now, you want the
new2.txtfile in your main branch, but it has two commits associated with it. You want to combine these two commits into a single commit. Moreover, you do not want thenew5.txtfile anymore.Checkout to
mySecondBranch:At this point, if you wanted to modify the commit history of
mySecondBranch, you can use:git rebase -i HEAD~4. Notice thatHEADrefers to the current commit (the latest commit onmySecondBranch), andHEAD~4refers to the commit which is four commits before the current commit (in this case, the first commit onmySecondBranch). This command will not rebase ontomain, but rather onto the commit denoted byHEAD~4. In this case, it will rebase onto itself, effectively allowing you to modify the commit history ofmySecondBranchby interacting with the last 4 commits onmySecondBranch. Note that you need to be careful to not rebase with a number greater than 4 if you have committed for a maximum of 4 times in the current branch, else the commits inmainbefore this branch will also be pulled in and will clutter the commit history.But for now, since you actually want to rebase onto
main, you can use the following command:git rebase -i main
You could also use a combination of
git rebase -i HEAD~4followed bygit rebase mainto achieve the same result. But for now, let's stick to the above command.A new file will open and you will see that it has a list of commits that are being rebased. You can modify this list to combine, delete, or edit commits.
In your case, you might see something like this:
Note:
gitdoesn't show the commit thatadded new3.txt. This is because you have already cherry-picked this commit onto themainbranch.gitis smart enough to know that this commit is already present in themainbranch and does not need to be rebased. If we had usedgit rebase -i HEAD~4, this commit would have been included in the list. -
You need to edit this file to combine the two commits that added
new2.txt. To do this, change the wordpicktodropcorresponding to the commit thatadded new5.txtand change the wordpicktosquashfor the commit thatmodified new2.txt.In case you are in the
viorvimeditor, and you do not know how to use it, you can pressito enter insert mode, make the necessary changes, pressEscto exit insert mode, and then type:wqto save and exit.After editing, the file should look like this:
-
Save and close the file. You will be prompted to enter a new commit message for the combined commit.
Edit the commit message and save and close the file.
The rebase should now be complete, and you should have the following commit history:
Notice that the
new5.txtfile is no longer present, and the two commits that modifiednew2.txthave been combined into a single commit. -
Finally, now that
mySecondBranchis ready, you can merge it with themainbranch. As you have already done a fast-forward merge, you can now try doing a three-way merge.Switch to the
mainbranch and use the following command to mergemySecondBranchwithmain:git merge mySecondBranch --no-ff
Git will open an editor to enter a commit message. You can use the default message by saving and closing the file.
You should now have the following commit history:
Now that you have completed all the steps, you can push the changes to your forked repository using the git push origin main command
Open your forked github repository and check whether all the changes have been updated.














