Peter Paul Gualtieri
Peter Paul Gualtieri

Reputation: 71

Reusing a merged development branch / Remerging into an unchanged stable branch with git

Two programmers, A & B, are working on a project with a github hosted repo:

Branch master exists.

Programmer A creates devBranchA based on the latest master

master$ git checkout -b devBranchA

Programmer B creates devBranchB based on the latest master

master$ git checkout -b devBranchB

They decide to merge stable changes into master whenever possible.

The agreed workflow is:

[on devBranch]

git commit -m 'Stuff to make branch stable enough to merge'

git checkout master

git pull origin master 

git merge devBranch [fix merge conflicts if any]

git checkout devBranch

git commit -m 'New cool stuff'

However, if there have been no commits to master since the last merge, it is then not possible to merge the devbranch back into master (unless a new dev branch was created, rather than the old one reused)

In this case, when Programmer B comes to merge his work into the master branch, it will not be the current intended master, but the state of master before the merge.

Is there a way to automatically force the master branch to update itself to the head of the dev branch on merge if there have been no interim commits?

What is the intended multi-user workflow when working with git and a centralised github repo? I feel as though I am not using git as it is intended to be used.

Upvotes: 7

Views: 3064

Answers (2)

VonC
VonC

Reputation: 1329262

You can find another illustration of the two workflow mentioned by Tchalvak in his answer in "git rebase vs git merge".

As explained in "What is the right git workflow with shared feature branches?", I prefer avoiding "back-merge" (from master to devBranch), and would rather rebase devBranch on top of master, provided that:

  • devBranch is regularly merged to master
  • I rebase only new local commits (that I haven't pushed yet).

Upvotes: 0

Kzqai
Kzqai

Reputation: 23102

Check out git fetch;git rebase origin/master or git pull --rebase, both honor the order of the commits in the master repository because it rebases, sticking local commits on top. You don't care about the order of the local commits as much on local branches anyway because only you have them. Try it out, but use with care, e.g. duplicate a branch before rebasing until you're used to it.

In general, you're talking about git workflow, and I've found that there are two general workflows that you should get familiar with. Be aware that I'm talking from personal experience on how to minimize conflicts:

  • Rebase-first workflow (for cleanest commit history, pushes the burden of conflicts generally to uncommitted code)
  • Merge workflow (sometimes simpler when there are a lot of changes that would conflict, I usually use this only as a fallback)

Example Initial workflow

git checkout master // For the sake of argument, let's say the latest commit in your local master is from august 1st or something old like that.
git branch temp_branch // copy of the master
git checkout temp_branch
git add changedFiles;git commit changedFiles; // A change from november 2nd.

git log // Now your dev branch has a new commit on top of an otherwise old branch.

git log origin/master // You get a listing of the commits from the origin repository, the master branch.  

Generally I use origin/master for development staging, with git tags standing for the commits that are made live releases.

Now here's where the problem occurs, and where the choice of workflow comes into play: let's say there's a commit that came from another dev repository up in master, e.g. a commit from october 15th. Maybe it was commited by another developer, maybe by yourself.

Your choices: Merge or rebase.

Merge

Introduces an extra commit, honors your local (unpushed) branched dev history over the canonical (origin/master) history, causes a little more potential for conflicts for others and other branches. Essentially you're saying "my commit order will be mixed with the master branch commit order" as opposed to reordering commit history.

git merge origin/master // merge commit introduced
... // Resolve any conflicts, and finalize the merge commit.
git checkout master;git rebase temp_branch // Move the changes to master.
git push origin/master // Pushing changes, including merge commit, to origin/master

At the end, commit history will look something like: August-October-November-MergeCommit

Rebase

No extra commits, honors commits already in the canonical repository (origin/master) over local commits, conflicts that occur will generally occur on commits that the developer has not yet commited (and thus no-one else can account for).

git rebase origin/master // 
... // Resolve any conflicts...
git rebase --continue or git rebase --abort
... // Resolve any conflicts...
git checkout master;git rebase temp_branch // Get the branch changes without a merge commit into master.
git push // Push all changes to the canonical repository.

Note: If you end up having to do more than two conflict resolutions, -then- it is a good time to git rebase --abort and fall back to doing a merge.


Try out the process, see if it makes sense for you! It takes some experimentation before you can really get tactics that work well for your development in git, I guess because there are so many more approaches once you get decentralized.

Upvotes: 1

Related Questions