Git is a gentle beast, but beasts are wild, and they require taming, here are some tips to resolve 99% of git problems.
Working with developers of different experience levels made me realize we should have a simple suitable method to resolve all possible issues when working on a git project, that's why I wrote this tutorial in the first place.
At my company, we follow a small variation of git flow, where there are no develop branch, but a release one
that gets merged every sprint with master and gets recreated for the next sprint until we merge again, deploying automatically to production.
We did this variation because we found out that keeping the develop branch neat and clean when there are different levels of git knowledge in the company is challenging.
We use git fetch to update our git database locally, so we have the latest changes. In case of doubt, we always rebase and create branches from origin, never from a local branch because we might mess up.
When developing a feature, we always use rebase to update our current feature from release. We squash the feature branches into one commit, so it's easy to rollback a feature once it is reviewed and ready to merge.
# Being on the feature/my-tasty-feature branch git fetch origin git rebase origin/release
Creating a feature branch:
# Being on master or release or any other branch different from the one created git fetch origin git checkout -b feature/my-tasty-feature origin/release
We need to update our code with release because we don't have the latest changes. In our feature branch we can do:
# Being on the feature/my-tasty-feature branch git fetch origin git rebase origin/release git push -f feature/my-tasty-feature
-f can only be used on an unmerged personal branch. It means force and it rewrites the git history, so we need to be very careful when using it.
We have to rebase from release, we have many commits, and we need to solve several conflicts on different painfully commits, we need to make our branch changes into one!
First, we need to know how many commits do we want to add to release and squash them.
# Being on the feature/my-tasty-feature branch git rebase -i HEAD~5 # where five is the number of commits
We replace all the first lines pick for squash except in the first line and save.
We can change the commit name and put something relevant, save the file.
Now we need to fix the conflict:
# Being on the feature/my-tasty-feature branch git rebase origin/release
We fix the conflicts on our favorite editor and add the files, then
# Being on the feature/my-tasty-feature branch git rebase --continue git push -f feature/my-tasty-feature
In our GitHub pull request we have commits that don't belong to our branch, but are from release, this might happen for two reasons:
- Because we didn't do the first solution
- Because we updated the master branch and some commit hashes have changed (This should seldom happen).
In this case, the best approach (or most straightforward) is usually to rebuild our branch. First, we need to know how many commits do we want to add to release and squash them, so we'll do the second solution entirely.
After doing the second solution, we'll do the following.
# We are on the feature/my-tasty-feature branch git fetch origin git checkout -b feature/my-backup-branch origin/feature/my-tasty-branch # We delete the branch we're going to rebuild locally # We are on feature/my-backup-branch git branch -D feature/my-tasty-branch git checkout -b feature/my-tasty-branch origin/release git log feature/my-backup-branch # We are on feature/my-tasty-branch # We copy the last commit hash (see screenshot below) git cherry-pick the-hash-we-have-copied git push -f origin/feature/my-tasty-branch
These are my tips for people starting on my team when they have problems with Git, what do you think? Would you change anything? Any recommendations?