We work with the Feature Branch Workflow, basically a central repository that we create branches from. When we're working on bugfixes and small patches we will create a branch off of master:
git checkout -b master_bug123 master
When we're done with our commits, we do the following to merge it back in:
git checkout master
git pull
git merge master_bug123
git branch -d master_bug123
Sometimes we have big projects that we need to all work on. For instance, making the site responsive:
git checkout -b responsive master
git push -u origin responsive
Then other members of the team can make their own feature branches like with the master:
git pull
git checkout -b responsive_fixmenu responsive
Currently, we're working on here, then to merge the changes back in for others to use:
git checkout responsive
git pull
git merge responsive_fixmenu
# possibly fix conflicts, add, commit, etc
git push -u origin responsive
Sometimes we find that code is going missing. My initial thought is that it might be down to one of us incorrectly resolving conflicts. When investigating though, I'm a bit confused. One particular file named core.js
was missing a large chunk of code. In the file contained a string mb-search
which I thought I could use as part of a git show
and grep
to see when it appeared and was removed. Using git log core.js
I am given a list of commits, then I use that list to do something like git show abc1234:path/to/core.js | grep -c 'mb-search'
to output how many times it appears in the file for that commit, but what that shows me is not a simple 0, 0, 0, 1, 1, 1, or even a 0, 0, 1, 1, 0 (which point it was deleted by mistake), but a quite random looking 0, 0, 1, 0, 1, 0, 0, 1, etc.
This leads me to the first part of my questions. Am I right in saying that if another user comes along and makes changes and makes a commit (let's call it abc1111), then does a git pull
(merging in other pushed changes) which creates a merge commit (let's call it abc2222 - where the mb-search is merged in), then commit abc1111 will not contain the mb-search
code that was later merged in with abc2222, after it has been pushed? If so, how can I reliably tell when some code was deleted?
This leads me on to rebase
. Before we were using the responsive
branch in the same way as the master
branch, we used to just make changes directly to responsive
, commit and push. At the time we were using rebase
by default. At this point we were finding we had a lot of problems, as I'm sure would be expected. As beginners using git, trying to get to grips with the basics, we decided to just use merge
and never rebase
and we thought we were problem free. However now I'm seeing the above problems, I', wondering if the above could be fixed (or at least helped) by using rebase
instead, but only in specific conditions.
I think before we were rebasing on the main responsive
repository so commits were all over the place, code missing, etc, generally what you'd expect from someone who doesn't yet grasp the rebase rules properly. However, would this be a legit use of rebase, and safe?
git checkout -b responsive_somefeature responsive
# write code, make commits
git pull --rebase responsive
git checkout responsive
git merge responsive_somefeature
Am I right in saying this would base all my new work in responsive_somefeature
on the HEAD
of responsive
, so that when I merge it back in it will be linear? Is the last merge
correct, or should/could that be a rebase
also?
What Does Git Rebase Do? A Git rebase changes the base of the developer's branch from one commit to another, so it looks like they have created their branch from a different commit. Internally, Git creates a new commit and applies it to the specified base.
In summary, when looking to incorporate changes from one Git branch into another: Use merge in cases where you want a set of commits to be clearly grouped together in history. Use rebase when you want to keep a linear commit history. DON'T use rebase on a public/shared branch.
Rebasing is better to streamline a complex history, you are able to change the commit history by interactive rebase. You can remove undesired commits, squash two or more commits into one or edit the commit message. Rebase will present conflicts one commit at a time whereas merge will present them all at once.
It is also very powerful, but sometimes things can go really wrong. One common issue is using git rebase when a branch is outdated and points to an old commit from master. Older branches can lead to a lot of conflicts, making rebase a nightmare.
Am I right in saying ...
Yes: merging a change creates a new commit with two (or more, but usually two) parents. It doesn't re-write either parent to include the other.
If so, how can I reliably tell when some code was deleted?
Not having introduced a feature isn't the same as having deleted it. The following graph following a merge:
base -> abc1111 [foo] -> {merge} abc2222 [with foo and mb-search]
\ /
\-> abc0000 [mb-search] /
Doesn't show abc1111
deleting mb-search. Looking for mb-search_ in that commit won't show it either, though. Basically, you're checking the wrong thing.
Instead, try git blame --reverse base..abc2222
--reverse
Walk history forward instead of backward. Instead of showing the revision in which a line appeared, this shows the last revision in which a line has existed. This requires a range of revision like START..END where the path to blame exists in START.
if you just want to see who deleted the line.
Oh, and your feature branch rebase workflow should probably be:
git checkout -b responsive_somefeature responsive
# write code, make commits
# update local branch
git checkout responsive
git pull
# rebase feature onto updated branch
git rebase responsive responsive_somefeature
## NB. this ^ will leave your feature branch checked out
# finally merge (this should be fast-forward since we just rebased)
git checkout responsive
git merge responsive_somefeature
where it's sensible to do the update & rebase periodically, so you're not working against a stale view of responsive
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With