We’ve come a long way since our first Git command! We’ve learned a lot about basic and advanced Git features and when to use them. But since we are only humans, we’re going to face a lot of problems during our Git journey. Most of these problems are the result of inadvertences, so just being aware of their existence is a big step forward toward avoiding them. But if you still run into them, here are the best solutions!
Repository
The repository is the backbone of your Git experience; everything begins and ends there. It’s very difficult to mess it up, but in the slight chance something bad happens, here are some tips.
Starting over
Change of work computers
Unreadable sectors in hard drive
Unrecoverable errors in “.git” directory
The repository location is the HTTPS or SSH link to your remote repository; you can find it on your GitHub project page.
Cloning has the same effect as initializing a repository but with a big bonus: all history and commits will also be copied on your new local repository. And you won’t need to precise the origin link anymore.
Change origin
Switching between HTTPS and SSH links
Transfer of the repository to another host
Addition of dedicated repository for release or testing
Doing this will allow me to push and pull to-and-from GitHub without providing my username and password. The authentication will be done by two sets of keys: a private key that I keep on my local computer and a public key that I must upload to GitHub. If you are interested in using SSH for your authentication, please head over to GitHub help for more information depending on your Operating System (https://help.github.com/en/articles/which-remote-url-should-i-use). If you decide to keep using HTTPS but what to cache for password so you don’t have to type it all the time, you can use a credential helper. Again, there is more information about this on GitHub help, depending on your Operating System (https://help.github.com/en/articles/caching-your-github-password-in-git).
Caution
If you change your remote name, don’t forget to use the new name for every push and pull action.
Working Directory
You will spend most for your time on the Working Directory, and here again, there’s not a lot of thing you can break.
Git diff is empty
Tip
Using a GUI tool would help you greatly when reviewing changes.
Undo changes to a file
This command will check out the file as it was on the commit and, thus, will change your Working Directory. Careful not to lose any uncommitted changes!
Commits
Most problems will arise when you’ll try to commit your current project. But don’t worry, there is always a simple solution for these kinds of problems. The most important thing to consider is: are the commands you are using destructive? Commands like reset or check out change your Working Directory, so please make sure that you know what you are doing before executing them.
Error in commit
The commit name will change because you are basically changing its content. That’s why you should not amend a commit that you’ve already pushed to a remote branch, especially if somebody else works on that branch. This is rewriting history and you should never do it.
The “-f” option forces Git to overwrite everything on the remote branch and replace it with your current branch history.
Caution
Rewriting history on a branch where somebody else is working is just plain rude and selfish. Don’t do it.
Amending commits should only be used when you want to modify the commit message or add/remove a file. Don’t amend a commit to change code.
Undo commits
If you committed on a branch but then realized it’s the wrong one, you can undo it, but only when you haven’t pushed to a remote branch.
The commit will then disappear, leaving you with some option to stash the changes and apply them to another branch.
Again, this is rewriting history and should not be used if you’ve already pushed to a remote branch.
Branches
You will need to work with branches a lot to have an optimized workflow. When working on a new feature or bugfix, your first instinct should be the creation of a branch. But the more you are getting comfortable with branches, the more you are likely to forget a little detail that can lead to problems. Here are the most common problems that you will encounter with Git.
Detached HEAD
HEAD is a reference to the current checked-out commit, meaning the parent commit of any future commit you will create. Usually, HEAD points to the last commit of the current branch; and all future branches and commits will have it as parent.
When you check out branches, the HEAD will go back and forth between the last commits of the branches. But when you check out a specific commit, you enter a state called “detached HEAD” which means that you are in a state where nothing you will create will be attached to anything. It’s useless then to try to commit during that state as any change will be lost.
Worked on wrong branch
This happens a lot. The situation is usually like this: you receive a task and you are so eager to complete it that you begin to code immediately. You are already an hour into the task when you notice that you were working the master branch all along! Don’t worry, it’s very simple to resolve this.
This will create a new branch with your current changes and check it out. You can then stage your modified files and commit the project.
However, this won’t work if you’ve already pushed the branch to a remote repository; history is history, don’t change it. The only way to fix that is to revert the commit you push and live with that shame all your life.
Catch up with parent branch
When you create a branch from another (usually master), their histories are not linked anymore, so what happens in a branch doesn’t have any incidence on the other. This means that while you are working on your branch, other people can commit on the base branch; and those commits won’t be available to your branch.
If you are still working your branch but are interested in having those new commits on the base branch, you must first have a clean plate, meaning that you must commit your project (or stash your current changes).
The commits on master might introduce conflicts in your branch, so be prepared to get your hands dirty. The resolving of those merge conflicts is the same as what we’ve seen previously: open each conflicted file and choose which code you want to keep; then you can stage them and commit.
If you work on a branch for a long time, it’s a good idea to rebase from time to time, so you aren’t left too far behind the parent branch. Of course, you can face merge conflicts, but those are more and more likely to appear the bigger your changes are. And if you delay rebases for a fear of conflicts, you will only set yourself up for failures because those conflicts will appear again when you’ll attempt to merge the branches anyway. It’s better to deal with small conflicts with a rebase from time to time than have to merge a lot of conflicted files at the same time on merge.
Branches have diverged
This will happen to you if you are using a bad Git workflow. As we said earlier, you should work on your own branch to resolve an issue, because multiple people committing on the same branch is the perfect recipe for disaster.
This results in lost commits and fistfight; don’t ever do this.
Again, this shouldn’t happen if you use a good Git and GitHub workflow.
Summary
This chapter is there to point you to the right solution when faced with common Git problems. Surely, you’ll discover new, harder problems but it’s a good way to start. The main thing to remember is always to check where you are before doing anything, especially committing.
But these problems shouldn’t appear at all if you use the common Git and GitHub workflow. So, let’s rediscover that in the next chapter. We’ve already talked about this in the earlier chapters, but it’s time to review it after you’ve seen all the most used Git and GitHub features.