29

I have a remote repository that I've pulled and am branching from. I want to keep the new branch up to date with changes done to master. I'm thinking about the workflow below, does it make sense or are there are better ways to do this?

  1. Initial branching and checkout:

    git checkout master
    
    git pull
    
    git checkout -b my_branch
    
  2. Do some work in my_branch, then periodically:

    git checkout master
    
    git pull
    
    git checkout my_branch
    
    git merge master --no-ff
    

Repeat step 2 as needed, with periodic pushes to the remote my_branch.

Then when ready for a merge back:

git checkout master

git merge my_branch --no-ff

Sound ok?

user229044
  • 232,980
  • 40
  • 330
  • 338
larryq
  • 15,713
  • 38
  • 121
  • 190

2 Answers2

24

You can simplify your commands:

1.

git fetch
git checkout -b my_branch origin/master

2.

git fetch
git merge origin/master

git fetch updates your remote branches, there usually is no need to have a local copy of a branch when your are not planning to work on this branch.

You can omit the --no-ff after setting git config --global merge.ff false.

git help config says:

   merge.ff
       By default, Git does not create an extra merge commit when merging
       a commit that is a descendant of the current commit. Instead, the
       tip of the current branch is fast-forwarded. When set to false,
       this variable tells Git to create an extra merge commit in such a
       case (equivalent to giving the --no-ff option from the command
       line). When set to only, only such fast-forward merges are allowed
       (equivalent to giving the --ff-only option from the command line).

Be aware that git pull is just a combination of git fetch and git merge.

Usually you just want git pull --rebase which is essentially git fetch plus git rebase, and creates a much cleaner history.

Is there any reason for your "periodic pushes"? If no one else is working on the same branch it would be perfectly fine, just to push after finishing everything.

michas
  • 25,361
  • 15
  • 76
  • 121
  • 1
    Thanks for your (and Christoph's) reply. To answer your question, no reason for the periodic pushes other than to act as a backup in case my box dies. And in case someone wants my code to do their own work with-- not entirely likely, until my code gets into master, plus doing a rebase on a public branch can lead to trouble, so I understand (but am not sure of why exactly.) – larryq Nov 04 '13 at 15:56
  • 1
    rebases are a double-edged sword. on the one hand they often lead to much clearer history. on the other hand they create completely new commits with basically the old content. If you push your commits, someone else could (theoretically) build her own changes on those commits. If you later decide to rebase you commits, you basically invalidate the old commits and all changes build on them. - Even if you remove your old branch, the other one might push his changes and therefore also push your old changes, which will result in duplicate commits and a resuting mess. :) – michas Nov 04 '13 at 18:50
  • 1
    Again, thanks very much. I've been reading about `git pull --rebase` and am not 100% what happens if I call it while currently in (say) `my_branch`. In that circumstance, the command pulls from the `my_branch` remote, and then rebases against...which branch? Not master I'd assume, since I didn't mention it anywhere in the command. So it must be rebasing against `my_branch`, which sounds a little strange to me since I've always rebased two separate branches. But I assume it's possible, and now that I think of it, why not? – larryq Nov 04 '13 at 23:20
  • 2
    `git pull` and `git pull --rebase` both work with the configured upstream (see `git branch -vv`). Typically a local branch "my_branch" will track a remote branch "origin/my_branch". But before you pushed the first time it is perfectly fine to track "origin/master". `git pull --rebase` simply fetches the current version of the upstream branch, resets your branch to that version and replays all commits you did. Hence you result in the same changes only based on the current version of the upstream branch. – michas Nov 05 '13 at 06:59
  • 1
    you can see the rebase at work with `git tag old_state; git pull --rebase; gitk HEAD old_state`. Given you already did some local commits and there are new commits on upstream you should see both your original commits based on the old version of upstream and the rebased commits based on the current version of upstream. – michas Nov 05 '13 at 07:09
14

I would advise to use a rebase workflow. So instead of using git pull you should use git pull --rebase.

I would do the same with the feature branch. So instead of doing a git merge master --no-ff I would use a git rebase master. However, if the feature branch is meant to be shared with co-workers during development, then you are better off to merge the master branch periodically into the feature branch.

But to be honest, I work on a small team and if we need to work on a feature branch together and we need to get it up to date with master then we just suspend our work for a short moment (and communicate the process clearly), rebase on master and force push the feature branch. But yep, that doesn't scale for bigger teams. However, I find it much more convenient to work with a feature branch that is rebased on master instead of having to deal with merges from master.

Make sure to read this.

Git workflow and rebase vs merge questions

Community
  • 1
  • 1
Christoph
  • 26,519
  • 28
  • 95
  • 133