0

I'm developing a system as part of a small team (3 people). The development has been running for a couple of years and probably has about another year to go. We are using git for version control and generally do our development on master, using pull and push.

About six months ago, when I was, maybe, 75% through developing a new feature, project priorities changed and I needed to start on a second feature. Before embarking on the new development, I committed most of the partially-finished development to a new branch - parked. The second feature turned into a third and a fourth - I'm sure you are familiar with the scenario.

We are now almost ready to resume development of the first feature and I'd like to recover the parked code. In the meantime, we have pre-released the system to some users who don't need the (original) first feature.

My instinct is merge the changes from trunk onto the parked branch via

$ git checkout parked
$ git merge origin/master

so as to have somewhere to continue/complete the development and to resolve any problems while we support our external users on master. Eventually (soon I hope) I will merge the changes back from parked to master.

I've found a couple of other questions on stackoverflow that seem to deal with similar questions. Version control - which way to git merge suggests merging from parked to master initially so as to allow use of git log --first-parent; we don't currently make extensive (any) use of this command - are we missing something that might be useful? Which way to merge with git recommends using git rebase; another command that we don't currently use - should we?

I've never used git before starting on this project, but I believe I'm familiar with version control concepts.

I'm still inclined to follow my first instinct and begin by merging from master to parked; complete the development there and then merge the changes to master, but I see there are valid alternatives. I don't at present understand the pros and cons of the alternatives - please could someone explain.

nurdglaw
  • 2,107
  • 19
  • 37

2 Answers2

2

The difference between your question and the one you linked is that parked isn't finished yet. When a feature is finished, then do what that question suggestions: merge your feature branch into master. On the other hand, when you want to update your current work with all the features in master, then you should go the other direction: merge master into the feature branch. This allows you to make sure your work is compatible with the existing features. It also lets you manage possible merge conflicts sooner rather than later.

We are using git for version control and generally do our development on master, using pull and push.

I suggest that for future development you create feature branches. This helps isolate work until it is considered "finished". Once you finish the feature, then merge it into master. For one possible use of feature branches, check out this Q&A on our sister site, Software Engineering.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • Thanks @Code-Apprentice, I rather agree about doing new development on feature branches; I'm not completely confident I'll be able to persuade the other two. – nurdglaw Jul 24 '19 at 22:21
  • @nurdglaw Committing directly to master is often frowned upon, especially in a team environment. In all of my projects, I treat `master` as the final word. Especially after releasing a product, `master` is the most recent release. I also tend to make multiple small, but still coherent, commits when I'm working on a feature rather than just one big commit per feature. – Code-Apprentice Jul 24 '19 at 22:33
2

So you're starting with this situation:

A - B - H - I - J - K - L - M - N - O master & origin/master
      \ C - D - E - F - G parked

By merging parked in now you'll create this situation:

A - B - H - I - J - K - L - M - N - O - P master, origin/master & parked
      \ C - D - E - F - G -------------/

This will mean that master, your development branch, will have unfinished, unreleasable work in it, which isn't ideal if it's going to last any length of time since it makes it harder to get new work out of the door. A big advantage of this approach is eliminates the risk of further merge conflicts and allows you to immediately make use of any components in parked that may be useful elsewhere in the codebase. One way to deal with the unreleasable code would be a feature flag.

Alternatively, by merging origin/master into parked now you'll create this situation:

A - B - H - I - J - K - L - M - N - O  master & origin/master
      \ C - D - E - F - G -----------\ P parked

You'll have your feature1 work in an up-to-date codebase but will leave you with a slightly confusing history, especially when you merge the parked branch back into master:

A - B - H - I - J - K - L - M - N - O - Q --- S master
      \ C - D - E - F - G -----------\ P - R /

It's really not too bad but we can make it a bit neater by rebasing onto origin/master rather than merging, which would result in this instead:

A - B - H - I - J - K - L - M - N - O ------------------/ U master & origin/master
                                     \ P - Q - R - S - T parked

This way doesn't require any feature flagging and keeps all the feature1 work together in a single merge, which can be collapsed in the log with git log --first-parent. That can make it easier to read the history at times, if you know which feature you want to look in (or don't want to look in) it's easy to find.

The downside of rebasing is that you're rewriting history, you no longer have a true reflection of exactly what happened. Your feature1 commits would be rewritten and would in fact be new commits; everyone would have to git reset --hard origin/parked afterwards to get a consistent history and they'll need to take care not to lose any uncommitted / unpushed work in the process.

Ultimately the correct approach depends on how you work, how many people are working with the repo, and your level of comfort with git.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
Calum Halpin
  • 1,945
  • 1
  • 10
  • 20
  • Thanks for you answer; as far as I can make out, you are also recommending that I start by merging from `trunk` to `parked`. You go on to discuss two approaches to move the work onto `master` once it is complete. Have I got this right? – nurdglaw Jul 25 '19 at 08:05
  • No, I was discussing the consequences of merging `origin/master` to `parked`, merging `parked` to `master`, or rebasing `parked` onto `master` from where you are now. I wasn't advocating any particular approach; the best one depends on your workflow, size of your team, knowledge of / comfort with git etc. – Calum Halpin Jul 25 '19 at 08:44
  • OK, thanks. I'm not completely clear on the situation you're describing, what problems may arise and what a rebase does to resolve them. It seems that I'm at commit P; I'll do a bit more work and commit Q and R to `parked`. I read the penultimate diagram as showing that something happens between R and S - a merge back into `master`? Then it seems that commits S and T are made on `master` and something else happens with the two branches. Your last diagram seems to show what happens if I rebase from 'parked` to `master` after commit T. Am I mis-reading the diagrams or reading too much into them? – nurdglaw Jul 25 '19 at 11:31
  • Ah! I had overlooked the penultimate paragraph that you have added. I thought that's what was going on. I don't like the idea of "rewriting history", and I think that the extra `git reset --hard` that everyone would have to do after a `git rebase` rules out this approach in our case. Thank you again, @Calum Halpin for your answer, and especially, your clarifications. – nurdglaw Jul 25 '19 at 12:00
  • No problem. To try to answer your previous comment: The penultimate diagram is supposed to show the result of merging `master` to `parked`, working on `parked` then merging it back into `master` but I think I've made a mess of it, I'll redo that one. The last diagram is what you'd get if you rebased `parked` onto `master` now, the letters changed because they have become different commits. – Calum Halpin Jul 25 '19 at 12:27