Adding git rebase and strategies
This commit is contained in:
parent
97e2714495
commit
9fb4a4ef70
1 changed files with 164 additions and 0 deletions
164
posts/revision-control/git-rebase-and-strategies.rst
Normal file
164
posts/revision-control/git-rebase-and-strategies.rst
Normal file
|
@ -0,0 +1,164 @@
|
|||
.. title: Git! Rebase and strategies
|
||||
.. date: 2019-08-10
|
||||
.. slug: git-rebase-and-strategies
|
||||
.. updated: 2019-08-10
|
||||
.. status: published
|
||||
.. tags: git, revision-control
|
||||
.. category: revision-control
|
||||
.. authors: Elijah Lazkani
|
||||
.. description: Getting a little handle on git rebase
|
||||
.. type: text
|
||||
|
||||
In the previous topic, I talked about git remotes because it felt natural after branching and merging.
|
||||
|
||||
Now, the time has come to talk a little bit about ``rebase`` and some good cases to use it for.
|
||||
|
||||
.. TEASER_END
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
This has not changed people, it is still ``git``.
|
||||
|
||||
Rebase
|
||||
======
|
||||
|
||||
In ``git`` there are 2 ways of integrating your changes from one branch into another.
|
||||
|
||||
|
||||
We already talked about one; ``git-merge``. For more information about ``git-merge`` consult
|
||||
the `git basic branching and merging <https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging#_basic_merging>`_
|
||||
manual.
|
||||
|
||||
|
||||
The other is ``git-rebase``.
|
||||
|
||||
While ``git-rebase`` has a lot of different uses,
|
||||
the basic use of it is described in the `git branching rebasing <https://git-scm.com/book/en/v2/Git-Branching-Rebasing>`_
|
||||
manual as:
|
||||
|
||||
"With the ``rebase`` command, you can take all the changes
|
||||
that were committed on one branch and replay them on
|
||||
a different branch."
|
||||
|
||||
In other words, all the commits you have made into the branch you are on will be set aside.
|
||||
Then, all the changes in the branch you are rebasing from will be applied to your branch.
|
||||
Finally, all your changes, that were set aside previously, will be applied back to your branch.
|
||||
|
||||
The beauty about this process is that you can keep your branch updated with upstream,
|
||||
while coding your changes. By the end of the process of adding your feature, your changes are
|
||||
ready to be merged upstream straight away. This is due to the fact that all the conflicts
|
||||
would've been resolved in each rebase.
|
||||
|
||||
.. note::
|
||||
|
||||
Branch and branch often!
|
||||
|
||||
if you merge, merge and merge often!
|
||||
|
||||
or rebase, and rebase often!
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Rebase is used just like merge in our case.
|
||||
|
||||
First, let's create a branch and make a change in that branch.
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ git checkout -b rebasing-example
|
||||
Switched to a new branch 'rebasing-example'
|
||||
$ printf "\n# Rebase\n\nThis is a rebase branch.\n" >> README.md
|
||||
$ git add README.md
|
||||
$ git commit -m "Adding rebase section"
|
||||
[rebasing-example 4cd0ffe] Adding rebase section
|
||||
1 file changed, 4 insertions(+)
|
||||
$
|
||||
|
||||
Now let's assume someone (or yourself) made a change to the ``master`` branch.
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ git checkout master
|
||||
Switched to branch 'master'
|
||||
Your branch is up to date with 'origin/master'.
|
||||
$ printf "# Master\n\nThis is a master branch" >> master.md
|
||||
$ git add master.md
|
||||
$ git commit -m "Adding master file"
|
||||
[master 7fbdab9] Adding master file
|
||||
1 file changed, 3 insertions(+)
|
||||
create mode 100644 master.md
|
||||
$
|
||||
|
||||
I want to take a look at how the tree looks like before I attempt any changes.
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ git log --graph --oneline --all
|
||||
* 7fbdab9 (HEAD -> master) Adding master file
|
||||
| * 4cd0ffe (rebasing-example) Adding rebase section
|
||||
|/
|
||||
* 4f6bb31 (origin/master) Adding the git remote section
|
||||
* 0bd01aa Second commit
|
||||
|
||||
After both of our commits, the tree diverged.
|
||||
We are pointing to the ``master`` branch, I know that because ``HEAD`` points to ``master.
|
||||
That commit is different than the commit that ``rebase-example`` branch points to.
|
||||
|
||||
These changes were introduced by someone else while I was adding the rebase section
|
||||
in the ``README.md`` file and they might be crucial for my application. In short,
|
||||
I was those changes in the code I am working on right now. Let's do that.
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ git checkout rebasing-example
|
||||
Switched to branch 'rebasing-example'
|
||||
$ git rebase master
|
||||
First, rewinding head to replay your work on top of it...
|
||||
Applying: Adding rebase section
|
||||
|
||||
And, let's look at the tree of course.
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ git log --graph --oneline --all
|
||||
* 1b2aa4a (HEAD -> rebasing-example) Adding rebase section
|
||||
* 7fbdab9 (master) Adding master file
|
||||
* 4f6bb31 (origin/master) Adding the git remote section
|
||||
* 0bd01aa Second commit
|
||||
|
||||
The tree lookr linear now. ``HEAD`` is pointing to our branch.
|
||||
That commit points to the ``7fbdab9`` commit which the ``master`` branch
|
||||
also points to. So rebase set aside ``1b2aa4a`` to apply ``7fbdab9`` and then
|
||||
re-applied it back. Pretty neat huh ?!
|
||||
|
||||
My Strategy
|
||||
===========
|
||||
|
||||
I'm going to be honest with you. I do not know the different kinds of merge strategies.
|
||||
I've glazed at names of a few but I've never looked at them closely enough to see which one is what.
|
||||
|
||||
What I use, I've used for a while. I learned it from somewhere and changed a few things in it to make it work for me.
|
||||
|
||||
First of all, I always fork a repository.
|
||||
I tend to stay away from creating a branch on the upstream repository unless it's my own personal project.
|
||||
On my fork, I freely roam. I am the king of my own fork and I create as many branches as I please.
|
||||
|
||||
I start with an assumption. The assumption is that my ``master`` branch is, for all intents and purposes,
|
||||
upstream. This means I keep it up to date with upstream's main branch.
|
||||
|
||||
When I make a branch, I make a branch from ``master``, this way I know it's up to date with upstream.
|
||||
I do my work on my branch. Every few hours, I update my ``master`` branch. After I update my ``master``
|
||||
branch, I ``rebase`` the ``master`` branch into my branch and voilà I'm up to date.
|
||||
|
||||
By the time my changes are ready to be merged back into upstream for any reason, they are ready to go.
|
||||
|
||||
That **MR** is gonna be ready to be merged in a jiffy.
|
||||
|
||||
Conclusion
|
||||
==========
|
||||
|
||||
From what I've read, I use one of those strategies described on some website. I don't know which one.
|
||||
But to me, it doesn't matter because it works for me. And if I need to adapt that for one reason or another,
|
||||
I can.
|
Reference in a new issue