예제 #1
0
        public void Process(ExecutionContext context)
        {
            Guid     sourceId = (Input as IMerge).FromId;
            CmdStore cs       = context.Store;
            Branch   target   = cs.Current;
            Branch   source   = cs.FindBranch(sourceId);

            if (source == null)
            {
                throw new ApplicationException($"Cannot locate branch {sourceId}");
            }

            // Merges can only be done between branches that are part
            // of the local store (fetches from remote stores should
            // involve a totally different set of branches)
            //if (target.Info.StoreId != source.Info.StoreId)
            //    throw new NotSupportedException("Attempt to merge with a remote store");

            // Determine the first command that needs to be merged from
            // the source branch. The source branch doesn't know anything
            // about merges that have already been done, so figuring this
            // out involves scanning back from the end of the target branch
            // to locate the last merge (if any).

            // How far we go back depends on whether we're merging from
            // a child branch to its parent, or vice versa. If the target
            // is the child we go back as far as command 0. If the target
            // is the parent, we go back as far the command that followed
            // the branch start point.

            bool targetIsParent = target.Id.Equals(source.Info.ParentId);

            // Define the range of commands to be merged from the source

            uint minCmd = 0;

            if (targetIsParent)
            {
                // Merging into the parent, so start from the command immediately
                // after the last command that was previously merged (or 0 if this
                // is the first time the parent has merged from the child).

                if (target.Info.LastMerge.TryGetValue(sourceId, out MergeInfo mi))
                {
                    minCmd = mi.ChildCount;
                }
            }
            else
            {
                // Merging from the parent into the child, so start from the command
                // immediately after the last command that was previously merged (it
                // could potentially be 0)

                minCmd = target.Info.RefreshCount;
            }

            uint maxCmd = (uint)source.Info.CommandCount - 1;

            // TODO: Round about here we need to actually include the new stuff
            // as part of the current stream. Replaying the commands may then
            // lead to some sort of conflict (things are not guaranteed to work),
            // so there needs to be some way to preview the results.

            // Write the command data
            Input.Add(nameof(IMerge.MinCmd), minCmd);
            Input.Add(nameof(IMerge.MaxCmd), maxCmd);
            target.SaveData(Input);
        }