views:

501

answers:

4

We use one branch for the our upcoming release, and trunk for the next release (later).

For example: v1.1 -> v1.2 -> trunk (Where v1.1 is in production, v1.2 is the upcoming release and trunk will turn into v1.3 closer to release).

While working on the upcoming release, we check in using SVN (TortoiseSVN). The problem with this is that all check ins must be manually merged to trunk if it's a change that will be relevant for later releases as well (Most changes in other words).

The problem is that when the developers are stressed, they tend to forget to merge. The consequence of this is that a fix which is done in a branch may need to be fixed again later because the developer forgot to merge the fix from branch to trunk

Is there a way to automatically merge the code to trunk when a check-in is made to the branch?

A: 

Hmm, this is awfully similar to what we do here, but I'm not aware of any way to currently do this.

Typically, errors like this are caught in our code-review process.

I would wonder what would happen in the case of a merge conflict, and when that happens, how would it get resolved.

Jim B
We have a huge code base and we are in a process of finding the missing merges. Doing reintegrate branch gives a list of possible candidates for forgotten merges. However, a lot of the conflicts are just refactoring of code or other major changes in the latter version of the file.
Unyttig
Sounds to me like you'd want to merge a range of revisions. Either way, this appears like it will be very manually intensive. Good luck.
Jim B
A: 

svnmerge.py will keep track of all your merges for you.

bmargulies
Since subversion 1.5 there's no longer a need for svnmerge.py. It was used to track merge info in 1.4
Sander Rijken
Still needed if you want to merge a branch more than once.
bmargulies
+2  A: 

No and I would strictly discourage from it. There are so many possible side effects that you will encouter with an automatic merging.

How would you resolve conflicts? The more development means more changes in branch and trunk, means more conflicts at merging. The merge must be done by hand.

What about unwanted merges? There are things (like changing version numbers, dependencies, etc.) you don't want to merge back. With an automatic merge you had to reverse merge the merges, wich causes more confusion and work.

With the merge tracking feature of SVN 1.5 you'll get good information and see if someone hasn't merged his/her changes back to trunk. You just have to use it properly.

Hardcoded
A: 

you cannot really automate it: even if there are no outright conflicts, the merge might result in non-working code.

two possibilities for future improvements, in increasing order of preference:

one: commit to trunk, have someone appointed to cherry-pick revisions into the release branch

two: switch to mercurial. srsly. it's very svn-like, and it's impossible to forget a merge, since merging branch A into branch B means adding into B all commits that are in A but not in B

# alice edits some files and commits two revisions
# into her repository, then pushes them into the master
alice ~/wc/stable % hg ci
alice ~/wc/stable % hg ci
alice ~/wc/stable % hg push
pushing to http://repo/stable
searching for changes
...

# bobby tries to push, but oops, his copy is stale
bobby ~/wc/stable % hg ci
bobby ~/wc/stable % hg ci
bobby ~/wc/stable % hg ci
bobby ~/wc/stable % hg push
pushing to http://repo/stable
searching for changes
abort: push creates new remote heads!
(did you forget to merge? use push -f to force)

# bobby must augment his repository such that a push
# to the master will leave the master with a single
# head.  this is achieved by pulling changes from
# the master, which will cause *his* repository to have
# two "head" revisions:
bobby ~/wc/stable % hg pull
searching for changes
...
added 2 changesets with 4 changes to 4 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)

# he will now merge the heads to reduce them to a single
# head.  pushing that into the master will be ok (since
# the result of such a push is a single head)
bobby ~/wc/stable % hg merge
bobby ~/wc/stable % hg ci
bobby ~/wc/stable % hg push
# ok!

you might say this is different from merging between branches, but in mercurial, every working copy is effectively a branch, and both situations are handled with a single set of commands:

alice ~/wc/stable % hg ci
alice ~/wc/stable % hg push
alice ~/wc/stable % logout
# alice went home without merging to trunk

bobby ~/wc/stable % hg pull -u
# alice's changeset is now his (only) head
# he edits a file, commits it, and pushes
bobby ~/wc/stable % hg ci
bobby ~/wc/stable % hg push
# his sole commit goes to the master
# the push is ok since it results in a single head
# bobby goes on to merge stable to trunk
bobby ~/wc/stable % cd ../trunk
bobby ~/wc/trunk % hg pull -u
# pulls changes from trunk master
bobby ~/wc/trunk % hg pull http://repo/stable
# pulls all changesets that are in stable but
# not in (this working copy of) trunk
bobby ~/wc/trunk % hg merge
bobby ~/wc/trunk % hg ci
bobby ~/wc/trunk % hg push

this working copy above is important, but a stale copy won't bite you: if bobby's working copy was stale WRT the master, the push would fail and prompt him to merge his previous merge with master's new changes before retrying.

just somebody