[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Merge changes made in a branch of repository-1 to a branch in reposi

From: MVR Raju
Subject: Re: Merge changes made in a branch of repository-1 to a branch in repository-2 ?
Date: 30 Jan 2003 16:49:06 -0000

Thanks a lot Mr. Pierre Asselin. I could not find your reply for this thread at info-cvs mailing list. I have copied your message for the benifit of other readers.

MVR Raju

=========== Pierre Asselin wrote: ===========================
In <address@hidden> "MVR Raju" <address@hidden> writes:

I have two repositories on a single system (just an internal
reason).  Let's call them as rep-1 and rep-2. I have several
branches on both of them, and  say one of them on rep-1 is
branch_A,  and  on rep-2 is branch_B.
I would like to merge changes made on either mainline of rep-1 or
branch_A to either mainline of rep-2 or branch_B.

Very difficult. The two repositories are independent. There is no easy way to communicate between the two. You should take the simpler of the two and (painfully) fold all interesting changes in the other, and do
all future work off the consolidated repository.

1. cvs -d <path_to_rep-1> checkout -r <rep-1_branch_A> <file>

Only one file?  Hm.  Here's what I would expect to do:

    cd some/where/quiet
    cvs -d path_to_rep-1 checkout module_name
    mv module_name module_name_1
    cvs -d path_to_rep-2 checkout module_name
    mv module_name module_name_2

This gives you two working copies ("sandboxes") named "module_name_1" and "module_name_2", one from each repository. Both sandboxes are on the trunk, but that can be changed at will with normal CVS commands.

Now, to repeat:
I would like to merge changes made on either mainline of rep-1 or
branch_A to either mainline of rep-2 or branch_B.

Is there any reason to believe that the two repositories were once identical? You need some sort of starting point. Let's assume that you have a tag BASE_1 in repository 1 and a tag BASE_2 in repository 2
that identify the common ancestor.  That is, if you do

    cd module_name_1
    cvs update -rBASE_1
    cd ../module_name_2
    cvs update -rBASE_2

you get two identical filesets. Don't run the commands, this is just to set the stage. If you don't have the tags, create them. If you don't have two revision numbers on which to plant the tags, give up now:
the two repos are completely different and CVS can't help you.

Ok. Now let's merge the trunk work of repo_1 since BASE_1 to the trunk of repo_2. The process would go like this; all the commands
are issued from sandbox 2.

    cd module_name_2
    cvs update -rBASE_2

sandbox 2 is now at the common ancestor release. It is locked to that release tag and you can't commit changes to it, you must first create a
working branch.

    cvs tag -b repo_1_work
    cvs update -rrepo_1_work

Sandbox 2 still holds the common ancestor, but it is now at the start of a new branch. You can commit changes to that branch. Meanwhile, you still have sandbox 1 one directory away, sitting at the end of its
trunk.  Overlay the sandbox_2 files by the sandbox_1 files.

    cp ../module_name_1/fileA fileA
    cp ../module_name_1/fileB fileB
    cp ../module_name1/dirC/fileD dirC/fileD

etc.  You could do a mass copy, but you have to leave the CVS/
subdirectories unscathed, so be careful.

Situation now: sandbox 2 has a copy of repository 1's trunk. CVS thinks all the files have been modified but it doesn't know that the changes come from the other repository. As far as it is concerned, you could have made all those changes by hand. A "cvs -nq update" will confirm
that the files appear modified.

Commit the changes.

    cvs commit

Sandbox 2 now has a non-empty branch "repo_1_work", the tip of which
is identical to repository 1's trunk.  Tag that.

    cvs tag repo_1_work_2003_01_26

Now put sandbox 2 back to its trunk.

    cvs update -A

All your edits go away, the files go back to the state they had as of the last trunk commit in repository 2. It's as if nothing had happened, except that you have a copy of the other repository's trunk tip hidden
on a side branch.  You can now attempt your merge:

    cvs tag pre_cross_merge
    cvs update -jBASE_2 -jrepo_1_work_2003_01_26

Two "-j" options. This says: take the differences between BASE_2 and repo_1_work_2003_01_26 and apply them to the current copies. Your sandbox is now in a broken state, containing a mix of the work from BASE_1 to tip on repo 1 and the work from BASE_2 to tip on repo 2. Your repository 2 is still fine, the mess is only in sandbox 2. Try to resolve the conflicts, build and test. If you manage to clean up the
mess, you can commit.

    cvs commit
    cvs tag post_cross_merge

Your question implied that you want to do this routinely, but you can see that this is not going to scale very well. There is a lot of manual work and it's easy to make a mistake. You can never be sure that your cross-sandbox overlays have been done right, because cvs diff only works within one repository. Also, if you want some intermediate state on repo 1's trunk between BASE_1 and the present, it's now too late because
you've already gone from BASE_1 to tip in one step.

Also, if you think you're going to merge changes *back and forth*
between the two repositories, give that up now.  It doesn't work
well even within a single repository.

Summary: your best course of action is to retire one of the repositories
as soon as possible.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]