4

I'm currently working a very simple git workflow using feature branches and rebasing on to master before pushing.

git checkout -b feature
.. make some commits
git checkout master
git pull

If there are no changes from the pull:

git merge feature
git push

If there are changes:

git checkout feature
git rebase master
git checkout master
git merge feature
git push

While has been great to learn how git works but it's getting a little tedious to type all the time and I suspect there's some faster ways to achieve what I'm doing but can't find them.

Nigel Sampson
  • 10,549
  • 1
  • 28
  • 31
  • You should check the examples from the [git-rebase man page](https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html), instead of a checkout followed by rebase you could simply do `git rebase master feature`. But see [my answer](http://stackoverflow.com/a/20420258/321973) for an even simpler way... – Tobias Kienzler Dec 06 '13 at 09:25
  • By the way, do you know ["A successful Git branching model"](http://nvie.com/posts/a-successful-git-branching-model/)? Totally worth a read – Tobias Kienzler Dec 06 '13 at 09:28

3 Answers3

4

Your shortest amount of steps had a total of 6 steps (no changes case):

git checkout -b feature
.. make some commits
git checkout master
git pull
git merge feature
git push

This technique should work in both cases (6 steps as well):

git checkout -b feature
.. make some commits
git fetch
git rebase origin/master
git checkout master
git merge feature
cforbish
  • 8,567
  • 3
  • 28
  • 32
  • For the last rebase step I'd suggest using `git merge --no-ff` so work can easily be identified. This avoids fast forward. – steadweb Oct 24 '14 at 09:35
2

Well, you could use git pull --rebase after merging, which does just that:

-r --rebase

Rebase the current branch on top of the upstream branch after fetching. If there is a remote-tracking branch corresponding to the upstream branch and the upstream branch was rebased since last fetched, the rebase uses that information to avoid rebasing non-local changes.

See pull.rebase, branch.<name>.rebase and branch.autosetuprebase in git-config(1) if you want to make git pull always use --rebase instead of merging.

Note

This is a potentially dangerous mode of operation. It rewrites history, which does not bode well when you published that history already. Do not use this option unless you have read git-rebase(1) carefully.

So in summary:

git branch -b feature
...
git checkout master
git merge feature  # By the way, merge's --no-ff might interest you
git pull --rebase  # rebases feature onto the new-fetched head if necessary

Just one note: The result of this is slightly different from your way if you made changes to master as well, since git pull --rebase rebases all your changes since the last pull/push onto the pulled HEAD, while you way would cause the pulled changes and your master changes to be merged and then feature be rebased upon that. This is mostly irrelevant (and personally I prefer not having unnecessary pull-induced merges in my history) but you should be aware of it nonetheless...

In pictures, before:

 /-O          origin/master
C--A--B       master
    \--F--G   feature

After your way:

 /-O-----\  
C--A--B--C*-----(FG)  (origin/)master - fast-forward merge (unless --no-ff)
          \-F-G-/     feature (rebased!)

git pull --rebase way:

 /-O
C--A--B--M*  => C--O--A--B--M*  (origin/)master
   \-F-G-/                      feature (not rebased!)

If instead you want the end result to be

C--O--A--B--F--G

use

git branch -b feature
...
git checkout master
git rebase feature
git pull --rebase

Also note how much fun you can have with git-rebase -i ;)

Tobias Kienzler
  • 25,759
  • 22
  • 127
  • 221
2

probably a nice alias could improve your workflow a little bit, I use this one

# full rebase
frb = "!sh -c 'x=`git rev-parse --abbrev-ref HEAD` && echo "rebasing to $0 ..." && git rebase $0 && git checkout $0 && git rebase $x'"

usage (on feature branch):

git frb master

of course you could also add a checkout at the beginning and push at the end

... tested on git 1.9.3 (osx), not tested what happens if there are conflicts

Marcel
  • 4,054
  • 5
  • 36
  • 50